diff options
Diffstat (limited to 'lib/vendors/table/update-vendor-sheet.tsx')
| -rw-r--r-- | lib/vendors/table/update-vendor-sheet.tsx | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/lib/vendors/table/update-vendor-sheet.tsx b/lib/vendors/table/update-vendor-sheet.tsx new file mode 100644 index 00000000..e65c4b1c --- /dev/null +++ b/lib/vendors/table/update-vendor-sheet.tsx @@ -0,0 +1,270 @@ +"use client" + +import * as React from "react" +import { zodResolver } from "@hookform/resolvers/zod" +import { useForm } from "react-hook-form" +import { Loader } from "lucide-react" +import { toast } from "sonner" + +import { Button } from "@/components/ui/button" +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { Input } from "@/components/ui/input" +import { + Sheet, + SheetClose, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, +} from "@/components/ui/sheet" +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" + +import { Vendor } from "@/db/schema/vendors" +import { updateVendorSchema, type UpdateVendorSchema } from "../validations" +import { modifyVendor } from "../service" +// 예: import { modifyVendor } from "@/lib/vendors/service" + +interface UpdateVendorSheetProps + extends React.ComponentPropsWithRef<typeof Sheet> { + vendor: Vendor | null +} + +// 폼 컴포넌트 +export function UpdateVendorSheet({ vendor, ...props }: UpdateVendorSheetProps) { + const [isPending, startTransition] = React.useTransition() + + console.log(vendor) + + // RHF + Zod + const form = useForm<UpdateVendorSchema>({ + resolver: zodResolver(updateVendorSchema), + defaultValues: { + vendorName: vendor?.vendorName ?? "", + vendorCode: vendor?.vendorCode ?? "", + address: vendor?.address ?? "", + country: vendor?.country ?? "", + phone: vendor?.phone ?? "", + email: vendor?.email ?? "", + website: vendor?.website ?? "", + status: vendor?.status ?? "ACTIVE", + }, + }) + + React.useEffect(() => { + if (vendor) { + form.reset({ + vendorName: vendor?.vendorName ?? "", + vendorCode: vendor?.vendorCode ?? "", + address: vendor?.address ?? "", + country: vendor?.country ?? "", + phone: vendor?.phone ?? "", + email: vendor?.email ?? "", + website: vendor?.website ?? "", + status: vendor?.status ?? "ACTIVE", + }); + } + }, [vendor, form]); + + console.log(form.getValues()) + // 제출 핸들러 + async function onSubmit(data: UpdateVendorSchema) { + if (!vendor) return + + startTransition(async () => { + // 서버 액션 or API + // const { error } = await modifyVendor({ id: vendor.id, ...data }) + // 여기선 간단 예시 + try { + // 예시: + const { error } = await modifyVendor({ id: String(vendor.id), ...data }) + if (error) throw new Error(error) + + toast.success("Vendor updated!") + form.reset() + props.onOpenChange?.(false) + } catch (err: any) { + toast.error(String(err)) + } + }) + } + + return ( + <Sheet {...props}> + <SheetContent className="flex flex-col gap-6 sm:max-w-md"> + <SheetHeader className="text-left"> + <SheetTitle>Update Vendor</SheetTitle> + <SheetDescription> + Update the vendor details and save the changes + </SheetDescription> + </SheetHeader> + <Form {...form}> + <form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-4"> + {/* vendorName */} + <FormField + control={form.control} + name="vendorName" + render={({ field }) => ( + <FormItem> + <FormLabel>Vendor Name</FormLabel> + <FormControl> + <Input placeholder="Vendor Name" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* vendorCode */} + <FormField + control={form.control} + name="vendorCode" + render={({ field }) => ( + <FormItem> + <FormLabel>Vendor Code</FormLabel> + <FormControl> + <Input placeholder="Code123" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* address */} + <FormField + control={form.control} + name="address" + render={({ field }) => ( + <FormItem> + <FormLabel>Address</FormLabel> + <FormControl> + <Input placeholder="123 Main St" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* country */} + <FormField + control={form.control} + name="country" + render={({ field }) => ( + <FormItem> + <FormLabel>Country</FormLabel> + <FormControl> + <Input placeholder="USA" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* phone */} + <FormField + control={form.control} + name="phone" + render={({ field }) => ( + <FormItem> + <FormLabel>Phone</FormLabel> + <FormControl> + <Input placeholder="+1 555-1234" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* email */} + <FormField + control={form.control} + name="email" + render={({ field }) => ( + <FormItem> + <FormLabel>Email</FormLabel> + <FormControl> + <Input placeholder="vendor@example.com" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* website */} + <FormField + control={form.control} + name="website" + render={({ field }) => ( + <FormItem> + <FormLabel>Website</FormLabel> + <FormControl> + <Input placeholder="https://www.vendor.com" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + {/* status */} + <FormField + control={form.control} + name="status" + render={({ field }) => ( + <FormItem> + <FormLabel>Status</FormLabel> + <FormControl> + <Select + value={field.value} + onValueChange={field.onChange} + > + <SelectTrigger className="capitalize"> + <SelectValue placeholder="Select a status" /> + </SelectTrigger> + <SelectContent> + <SelectGroup> + {/* enum ["ACTIVE","INACTIVE","BLACKLISTED"] */} + <SelectItem value="ACTIVE">ACTIVE</SelectItem> + <SelectItem value="INACTIVE">INACTIVE</SelectItem> + <SelectItem value="BLACKLISTED">BLACKLISTED</SelectItem> + </SelectGroup> + </SelectContent> + </Select> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + + <SheetFooter className="gap-2 pt-2 sm:space-x-0"> + <SheetClose asChild> + <Button type="button" variant="outline"> + Cancel + </Button> + </SheetClose> + <Button disabled={isPending}> + {isPending && ( + <Loader className="mr-2 h-4 w-4 animate-spin" aria-hidden="true" /> + )} + Save + </Button> + </SheetFooter> + </form> + </Form> + </SheetContent> + </Sheet> + ) +}
\ No newline at end of file |
