- React 19 + TypeScript 5.9 + Vite 7 + Tailwind CSS 4
@tailwindcss/viteplugin — Tailwind configured via@themeinsrc/index.css(notailwind.config.*)vite-plugin-singlefile—vite buildoutputs a singledist/index.html(all JS/CSS inlined)
| Action | Command |
|---|---|
| Dev server | npm run dev |
| Build | npm run build (outputs self-contained dist/index.html) |
| Preview | npm run preview |
| Typecheck | npx tsc --noEmit |
No test framework or lint runner is configured. No CI.
@/ → src/ (configured in both tsconfig.json and vite.config.ts).
- Entrypoint:
src/main.tsx→src/App.tsx - State: Plain React state persisted to
localStoragekeysimplyfly:v1viasrc/store.ts. Not Zustand/Redux. TheAppcomponent holds the singleAppStateand passes it down withonChangecallbacks. - Types:
src/types.ts—User,Block,Aircraft,Availability,Assignment,AppState.Userhastrack("student" | "ip"),qualificationfor IPs,lessonanddolffor students.Assignmenthas optional fieldsmissionandareaAssignment. Also exportsrangesOverlap()and day label arrays. - Auth: Email lookup against the seed users list. No real auth, no password check. A "quick access" button skips the form.
- Admin scheduling: Drag-and-drop flyer cards onto a grid of aircraft×blocks (native HTML5 DragEvent, no library).
- Styling: Custom
cn()utility wrappingclsx+tailwind-mergeinsrc/utils/cn.ts. Customnavyandskycolor palettes defined inindex.css. - ID generation:
uid(prefix)insrc/store.tsgenerates random IDs (prefix-random). Used by Block, Aircraft, etc.
src/
components/ AppShell, Login, FlyerDashboard, AdminDashboard, Logo, ui (shared)
utils/cn.ts class merge helper
types.ts all domain types
store.ts seed data, localStorage persistence
index.css Tailwind v4 @import + @theme + custom utilities
- Tailwind v4 uses CSS-first config. To customize theme values, edit the
@themeblock insrc/index.css. - Seed blocks are fixed to day 4 (Thursday) with six operating periods (04:58–17:55).
- Admin tab order: Daily scheduler > Block times > Aircraft > Overview > Flyers.
- The prototype uses
simplyfly:aeroemail domain for all users. - Block times tab supports inline editing (click time to edit start/end). When adding a block, end auto-fills to start + 1h30m until the end field is manually touched.
- Scheduler cell inline-editing: Enter/blur saves, Escape cancels.
- Roster panel has collapsible toggle, track filter (All / AS / IP), and grays out already-assigned flyers when a block is selected.
- Import path alias
@/forsrc/imports. - Use
cn()from@/utils/cnfor conditional className merging. - State types in
types.ts, seed data and persistence instore.ts.