"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, RhfTextareaField, RhfAsyncSelectField, RhfSelectField, RhfCheckboxField, } from "@/shared/components/form" import { ShopTypeInlineForm } from "@/modules/vehicles/inline-forms/shop-type-inline-form" import { InventoryCategoryInlineForm } from "./inline-forms/inventory-category-inline-form" import { UnitTypeInlineForm } from "./inline-forms/unit-type-inline-form" import { DepartmentInlineForm } from "./inline-forms/department-inline-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 { toId, toRelation } from "@/shared/lib/utils" import { DEPARTMENT_ROUTES, INVENTORY_ROUTES, SERVICE_ROUTES, SHOP_TYPE_ROUTES, VENDOR_ROUTES, } from "@garage/api" import { RATE_TYPE_OPTIONS, serviceFormSchema, type ServiceFormValues } from "./service.schema" // ── Props ── export type ServiceFormProps = { resourceId?: string | null initialData?: unknown onSuccess?: () => void } // ── Default values ── const DEFAULT_VALUES: ServiceFormValues = { shop_type: { value: "", label: "" }, category: { value: "", label: "" }, unit_type: { value: "", label: "" }, department: { value: "", label: "" }, labor_name: "", service_code: "", labor_matrix: "", description: "", sales_information: false, rate_type: undefined, labor_rate: null, labor_hours: undefined, sales_chart_of_account: undefined, selling_price: undefined, purchase_information: false, purchase_chart_of_account: undefined, purchase_preferred_vendor: null, purchase_price: undefined, } // ── Mapping helpers ── const mapLookupOption = (item: any) => ({ value: String(item.id), label: item.name ?? item.title ?? String(item.id), }) const mapLaborRateOption = (item: any) => ({ value: String(item.id), label: item.title ?? item.name ?? String(item.id), }) const STORE_OBJECT = { getOptionValue: (o: any) => o, getOptionLabel: (o: any) => o.label } const RATE_TYPE_SELECT_OPTIONS = RATE_TYPE_OPTIONS.map((value) => ({ value, label: value === "flat_rate" ? "Flat Rate" : "Hourly", })) function mapToFormValues(data: unknown): ServiceFormValues { const d = (data as any)?.data ?? data ?? {} return { shop_type: toRelation(d.shop_type_id, d.shop_type?.name ?? d.shop_type_name ?? d.shop_type_title), category: toRelation(d.category_id, d.category?.name ?? d.category?.title ?? d.category_name ?? d.category_title), unit_type: toRelation(d.unit_type_id, d.unit_type?.name ?? d.unit_type?.title ?? d.unit_type_name ?? d.unit_type_title), department: toRelation(d.department_id, d.department?.name ?? d.department_name ?? d.department_title), labor_name: d.name ?? d.labor_name ?? "", service_code: d.service_code ?? "", labor_matrix: d.labor_matrix ?? "", description: d.description ?? "", sales_information: d.sales_information ?? false, rate_type: RATE_TYPE_OPTIONS.includes(d.rate_type) ? d.rate_type : undefined, labor_rate: toRelation(d.labor_rate_id, d.labor_rate?.title ?? d.labor_rate_title ?? d.labor_rate_name), labor_hours: d.labor_hours != null ? Number(d.labor_hours) : undefined, sales_chart_of_account: d.sales_chart_of_account != null ? Number(d.sales_chart_of_account) : undefined, selling_price: d.selling_price != null ? Number(d.selling_price) : undefined, purchase_information: d.purchase_information ?? false, purchase_chart_of_account: d.purchase_chart_of_account != null ? Number(d.purchase_chart_of_account) : undefined, purchase_preferred_vendor: toRelation( d.purchase_preferred_vendor_id, d.purchase_preferred_vendor?.name ?? d.purchase_preferred_vendor_name, ), purchase_price: d.purchase_price != null ? Number(d.purchase_price) : undefined, } } function mapFormToPayload(values: ServiceFormValues) { return { shop_type_id: toId(values.shop_type), category_id: toId(values.category), unit_type_id: toId(values.unit_type), department_id: toId(values.department), labor_name: values.labor_name, service_code: values.service_code, labor_matrix: values.labor_matrix, description: values.description || undefined, sales_information: values.sales_information, rate_type: values.rate_type ?? undefined, labor_rate_id: toId(values.labor_rate), labor_hours: values.labor_hours ?? undefined, sales_chart_of_account: values.sales_chart_of_account ?? undefined, selling_price: values.selling_price ?? undefined, purchase_information: values.purchase_information, purchase_chart_of_account: values.purchase_chart_of_account ?? undefined, purchase_preferred_vendor_id: toId(values.purchase_preferred_vendor), purchase_price: values.purchase_price ?? undefined, } } // ── Component ── export function ServiceForm({ resourceId, initialData, onSuccess }: ServiceFormProps) { const api = useAuthApi() const isEditing = Boolean(resourceId) const { form } = useResourceForm({ schema: serviceFormSchema, defaultValues: DEFAULT_VALUES, resourceId, initialData, initialize: (id) => api.services.show(id), queryKey: [SERVICE_ROUTES.BY_ID, resourceId], mapToFormValues, }) const { mutate, error, isPending } = useFormMutation(form, { mutationFn: (values: ServiceFormValues) => { const payload = mapFormToPayload(values) const promise = isEditing && resourceId ? api.services.update(resourceId, payload) : api.services.create(payload) toast.promise(promise, { loading: isEditing ? "Updating service..." : "Creating service...", success: isEditing ? "Service updated successfully" : "Service created successfully", error: isEditing ? "Failed to update service" : "Failed to create service", }) return promise }, onSuccess: () => { form.reset() onSuccess?.() }, }) return ( mutate(values)}> {error && ( {isEditing ? "Failed to update service" : "Failed to create service"} {error.message} )}
api.shopTypes.list()} mapOption={mapLookupOption} createForm={(props) => } createLabel="Shop Type" {...STORE_OBJECT} /> api.inventory.listCategories()} mapOption={mapLookupOption} createForm={(props) => } createLabel="Category" {...STORE_OBJECT} />
api.inventory.listUnitTypes()} mapOption={mapLookupOption} createForm={(props) => } createLabel="Unit Type" {...STORE_OBJECT} /> api.departments.list()} mapOption={(item: any) => ({ value: String(item.id), label: item.name ?? String(item.id) })} createForm={(props) => } createLabel="Department" {...STORE_OBJECT} />
api.inventory.listLaborRates()} mapOption={mapLaborRateOption} {...STORE_OBJECT} />
api.vendors.list()} mapOption={(item: any) => ({ value: String(item.id), label: item.name ?? String(item.id) })} {...STORE_OBJECT} />
) }