"use client" import { AlertTriangle, Plus, Save } from "lucide-react" import { Button } from "@/shared/components/ui/button" import { Alert, AlertTitle } from "@/shared/components/ui/alert" import { FieldGroup } from "@/shared/components/ui/field" import { Rhform, RhfTextField, RhfSelectField, RhfAsyncSelectField, RhfDateField, RhfTimeField, } from "@/shared/components/form" import { toast } from "sonner" import { useAuthApi } from "@/shared/useApi" import { useResourceForm } from "@/shared/hooks/use-resource-form" import { useFormMutation } from "@/shared/hooks/use-form-mutation" import { toRelation, toId } from "@/shared/lib/utils" import { jobCardFormSchema, type JobCardFormValues, TAX_INCLUSIVE_OPTIONS, DISCOUNT_TYPE_OPTIONS, DISCOUNT_AT_OPTIONS, ESTIMATE_TO_OPTIONS, FUEL_LEVEL_OPTIONS, JOB_CARD_STATUS_OPTIONS, } from "./job-card.schema" import { JOB_CARD_ROUTES, EMPLOYEE_ROUTES, DEPARTMENT_ROUTES } from "@garage/api" import { RhfCustomerSelectField } from "@/modules/customers/rhf-customer-select-field" import { RhfVehicleSelectField } from "@/modules/vehicles/rhf-vehicle-select-field" // ── Props ── export type JobCardFormProps = { resourceId?: string | null initialData?: unknown onSuccess?: () => void } // ── Default values ── const DEFAULT_VALUES: JobCardFormValues = { title: "", customer: null, vehicle: null, department: null, service_writer: null, status: "check_in", estimate_to: "Customer", tax_inclusive: "Tax Inclusive", discount_type: "no", discount_at: "inclusive_of_tax", // check_in_date: "", // check_in_time: (() => { const n = new Date(); return `${String(n.getHours()).padStart(2,"0")}:${String(n.getMinutes()).padStart(2,"0")}:${String(n.getSeconds()).padStart(2,"0")}` })(), km_in: "", fuel_level: "", } // ── Mapping helpers ── function mapToFormValues(data: unknown): JobCardFormValues { const d = (data as any)?.data ?? data ?? {} return { title: d.title || "", customer: toRelation(d.customer_id, d.customer ? `${d.customer.first_name} ${d.customer.last_name}` : undefined), vehicle: toRelation(d.vehicle_id, d.vehicle ? `${d.vehicle.make} ${d.vehicle.model}` : undefined), department: toRelation(d.department_id, d.department?.name), service_writer: toRelation(d.service_writer_id, d.service_writer ? `${d.service_writer.first_name} ${d.service_writer.last_name}` : undefined), status: d.status || "draft", estimate_to: d.estimate_to || "Customer", tax_inclusive: d.tax_inclusive || "Tax Inclusive", discount_type: d.discount_type || "no", discount_at: d.discount_at || "inclusive_of_tax", check_in_date: d.check_in_date ? d.check_in_date.split("T")[0] : "", check_in_time: d.check_in_time ? d.check_in_time.split("T")[0] : "", km_in: d.km_in != null ? String(d.km_in) : "", fuel_level: d.fuel_level || "", } } function mapFormToPayload(values: JobCardFormValues) { return { title: values.title, customer_id: toId(values.customer), vehicle_id: toId(values.vehicle), department_id: toId(values.department), service_writer_id: toId(values.service_writer), status: values.status || undefined, estimate_to: values.estimate_to || undefined, tax_inclusive: values.tax_inclusive || undefined, discount_type: values.discount_type || undefined, discount_at: values.discount_at || undefined, check_in_date: values.check_in_date || undefined, check_in_time: values.check_in_time || undefined, km_in: values.km_in ? Number(values.km_in) : undefined, fuel_level: values.fuel_level || undefined, } } // ── Shared mapOption for async selects ── const mapLookupOption = (item: any) => ({ value: String(item.id), label: item.name, }) const mapEmployeeOption = (item: any) => ({ value: String(item.id), label: `${item.first_name} ${item.last_name}`, }) const STORE_OBJECT = { getOptionValue: (o: any) => o, getOptionLabel: (o: any) => o.label } // ── Component ── export function JobCardForm({ resourceId, initialData, onSuccess }: JobCardFormProps) { const api = useAuthApi() const { form, isEditing } = useResourceForm({ schema: jobCardFormSchema, defaultValues: DEFAULT_VALUES, resourceId, initialData, queryKey: [JOB_CARD_ROUTES.BY_ID, resourceId], mapToFormValues, }) const { mutate, error, isPending } = useFormMutation(form, { mutationFn: (values: JobCardFormValues) => { const payload = mapFormToPayload(values) const promise = (isEditing && resourceId ? api.jobCards.update(resourceId, payload) : api.jobCards.create(payload)) as Promise toast.promise(promise, { loading: isEditing ? "Updating job card..." : "Creating job card...", success: isEditing ? "Job card updated successfully" : "Job card created successfully", error: isEditing ? "Failed to update job card" : "Failed to create job card", }) return promise }, onSuccess: () => { form.reset() onSuccess?.() }, }) return ( mutate(values)}> {error && ( {isEditing ? "Failed to update job card" : "Failed to create job card"} {error.message} )}
{/* */}
api.departments.list()} mapOption={mapLookupOption} {...STORE_OBJECT} /> api.employees.list()} mapOption={mapEmployeeOption} {...STORE_OBJECT} />
{/*
*/}
) }