"use client" import { use, useState } from "react" import { useQuery, useQueryClient } from "@tanstack/react-query" import { useAuthApi } from "@/shared/useApi" import { ColumnHeader, DataTable } from "@/shared/data-view/table-view" import { Button } from "@/shared/components/ui/button" import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, } from "@/shared/components/ui/dialog" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/shared/components/ui/dropdown-menu" import { confirm } from "@/shared/components/confirm-dialog" import { toast } from "sonner" import { Ellipsis, Plus } from "lucide-react" import type { ColumnDef } from "@tanstack/react-table" import { JobCardPartForm } from "@/modules/job-cards/job-card-part-form" import { formatDate } from "@/shared/utils/formatters" export default function JobCardPartsPage({ params, }: { params: Promise<{ id: string }> }) { const { id: jobCardId } = use(params) const api = useAuthApi() const queryClient = useQueryClient() const queryKey = ["job-card-parts", jobCardId] const [dialogOpen, setDialogOpen] = useState(false) const [editItem, setEditItem] = useState(null) const { data, isLoading } = useQuery({ queryKey, queryFn: () => api.jobCards.getParts(jobCardId), }) const rows = (data as any)?.data ?? [] const invalidate = () => queryClient.invalidateQueries({ queryKey }) async function handleDelete(row: any) { const confirmed = await confirm({ title: "Delete this part?", description: `Remove part "${row.part?.title ?? "this part"}" from the job card?`, }) if (!confirmed) return const promise = api.jobCards.deletePart(jobCardId, row.id) toast.promise(promise, { loading: "Deleting...", success: "Part deleted", error: "Failed to delete part", }) await promise invalidate() } const columns: ColumnDef[] = [ { accessorKey: "part.title", header: ({ column }) => , cell: ({ row }) => { const part = row.original.part return part ? (
{part.title} {part.sku && ( {part.sku} )}
) : "—" }, }, { accessorKey: "quantity", header: ({ column }) => , cell: ({ row }) => row.original.quantity ?? "—", }, { accessorKey: "rate", header: ({ column }) => , cell: ({ row }) => { const val = row.original.rate return val != null ? `$${Number(val).toFixed(2)}` : "—" }, }, { accessorKey: "tax", header: ({ column }) => , cell: ({ row }) => row.original.tax || "—", }, { accessorKey: "department.name", header: ({ column }) => , cell: ({ row }) => row.original.department?.name || "—", }, { accessorKey: "description", header: ({ column }) => , cell: ({ row }) => row.original.description || "—", }, { accessorKey: "created_at", header: ({ column }) => , cell: ({ row }) => formatDate(row.original.created_at), }, { id: "actions", cell: ({ row }) => ( { setEditItem(row.original) setDialogOpen(true) }} > Edit handleDelete(row.original)} > Delete ), }, ] return (
{ setDialogOpen(open) if (!open) setEditItem(null) }} > {editItem ? "Edit Part" : "Add Part"} { setDialogOpen(false) setEditItem(null) invalidate() }} onCancel={() => { setDialogOpen(false) setEditItem(null) }} />
) }