# Feature page conventions (read before writing any page) This is a **static-export** Next.js 16 SPA. Every page is a Client Component (`"use client"` at the top). All data fetching happens in the browser via the helpers below. Persian (Farsi), RTL. Look at the reference page `app/dashboard/media/categories/page.tsx` and copy its structure. ## Imports & contracts ```ts import { apiFetch, ApiError, toFormData, unwrap } from "@/lib/api"; import { useList, useItem } from "@/lib/useResource"; import { useToast } from "@/components/toast"; import { DataTable, type Column } from "@/components/DataTable"; import { Button, ConfirmDialog, Field, Input, Textarea, Select, Switch, Modal, PageHeader, Card, Badge, EmptyState, } from "@/components/ui"; import { EditIcon, PlusIcon, TrashIcon } from "@/components/icons"; import { toFa, formatDuration } from "@/lib/utils"; ``` ### `apiFetch(path, { method, body, query, baseUrl, auth })` - `path` is appended to the meditation base (`/api` already implied — pass e.g. `"/media"`). - `body`: pass a **plain object** for JSON, or a **FormData** for multipart. Build multipart with `toFormData({...})` (handles File, arrays as `key[]`, booleans as 1/0, skips empty). - Bearer token is attached automatically. Throws `ApiError` (has `.message`, `.status`). ### `useList(path, query?)` → `{ data: T[], loading, error, reload }` Use for GET list endpoints. Already unwraps `{ data: [...] }`. ### `useItem(path)` → `{ data, loading, error, reload }` Use for a single GET record (e.g. settings). ### `DataTable` props: `columns`, `rows`, `loading`, `error`, `emptyMessage?`, `actions?(row)` `Column = { key, header, render?(row), className? }`. ### Form components - `{children}` wraps an input with a label. - ``, `