67 lines
4.6 KiB
Markdown
67 lines
4.6 KiB
Markdown
# AGENTS.md — Balinyaar Web Client
|
|
|
|
Agent-oriented guide to the frontend. For human setup/run instructions see [README.md](README.md).
|
|
|
|
## Stack
|
|
|
|
- **Next.js** with the **App Router** (`src/app/`), statically exported (`output: 'export'` in `next.config.mjs` → builds to `out/`)
|
|
- **React** + **TypeScript** (`strict` mode)
|
|
- **Material UI (MUI)** for components and theming (Emotion under the hood)
|
|
- **Jest** + **Testing Library** for unit tests
|
|
- ESLint (`eslint-config-next`) + Prettier
|
|
|
|
## Commands
|
|
|
|
| Task | Command |
|
|
| ------------ | ------------------ |
|
|
| Dev server | `npm run dev` |
|
|
| Build | `npm run build` |
|
|
| Lint | `npm run lint` |
|
|
| Type-check | `npm run type` |
|
|
| Format | `npm run format` |
|
|
| Test (watch) | `npm test` |
|
|
| Test (CI) | `npm run test:ci` |
|
|
|
|
Always run `npm run lint` and `npm run type` after a change. Run `npm run test:ci` when you touch a component that has a `*.test.tsx`.
|
|
|
|
## Directory map
|
|
|
|
```
|
|
src/
|
|
├── app/ Routes (App Router). Each folder = a route; page.tsx = the page.
|
|
│ ├── layout.tsx Root layout: store + theme providers, global <metadata>
|
|
│ ├── page.tsx "/" entry (delegates to home)
|
|
│ ├── home/ about/ Content pages
|
|
│ ├── auth/login|signup Auth pages (LoginForm is currently a stub)
|
|
│ └── me/ Authenticated user page
|
|
├── components/
|
|
│ ├── common/ Reusable App* primitives (see below) + ErrorBoundary
|
|
│ └── UserInfo/ Logged-in user summary
|
|
├── hooks/ useIsAuthenticated, useIsMobile, event hooks, useWindowSize
|
|
├── layout/ PublicLayout / PrivateLayout + TopBar, SideBar, BottomBar, config
|
|
├── store/ Global state: React context + reducer (AppStore, AppReducer)
|
|
├── theme/ ThemeProvider, light/dark palettes, colors, MUI-for-Next bridge
|
|
└── utils/ storage (local/session), navigation, environment, text, types
|
|
```
|
|
|
|
## Conventions (follow these)
|
|
|
|
- **Imports**: use the `@/*` alias for anything under `src/` (e.g. `import { AppButton } from '@/components'`). The alias is defined in `tsconfig.json`.
|
|
- **Barrel files**: most folders export through an `index.ts(x)`. Add new public exports there (e.g. a new common component is re-exported from `src/components/common/index.tsx`, which `src/components/index.tsx` re-exports).
|
|
- **Common components** live in `src/components/common/<Name>/` as a folder containing `<Name>.tsx`, `index.tsx` (re-export), and an optional `<Name>.test.tsx`. Existing ones: `AppAlert`, `AppButton`, `AppIcon`, `AppIconButton`, `AppImage`, `AppLink`, `AppLoading`. Prefer reusing these over raw MUI where one exists.
|
|
- **Icons**: reference icons by string name through `AppIcon`. The name→icon map is in `src/components/common/AppIcon/config.ts`; add new icons there (custom SVGs go in `AppIcon/icons/`).
|
|
- **Navigation**: sidebar/bottom-bar items are arrays of `LinkToPage` defined inside `PublicLayout.tsx` / `PrivateLayout.tsx`. Add a route → add an entry there to surface it in the nav.
|
|
- **Two layouts**: `PrivateLayout` (after auth) and `PublicLayout` (before auth); `CurrentLayout` picks between them based on auth state. The app name lives in the `TITLE_PRIVATE` / `TITLE_PUBLIC` constants in those files.
|
|
- **Auth is a stub.** `src/hooks/auth.ts` and `src/app/auth/login/LoginForm.tsx` fake login by writing a placeholder token to session storage (`// TODO: AUTH:`). When implementing real auth, replace those spots and point requests at `NEXT_PUBLIC_API_URL` (the `server` project's JWT endpoints).
|
|
- **Theming**: use the theme/palette via MUI's `sx` / `useTheme`; don't hardcode colors. Light/dark values are in `src/theme/light.ts` and `dark.ts`; dark-mode toggle flows through the store.
|
|
- **Client vs server components**: files needing hooks/browser APIs start with `'use client';` (see `LoginForm.tsx`). Pages that only render markup can stay server components.
|
|
|
|
## Environment
|
|
|
|
Browser-exposed config comes from `NEXT_PUBLIC_*` variables (copy `.env.sample` → `.env`). The ones actually read in code: `NEXT_PUBLIC_ENV`, `NEXT_PUBLIC_DEBUG`, `NEXT_PUBLIC_PUBLIC_URL` (see `src/config.ts`) and `NEXT_PUBLIC_VERSION` (see `src/utils/environment.ts`). `NEXT_PUBLIC_API_URL` is the backend base URL.
|
|
|
|
## Gotchas
|
|
|
|
- Static export (`output: 'export'`) means **no server-side runtime** — no API routes, no SSR-only features, `images.unoptimized` is on.
|
|
- Don't reintroduce the removed demo/showcase route (`src/app/dev`) or `Demo*` components — they were template content.
|