"use client"; import * as React from "react"; import { z } from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { Check, ChevronsUpDown, Loader } from "lucide-react"; import { toast } from "sonner"; import { useRouter } from "next/navigation"; // Add this import import { Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, } from "@/components/ui/sheet"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage, } from "@/components/ui/form"; import { Popover, PopoverTrigger, PopoverContent, } from "@/components/ui/popover" import { Command, CommandInput, CommandList, CommandGroup, CommandItem, CommandEmpty, } from "@/components/ui/command" import { DataTableColumnJSON } from "./form-data-table-columns"; import { updateFormDataInDB } from "@/lib/forms/services"; import { cn } from "@/lib/utils"; interface UpdateTagSheetProps extends React.ComponentPropsWithoutRef { open: boolean; onOpenChange: (open: boolean) => void; columns: DataTableColumnJSON[]; rowData: Record | null; formCode: string; contractItemId: number; /** 업데이트 성공 시 호출될 콜백 */ onUpdateSuccess?: (updatedValues: Record) => void; } export function UpdateTagSheet({ open, onOpenChange, columns, rowData, formCode, contractItemId, onUpdateSuccess, ...props }: UpdateTagSheetProps) { const [isPending, startTransition] = React.useTransition(); const router = useRouter(); // Add router hook // 1) zod 스키마 const dynamicSchema = React.useMemo(() => { const shape: Record> = {}; for (const col of columns) { if (col.type === "NUMBER") { shape[col.key] = z .union([z.coerce.number(), z.nan()]) .transform((val) => (isNaN(val) ? undefined : val)) .optional(); } else { shape[col.key] = z.string().optional(); } } return z.object(shape); }, [columns]); // 2) form init const form = useForm({ resolver: zodResolver(dynamicSchema), defaultValues: React.useMemo(() => { if (!rowData) return {}; const defaults: Record = {}; for (const col of columns) { defaults[col.key] = rowData[col.key] ?? ""; } return defaults; }, [rowData, columns]), }); React.useEffect(() => { if (!rowData) { form.reset({}); return; } const defaults: Record = {}; for (const col of columns) { defaults[col.key] = rowData[col.key] ?? ""; } form.reset(defaults); }, [rowData, columns, form]); async function onSubmit(values: Record) { startTransition(async () => { try { const { success, message } = await updateFormDataInDB( formCode, contractItemId, values ); if (!success) { toast.error(message); return; } // Success handling toast.success("Updated successfully!"); // Create a merged object of original rowData and new values const updatedData = { ...rowData, ...values, TAG_NO: rowData?.TAG_NO, }; // Call the success callback onUpdateSuccess?.(updatedData); // Refresh the entire route to get fresh data router.refresh(); // Close the sheet onOpenChange(false); } catch (error) { console.error("Error updating form data:", error); toast.error("An unexpected error occurred while updating"); } }); } return ( Update Row Modify the fields below and save changes
{columns.map((col) => { const isTagNumberField = col.key === "TAG_NO" || col.key === "TAG_DESC"; return ( { switch (col.type) { case "NUMBER": return ( {col.displayLabel} { const num = parseFloat(e.target.value); field.onChange(isNaN(num) ? "" : num); }} value={field.value ?? ""} /> ); case "LIST": return ( {col.label} No option found. {col.options?.map((opt) => ( { field.onChange(opt); }} > {opt} ))} ); // case "date": // return ( // // {col.label} // // // // // // ) case "STRING": default: return ( {col.label} ); } }} /> ); })}
); }