"use client"; import Link from "next/link"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { Badge, Button, Card, ErrorBanner, Field, Input, Modal, PageHeader, Select, Textarea } from "@/components/ui"; import { apiFetch, ApiClientError } from "@/lib/client-api"; interface ProjectRow { id: string; code: string; name: string; customerCode: string | null; status: string; dueDate: string | null; assemblyCount: number; } const STATUS_TONE: Record = { planning: "slate", in_progress: "blue", completed: "green", cancelled: "red", }; const STATUS_LABEL: Record = { planning: "Planning", in_progress: "In progress", completed: "Completed", cancelled: "Cancelled", }; function formatDate(iso: string | null) { if (!iso) return "—"; const d = new Date(iso); return d.toLocaleDateString(undefined, { year: "numeric", month: "short", day: "numeric" }); } export default function ProjectsClient({ initial }: { initial: ProjectRow[] }) { const router = useRouter(); const [newOpen, setNewOpen] = useState(false); return (
setNewOpen(true)}>New project} /> {initial.map((p) => ( ))} {initial.length === 0 && ( )}
Code Name Customer Due Assemblies Status
{p.code} {p.name} {p.customerCode ?? "—"} {formatDate(p.dueDate)} {p.assemblyCount} {STATUS_LABEL[p.status] ?? p.status} Open →
No projects yet.
{newOpen && ( setNewOpen(false)} onSaved={(id) => { setNewOpen(false); router.push(`/admin/projects/${id}`); }} /> )}
); } function NewProjectModal({ onClose, onSaved }: { onClose: () => void; onSaved: (id: string) => void }) { const [code, setCode] = useState(""); const [name, setName] = useState(""); const [customerCode, setCustomerCode] = useState(""); const [dueDate, setDueDate] = useState(""); const [notes, setNotes] = useState(""); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); async function submit(e: React.FormEvent) { e.preventDefault(); setBusy(true); setError(null); try { const res = await apiFetch<{ project: { id: string } }>("/api/v1/projects", { method: "POST", body: JSON.stringify({ code, name, customerCode: customerCode || null, dueDate: dueDate || null, notes: notes || null, }), }); onSaved(res.project.id); } catch (err) { setError(err instanceof ApiClientError ? err.message : "Save failed"); setBusy(false); } } return (
} >
setCode(e.target.value)} required autoFocus /> setName(e.target.value)} required /> setCustomerCode(e.target.value)} /> setDueDate(e.target.value)} />