Gamified pomodoro productivity app where focus sessions and tasks power Pokémon-style progression.
- Frontend: Next.js 16 (App Router), React 19, Tailwind CSS, Radix UI primitives
- Auth (client): Supabase auth session via
src/context/auth-context.jsx - API (server): Next.js Route Handlers in
frontend/src/app/api/* - Persistence:
- Guest progress: local storage (see
src/lib/guest-storage) /api/register+/api/login: in-memory demo store (non-persistent)
- Guest progress: local storage (see
- Tests:
- Integration: Vitest + React Testing Library
- E2E: Playwright
- Node.js >= 20.9 (Next 16 requirement)
cd frontend
npm install
npm run devApp runs on http://localhost:3000.
From frontend/:
npm run testnpm run test:e2e:install
npm run test:e2ePOST /api/registerPOST /api/login
Example register body:
{ "username": "ash", "email": "ash@example.com", "password": "secret" }The container always uses Node 22 + its bundled npm — no need for
nvm useon the host.
From the project root:
# First run — builds the image and starts the dev server
docker compose up --build
# Subsequent runs — skip the build step
docker compose upThe dev server starts on http://localhost:3000 with hot reload via a volume mount.
Source changes in ./frontend are reflected immediately inside the container.
NEXT_PUBLIC_* env vars are baked into the bundle at build time, so they must be available when building the image:
cd frontend
docker build \
--build-arg NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co \
--build-arg NEXT_PUBLIC_SUPABASE_ANON_KEY=your-key \
-t pomopet-frontend .
docker run -p 3000:3000 pomopet-frontendOr export them first:
export NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
export NEXT_PUBLIC_SUPABASE_ANON_KEY=your-key
docker build \
--build-arg NEXT_PUBLIC_SUPABASE_URL \
--build-arg NEXT_PUBLIC_SUPABASE_ANON_KEY \
-t pomopet-frontend .
docker run -p 3000:3000 pomopet-frontendApp runs on http://localhost:3000.
- Starter selection happens on first dashboard visit for guests.
- Guest progress persists locally; the demo register/login endpoints do not persist across restarts.