Skip to content

Where things are ​

PathWhat it holds
app/[locale]/The pages: landing, create (new), a plan (p/[slug]), its created screen and Max's screens (p/[slug]/max)
components/The UI, grouped by area: landing/, plan/, sheets/, max/
lib/actions/Server actions
lib/data/Reading a plan and working out who is looking at it
lib/max/Max's logic, as pure functions
lib/hooks/Client hooks: device identity, the plan's viewer, Max
messages/All copy, one file per language
styles/styles.css, app/globals.cssThe design system, then the screens built with it
prisma/The schema and its migrations
tests/unit/ for Max's logic, integration/ for the server actions
docs/This documentation site

Pages and languages ​

Every page lives under app/[locale]/. The locale is the first part of the URL: /fr, /en or /es, with French as the default. app/[locale]/layout.tsx is the root layout: it loads the fonts, the messages and the header.

Copy never sits in components. Each string has a key in messages/en.json, fr.json and es.json, and the three files have the same keys.

Server actions ​

Each action in lib/actions/ comes in two files:

  • item.core.ts, attendee.core.ts, plan.core.ts hold the logic. They take a database client, validate their input with the schemas in lib/validation.ts, and can be tested on their own.
  • item.ts, attendee.ts, plan.ts are what the UI calls. They add rate limiting, set the device cookie where it is needed and revalidate the plan's page.

The plan page ​

app/[locale]/p/[slug]/page.tsx loads the plan on the server and hands it to PlanBoard, a client component. PlanBoard owns the two sheets (answer, add an item), which open from the ?sheet= query parameter, and wires in Max.