"use client" import * as React from "react" import { zodResolver } from "@hookform/resolvers/zod" import { useForm } from "react-hook-form" import { Loader, Activity, AlertCircle, AlertTriangle, ClipboardList, FilePenLine, XCircle, Circle as CircleIcon, Building, } from "lucide-react" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, FormDescription } 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 { useSession } from "next-auth/react" // Import useSession import { TechVendor, techVendors } from "@/db/schema/techVendors" import { updateTechVendorSchema, type UpdateTechVendorSchema } from "../validations" import { modifyTechVendor } from "../service" interface UpdateVendorSheetProps extends React.ComponentPropsWithRef { vendor: TechVendor | null } type StatusType = (typeof techVendors.status.enumValues)[number]; type StatusConfig = { Icon: React.ElementType; className: string; label: string; }; // 상태 표시 유틸리티 함수 const getStatusConfig = (status: StatusType): StatusConfig => { switch(status) { case "ACTIVE": return { Icon: Activity, className: "text-emerald-600", label: "활성 상태" }; case "INACTIVE": return { Icon: AlertCircle, className: "text-gray-600", label: "비활성 상태" }; case "BLACKLISTED": return { Icon: AlertTriangle, className: "text-slate-800", label: "거래 금지" }; default: return { Icon: CircleIcon, className: "text-gray-600", label: status }; } }; // 폼 컴포넌트 export function UpdateVendorSheet({ vendor, ...props }: UpdateVendorSheetProps) { const [isPending, startTransition] = React.useTransition() const { data: session } = useSession() // 폼 정의 - UpdateVendorSchema 타입을 직접 사용 const form = useForm({ resolver: zodResolver(updateTechVendorSchema), defaultValues: { // 업체 기본 정보 vendorName: vendor?.vendorName ?? "", vendorCode: vendor?.vendorCode ?? "", address: vendor?.address ?? "", country: vendor?.country ?? "", phone: vendor?.phone ?? "", email: vendor?.email ?? "", website: vendor?.website ?? "", techVendorType: vendor?.techVendorType ? vendor.techVendorType.split(',').filter(Boolean) : [], 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 ?? "", techVendorType: vendor?.techVendorType ? vendor.techVendorType.split(',').filter(Boolean) : [], status: vendor?.status ?? "ACTIVE", }); } }, [vendor, form]); // 제출 핸들러 async function onSubmit(data: UpdateTechVendorSchema) { if (!vendor) return if (!session?.user?.id) { toast.error("사용자 인증 정보를 찾을 수 없습니다.") return } startTransition(async () => { try { // Add status change comment if status has changed const oldStatus = vendor.status ?? "ACTIVE" // Default to ACTIVE if undefined const newStatus = data.status ?? "ACTIVE" // Default to ACTIVE if undefined const statusComment = oldStatus !== newStatus ? `상태 변경: ${getStatusConfig(oldStatus).label} → ${getStatusConfig(newStatus).label}` : "" // Empty string instead of undefined // 업체 정보 업데이트 - userId와 상태 변경 코멘트 추가 const { error } = await modifyTechVendor({ id: String(vendor.id), userId: Number(session.user.id), // Add user ID from session comment: statusComment, // Add comment for status changes ...data, // 모든 데이터 전달 - 서비스 함수에서 필요한 필드만 처리 techVendorType: data.techVendorType ? data.techVendorType.join(',') : undefined, }) if (error) throw new Error(error) toast.success("업체 정보가 업데이트되었습니다!") form.reset() props.onOpenChange?.(false) } catch (err: any) { toast.error(String(err)) } }) } return ( 업체 정보 수정 업체 세부 정보를 수정하고 변경 사항을 저장하세요
{/* 업체 기본 정보 섹션 */}

업체 기본 정보

업체가 제공한 기본 정보입니다. 필요시 수정하세요.
{/* vendorName */} ( 업체명 )} /> {/* vendorCode */} ( 업체 코드 )} /> {/* address */} ( 주소 )} /> {/* country */} ( 국가 )} /> {/* phone */} ( 전화번호 )} /> {/* email */} ( 이메일 )} /> {/* website */} ( 웹사이트 )} /> {/* techVendorType */} ( 벤더 타입 *
{["조선", "해양TOP", "해양HULL"].map((type) => (
{ const currentValue = field.value || []; if (e.target.checked) { field.onChange([...currentValue, type]); } else { field.onChange(currentValue.filter((v) => v !== type)); } }} className="w-4 h-4" />
))}
)} /> {/* status with icons */} { // 현재 선택된 상태의 구성 정보 가져오기 const selectedConfig = getStatusConfig(field.value ?? "ACTIVE"); const SelectedIcon = selectedConfig?.Icon || CircleIcon; return ( 업체승인상태 ); }} />
) }