# AGENTS.md — Frontend Components > **Parent**: `../../AGENTS.md` — commands, auth flow, Next.js 16 rules, deployment. ## Overview 100+ client components organized by domain. The `(frontend)` layout renders guests `LandingPage` (no app shell); authed users get `AppSidebar` + `SiteHeader` + `CommandPalette`. ## Structure ``` components/frontend/ auth/ 2 files LoginForm, LoginLink (returnTo via usePathname) account/ 16 files Profile, password, preferences, Discord link awards/ 4 files Medal/ribbon display, award dialogs banking/ 9 files Account cards, ledger, deposit/withdraw/transfer dialogs baseManagement/ 4 files StaffRoster, HireStaffDialog, EmploymentCard, UpgradeCard (structure page) blocks/ 7 files AppSidebar (data in sidebarData.ts), NavCore, NavUser, XPDisplay dashboard/ 6 files ProfileSummary, QuickStats, MissionBriefing, RecentEvents eod/ 4 files Minefield Clearance minigame evaluations/ 0 files EMPTY directory (placeholder — no components yet) flappy/ 4 files Flight Simulator canvas game, leaderboard, sounds helpdesk/ 8 files Ticket list/detail, create dialog, timeline impersonation/ 2 files Admin impersonation banner/controls intelligence/ 17 files Mission cards/attendance/comms, campaign/faction cards locker/ 13 files Grid, equipment editor, loadouts, wardrobe logistics/ 8 files Shipment cards/actions, toast notifications market/ 10 files Listing cards, negotiation flow, NPC chat, patience meter notifications/ 2 files Bell (polling), inbox page personnel/ 3 files NpcDirectory, NpcCard, NpcProfile (/personnel/contacts) profile/ 3 files Profile page components (incl. rating dialog) projects/ 12 files Jira-like boards, releases, sprints qualification/ 6 files Aim trainer arena/game/canvas/leaderboard, sounds radio/ 5 files Radio Traffic game, message generator, leaderboard realtime/ 1 file GameTickRealtime (SSE -> router.refresh) roster/ 1 file Org chart view session/ 1 file Session expiry UI (pairs with useSessionExpired hook) shims/ 1 file Frontend shim renderer storage/ 14 files Structure grid, storage dialogs, event ledger transfers/ 7 files Assignment transfer request/decision UI wiki/ 11 files Index, editor + toolbar, content renderer, revisions, standards dialog + root files: LandingPage.tsx, SiteHeader.tsx, ClientDate.tsx, PayloadButtons.tsx ``` ## Conventions ### Server → Client data flow Pages are server components that fetch via `getPayload()`, then pass data as props to client components. Client components receive typed props and never call Payload directly. ### Item compound component `storage/` uses a compound `` component for grid cells with slots: ``, ``, ``. Attachments render as stacked badges on the grid cell; popover shows full detail on hover. ### SSE consumers - `GameTickRealtime` mounts in `(frontend)/layout.tsx` for all authed users. - `ShipmentToasts` mounts only for logistics-qualified users. - Both use `useGameTick()` hook (custom `ptf:game-tick` event dispatch). ### Nested dialogs Market negotiation uses `MakeOfferDialog` nested inside `ListingCard` dialog. Loadout editor uses `EquipmentEditorDialog` nested inside locker grid. When a parent dialog unmounts (e.g., sold listing), the child stays visible for 3.5s minimum via `useNow()` hook for readability before refresh. ### Route anomalies `logistics/vehicles/VehiclesList.tsx` is a client component placed directly in the route directory (not under `components/frontend/`). This is the only route with an inline component file. ## Where to look | Task | Path | |------|------| | Add a new page | `src/app/(frontend)//page.tsx` + create client component here | | Add nav entry | `src/components/frontend/blocks/sidebarData.ts` (nav data extracted from `AppSidebar`) | | Modify auth gate | `src/app/(frontend)/layout.tsx` (conditional renders `LandingPage` or shell) | | Add SSE consumer | `src/hooks/useGameTick.ts` + mount in layout | | NPC dialogue/chatter | `src/lib/market/npcDialogue.ts` (pure, client-safe import) | | Minigame game rules | `src/lib/aim-trainer.ts` etc. — pure libs, components consume them | | Keyboard shortcuts | `src/components/command-palette/` | | Admin custom fields | `src/components/admin/` (awards designers, CollapsibleGroupField, narrative-flow, shims) | ## Anti-patterns - **NEVER** call `getPayload()` in client components — fetch in server page, pass as props - **NEVER** add `useRouter().refresh()` in SSE consumers without a guard — use the `useGameTick()` hook - **NEVER** use shadcn defaults for dark theme — the admin panel's theme handles styling - **NEVER** place server-side logic (hooks, Payload calls) in `"use client"` files