diff --git a/.env.example b/.env.example index 23dee0b..58d7a88 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,9 @@ VITE_API_BASE_URL= VITE_MATOMO_URL= VITE_MATOMO_SITE_ID= +VITE_MAINTENANCE_MODE= # nothing = false, anything else = true +VITE_MAINTENANCE_MODE_MESSAGE="ChessScribe is currently undergoing maintenance. Some features may be unavailable." DISCORD_CONTACT_WEBHOOK= DISCORD_ERROR_LOG_WEBHOOK= -LICHESS_CLIENT_ID= +LICHESS_CLIENT_ID= \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8b25bb5..c520d81 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ dist-ssr .vinxi __unconfig* todos.json +data diff --git a/.vscode/settings.json b/.vscode/settings.json index 70dd163..b001961 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,35 +1,35 @@ { - "files.watcherExclude": { - "**/routeTree.gen.ts": true - }, - "search.exclude": { - "**/routeTree.gen.ts": true - }, - "files.readonlyInclude": { - "**/routeTree.gen.ts": true - }, - "[javascript]": { - "editor.defaultFormatter": "biomejs.biome" - }, - "[javascriptreact]": { - "editor.defaultFormatter": "biomejs.biome" - }, - "[typescript]": { - "editor.defaultFormatter": "biomejs.biome" - }, - "[typescriptreact]": { - "editor.defaultFormatter": "biomejs.biome" - }, - "[json]": { - "editor.defaultFormatter": "biomejs.biome" - }, - "[jsonc]": { - "editor.defaultFormatter": "biomejs.biome" - }, - "[css]": { - "editor.defaultFormatter": "biomejs.biome" - }, - "editor.codeActionsOnSave": { - "source.organizeImports.biome": "explicit" - } + "files.watcherExclude": { + "**/routeTree.gen.ts": true + }, + "search.exclude": { + "**/routeTree.gen.ts": true + }, + "files.readonlyInclude": { + "**/routeTree.gen.ts": true + }, + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[jsonc]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[css]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "editor.codeActionsOnSave": { + "source.organizeImports.biome": "explicit" + } } diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4e4cec6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +# --- Stage 1: Build Stage --- +FROM node:24-alpine AS builder +WORKDIR /app +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ +RUN corepack enable pnpm && pnpm i --frozen-lockfile +COPY . . +RUN pnpm run build + +# --- Stage 2: Production Stage --- +FROM node:24-alpine AS runner +WORKDIR /app + +ENV NODE_ENV=production +ENV PORT=3000 +ENV HOST=0.0.0.0 + +# Nitro compiles everything needed into the .output directory +COPY --from=builder /app/.output ./.output + +EXPOSE 3000 + +# Run the compiled Nitro server +CMD ["node", ".output/server/index.mjs"] \ No newline at end of file diff --git a/TODO b/TODO index 79e7493..26a35de 100644 --- a/TODO +++ b/TODO @@ -8,4 +8,8 @@ - generate state and check it against the state returned from lichess https://lichess.org/api#tag/oauth/GET/oauth - checkbox and toggle disabled states - react query on for study and chapter load, to allow caching -- https://specification.website/checklist/ \ No newline at end of file +- https://specification.website/checklist/ + +- Custom headers do not work - the subtitle is appearing above every thing on first page, and the game starts 2nd page + +- react query to cache the study and chapters \ No newline at end of file diff --git a/biome.json b/biome.json index 810dfd2..334621e 100644 --- a/biome.json +++ b/biome.json @@ -13,7 +13,12 @@ "**/index.html", "**/vite.config.ts", "!**/src/routeTree.gen.ts", - "!**/src/styles.css" + "!**/src/styles.css", + "!**/.tanstack/*", + "!**/.output/*", + "!**/.nitro/*", + "!**/node_modules/*", + "!**/styles/vendor/*" ] }, "formatter": { @@ -33,4 +38,3 @@ } } } - diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f8793bc --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +services: + chess-scribe-frontend: + build: + context: . + dockerfile: Dockerfile + container_name: chess-scribe-frontend + ports: + - "3000:3000" + environment: + - NODE_ENV=production + - PORT=3000 + env_file: + - .env + restart: unless-stopped \ No newline at end of file diff --git a/package.json b/package.json index 8e288e1..7b08520 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,11 @@ "dev": "vite dev --port 3000 --host", "build": "vite build", "preview": "vite preview", + "start": "node .output/server/index.mjs", "test": "vitest run", + "lint:fix": "biome lint --write", "format": "biome format", + "format:fix": "biome format --write", "lint": "biome lint", "check": "biome check" }, @@ -48,11 +51,5 @@ "typescript": "^6.0.2", "vite": "^8.0.0", "vitest": "^4.1.5" - }, - "pnpm": { - "onlyBuiltDependencies": [ - "esbuild", - "lightningcss" - ] } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4f66bbd..12e086b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -315,6 +315,9 @@ packages: '@emnapi/runtime@1.10.0': resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} @@ -1903,8 +1906,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.8.1: - resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} engines: {node: '>=10'} hasBin: true @@ -2489,6 +2492,11 @@ snapshots: tslib: 2.8.1 optional: true + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.8.1 + optional: true + '@emnapi/wasi-threads@1.2.1': dependencies: tslib: 2.8.1 @@ -2583,7 +2591,7 @@ snapshots: '@img/sharp-wasm32@0.34.5': dependencies: - '@emnapi/runtime': 1.10.0 + '@emnapi/runtime': 1.11.1 optional: true '@img/sharp-win32-arm64@0.34.5': @@ -3912,7 +3920,7 @@ snapshots: semver@6.3.1: {} - semver@7.8.1: + semver@7.8.5: optional: true seroval-plugins@1.5.4(seroval@1.5.4): @@ -3925,7 +3933,7 @@ snapshots: dependencies: '@img/colour': 1.1.0 detect-libc: 2.1.2 - semver: 7.8.1 + semver: 7.8.5 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.5 '@img/sharp-darwin-x64': 0.34.5 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..1348c6c --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,9 @@ +# pnpm v11 configuration file +packages: + - "." + +# This replaces 'onlyBuiltDependencies' +allowBuilds: + "sharp": true + "esbuild": true + "lightningcss": true \ No newline at end of file diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 4464614..4513439 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,12 +1,18 @@ import { Link } from "@tanstack/react-router"; import { Image } from "@unpic/react"; - +import MaintenanceModeBanner from "#/components/MaintenanceModeBanner.tsx"; +import { env } from "#/env.ts"; import logo from "@/assets/images/logo.svg?url"; export default function Header() { return (
-