Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React boilerplate #123

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ trim_trailing_whitespace = false
indent_size = 2
tab_width = 2

[{*.js, *.vue}]
[{*.js, *.vue, *.ts, *.tsx}]
# General
indent_size = 2
tab_width = 2
Expand Down
4 changes: 4 additions & 0 deletions bin/fresh_install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ docker-compose up -d
# necessary

# Make frontend assets
#if [ -f "src/frontend/next.config.js" ]; then
#fi
docker-compose exec -T builder yarn

docker-compose exec -T builder yarn run generate

# setup database and gather assets; make sure we run this _after_ building frontend assets
Expand Down
12 changes: 7 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ services:
env_file: .env
volumes:
- ./src/backend:/app
- ./src/frontend/build:/frontend:delegated
# skeletor.sh defines the static volume
- STATIC_VOLUME
ports:
- 8000:8000
depends_on:
Expand Down Expand Up @@ -66,11 +67,12 @@ services:
- 6379:6379
logging: *default-logging
volumes:
- ./volumes/redis:/data
- ./docker/redis.conf:/redis.conf
- ./docker/sysctl.conf:/etc/sysctl.conf
- redis_data:/data
# - ./docker/redis.conf:/redis.conf
# - ./docker/sysctl.conf:/etc/sysctl.conf
restart: unless-stopped
command: redis-server /redis.conf --bind 0.0.0.0
#command: redis-server /redis.conf --bind 0.0.0.0

volumes:
db_data:
redis_data:
2 changes: 1 addition & 1 deletion docker/Dockerfile.frontend
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:12
FROM node:NODE_VERSION

RUN mkdir /app

Expand Down
24 changes: 20 additions & 4 deletions skeletor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,20 +117,23 @@ cat << EOF
${underline}Available frontends:${reset}
${green}${bold}1. Vue (web only) [recommended/default]${reset}
2. Vue (web) + React Native (mobile)
3. Nextjs (web only)

EOF

FRONTEND_WEB_VUEJS=1
FRONTEND_WEB_VUEJS_MOBILE_REACT_NATIVE=2
FRONTEND_WEB_NEXTJS_REACT=3

read -p "Please select your preferred frontend: ${green}" FRONTEND
echo "${reset}"

# Set default to 1 if no input given
FRONTEND=${FRONTEND:-1}
echo ${FRONTEND}

if [[ $FRONTEND -gt 2 ]]; then
echo -e "\n${red}${bold}ERROR: Invalid FRONTEND choice... must be 1 or 2!${reset}"
if [[ $FRONTEND -gt 3 ]]; then
echo -e "\n${red}${bold}ERROR: Invalid FRONTEND choice... must be 1 2, or 3!${reset}"
exit 2
fi

Expand Down Expand Up @@ -158,11 +161,24 @@ sed -i '' '1,/^-----------------$/d' README.md
grep -rl "SKELETOR_NAME_PLACEHOLDER" . | xargs sed -i "" -e "s@SKELETOR_NAME_PLACEHOLDER@$PROJECT_NAME@g"


# Remove mobile dir if we don't need it
# Remove mobile dir if we don't need it. set node version in Dockerfile.frontend
NODE_VERSION=12
# - ./src/frontend/build:/frontend:delegated
VOLUME_DIR_SEARCH="STATIC_VOLUME"
VOLUME_DIR="\.\/src\/frontend\/build:\/frontend:delegated"
if [[ $FRONTEND == "$FRONTEND_WEB_VUEJS" ]]; then
rm -rf src/mobile
fi

elif [[ $FRONTEND == "$FRONTEND_WEB_NEXTJS_REACT" ]]; then
rm -rf src/mobile
rm -rf src/frontend
cp -r src/react_frontend src/frontend
rm -rf src/react_frontend
NODE_VERSION=19
VOLUME_DIR="./src/frontend/build:/frontend/generated/static:delegated"
fi
sed -i -e "s/^FROM node:NODE_VERSION/FROM node:${NODE_VERSION}/g" docker/Dockerfile.frontend
sed -i -e "s/${VOLUME_DIR_SEARCH}/${VOLUME_DIR}/g" docker-compose.yml

# Remove Skeletor specific stuff
echo -e "Cleaning up stuff...\n"
Expand Down
16 changes: 16 additions & 0 deletions src/backend/apps/users/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.contrib.auth import authenticate, login, logout, get_user_model
from django.contrib.auth.tokens import default_token_generator
from django.http import JsonResponse
from django.utils.encoding import force_str
from django.utils.http import urlsafe_base64_decode
from rest_framework import views, status, viewsets
Expand Down Expand Up @@ -51,6 +52,21 @@ def post(self, request, format=None):
return Response(status=status.HTTP_200_OK)


class UserProfileView(views.APIView):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi I added something like this to master, so can prob pull this -- hit /api/auth/user/ like how it used to work

permission_classes = [IsAuthenticated]

def get(self, request, format=None):
from pprint import pprint
pprint(request.__dict__)
if request.user:
print('user found')
return JsonResponse({
"username": "you_are_admin",
"id": 1,
"dummy_data": "testing data",
})


class UserPasswordResetViewSet(viewsets.ViewSet):
serializer_class = PasswordResetSerializer
permission_classes = [AllowAny]
Expand Down
23 changes: 20 additions & 3 deletions src/backend/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,21 @@
)

ROOT_URLCONF = 'urls'

template_dirs = []
if os.path.exists('/frontend/generated/'):
template_dirs.append('/frontend/generated/')
if os.path.exists('/frontend/out/'):
template_dirs.append('/frontend/out')
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates'),
'/frontend/generated',

# We "collectstatic" either a Vue or React frontend, which pushes an
# index.html to this directory that we can serve from urls.py on `/` endpoint
'staticfiles/',
*template_dirs
],
'APP_DIRS': True,
'OPTIONS': {
Expand Down Expand Up @@ -150,6 +158,10 @@
SESSION_COOKIE_HTTPONLY = True


SESSION_COOKIE_DOMAIN = os.environ.get("SESSION_COOKIE_DOMAIN", "localhost:8000")
SESSION_COOKIE_SAMESITE = os.environ.get('SESSION_COOKIE_SAMESITE', 'None')


# =============================================================================
# Whitenoise
# =============================================================================
Expand All @@ -166,10 +178,15 @@
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
'/frontend/generated/static',
# '/frontend/generated/static',
)
if os.path.exists('/frontend/generated/static'):
STATICFILES_DIRS += ('/frontend/generated/static',)
if os.path.exists('/frontend/out/'): #
STATICFILES_DIRS += ('/frontend/out',)
MEDIA_ROOT = os.path.join(BASE_DIR, 'uploads')
MEDIA_URL = '/media/'

Expand Down
3 changes: 2 additions & 1 deletion src/backend/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.views.generic import TemplateView
from rest_framework import routers

from users.views import LoginView, LogoutView, UserPasswordResetViewSet
from users.views import LoginView, LogoutView, UserPasswordResetViewSet, UserProfileView

router = routers.DefaultRouter()

Expand All @@ -23,6 +23,7 @@
# TODO: Add these auth endpoints to api docs, like password reset ??
path('api/auth/login/', LoginView.as_view(), name="rest_login"),
path('api/auth/logout/', LogoutView.as_view(), name="rest_logout"),
path('api/users/me/', UserProfileView.as_view(), name="user_profile_view"),

# Django built in
path('admin/', admin.site.urls),
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export default {
*/
vuetify: vuetify_config,
router: {
mode: process.env.NODE_ENV === 'production' ? 'hash' : 'history',
mode: process.env.NODE_ENV === 'development' ? 'history' : 'hash',
middleware: ['auth']
},
/*
Expand Down
3 changes: 3 additions & 0 deletions src/react_frontend/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
36 changes: 36 additions & 0 deletions src/react_frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
34 changes: 34 additions & 0 deletions src/react_frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.

[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.

The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
17 changes: 17 additions & 0 deletions src/react_frontend/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const withPlugins = require('next-with-plugins')

/** @type {import('next').NextConfig} */
const nextConfig = withPlugins({
reactStrictMode: true,
swcMinify: true,
env: {
NEXT_PUBLIC_BACKEND_URL: 'http://localhost:8000'
},
pageFolder: 'src/pages',
images: { unoptimized: true },
plugins: [
'next-stylus'
]
})

module.exports = nextConfig
33 changes: 33 additions & 0 deletions src/react_frontend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "ckc_project",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"generate": "next build && next export",
"lint": "next lint"
},
"devDependencies": {
"@types/node": "18.11.9",
"@types/react": "18.0.25",
"@types/react-dom": "18.0.9"
},
"dependencies": {
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@mui/icons-material": "^5.11.0",
"@mui/material": "^5.11.0",
"axios": "1.2.0",
"eslint-config-next": "^13.0.7",
"material-ui": "^0.20.2",
"next": "13.0.5",
"next-stylus": "^0.0.2",
"next-with-plugins": "^0.0.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"stylus": "^0.59.0",
"typescript": "4.9.3"
}
}
Binary file added src/react_frontend/public/favicon.ico
Binary file not shown.
4 changes: 4 additions & 0 deletions src/react_frontend/public/vercel.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/react_frontend/src/assets/images/ckc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions src/react_frontend/src/components/layout/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, {useMemo} from 'react';
import Link from 'next/link';
import Image from "next/image";
import logo from '../../../assets/images/ckc.png';
import {AppBar, Toolbar, Typography} from '@mui/material';
import styles from './header.module.css'

function Header() {
return (
<AppBar position="static">
<Toolbar className="d-flex justify-between">
<Link href="/">
<Image src={logo} alt="Logo" className={styles.image} />
</Link>
<div className="d-flex">
<Link className={styles.link} href="/">
Home
</Link>
<Link className={styles.link} href="/">
Pricing
</Link>
<Link className={styles.link} href="/">
Projects
</Link>
<Link className={styles.link} href="/">
Settings
</Link>
<Link className={styles.link} href="/harvey_login">
Login
</Link>
</div>
</Toolbar>
</AppBar>
);
}

export default Header;
11 changes: 11 additions & 0 deletions src/react_frontend/src/components/layout/header/header.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.image {
width: 160px;
height: 50px;
}

.link {
text-decoration: none;
margin-right: 24px;
font-size: 24px;
color: white;
}
Loading