If you want a beginner-friendly walkthrough, start with Non Techie Readme.md. This README is for people who are comfortable running commands and want details on how the app works.
- Real-time multiplayer quiz game built with Next.js 14 (App Router), Socket.io, Prisma, and Tailwind.
- Admin builds quizzes (with AI assist, themes, media, translations), hosts games, and shares a QR/join link.
- Players join via code/QR, answer in real time, and see live leaderboards; certificates can be generated and downloaded.
- Built-in ngrok support to expose player routes publicly while keeping admin/host routes local-only.
- Quiz editing: create/import/export quizzes (ZIP with media), reorder questions, rich media, power-ups, host notes, theme presets/JSON editing.
- AI helpers: AI quiz generator (OpenAI) and Unsplash image sourcing.
- Translations: translation status indicators; copy English answers into translations.
- Game flow: real-time scoreboard, host display + control panel, QR/join links, admission controls, delete previous games.
- Certificates: host/player certificate generation and download.
- Safety: middleware blocks admin/host APIs from ngrok/public; player routes stay open.
- Next.js 14, React 18, TypeScript
- Socket.io for realtime play
- Prisma + SQLite (local file database)
- Tailwind + shadcn/ui for UI
- ngrok for tunneling
- Node.js 18.17+ and npm
- SQLite (bundled via Prisma; no external DB needed)
- Docker (optional) for containerized runs
npm run setup # installs deps, creates .env, sets up database
npm run dev # starts the app at http://localhost:3000Manual setup steps (if you prefer)
# 1) Install dependencies
npm install
# 2) Create .env with the SQLite URL if it does not exist
echo 'DATABASE_URL="file:./data/quiz.db"' > .env # only if .env is missing
# 3) Apply schema (repo ships without migrations)
npx prisma db push
# 4) Start the dev server
npm run dev
# App: http://localhost:3000docker compose up -d --build
docker compose logs -f # wait for "Ready on http://localhost:3000"- The image entrypoint runs
npx prisma migrate deploy; if you see migration errors, replace that withnpx prisma db pushfor a migration-less setup. - For persistent data, align the DB path with the mounted volume. Easiest: set
DATABASE_URL=file:./prisma/data/quiz.dbindocker-compose.ymlto match the/app/prisma/datavolume. - App URL: http://localhost:3000
DATABASE_URL(required): e.g.,file:./data/quiz.dborfile:./prisma/data/quiz.dbwhen matching the Docker volume.- Optional (used in admin/settings):
OPENAI_API_KEY(AI quiz generator)UNSPLASH_API_KEY(image sourcing)NGROK_AUTHTOKENcan also be saved via the UI.
- Add your authtoken in the admin UI:
http://localhost:3000/admin/settings. - The server auto-starts a tunnel when a token is saved or present at boot (
src/lib/tunnel.ts). - QR/join links use the tunnel URL for players. Admin/host routes remain local-only (
src/middleware.ts). - Players may see ngrok’s one-time warning page; after clicking through, the cookie suppresses it.
npm run dev— start Next.js + Socket.io server (tsxserver.ts).npm run build— Next build.npm run start— production start (usesNODE_ENV=production tsx server.ts).npm run db:push— apply Prisma schema to SQLite.npm run db:studio— Prisma Studio.npm run lint— Next lint.node scripts/cleanup-old-games.ts— delete sessions older than 1 hour (manual/cron).
.
├─ src/
│ ├─ app/ # Next.js App Router pages + API routes
│ │ ├─ page.tsx # Landing page
│ │ ├─ menu/ # Menu selection screen
│ │ ├─ play/[gameCode]/page.tsx # Player join/answer view (public)
│ │ ├─ host/[gameCode]/{display,control,playermonitor}/page.tsx # Host display + control panels
│ │ ├─ admin/ # Admin dashboard and tools
│ │ │ ├─ page.tsx # Admin home
│ │ │ ├─ games/page.tsx # Game history/controls
│ │ │ ├─ quiz/new/page.tsx # New quiz creation
│ │ │ ├─ themes/[themeId]/page.tsx # Theme editor
│ │ │ └─ settings/page.tsx # App settings (API keys, tunnel, etc.)
│ │ ├─ api/ # Route handlers for admin/host/player APIs
│ │ │ ├─ quizzes/(route.ts, ai-generate, import, [quizId]) # CRUD + AI generation
│ │ │ ├─ games/(route.ts, [gameCode]) # Game lifecycle endpoints
│ │ │ ├─ themes/(route.ts, generate, [themeId]) # Theme CRUD + AI generate
│ │ │ ├─ settings/(route.ts, tunnel) # Settings and tunnel start/stop
│ │ │ ├─ tunnel/route.ts # ngrok status
│ │ │ ├─ shorten/route.ts # URL shortener
│ │ │ └─ upload/route.ts # Media upload
│ │ └─ uploads/[...path]/route.ts # Serves uploaded assets
│ ├─ components/ # UI primitives + domain components
│ │ ├─ ui/ # shadcn-based primitives (buttons, dialog, tabs, etc.)
│ │ ├─ landing/ # Marketing/landing sections
│ │ ├─ quiz/ # Quiz editing + player inputs
│ │ │ ├─ editor/ # Question/section modals
│ │ │ ├─ questions/ # Question list and stats
│ │ │ └─ settings/ # Admission/power-up controls
│ │ ├─ admin/ # Admin cards, pagination, side panels
│ │ ├─ certificate/ # Certificate status/download/regeneration
│ │ ├─ theme/ # Theme provider and background effects
│ │ └─ display/AspectRatioHelper.tsx # Host display scaling helper
│ ├─ contexts/ # React contexts (dark mode)
│ ├─ hooks/ # Client hooks (Socket.io connection, quiz preloading)
│ ├─ lib/ # Services and utilities
│ │ ├─ openai-*.ts # AI quiz/theme/translation helpers
│ │ ├─ certificate-* # Certificate generation and helpers
│ │ ├─ theme-*.ts # Theme presets, contrast, color utilities
│ │ ├─ tunnel.ts # ngrok tunnel control
│ │ ├─ scoring.ts # Game scoring logic
│ │ ├─ db.ts # Prisma client helper
│ │ └─ utils.ts # Shared client/server helpers
│ ├─ middleware.ts # Blocks admin/host routes from ngrok/public traffic
│ ├─ server/game-manager.ts # Socket.io game state manager
│ └─ types/ # Shared TypeScript types (quizzes, settings, certificates, themes)
├─ public/ # Static assets; upload root kept under version control via .gitkeep
├─ prisma/schema.prisma # Database schema
├─ data/ # SQLite database location (gitignored)
├─ scripts/ # Setup/maintenance scripts (setup, cleanup-old-games, contrast checks)
├─ server.ts # Custom Next.js + Socket.io entrypoint
├─ list-players.ts # Utility to list currently connected players from the socket server
├─ docker-compose.yml, Dockerfile # Container build/run setup
├─ components.json, tailwind.config.ts, postcss.config.mjs, next.config.mjs, tsconfig.json # Tooling/config
└─ package.json, package-lock.json # Dependencies and npm scripts
- Default SQLite file:
data/quiz.db(ignored by git). - Uploaded media lives under
public/uploads; compose mountsquiz-uploadsvolume there. - When changing DB paths, update both
DATABASE_URLand any Docker volume mappings.
- Player-facing routes (
/play,/play/[gameCode]and related APIs) stay accessible over ngrok. - Admin/host routes (
/admin,/host,/api/quizzes,/api/settings,/api/tunnel) are blocked from external/ngrok traffic by middleware (src/middleware.ts).
This project is licensed under the ERROR.DEV OPEN USE LICENSE