Skip to content

err0r-dev/Quiz0r

Repository files navigation

Quiz0r

Next.js Node Socket.io Prisma Docker Vibe coded with Claude Vibe coded with OpenAI License

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.

Overview

  • 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.

Features

  • 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.

Stack

  • Next.js 14, React 18, TypeScript
  • Socket.io for realtime play
  • Prisma + SQLite (local file database)
  • Tailwind + shadcn/ui for UI
  • ngrok for tunneling

Prerequisites

  • Node.js 18.17+ and npm
  • SQLite (bundled via Prisma; no external DB needed)
  • Docker (optional) for containerized runs

Quick Start

npm run setup   # installs deps, creates .env, sets up database
npm run dev     # starts the app at http://localhost:3000
Manual 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:3000

Running with Docker

docker 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 with npx prisma db push for a migration-less setup.
  • For persistent data, align the DB path with the mounted volume. Easiest: set DATABASE_URL=file:./prisma/data/quiz.db in docker-compose.yml to match the /app/prisma/data volume.
  • App URL: http://localhost:3000

Environment variables

  • DATABASE_URL (required): e.g., file:./data/quiz.db or file:./prisma/data/quiz.db when matching the Docker volume.
  • Optional (used in admin/settings):
    • OPENAI_API_KEY (AI quiz generator)
    • UNSPLASH_API_KEY (image sourcing)
    • NGROK_AUTHTOKEN can also be saved via the UI.

ngrok (external access)

  • 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.

Key scripts

  • npm run dev — start Next.js + Socket.io server (tsx server.ts).
  • npm run build — Next build.
  • npm run start — production start (uses NODE_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).

Project structure

.
├─ 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

Data and storage

  • Default SQLite file: data/quiz.db (ignored by git).
  • Uploaded media lives under public/uploads; compose mounts quiz-uploads volume there.
  • When changing DB paths, update both DATABASE_URL and any Docker volume mappings.

Security and routing

  • 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).

License

This project is licensed under the ERROR.DEV OPEN USE LICENSE

About

A lightweight local quiz runner for live events, clubs and meetups. Create rounds, launch sessions and let players join instantly from their phones.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages