"use client" import { use, useState, useRef, useCallback } from "react" import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query" import { useAuthApi } from "@/shared/useApi" import { DataTable, ColumnHeader } from "@/shared/data-view/table-view" import DashboardPage from "@/base/components/layout/dashboard/dashboard-page" import { Badge } from "@/shared/components/ui/badge" import { Button } from "@/shared/components/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/shared/components/ui/dropdown-menu" import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/shared/components/ui/dialog" import { Input } from "@/shared/components/ui/input" import { Label } from "@/shared/components/ui/label" import { Textarea } from "@/shared/components/ui/textarea" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/shared/components/ui/select" import { toast } from "sonner" import { Plus, Ellipsis, Pencil, Trash2, CheckCircle2, AlertTriangle, XCircle, MinusCircle, CircleDot, Paperclip, FileUp, FileText, FileImage, File, X, } from "lucide-react" import { INSPECTION_ROUTES } from "@garage/api" // ── Types ── type CheckpointItem = { id: number inspection_id?: number name?: string description?: string record_type?: string condition_rate?: number file?: string status?: string created_at?: string updated_at?: string } // ── Constants ── const CHECKPOINT_STATUSES = [ { value: "passed", label: "Passed", icon: CheckCircle2, color: "bg-green-100 text-green-800" }, { value: "need_attention", label: "Need Attention", icon: AlertTriangle, color: "bg-yellow-100 text-yellow-800" }, { value: "failed", label: "Failed", icon: XCircle, color: "bg-red-100 text-red-800" }, { value: "not_applicable", label: "Not Applicable", icon: MinusCircle, color: "bg-gray-100 text-gray-800" }, { value: "not_inspected", label: "Not Inspected", icon: CircleDot, color: "bg-blue-100 text-blue-800" }, ] as const const RECORD_TYPES = [ { value: "record_conditions", label: "Record Conditions" }, { value: "record_audio", label: "Record Audio" }, { value: "record_video", label: "Record Video" }, { value: "capture_photo", label: "Capture Photo" }, ] as const function formatStatus(status?: string) { if (!status) return "Not Inspected" return status.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()) } function getStatusConfig(status?: string) { return CHECKPOINT_STATUSES.find((s) => s.value === status) || CHECKPOINT_STATUSES[4] } // ── Checkpoint Form Dialog ── function CheckpointFormDialog({ open, onOpenChange, inspectionId, checkpoint, onSuccess, }: { open: boolean onOpenChange: (open: boolean) => void inspectionId: string checkpoint?: CheckpointItem | null onSuccess: () => void }) { const api = useAuthApi() const [name, setName] = useState(checkpoint?.name ?? "") const [description, setDescription] = useState(checkpoint?.description ?? "") const [recordType, setRecordType] = useState(checkpoint?.record_type ?? "record_conditions") const [isPending, setIsPending] = useState(false) const isEditing = !!checkpoint const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!name.trim()) { toast.error("Name is required") return } setIsPending(true) try { const payload = { inspection_id: Number(inspectionId), name: name.trim(), description: description.trim() || undefined, record_type: recordType, } if (isEditing) { const promise = api.inspections.updateCheckpoint(String(checkpoint.id), payload) toast.promise(promise, { loading: "Updating checkpoint...", success: "Checkpoint updated", error: "Failed to update checkpoint", }) await promise } else { const promise = api.inspections.createCheckpoint(payload) toast.promise(promise, { loading: "Creating checkpoint...", success: "Checkpoint created", error: "Failed to create checkpoint", }) await promise } onSuccess() onOpenChange(false) } finally { setIsPending(false) } } return ( {isEditing ? "Edit Checkpoint" : "Add Checkpoint"}
setName(e.target.value)} required />