"use client" import { AlertTriangle, Plus, Save, Trash2 } from "lucide-react" import { useFieldArray } from "react-hook-form" 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, } 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 { inventoryAdjustmentFormSchema, type InventoryAdjustmentFormValues, } from "./inventory-adjustment.schema" import { INVENTORY_ADJUSTMENT_ROUTES, REASON_ROUTES, PARTS_ROUTES } from "@garage/api" // ── Props ── export type InventoryAdjustmentFormProps = { resourceId?: string | null initialData?: unknown onSuccess?: () => void } // ── Default values ── const DEFAULT_VALUES: InventoryAdjustmentFormValues = { reference_number: "", date: "", chart_of_account: "", reason: null, notes: "", parts: [{ part: null, quantity: 1, rate: 0 }], } // ── Mapping helpers ── function mapToFormValues(data: unknown): InventoryAdjustmentFormValues { const d = (data as any)?.data ?? data ?? {} return { reference_number: d.reference_number || "", date: d.date || "", chart_of_account: d.chart_of_account || "", reason: toRelation(d.reason_id, d.reason_name), notes: d.notes || "", parts: Array.isArray(d.parts) && d.parts.length > 0 ? d.parts.map((p: any) => ({ part: toRelation(p.part_id, p.part_name), quantity: p.quantity ?? 1, rate: p.rate ?? 0, })) : [{ part: null, quantity: 1, rate: 0 }], } } function mapFormToPayload(values: InventoryAdjustmentFormValues) { return { reference_number: values.reference_number || undefined, date: values.date || undefined, chart_of_account: values.chart_of_account || undefined, reason_id: toId(values.reason) ? Number(toId(values.reason)) : undefined, notes: values.notes || undefined, parts: values.parts.map((p) => ({ part_id: toId(p.part) ? Number(toId(p.part)) : undefined, quantity: p.quantity, rate: p.rate, })), } } const mapLookupOption = (item: any) => ({ value: String(item.id), label: item.name ?? item.title }) const STORE_OBJECT = { getOptionValue: (o: any) => o, getOptionLabel: (o: any) => o.label } // ── Component ── export function InventoryAdjustmentForm({ resourceId, initialData, onSuccess }: InventoryAdjustmentFormProps) { const api = useAuthApi() const { form, isEditing } = useResourceForm({ schema: inventoryAdjustmentFormSchema, defaultValues: DEFAULT_VALUES, resourceId, initialData, mapToFormValues, }) const { fields, append, remove } = useFieldArray({ control: form.control, name: "parts", }) const { mutate, error, isPending } = useFormMutation(form, { mutationFn: (values: InventoryAdjustmentFormValues) => { const payload = mapFormToPayload(values) const promise = isEditing && resourceId ? api.inventoryAdjustments.update(resourceId, payload as never) : api.inventoryAdjustments.create(payload as never) return promise }, onSuccess: () => { toast.success(isEditing ? "Adjustment updated." : "Adjustment created.") onSuccess?.() }, }) return ( {error && ( {isEditing ? "Failed to update adjustment" : "Failed to create adjustment"} {error.message} )}
api.reasons.list()} mapOption={mapLookupOption} {...STORE_OBJECT} />
Parts
{fields.length === 0 && (

No parts added. Click "Add Part" to begin.

)} {fields.map((field, index) => (
api.parts.list()} mapOption={mapLookupOption} {...STORE_OBJECT} />
))}
) }