hasari-api / apps /web /README.md
erdoganpeker's picture
v0.3.0 β€” multimodal vehicle damage MVP
e327f0d
# @arac-hasar/web
Next.js 15 (App Router) frontend for the **HasarΔ°** β€” araΓ§ hasar tespiti MVP.
## Stack
- Next.js 15 + React 18.3 + TypeScript (strict)
- Tailwind CSS 3.4 with shared preset from `@arac-hasar/ui`
- Shared UI components from `@arac-hasar/ui`
- Shared types from `@arac-hasar/types`
- `axios` for backend calls (FastAPI on `:8000`)
## Quick start
From the monorepo root:
```bash
pnpm install
pnpm --filter @arac-hasar/web dev
# or
pnpm dev:web
```
App will be available at <http://localhost:3000>.
Make sure the backend is running on `:8000`:
```bash
pnpm backend:dev
```
## Environment
Copy `.env.example` to `.env.local`:
```
NEXT_PUBLIC_API_URL=http://localhost:8000
# BACKEND_API_KEY=dev-secret # optional β€” used only by /api/inspect proxy
```
| Variable | Required | Purpose |
| ----------------------- | -------- | ------------------------------------ |
| `NEXT_PUBLIC_API_URL` | yes | Base URL of the FastAPI backend |
| `BACKEND_API_KEY` | no | Forwarded by `/api/inspect` (server) |
## Routes
| Path | Description |
| ------------------- | ------------------------------------------------- |
| `/` | Landing β€” value props + CTA |
| `/inspect` | Multi-file upload + mode selection (sync / async) |
| `/results/[id]` | Inspection result with polling + part-centric UI |
| `/history` | Past inspections grid (falls back to demo data) |
| `/api/inspect` | Optional pass-through to backend `POST /api/v1/inspect` |
## Scripts
| Script | Purpose |
| ------------------- | ------------------- |
| `pnpm dev` | Dev server (`:3000`) |
| `pnpm build` | Production build |
| `pnpm start` | Run prod server |
| `pnpm lint` | ESLint |
| `pnpm typecheck` | `tsc --noEmit` |
## Backend endpoints consumed
- `POST /api/v1/inspect` β€” multipart upload, returns `inspection_id` (queued)
- `POST /api/v1/inspect/sync` β€” inline (≀ 5 images)
- `GET /api/v1/inspect/{id}` β€” status + result (polled every 2 s, max 60 s)
- `GET /api/v1/inspect` β€” history list (paginated)
- `GET /health` β€” liveness probe (`/healthz` kept as alias)
Contract: `packages/types/src/api.ts`. Full reference: [`docs/API_GUIDE.md`](../../docs/API_GUIDE.md).
## Folder layout
```
apps/web/
β”œβ”€ app/
β”‚ β”œβ”€ layout.tsx Root layout (Header, Footer, Inter font)
β”‚ β”œβ”€ globals.css Tailwind + UI styles
β”‚ β”œβ”€ page.tsx Landing
β”‚ β”œβ”€ inspect/page.tsx Upload flow
β”‚ β”œβ”€ results/[id]/page.tsx Result + polling
β”‚ β”œβ”€ history/page.tsx History grid
β”‚ └─ api/inspect/route.ts Backend proxy
β”œβ”€ components/ Web-only components
β”‚ β”œβ”€ Header.tsx
β”‚ β”œβ”€ Footer.tsx
β”‚ β”œβ”€ PartList.tsx Part-centric list (damaged sorted + clean)
β”‚ └─ ResultsTabs.tsx 3 tabs (overview/parts/damages) + overlay
β”œβ”€ lib/
β”‚ β”œβ”€ api.ts Typed axios wrappers
β”‚ └─ use-inspection-polling.ts
β”œβ”€ next.config.ts
β”œβ”€ tailwind.config.ts
└─ tsconfig.json
```