import Link from "next/link"; import { notFound } from "next/navigation"; import { Plus } from "lucide-react"; import { getTranslations } from "next-intl/server"; import { PageHead } from "@/components/mockup-ui"; import { Modal } from "@/components/modal"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { CustomerForm } from "@/components/customers/customer-form"; import { CustomerStatusPill } from "@/components/customers/status"; import { buttonLinkClass, controlClass, hrefWith, Pagination, paginationSummary, primaryButtonClass } from "@/components/customers/form-ui"; import { createCustomerAction } from "@/server/actions/customers/customers"; import { requirePageContext } from "@/server/api/context"; import { can } from "@/server/services/context"; import { CUSTOMER_LIST_STATUSES, listCustomers, type CustomerListStatus } from "@/server/services/customers/customers"; import { customerDisplayName } from "@/server/services/customers/format"; type SearchParams = Promise<{ q?: string; status?: string; page?: string; new?: string }>; /** Customer list (spec §7): search, status filter incl. "provisional", 25 per page, create popup. */ export default async function CustomersPage({ searchParams }: { searchParams: SearchParams }) { const ctx = await requirePageContext("customers"); if (!can(ctx, "customer:read")) notFound(); const [t, tc] = await Promise.all([getTranslations("customers"), getTranslations("common")]); const sp = await searchParams; const status: CustomerListStatus | "all" = (CUSTOMER_LIST_STATUSES as readonly string[]).includes(sp.status ?? "") ? (sp.status as CustomerListStatus) : "all"; const q = sp.q?.trim() || undefined; const page = Math.max(1, Math.floor(Number(sp.page)) || 1); const result = await listCustomers(ctx, { q, status, page, pageSize: 25 }); const canWrite = can(ctx, "customer:write"); const listHref = (p: number) => hrefWith("/customers", { q, status: status === "all" ? undefined : status, page: p > 1 ? p : undefined }); const closeHref = listHref(page); return (
1 ? page : undefined, new: 1 })} className={primaryButtonClass}> {t("new")} ) : undefined } />
{(q || status !== "all") && ( {t("filter.reset")} )}
{t("columns.number")} {t("columns.name")} {t("columns.city")} {t("columns.contact")} {t("columns.sites")} {t("columns.status")} {result.items.map((c) => { const href = `/customers/${c.id}`; return ( {c.customerNumber ?? "—"} {customerDisplayName(c) || "—"} {[c.postalCode, c.city].filter(Boolean).join(" ") || "—"} {c.phone || c.email || "—"} {c._count.sites} ); })} {result.items.length === 0 && ( {t("empty")} )}
{canWrite && sp.new && ( )}
); }