# honeyDue Web (`honeyDueAPI-Web`)

Next.js web client for the honeyDue property management platform. Talks to the Go REST API backend.

## Build & Run

```bash
npm run dev          # Dev server (localhost:3000)
npm run build        # Production build (catches type errors)
npm run lint         # ESLint
npm run test:e2e     # Playwright end-to-end tests
npm run test:e2e:ui  # Playwright with UI
npm run analyze      # Bundle analysis
```

## Stack

- **Framework**: Next.js 16 (App Router, React 19)
- **Styling**: Tailwind CSS v4 + shadcn/ui (Radix primitives)
- **State**: Zustand (auth, onboarding, theme), TanStack React Query (server state)
- **Forms**: React Hook Form + Zod validation
- **Drag & Drop**: @dnd-kit (kanban boards)
- **Charts**: Recharts
- **Icons**: Lucide React
- **Analytics**: PostHog
- **Testing**: Playwright (E2E), Vitest (unit)

## Architecture

### Request Flow

```
Browser → Next.js page (client component)
       → apiFetch("/tasks/") → /api/proxy/tasks (Next.js route handler)
       → Go API (reads honeydue-token httpOnly cookie, forwards as Authorization header)
```

Auth tokens are stored as httpOnly cookies (`honeydue-token`), never exposed to JS. The Next.js `/api/proxy/[...path]` catch-all route forwards requests to the Go API.

### Directory Structure

```
src/
├── app/
│   ├── (auth)/           # Login, register, forgot-password (public)
│   ├── api/proxy/        # Catch-all proxy to Go API
│   ├── app/              # Authenticated app pages
│   │   ├── contractors/  # Contractor CRUD
│   │   ├── documents/    # Document management
│   │   ├── residences/   # Residence CRUD + detail with kanban
│   │   ├── settings/     # User settings, theme
│   │   └── tasks/        # Task CRUD, kanban board
│   ├── demo/             # Demo mode (fake data, no auth)
│   └── page.tsx          # Landing page
├── components/
│   ├── contractors/      # Contractor cards, forms
│   ├── dashboard/        # Stats, activity, template suggestions
│   ├── demo/             # Demo banner
│   ├── documents/        # Document cards, forms
│   ├── forms/            # Auth form wrapper
│   ├── layout/           # TopBar, MobileNav, Sidebar
│   ├── notifications/    # Notification components
│   ├── onboarding/       # Onboarding flow
│   ├── residences/       # Residence cards, forms, summary, share
│   ├── settings/         # Theme picker
│   ├── shared/           # PageHeader, EmptyState, ErrorBanner, etc.
│   ├── sharing/          # Share code UI
│   ├── tasks/            # TaskCard, TaskForm, KanbanBoard, KanbanColumn
│   └── ui/               # shadcn primitives (button, card, dialog, etc.)
├── lib/
│   ├── api/              # API client functions per domain
│   │   ├── client.ts     # apiFetch (client-side) + serverFetch (server-side)
│   │   ├── tasks.ts      # Task API (CRUD, kanban, completions)
│   │   ├── residences.ts # Residence API (CRUD, sharing, reports)
│   │   ├── contractors.ts
│   │   ├── documents.ts
│   │   └── ...
│   ├── hooks/            # React Query hooks per domain
│   │   ├── use-tasks.ts  # useTasks, useTask, useCreateTask, etc.
│   │   ├── use-residences.ts
│   │   └── ...
│   ├── demo/             # Demo mode: DataProvider abstraction
│   │   ├── data-provider-context.tsx  # React context
│   │   ├── real-provider.ts           # Real API calls
│   │   ├── demo-provider.ts           # Fake data
│   │   └── mock-data/                 # Static demo data
│   ├── themes/           # Theme system (Warm Sage palette)
│   ├── validations/      # Zod schemas
│   └── utils.ts          # cn() helper
├── stores/
│   ├── auth.ts           # Zustand: user, token, login/logout
│   ├── onboarding.ts     # Zustand: onboarding state
│   └── theme.ts          # Zustand: theme preferences
└── styles/
    └── themes.css        # CSS custom properties for theme
```

### Key Patterns

**Data fetching**: All server data uses React Query hooks (`use-*.ts`). Hooks call API functions from `lib/api/`. API functions call `apiFetch()` which proxies through Next.js.

**Demo mode**: The app supports a `/demo` route with fake data. Components use `useDataProvider()` to get API functions and `basePath` — this returns either real or demo implementations depending on the route.

**Kanban boards**: Tasks display in kanban columns (overdue, due_soon, in_progress, not_started, completed). Uses `@dnd-kit` for drag-and-drop. Column names match Go API: `overdue_tasks`, `due_soon_tasks`, `in_progress_tasks`, `not_started_tasks`, `completed_tasks`.

**Middleware** (`src/middleware.ts`): Checks `honeydue-token` cookie. Redirects unauthenticated users to `/login` for protected routes. Skips API routes, static files, and public paths.

## Conventions

- All pages under `/app/` are `"use client"` components
- Use `apiFetch()` for client-side API calls, `serverFetch()` for server components/route handlers
- React Query hooks go in `src/lib/hooks/use-{domain}.ts`
- API client functions go in `src/lib/api/{domain}.ts`
- shadcn components in `src/components/ui/` — don't modify these directly
- Custom components use Tailwind classes, warm shadow CSS variables (`--shadow-warm-sm`, `--shadow-warm-md`)
- Brand colors: `primary` (sage green), `brand-clay`, `brand-sage` variants defined in CSS custom properties
- Font: `font-heading` for headings (tracking-tight), system font for body
- Toast notifications via `sonner` — use `toast.success()`, `toast.error()`
- Form validation with Zod schemas in `src/lib/validations/`
- Icons from `lucide-react` — keep consistent sizes (size-4 for inline, size-5 for cards)

## Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `NEXT_PUBLIC_API_URL` | Go API URL (client-side) | `https://honeyDue.treytartt.com/api` |
| `API_URL` | Go API URL (server-side, no proxy) | Falls back to `NEXT_PUBLIC_API_URL` |
| `NEXT_PUBLIC_POSTHOG_KEY` | PostHog analytics key | — |
| `NEXT_PUBLIC_POSTHOG_HOST` | PostHog host | — |

## Common Tasks

**Add a new page**: Create `src/app/app/{route}/page.tsx` (client component). Add nav item to `src/components/layout/nav-items.ts`.

**Add a new API domain**: Create `src/lib/api/{domain}.ts` with typed functions using `apiFetch()`. Create `src/lib/hooks/use-{domain}.ts` with React Query hooks. Add demo provider methods if needed.

**Add a shadcn component**: `npx shadcn@latest add {component}` — installs to `src/components/ui/`.
