# AGNET Dashboard UI Library

Component reference for the farmer dashboard (`components/ui/*` primitives and `components/agnet/*` modules).

## i18n

Module strings live in `lib/i18n/dashboard-labels.ts`:

| Namespace | Helper | Modules |
|-----------|--------|---------|
| Shell / inputs shared | `td(key, locale, vars?)` | Overview, inputs KPIs, delivery |
| Finance | `tf(key, locale, vars?)` | Finance cards, steppers |
| Identity | `ti(key, locale)` | Identity cards, compliance |

Always pass `locale` from `useLocale()` — do not hardcode English in module components.

---

## UI primitives (`components/ui/`)

### Card

```tsx
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";

<Card padding="md" variant="default">
  <CardHeader className="mb-3">
    <CardTitle className="text-base">Section title</CardTitle>
  </CardHeader>
  <CardContent>…</CardContent>
</Card>
```

Variants: `default` | `elevated` | `dark`. Padding: `none` | `sm` | `md` | `lg`.

### Badge

```tsx
import { Badge } from "@/components/ui/badge";

<Badge variant="success">GIS Verified</Badge>
<Badge variant="brand">Best Match</Badge>
```

Variants: `success` | `warning` | `neutral` | `brand`.

### KpiCard

```tsx
import { KpiCard } from "@/components/ui/kpi-card";
import { Leaf } from "lucide-react";

<KpiCard
  label="Seed"
  value={12}
  hint="Products available"
  icon={<Leaf className="size-5" />}
  accent="default"
/>
```

### Stepper

```tsx
import { Stepper } from "@/components/ui/stepper";

<Stepper
  ariaLabel="Approval path"
  steps={[
    { id: "1", label: "Submitted", state: "complete" },
    { id: "2", label: "Scoring", state: "active" },
    { id: "3", label: "Decision", state: "pending" },
  ]}
/>
```

States: `complete` | `active` | `pending`.

### ProgressRing

```tsx
import { ProgressRing } from "@/components/ui/progress-ring";

<ProgressRing
  value={18}
  max={48}
  label="SLA"
  variant="circle"
  size="sm"
/>
```

### DataRow

```tsx
import { DataRow } from "@/components/ui/data-row";

<DataRow label="Farm Name" value="Green Valley" />
```

### StatusBanner

```tsx
import { StatusBanner } from "@/components/ui/status-banner";

<StatusBanner variant="success" title="Compliant" description="All checks passed." />
```

### Tabs

```tsx
import { Tabs, TabsList, TabsPanel } from "@/components/ui/tabs";

<Tabs defaultTab="seed" tabs={[{ id: "seed", label: "Seed" }, { id: "fert", label: "Fertiliser" }]}>
  <TabsList />
  <TabsPanel id="seed">…</TabsPanel>
</Tabs>
```

---

## Layout (`components/agnet/layout/`)

### DashboardPageLayout

Shell used by `FarmerDashboardShell`. Provides sidebar, sticky header, and mobile bottom nav.

```tsx
import DashboardPageLayout from "@/components/agnet/layout/DashboardPageLayout";
import { getDashboardNavItems, getActiveNavItem } from "@/components/agnet/layout/dashboard-nav";

const navItems = getDashboardNavItems(locale);
const active = getActiveNavItem(pathname, navItems);

<DashboardPageLayout
  navItems={navItems}
  title={active.moduleTitle}
  userPhone={user?.phone}
  gisVerified={identity?.hasGisMapping}
  onLogout={handleLogout}
>
  {children}
</DashboardPageLayout>
```

**Test IDs (owned by layout):** `dashboard-sidebar`, `dashboard-header`, `dashboard-nav-{overview|finance|trade|identity|inputs}`, `dashboard-mobile-nav`.

---

## Identity module (`components/agnet/identity/`)

Compose inside `IdentityModule`:

```tsx
import {
  GisMapCard,
  EkycCard,
  FarmProfileCard,
  LandEvidenceList,
  YieldHistoryChart,
  ComplianceChecklist,
} from "@/components/agnet/identity";
import { ti } from "@/lib/i18n/dashboard-labels";

<GisMapCard gis={data.gis} />
<EkycCard fullName={data.fullName} ekyc={data.ekyc} kycStatus={data.kycStatus} />
<FarmProfileCard data={data} />
<ComplianceChecklist items={data.compliance} />
```

**Test IDs:** `identity-module`, `identity-gis-card`, `identity-ekyc-card`, `identity-compliance-banner`.

---

## Finance module (`components/agnet/finance/`)

Compose inside `FinanceModule`:

```tsx
import {
  CaseHeaderMetrics,
  ApprovalPathStepper,
  BankRoutingList,
  DocumentChecklist,
  EligibilityGauge,
} from "@/components/agnet/finance";
import { tf } from "@/lib/i18n/dashboard-labels";

<CaseHeaderMetrics finance={data} gisVerified={identity?.hasGisMapping} locale={locale} />
<BankRoutingList matches={data.bankMatches} locale={locale} />
<DocumentChecklist documents={data.documents} locale={locale} />
<ApprovalPathStepper stages={data.stages} locale={locale} />
```

`EligibilityGauge` is embedded in `CaseHeaderMetrics` but can be used standalone for score display.

---

## Inputs module (`components/agnet/inputs/`)

Compose inside `InputsModule`:

```tsx
import {
  InputsKpiRow,
  SupplierRatingList,
  FeaturedCatalogTabs,
  VoucherCard,
  DeliveryTrackingStepper,
} from "@/components/agnet/inputs";
import { td } from "@/lib/i18n/dashboard-labels";

<InputsKpiRow kpis={data.kpis} locale={locale} />
<SupplierRatingList suppliers={data.suppliers} locale={locale} />
<FeaturedCatalogTabs catalog={data.catalog} locale={locale} />
<VoucherCard voucher={data.voucher} locale={locale} />
<DeliveryTrackingStepper delivery={data.delivery} locale={locale} />
```

**Test IDs:** `inputs-module`, `inputs-kpi-row`, `inputs-supplier-list`, `inputs-catalog-tabs`, `inputs-voucher-card`, `inputs-delivery-stepper`.

---

## Data flow

1. BFF returns `FarmerDashboardResponse` (see `specs/contracts/dashboard-v2.openapi.yaml`).
2. `mapDashboardResponse()` in `lib/farmer-dashboard.ts` normalizes API → view models.
3. Dev mock personas: `lib/fixtures/dashboard-mockup-personas.ts` via `handleDevFarmerDashboard()`.
4. Pages under `app/farmers/dashboard/*` render module shells with `useFarmerDashboard()`.

---

## Testing

| Suite | Command |
|-------|---------|
| UI unit tests | `npm test -- tests/ui/` |
| Contract tests | `npm run test:contract` |
| Farmer dashboard E2E | `npm run test:e2e -- e2e/tests/farmer-dashboard.spec.ts` |
| Accessibility (axe) | `npm run test:e2e:a11y` |

E2E uses `PLAYWRIGHT=1` and `CORE_API_USE_MOCK=true` (see `playwright.config.ts`).

---

## Performance (optional)

LCP spot-check methodology:

1. Run `npm run test:e2e:perf` or Chrome DevTools → Performance → 3G throttling.
2. Target routes: `/farmers/dashboard`, `/identity`, `/finance`, `/inputs`.
3. Goal: LCP &lt; 2.5s on throttled mobile (per `UI_UX_LIBRARY_PLAN.md` §11).

Not run in Wave 3 integration — use the command above when validating before release.
