diff options
Diffstat (limited to 'lib/tech-vendor-candidates/table/update-candidate-sheet.tsx')
| -rw-r--r-- | lib/tech-vendor-candidates/table/update-candidate-sheet.tsx | 437 |
1 files changed, 0 insertions, 437 deletions
diff --git a/lib/tech-vendor-candidates/table/update-candidate-sheet.tsx b/lib/tech-vendor-candidates/table/update-candidate-sheet.tsx deleted file mode 100644 index 3d278126..00000000 --- a/lib/tech-vendor-candidates/table/update-candidate-sheet.tsx +++ /dev/null @@ -1,437 +0,0 @@ -"use client" - -import * as React from "react" -import { zodResolver } from "@hookform/resolvers/zod" -import { Check, ChevronsUpDown, Loader } from "lucide-react" -import { useForm } from "react-hook-form" -import { toast } from "sonner" -import i18nIsoCountries from "i18n-iso-countries" -import enLocale from "i18n-iso-countries/langs/en.json" -import koLocale from "i18n-iso-countries/langs/ko.json" -import { cn } from "@/lib/utils" - -import { Button } from "@/components/ui/button" -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@/components/ui/form" -import { - Select, - SelectContent, - SelectGroup, - SelectItem, - SelectTrigger, - SelectValue, -} from "@/components/ui/select" -import { - Sheet, - SheetClose, - SheetContent, - SheetDescription, - SheetFooter, - SheetHeader, - SheetTitle, -} from "@/components/ui/sheet" -import { Input } from "@/components/ui/input" -import { Textarea } from "@/components/ui/textarea" -import { - Popover, - PopoverContent, - PopoverTrigger, -} from "@/components/ui/popover" -import { - Command, - CommandEmpty, - CommandGroup, - CommandInput, - CommandItem, - CommandList, -} from "@/components/ui/command" -import { useSession } from "next-auth/react" // next-auth 세션 훅 - -import { updateVendorCandidateSchema, UpdateVendorCandidateSchema } from "../validations" -import { updateVendorCandidate } from "../service" -import { vendorCandidates,VendorCandidatesWithVendorInfo} from "@/db/schema" - -// Register locales for countries -i18nIsoCountries.registerLocale(enLocale) -i18nIsoCountries.registerLocale(koLocale) - -// Generate country array -const locale = "ko" -const countryMap = i18nIsoCountries.getNames(locale, { select: "official" }) -const countryArray = Object.entries(countryMap).map(([code, label]) => ({ - code, - label, -})) - -interface UpdateCandidateSheetProps - extends React.ComponentPropsWithRef<typeof Sheet> { - candidate: VendorCandidatesWithVendorInfo | null -} - -export function UpdateCandidateSheet({ candidate, ...props }: UpdateCandidateSheetProps) { - const [isUpdatePending, startUpdateTransition] = React.useTransition() - const { data: session, status } = useSession() - - // Set default values from candidate data when the component receives a new candidate - - React.useEffect(() => { - if (candidate) { - form.reset({ - id: candidate.id, - companyName: candidate.companyName, - taxId: candidate.taxId, - contactEmail: candidate.contactEmail || "", // null을 빈 문자열로 변환 - contactPhone: candidate.contactPhone || "", - address: candidate.address || "", - country: candidate.country || "", - source: candidate.source || "", - items: candidate.items, - remark: candidate.remark || "", - status: candidate.status, - }) - } - }, [candidate]) - - - const form = useForm<UpdateVendorCandidateSchema>({ - resolver: zodResolver(updateVendorCandidateSchema), - defaultValues: { - id: candidate?.id || 0, - companyName: candidate?.companyName || "", - taxId: candidate?.taxId || "", - contactEmail: candidate?.contactEmail || "", - contactPhone: candidate?.contactPhone || "", - address: candidate?.address || "", - country: candidate?.country || "", - source: candidate?.source || "", - items: candidate?.items || "", - remark: candidate?.remark || "", - status: candidate?.status || "COLLECTED", - }, - }) - - function onSubmit(input: UpdateVendorCandidateSchema) { - startUpdateTransition(async () => { - - if (!session?.user?.id) { - toast.error("인증 오류. 로그인 정보를 찾을 수 없습니다.") - return - } - const userId = Number(session.user.id) - - if (!candidate) return - - const { error } = await updateVendorCandidate({ - ...input, - }, userId) - - if (error) { - toast.error(error) - return - } - - form.reset() - props.onOpenChange?.(false) - toast.success("Vendor candidate updated") - }) - } - - return ( - <Sheet {...props}> - <SheetContent className="flex flex-col gap-6 sm:max-w-md overflow-y-auto"> - <SheetHeader className="text-left"> - <SheetTitle>Update Vendor Candidate</SheetTitle> - <SheetDescription> - Update the vendor candidate details and save the changes - </SheetDescription> - </SheetHeader> - <Form {...form}> - <form - onSubmit={form.handleSubmit(onSubmit)} - className="flex flex-col gap-4" - > - {/* Company Name Field */} - <FormField - control={form.control} - name="companyName" - render={({ field }) => ( - <FormItem> - <FormLabel>Company Name <span className="text-red-500">*</span></FormLabel> - <FormControl> - <Input - placeholder="Enter company name" - {...field} - disabled={isUpdatePending} - /> - </FormControl> - <FormMessage /> - </FormItem> - )} - /> - - {/* Tax ID Field */} - <FormField - control={form.control} - name="taxId" - render={({ field }) => ( - <FormItem> - <FormLabel>Tax ID</FormLabel> - <FormControl> - <Input - placeholder="Enter tax ID" - {...field} - disabled={isUpdatePending} - /> - </FormControl> - <FormMessage /> - </FormItem> - )} - /> - - {/* Contact Email Field */} - <FormField - control={form.control} - name="contactEmail" - render={({ field }) => ( - <FormItem> - <FormLabel>Contact Email</FormLabel> - <FormControl> - <Input - placeholder="email@example.com" - type="email" - {...field} - disabled={isUpdatePending} - /> - </FormControl> - <FormMessage /> - </FormItem> - )} - /> - - {/* Contact Phone Field */} - <FormField - control={form.control} - name="contactPhone" - render={({ field }) => ( - <FormItem> - <FormLabel>Contact Phone</FormLabel> - <FormControl> - <Input - placeholder="+82-10-1234-5678" - {...field} - disabled={isUpdatePending} - /> - </FormControl> - <FormMessage /> - </FormItem> - )} - /> - - {/* Address Field */} - <FormField - control={form.control} - name="address" - render={({ field }) => ( - <FormItem> - <FormLabel>Address</FormLabel> - <FormControl> - <Input - placeholder="Enter company address" - {...field} - disabled={isUpdatePending} - /> - </FormControl> - <FormMessage /> - </FormItem> - )} - /> - - {/* Country Field */} - <FormField - control={form.control} - name="country" - render={({ field }) => { - const selectedCountry = countryArray.find( - (c) => c.code === field.value - ) - return ( - <FormItem> - <FormLabel>Country</FormLabel> - <Popover> - <PopoverTrigger asChild> - <FormControl> - <Button - variant="outline" - role="combobox" - className={cn( - "w-full justify-between", - !field.value && "text-muted-foreground" - )} - disabled={isUpdatePending} - > - {selectedCountry - ? selectedCountry.label - : "Select a country"} - <ChevronsUpDown className="ml-2 h-4 w-4 opacity-50" /> - </Button> - </FormControl> - </PopoverTrigger> - <PopoverContent className="w-[300px] p-0"> - <Command> - <CommandInput placeholder="Search country..." /> - <CommandList> - <CommandEmpty>No country found.</CommandEmpty> - <CommandGroup className="max-h-[300px] overflow-y-auto"> - {countryArray.map((country) => ( - <CommandItem - key={country.code} - value={country.label} - onSelect={() => - field.onChange(country.code) - } - > - <Check - className={cn( - "mr-2 h-4 w-4", - country.code === field.value - ? "opacity-100" - : "opacity-0" - )} - /> - {country.label} - </CommandItem> - ))} - </CommandGroup> - </CommandList> - </Command> - </PopoverContent> - </Popover> - <FormMessage /> - </FormItem> - ) - }} - /> - - {/* Source Field */} - <FormField - control={form.control} - name="source" - render={({ field }) => ( - <FormItem> - <FormLabel>Source <span className="text-red-500">*</span></FormLabel> - <FormControl> - <Input - placeholder="Where this candidate was found" - {...field} - disabled={isUpdatePending} - /> - </FormControl> - <FormMessage /> - </FormItem> - )} - /> - - {/* Items Field */} - <FormField - control={form.control} - name="items" - render={({ field }) => ( - <FormItem> - <FormLabel>Items <span className="text-red-500">*</span></FormLabel> - <FormControl> - <Textarea - placeholder="List of items or products this vendor provides" - className="min-h-[80px]" - {...field} - disabled={isUpdatePending} - /> - </FormControl> - <FormMessage /> - </FormItem> - )} - /> - - {/* Remark Field */} - <FormField - control={form.control} - name="remark" - render={({ field }) => ( - <FormItem> - <FormLabel>Remark</FormLabel> - <FormControl> - <Textarea - placeholder="Additional notes or comments" - className="min-h-[80px]" - {...field} - disabled={isUpdatePending} - /> - </FormControl> - <FormMessage /> - </FormItem> - )} - /> - - {/* Status Field */} - <FormField - control={form.control} - name="status" - render={({ field }) => ( - <FormItem> - <FormLabel>Status</FormLabel> - <Select - onValueChange={field.onChange} - defaultValue={field.value} - disabled={isUpdatePending} - > - <FormControl> - <SelectTrigger className="capitalize"> - <SelectValue placeholder="Select a status" /> - </SelectTrigger> - </FormControl> - <SelectContent> - <SelectGroup> - {vendorCandidates.status.enumValues.map((item) => ( - <SelectItem - key={item} - value={item} - className="capitalize" - > - {item} - </SelectItem> - ))} - </SelectGroup> - </SelectContent> - </Select> - <FormMessage /> - </FormItem> - )} - /> - - <SheetFooter className="gap-2 pt-2 sm:space-x-0"> - <SheetClose asChild> - <Button type="button" variant="outline" disabled={isUpdatePending}> - Cancel - </Button> - </SheetClose> - <Button disabled={isUpdatePending}> - {isUpdatePending && ( - <Loader - className="mr-2 size-4 animate-spin" - aria-hidden="true" - /> - )} - Save - </Button> - </SheetFooter> - </form> - </Form> - </SheetContent> - </Sheet> - ) -}
\ No newline at end of file |
