diff --git a/Dockerfile.frontend b/Dockerfile.frontend deleted file mode 100644 index 9585fa6..0000000 --- a/Dockerfile.frontend +++ /dev/null @@ -1,41 +0,0 @@ -FROM ubuntu:noble - -RUN apt-get -q update \ - && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - ca-certificates curl gnupg \ - curl \ - nano \ - sqlite3 \ - psmisc \ - wget \ - jq \ - less \ - git \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/{apt,dpkg,cache,log} -RUN mkdir -p /etc/apt/keyrings -RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg - -# https://nodejs.org/en/about/previous-releases -ENV NODE_MAJOR=24 -RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list - -RUN apt-get -q update \ - && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \ - nodejs \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/{apt,dpkg,cache,log} - -COPY /client /client -WORKDIR /client - -# Set environment variable for production mode (default: development) -ENV PRODUCTION=false - -# Disable HTTPS by default for npm development server -ENV HTTPS=false - -COPY ./client/entrypoint.sh /entrypoint.sh -RUN chmod +x /entrypoint.sh - -ENTRYPOINT [ "/entrypoint.sh" ] diff --git a/TYPESCRIPT_GENERATION.md b/TYPESCRIPT_GENERATION.md index 55f1e0d..285ea01 100644 --- a/TYPESCRIPT_GENERATION.md +++ b/TYPESCRIPT_GENERATION.md @@ -78,10 +78,10 @@ const newLobby = await sessionsApi.createLobby("session-id", lobbyRequest); docker compose exec server uv run python3 generate_schema_simple.py # Generate TypeScript types -docker compose exec static-frontend npx openapi-typescript openapi-schema.json -o src/api-types.ts +docker compose exec client npx openapi-typescript openapi-schema.json -o src/api-types.ts # Type check -docker compose exec static-frontend npm run type-check +docker compose exec client npm run type-check ``` ### Automated Generation @@ -143,8 +143,8 @@ client/ If the frontend container has dependency conflicts: ```bash # Rebuild the frontend container -docker compose build static-frontend -docker compose up -d static-frontend +docker compose build client +docker compose up -d client ``` ### TypeScript Errors diff --git a/check-api-evolution.sh b/check-api-evolution.sh index 4ac8054..ffd76c0 100755 --- a/check-api-evolution.sh +++ b/check-api-evolution.sh @@ -18,13 +18,13 @@ if [ ! -f "client/openapi-schema.json" ]; then fi # Check if the frontend container is running -if ! docker compose ps static-frontend | grep -q "Up"; then +if ! docker compose ps client | grep -q "Up"; then echo "📋 Starting frontend container..." - docker compose up -d static-frontend + docker compose up -d client fi echo "📋 Running API evolution check..." -docker compose exec static-frontend node check-api-evolution.js +docker compose exec client node check-api-evolution.js echo "" echo "💡 To regenerate types and schema: ./generate-ts-types.sh" diff --git a/client/src/App.tsx b/client/src/App.tsx index c8f3ccf..4f9c5f6 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect, KeyboardEvent, useCallback } from "react"; import { Input, Paper, Typography } from "@mui/material"; -import { Session } from "./GlobalContext"; +import { Session, Lobby } from "./GlobalContext"; import { UserList } from "./UserList"; import { LobbyChat } from "./LobbyChat"; import "./App.css"; @@ -19,12 +19,6 @@ type LobbyProps = { setError: React.Dispatch>; }; -type Lobby = { - id: string; - name: string; - private: boolean; -}; - const LobbyView: React.FC = (props: LobbyProps) => { const { session, setSession, setError } = props; const { lobbyName = "default" } = useParams<{ lobbyName: string }>(); @@ -35,18 +29,14 @@ const LobbyView: React.FC = (props: LobbyProps) => { const [creatingLobby, setCreatingLobby] = useState(false); const [reconnectAttempt, setReconnectAttempt] = useState(0); - const { - sendJsonMessage, - lastJsonMessage, - readyState - } = useWebSocket(socketUrl, { + const { sendJsonMessage, lastJsonMessage, readyState } = useWebSocket(socketUrl, { onOpen: () => { console.log("app - WebSocket connection opened."); setReconnectAttempt(0); }, onClose: () => { console.log("app - WebSocket connection closed."); - setReconnectAttempt(prev => prev + 1); + setReconnectAttempt((prev) => prev + 1); }, onError: (event: Event) => console.error("app - WebSocket error observed:", event), shouldReconnect: (closeEvent) => true, // Will attempt to reconnect on all close events @@ -69,10 +59,10 @@ const LobbyView: React.FC = (props: LobbyProps) => { } const data: any = lastJsonMessage; switch (data.type) { - case "update": - if ("name" in data) { - console.log(`Lobby - name set to ${data.name}`); - setSession((s) => (s ? { ...s, name: data.name } : null)); + case "update_name": + if (data.data && "name" in data.data) { + console.log(`Lobby - name set to ${data.data.name}`); + setSession((s) => (s ? { ...s, name: data.data.name } : null)); } break; case "error": diff --git a/client/src/GlobalContext.tsx b/client/src/GlobalContext.tsx index 9e8c03f..2b52601 100644 --- a/client/src/GlobalContext.tsx +++ b/client/src/GlobalContext.tsx @@ -1,6 +1,13 @@ +type Lobby = { + id: string; + name: string; + private: boolean; +}; + type Session = { id: string; name: string | null; - lobbies: string[]; + lobbies: Lobby[]; }; -export type { Session }; + +export type { Session, Lobby }; diff --git a/docker-compose.yml b/docker-compose.yml index 16ca5fa..1f7e229 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,10 +1,10 @@ services: - static-frontend: - container_name: static-frontend - hostname: static-frontend + client: + container_name: client + hostname: client build: context: . - dockerfile: Dockerfile.frontend + dockerfile: Dockerfile.client env_file: - ./.env environment: diff --git a/generate-ts-types.sh b/generate-ts-types.sh index e97b6a9..c090dab 100755 --- a/generate-ts-types.sh +++ b/generate-ts-types.sh @@ -16,19 +16,19 @@ echo "📋 Step 1: Generating OpenAPI schema from FastAPI server..." docker compose exec server uv run python3 generate_schema_simple.py echo "📋 Step 2: Ensuring frontend container is running..." -docker compose up -d static-frontend +docker compose up -d client echo "📋 Step 3: Installing/updating frontend dependencies..." -docker compose exec static-frontend npm install --legacy-peer-deps +docker compose exec client npm install --legacy-peer-deps echo "📋 Step 4: Generating TypeScript types from OpenAPI schema..." -docker compose exec static-frontend npx openapi-typescript openapi-schema.json -o src/api-types.ts +docker compose exec client npx openapi-typescript openapi-schema.json -o src/api-types.ts echo "📋 Step 5: Running TypeScript type checking..." -docker compose exec static-frontend npm run type-check +docker compose exec client npm run type-check echo "📋 Step 6: Running API evolution check..." -docker compose exec static-frontend node check-api-evolution.js +docker compose exec client node check-api-evolution.js echo "✅ TypeScript generation complete!" echo "📄 Generated files:" diff --git a/server/main.py b/server/main.py index 1fe02aa..d8a473b 100644 --- a/server/main.py +++ b/server/main.py @@ -1233,7 +1233,7 @@ if PRODUCTION: else: - logger.info(f"Proxying static files to http://static-frontend:3000 at {public_url}") + logger.info(f"Proxying static files to http://client:3000 at {public_url}") import ssl @@ -1245,9 +1245,9 @@ else: # Do not proxy API or websocket paths if path.startswith("api/") or path.startswith("ws/"): return Response(status_code=404) - url = f"{request.url.scheme}://static-frontend:3000/{public_url.strip('/')}/{path}" + url = f"{request.url.scheme}://client:3000/{public_url.strip('/')}/{path}" if not path: - url = f"{request.url.scheme}://static-frontend:3000/{public_url.strip('/')}" + url = f"{request.url.scheme}://client:3000/{public_url.strip('/')}" headers = dict(request.headers) try: # Accept self-signed certs in dev @@ -1284,7 +1284,7 @@ else: logger.info("REACT: WebSocket proxy connection established.") # Get scheme from websocket.url (should be 'ws' or 'wss') scheme = websocket.url.scheme if hasattr(websocket, "url") else "ws" - target_url = f"{scheme}://static-frontend:3000/ws" + target_url = f"{scheme}://client:3000/ws" await websocket.accept() try: # Accept self-signed certs in dev for WSS