diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6c01622..a4effa9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,76 +1,84 @@ // For format details, see https://containers.dev/implementors/json_reference/ { - "name": "sky_viewer_dev", - "dockerComposeFile": [ - "../docker-compose.local.yml", - "docker-compose.yml" - ], - "init": true, - "mounts": [ - { - "source": "./.devcontainer/bash_history", - "target": "/home/dev-user/.bash_history", - "type": "bind" + "name": "sky_viewer_dev", + "dockerComposeFile": [ + "../docker-compose.local.yml", + "docker-compose.yml" + ], + "init": true, + "mounts": [ + { + "source": "./.devcontainer/bash_history", + "target": "/home/dev-user/.bash_history", + "type": "bind" + }, + { + "source": "~/.ssh", + "target": "/home/dev-user/.ssh", + "type": "bind" + }, + { + "source": "..", + "target": "/workspaces", + "type": "bind" + } + ], + // Tells devcontainer.json supporting services / tools whether they should run + // /bin/sh -c "while sleep 1000; do :; done" when starting the container instead of the container’s default command + "overrideCommand": false, + "service": "vscode", + // "remoteEnv": {"PATH": "/home/dev-user/.local/bin:${containerEnv:PATH}"}, + // "remoteUser": "dev-user", + // The optional 'workspaceFolder' property is the path VS Code should open by default when + // connected. This is typically a file mount in .devcontainer/docker-compose.yml + "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", + // Set *default* container specific settings.json values on container create. + // Features to add to the dev container. More info: https://containers.dev/features. + "features": { + "ghcr.io/devcontainers/features/node:1": {}, + "ghcr.io/devcontainers/features/github-cli:1": {} + }, + "customizations": { + "vscode": { + "settings": { + "editor.formatOnSave": true, + "[python]": { + "analysis.autoImportCompletions": true, + "analysis.typeCheckingMode": "basic", + "defaultInterpreterPath": "/usr/local/bin/python", + "editor.codeActionsOnSave": { + "source.organizeImports": "always" + }, + "editor.defaultFormatter": "charliermarsh.ruff", + "languageServer": "Pylance", + "linting.enabled": true, + "linting.mypyEnabled": true, + "linting.mypyPath": "/usr/local/bin/mypy", }, - { - "source": "~/.ssh", - "target": "/home/dev-user/.ssh", - "type": "bind" + "[javascript]": { + "editor.tabSize": 2 }, - { - "source": "..", - "target": "/workspaces", - "type": "bind" - } - ], - // Tells devcontainer.json supporting services / tools whether they should run - // /bin/sh -c "while sleep 1000; do :; done" when starting the container instead of the container’s default command - "overrideCommand": false, - "service": "vscode", - // "remoteEnv": {"PATH": "/home/dev-user/.local/bin:${containerEnv:PATH}"}, - // "remoteUser": "dev-user", - // The optional 'workspaceFolder' property is the path VS Code should open by default when - // connected. This is typically a file mount in .devcontainer/docker-compose.yml - "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", - // Set *default* container specific settings.json values on container create. - "customizations": { - "vscode": { - "settings": { - "editor.formatOnSave": true, - "[python]": { - "analysis.autoImportCompletions": true, - "analysis.typeCheckingMode": "basic", - "defaultInterpreterPath": "/usr/local/bin/python", - "editor.codeActionsOnSave": { - "source.organizeImports": "always" - }, - "editor.defaultFormatter": "charliermarsh.ruff", - "languageServer": "Pylance", - "linting.enabled": true, - "linting.mypyEnabled": true, - "linting.mypyPath": "/usr/local/bin/mypy", - } - }, - // https://code.visualstudio.com/docs/remote/devcontainerjson-reference#_vs-code-specific-properties - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "davidanson.vscode-markdownlint", - "mrmlnc.vscode-duplicate", - "visualstudioexptteam.vscodeintellicode", - "visualstudioexptteam.intellicode-api-usage-examples", - // python - "ms-python.python", - "ms-python.vscode-pylance", - "charliermarsh.ruff", - // django - "batisteo.vscode-django" - ] - } - }, - // Uncomment the next line if you want start specific services in your Docker Compose config. - // "runServices": [], - // Uncomment the next line if you want to keep your containers running after VS Code shuts down. - // "shutdownAction": "none", - // Uncomment the next line to run commands after the container is created. - "postCreateCommand": "cat .devcontainer/bashrc.override.sh >> ~/.bashrc" + }, + // https://code.visualstudio.com/docs/remote/devcontainerjson-reference#_vs-code-specific-properties + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "davidanson.vscode-markdownlint", + "mrmlnc.vscode-duplicate", + "visualstudioexptteam.vscodeintellicode", + "visualstudioexptteam.intellicode-api-usage-examples", + // python + "ms-python.python", + "ms-python.vscode-pylance", + "charliermarsh.ruff", + // django + "batisteo.vscode-django" + ] + } + }, + // Uncomment the next line if you want start specific services in your Docker Compose config. + // "runServices": [], + // Uncomment the next line if you want to keep your containers running after VS Code shuts down. + // "shutdownAction": "none", + // Uncomment the next line to run commands after the container is created. + "postCreateCommand": "cat .devcontainer/bashrc.override.sh >> ~/.bashrc" } \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8f85aaa..2c598e4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,6 +42,16 @@ repos: - id: djlint-reformat-django - id: djlint-django + - repo: https://github.com/pre-commit/mirrors-eslint + rev: v8.56.0 + hooks: + - id: eslint + name: Eslint + entry: bash -c 'cd frontend && npm run lint' + additional_dependencies: + - eslint@8.28.0 + - eslint-config-next@14.2.7 + # sets up .pre-commit-ci.yaml to ensure pre-commit dependencies stay up to date ci: autoupdate_schedule: weekly diff --git a/backend/config/settings/base.py b/backend/config/settings/base.py index 674c43a..769df82 100644 --- a/backend/config/settings/base.py +++ b/backend/config/settings/base.py @@ -152,7 +152,7 @@ # https://docs.djangoproject.com/en/dev/ref/settings/#static-root STATIC_ROOT = str(BASE_DIR / "staticfiles") # https://docs.djangoproject.com/en/dev/ref/settings/#static-url -STATIC_URL = "/static/" +STATIC_URL = "/django_static/" # https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS STATICFILES_DIRS = [str(APPS_DIR / "static")] # https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders diff --git a/backend/config/settings/local.py b/backend/config/settings/local.py index 5bd2a34..066b208 100644 --- a/backend/config/settings/local.py +++ b/backend/config/settings/local.py @@ -14,7 +14,7 @@ default="nFK0g6mvH2IjeawVrOykaac3UD9hRLJoWzmlnWiDlJM1joaFM4KUQWiGZPad7pRc", ) # https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts -ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1"] # noqa: S104 +ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1", "srvapi"] # noqa: S104 # CACHES # ------------------------------------------------------------------------------ diff --git a/backend/config/urls.py b/backend/config/urls.py index 907f372..4848f2c 100644 --- a/backend/config/urls.py +++ b/backend/config/urls.py @@ -11,17 +11,17 @@ from rest_framework.authtoken.views import obtain_auth_token urlpatterns = [ - path("", TemplateView.as_view(template_name="pages/home.html"), name="home"), - path( - "about/", - TemplateView.as_view(template_name="pages/about.html"), - name="about", - ), + # path("", TemplateView.as_view(template_name="pages/home.html"), name="home"), + # path( + # "about/", + # TemplateView.as_view(template_name="pages/about.html"), + # name="about", + # ), # Django Admin, use {% url 'admin:index' %} path(settings.ADMIN_URL, admin.site.urls), # User management - path("users/", include("sky_viewer.users.urls", namespace="users")), - path("accounts/", include("allauth.urls")), + # path("users/", include("sky_viewer.users.urls", namespace="users")), + # path("accounts/", include("allauth.urls")), # Your stuff: custom urls includes go here # ... # Media files diff --git a/compose/local/django/celery/flower/start b/compose/local/django/celery/flower/start index cebb622..e76c085 100644 --- a/compose/local/django/celery/flower/start +++ b/compose/local/django/celery/flower/start @@ -13,4 +13,4 @@ echo 'Starting flower' exec watchfiles --filter python celery.__main__.main \ --args \ - "-A config.celery_app -b \"${CELERY_BROKER_URL}\" flower --basic_auth=\"${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}\"" + "-A config.celery_app -b \"${CELERY_BROKER_URL}\" flower --basic_auth=\"${CELERY_FLOWER_USER}:${CELERY_FLOWER_PASSWORD}\" --url-prefix=flower" diff --git a/compose/production/react/Dockerfile b/compose/production/react/Dockerfile new file mode 100644 index 0000000..627a684 --- /dev/null +++ b/compose/production/react/Dockerfile @@ -0,0 +1,18 @@ +FROM node:22.7.0-bookworm-slim AS base + +ENV GENERATE_SOURCEMAP=false +ENV NODE_OPTIONS=--max_old_space_size=8192 + +COPY ./compose/local/react/start /start +RUN sed -i 's/\r$//g' /start +RUN chmod +x /start + +RUN mkdir /app && chown -R node:node /app + +COPY ./frontend /app +WORKDIR /app + +USER node + +RUN yarn -v +RUN yarn --non-interactive --ignore-optional --network-timeout 500000 diff --git a/compose/production/react/start b/compose/production/react/start new file mode 100644 index 0000000..42c0107 --- /dev/null +++ b/compose/production/react/start @@ -0,0 +1,7 @@ +#!/bin/bash + +set -o errexit +set -o pipefail +set -o nounset + +yarn dev diff --git a/docker-compose.local.yml b/docker-compose.local.yml index b7270e0..de7bc18 100644 --- a/docker-compose.local.yml +++ b/docker-compose.local.yml @@ -4,12 +4,12 @@ volumes: sky_viewer_local_redis_data: {} services: - django: &django + backend: &backend build: context: ./ dockerfile: ./compose/local/django/Dockerfile image: sky_viewer_local_django - container_name: sky_viewer_local_django + container_name: sky_viewer_local_backend depends_on: - postgres - redis @@ -19,10 +19,17 @@ services: env_file: - ./.envs/.local/.django - ./.envs/.local/.postgres - ports: - - '80:8000' command: /start + frontend: + image: node:22.7.0-bookworm-slim + container_name: sky_viewer_local_react + user: 1000:1000 + working_dir: /app + volumes: + - ./frontend:/app:z + command: yarn dev + postgres: build: context: . @@ -35,21 +42,35 @@ services: env_file: - ./.envs/.local/.postgres + nginx: + image: nginx:latest + ports: + - ${PORT:-80}:80 + volumes: + # Arquivo de configuração do Ngnix para este ambiente. + - ${PROJ_DIR:-.}/nginx-proxy.conf:/etc/nginx/conf.d/default.conf:ro + depends_on: + - backend + - frontend + - flower + - mailpit + mailpit: image: docker.io/axllent/mailpit:latest container_name: sky_viewer_local_mailpit + environment: + - MP_WEBROOT=/mailpit/ ports: - "8025:8025" redis: image: docker.io/redis:6 container_name: sky_viewer_local_redis - volumes: - sky_viewer_local_redis_data:/data celeryworker: - <<: *django + <<: *backend image: sky_viewer_local_celeryworker container_name: sky_viewer_local_celeryworker depends_on: @@ -60,7 +81,7 @@ services: command: /start-celeryworker celerybeat: - <<: *django + <<: *backend image: sky_viewer_local_celerybeat container_name: sky_viewer_local_celerybeat depends_on: @@ -71,7 +92,7 @@ services: command: /start-celerybeat flower: - <<: *django + <<: *backend image: sky_viewer_local_flower container_name: sky_viewer_local_flower ports: diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/frontend/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..fd3dbb5 --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000..0dc9ea2 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,36 @@ +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 +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. + +## 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. diff --git a/frontend/app/about/page.js b/frontend/app/about/page.js new file mode 100644 index 0000000..3b82668 --- /dev/null +++ b/frontend/app/about/page.js @@ -0,0 +1,28 @@ +import * as React from 'react'; +import Typography from '@mui/material/Typography'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import NextLink from 'next/link'; + +export default function About() { + return ( + + + About Page + + + + + + ); +} diff --git a/frontend/app/contact/page.js b/frontend/app/contact/page.js new file mode 100644 index 0000000..6f688df --- /dev/null +++ b/frontend/app/contact/page.js @@ -0,0 +1,28 @@ +import * as React from 'react'; +import Typography from '@mui/material/Typography'; +import Box from '@mui/material/Box'; +import Button from '@mui/material/Button'; +import NextLink from 'next/link'; + +export default function Contact() { + return ( + + + Contact Page + + + + + + ); +} diff --git a/frontend/app/favicon.ico b/frontend/app/favicon.ico new file mode 100644 index 0000000..718d6fe Binary files /dev/null and b/frontend/app/favicon.ico differ diff --git a/frontend/app/globals.css b/frontend/app/globals.css new file mode 100644 index 0000000..4ce4a99 --- /dev/null +++ b/frontend/app/globals.css @@ -0,0 +1,10 @@ +html, +body { + max-width: 100vw; + overflow-x: hidden; +} + +a { + color: inherit; + text-decoration: none; +} diff --git a/frontend/app/layout.js b/frontend/app/layout.js new file mode 100644 index 0000000..20c2e45 --- /dev/null +++ b/frontend/app/layout.js @@ -0,0 +1,47 @@ +import "./globals.css"; +import '@fontsource/roboto/300.css'; +import '@fontsource/roboto/400.css'; +import '@fontsource/roboto/500.css'; +import '@fontsource/roboto/700.css'; +import { AppRouterCacheProvider } from '@mui/material-nextjs/v13-appRouter'; +import { ThemeProvider } from '@mui/material/styles'; +import Box from "@mui/material/Box"; +import theme from './theme'; +import Header from "@/components/Header"; +import Footer from "@/components/Footer"; +import { Inter } from "next/font/google"; +import CssBaseline from '@mui/material/CssBaseline'; +const inter = Inter({ subsets: ["latin"] }); + +export const metadata = { + title: "Create Next App", + description: "Generated by create next app", +}; + +export default function RootLayout({ children }) { + return ( + + + + + +
+ + {children} + +