"use client" import type { FieldValues, FieldPath } from "react-hook-form" import { Trash2 } from "lucide-react" import { Button } from "@/shared/components/ui/button" import { Input } from "@/shared/components/ui/input" import { Table, TableHeader, TableBody, TableHead, TableRow, TableCell, } from "@/shared/components/ui/table" import { RhfResourceField } from "@/shared/components/resource-selector" import { expenseItemColumns } from "./expense-items-columns" import { EXPENSE_ITEM_ROUTES } from "@garage/api" import type { ExpenseItemsClient } from "@garage/api" type ExpenseLineItem = { expense_id: number title: string quantity: number rate: number chart_of_account?: string discount_amount?: number description?: string } type ExpenseItemsFieldConstraint = ExpenseLineItem[] | undefined export type ExpenseItemsSelectorFieldProps< TValues extends FieldValues, TName extends FieldPath, > = { name: TName & (TValues[TName] extends ExpenseItemsFieldConstraint ? TName : never) label?: string triggerLabel?: string showChartOfAccount?: boolean showDiscount?: boolean } export function ExpenseItemsSelectorField< TValues extends FieldValues, TName extends FieldPath, >({ name, label = "Expense Items", triggerLabel = "Add Expense Items", showChartOfAccount = false, showDiscount = false, }: ExpenseItemsSelectorFieldProps) { return ( name={name} label={label} triggerLabel={triggerLabel} itemKey="expense_id" dialogProps={{ title: "Select Expense Items", crudProps: { routeKey: EXPENSE_ITEM_ROUTES.INDEX, getClient: (api) => api.expenseItems, columns: [ expenseItemColumns.name, expenseItemColumns.purchasePrice, expenseItemColumns.chartOfAccount, ], }, }} mapSelected={(row) => { const r = row as any return { expense_id: r.id, title: r.item_name || "", quantity: 1, rate: Number(r.purchase_price) || 0, chart_of_account: r.purchase_chart_of_account ? String(r.purchase_chart_of_account) : "", description: "", } as any }} renderItems={(items, { remove, update }) => ( Expense Item Qty Rate {showChartOfAccount && Chart of Account} {showDiscount && Discount} Description {((items as ExpenseLineItem[] | undefined) ?? []).map((item, index) => ( {item.title} update(index, { ...item, quantity: Number(e.target.value) || 1 } as any) } className="h-8 w-20" /> update(index, { ...item, rate: Number(e.target.value) || 0 } as any) } className="h-8 w-24" /> {showChartOfAccount && ( update(index, { ...item, chart_of_account: e.target.value } as any) } placeholder="Optional" className="h-8 w-32" /> )} {showDiscount && ( update(index, { ...item, discount_amount: Number(e.target.value) || 0 } as any) } className="h-8 w-24" /> )} update(index, { ...item, description: e.target.value } as any) } placeholder="Optional description" className="h-8" /> ))}
)} /> ) }