nessi a532cae9bd Add user editing functionality to admin panel with improved UI and self-protection safeguards
Implemented comprehensive user editing in admin dashboard with PATCH endpoint for updating email, display name, role, password, and disabled status. Added validation to prevent admins from demoting or disabling themselves, and duplicate email detection. Refactored AdminPanel to modal-based editor with separate create/edit modes, form state management, and save/cancel actions. Enhanced UI with field labels, checkbox for account status, action
2026-08-02 10:11:38 +02:00

Cluedo HP Webapp

A small multiplayer web app that acts as a digital note sheet for a Harry Potter-inspired Cluedo game. Several logged-in players can join the same game and manage their personal clues independently.

Features

  • Login with user and admin roles
  • Admin-managed user creation and deactivation
  • Multiple games per user
  • Join games using a short join code
  • Host-controlled game start with automatic player chips
  • Pre-game lobby with live player list, host status, and start confirmation
  • Player chips are generated from the first name initial and first two surname letters, e.g. SNE for Sascha Nesterovic
  • Automatic player list with host indication
  • Personal note sheet for each player and game
  • Categories for suspects, items, and locations
  • Entry status tracking: empty, ruled out, present, or maybe
  • Additional notes using i, m, and s.<chip>
  • Winner selection by the game host
  • Winner badge and confetti animation for all players
  • Live updates for new players and winner changes
  • Personal game statistics
  • Password change functionality
  • Harry Potter house themes: Default, Gryffindor, Slytherin, Ravenclaw, and Hufflepuff
  • Installable as a Progressive Web App

Technology

Frontend

  • React 18
  • Vite
  • Nginx as the production web server
  • canvas-confetti for the winner animation
  • vite-plugin-pwa for PWA support

Backend

  • Python 3.12
  • FastAPI
  • SQLAlchemy 2
  • SQLite 3
  • Passlib and bcrypt for password hashing

Deployment

  • Docker Compose
  • Frontend on port 8081
  • Backend on port 8080
  • SQLite database stored in a persistent Docker volume

Quick start with Docker

Requirements:

  • Docker
  • Docker Compose
  1. Copy .env.example to .env and set a strong secret:
BACKEND_SECRET_KEY=use-a-long-random-secret-value
  1. Build and start the containers:
docker compose up --build
  1. Open the application:

On the first startup, the application opens a setup screen where you create the first administrator with an email address, display name, and password. The default suspects, items, and locations are seeded automatically as well.

The SQLite database is stored in the Docker volume cluedo-data and survives normal container restarts.

Start the containers in the background:

docker compose up -d --build

View logs:

docker compose logs -f backend

Stop the containers:

docker compose down

Local development without Docker

Backend

cd backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

export DATABASE_URL=sqlite:///./data/cluedo.db
export SECRET_KEY=use-a-long-random-secret-value

uvicorn app.main:app --reload --port 8080

On Windows PowerShell, set the environment variables like this:

$env:DATABASE_URL = "sqlite:///./data/cluedo.db"
$env:SECRET_KEY = "use-a-long-random-secret-value"
uvicorn app.main:app --reload --port 8080

Frontend

cd frontend
npm install
npm run dev

The frontend is normally available at http://localhost:5173. During development, the API must be reachable under /api; the production Docker setup provides this through Nginx.

Create a production build:

npm run build

Project structure

.
├── backend/
│   ├── app/
│   │   ├── main.py              # FastAPI app, startup, seed data
│   │   ├── models.py            # SQLAlchemy models
│   │   ├── db.py                # SQLite engine and sessions
│   │   ├── security.py          # Password and cookie logic
│   │   └── routes/              # Auth, admin, and game APIs
│   ├── Dockerfile
│   └── requirements.txt
├── frontend/
│   ├── src/
│   │   ├── App.jsx              # Main UI and game flow
│   │   ├── api/client.js         # API client
│   │   ├── components/           # Pages, cards, and modals
│   │   ├── styles/               # Themes and inline styles
│   │   └── utils/                # Small helpers and storage utilities
│   ├── Dockerfile
│   └── nginx.conf
├── docker-compose.yml
└── .env

Data model

  • users: users, roles, status, display names, and themes
  • games: game name, join code, host, and winner
  • game_members: assignment of users to games
  • entries: seeded suspects, items, and locations
  • sheet_state: personal status and notes for an entry

Each player has their own set of sheet_state records for every game. A player's notes are therefore not visible to other players.

API overview

Authentication

  • POST /auth/login
  • POST /auth/logout
  • GET /auth/me
  • PATCH /auth/password
  • PATCH /auth/theme
  • GET /auth/me/stats

First-run setup

  • GET /setup/status
  • POST /setup/admin

The setup endpoint is available only while no administrator exists. After the first administrator has been created, the setup screen is disabled automatically.

Administration

  • GET /admin/users
  • POST /admin/users
  • DELETE /admin/users/{user_id} deactivates a user

Games

  • GET /games
  • POST /games
  • POST /games/join
  • GET /games/{game_id}
  • GET /games/{game_id}/members
  • PATCH /games/{game_id}/winner
  • POST /games/{game_id}/start
  • GET /games/{game_id}/chips
  • GET /games/{game_id}/sheet
  • PATCH /games/{game_id}/sheet/{entry_id}

SQLite notes

SQLite is a good fit for this application: the data volume is small, the app is intended for internal use, and write operations are short. The database file is stored inside the container at /app/data/cluedo.db and persisted through the cluedo-data volume.

For larger deployments with many concurrent write operations, PostgreSQL would still be the more robust choice. For the intended private or small-group use case, SQLite is sufficient.

Security notes

  • The values in .env are examples and should be changed before production use.
  • When using HTTPS, set COOKIE_SECURE to true.
  • The application is intended for an internal or small user group.
  • The automatic database migration is intentionally pragmatic and does not replace a migration system such as Alembic.
S
Description
No description provided
Readme
5.3 MiB
Languages
JavaScript 74.1%
Python 22.9%
HTML 2.8%
Dockerfile 0.2%