"use client" import { useCallback, useEffect, useState } from "react" import Link from "next/link" import { useParams } from "next/navigation" import { ChevronLeft, Pencil, Plus, Trash2 } from "lucide-react" import { toast } from "sonner" import { Button } from "@/shared/components/ui/button" import { Input } from "@/shared/components/ui/input" import { Textarea } from "@/shared/components/ui/textarea" import { Switch } from "@/shared/components/ui/switch" import { useAuthApi } from "@/shared/useApi" import { confirm } from "@/shared/components/confirm-dialog" import { prompt } from "@/shared/components/prompt-dialog" import { TemplateCheckpointEditDialog } from "@/modules/inspections/template-checkpoint-edit-dialog" import type { InspectionTemplate, InspectionTemplateSection, InspectionTemplateCheckPoint, InspectionSeverity, } from "@garage/api" const SEVERITY_BADGE: Record = { good: { label: "Good", cls: "bg-emerald-100 text-emerald-800" }, attention: { label: "Attention", cls: "bg-amber-100 text-amber-800" }, critical: { label: "Critical", cls: "bg-rose-100 text-rose-800" }, na: { label: "N/A", cls: "bg-slate-100 text-slate-700" }, not_inspected: { label: "Not inspected", cls: "bg-gray-100 text-gray-700" }, } const RECORD_TYPE_LABEL: Record = { capture_photo: "Photo", record_video: "Video", record_audio: "Audio", record_conditions: "0–100", wire_frame: "Wireframe", none: "No media", } export default function InspectionTemplateEditorPage() { const params = useParams<{ id: string }>() const id = params.id const api = useAuthApi() const [template, setTemplate] = useState(null) const [loading, setLoading] = useState(true) const [editing, setEditing] = useState<{ section: InspectionTemplateSection checkpoint: InspectionTemplateCheckPoint | null } | null>(null) const load = useCallback(async () => { setLoading(true) try { const res = await api.inspectionTemplates.show(id) setTemplate(res.data) } catch (e: any) { toast.error(e?.message ?? "Failed to load template") } finally { setLoading(false) } }, [id]) useEffect(() => { load() }, [load]) const updateMeta = async (partial: Partial) => { if (!template) return try { const res = await api.inspectionTemplates.update(template.id, partial) setTemplate(res.data) } catch (e: any) { toast.error(e?.message ?? "Failed to save") } } const addSection = async () => { if (!template) return const name = await prompt({ title: "New section", label: "Section name", placeholder: "e.g. Brakes", confirmLabel: "Add section", }) if (!name) return const nextOrder = (template.sections?.length ?? 0) + 1 try { await api.inspectionTemplates.createSection(template.id, { name, sort_order: nextOrder }) await load() } catch (e: any) { toast.error(e?.message ?? "Failed to add section") } } const deleteSection = async (section: InspectionTemplateSection) => { if (!template) return const confirmed = await confirm({ title: `Delete section "${section.name}"?`, description: "This will remove the section and all its checkpoints.", confirmLabel: "Delete", variant: "destructive", }) if (!confirmed) return try { await api.inspectionTemplates.destroySection(template.id, section.id) await load() } catch (e: any) { toast.error(e?.message ?? "Failed to delete section") } } const renameSection = async (section: InspectionTemplateSection, name: string) => { if (!template || name === section.name) return try { await api.inspectionTemplates.updateSection(template.id, section.id, { name }) await load() } catch (e: any) { toast.error(e?.message ?? "Failed to rename section") } } const deleteCheckpoint = async (section: InspectionTemplateSection, cp: InspectionTemplateCheckPoint, e: React.MouseEvent) => { e.stopPropagation() if (!template) return const confirmed = await confirm({ title: `Delete "${cp.name}"?`, description: "This checkpoint will be removed from the template.", confirmLabel: "Delete", variant: "destructive", }) if (!confirmed) return try { await api.inspectionTemplates.destroyCheckpoint(template.id, section.id, cp.id) await load() } catch (e: any) { toast.error(e?.message ?? "Failed to delete checkpoint") } } if (loading) return
Loading…
if (!template) return
Template not found
return (
e.currentTarget.value !== template.name && updateMeta({ name: e.currentTarget.value })} />
updateMeta({ is_active: checked })} /> {template.is_active ? "Active" : "Inactive"}