From ef4c533ebacc2cdc97e518f30e9a9350004fcdfb Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Mon, 28 Apr 2025 02:13:30 +0000
Subject: ~20250428 작업사항
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/signup/join-form.tsx | 323 +++++++++++++++++++++++++++++++++-------
 1 file changed, 270 insertions(+), 53 deletions(-)

(limited to 'components/signup/join-form.tsx')

diff --git a/components/signup/join-form.tsx b/components/signup/join-form.tsx
index 6f9ad891..e53e779f 100644
--- a/components/signup/join-form.tsx
+++ b/components/signup/join-form.tsx
@@ -39,7 +39,7 @@ import { Check, ChevronsUpDown, Loader2, Plus, X } from "lucide-react"
 import { cn } from "@/lib/utils"
 import { useTranslation } from "@/i18n/client"
 
-import { createVendor } from "@/lib/vendors/service"
+import { createVendor, getVendorTypes } from "@/lib/vendors/service"
 import { createVendorSchema, CreateVendorSchema } from "@/lib/vendors/validations"
 import {
   Select,
@@ -81,6 +81,63 @@ const countryArray = Object.entries(countryMap).map(([code, label]) => ({
   label,
 }))
 
+// Sort countries to put Korea first, then alphabetically
+const sortedCountryArray = [...countryArray].sort((a, b) => {
+  // Put Korea (KR) at the top
+  if (a.code === "KR") return -1;
+  if (b.code === "KR") return 1;
+  
+  // Otherwise sort alphabetically
+  return a.label.localeCompare(b.label);
+});
+
+// Add English names for Korean locale
+const enhancedCountryArray = sortedCountryArray.map(country => ({
+  ...country,
+  label: locale === "ko" && country.code === "KR" 
+    ? "대한민국 (South Korea)" 
+    : country.label
+}));
+
+// Comprehensive list of country dial codes
+const countryDialCodes: { [key: string]: string } = {
+  AF: "+93", AL: "+355", DZ: "+213", AS: "+1-684", AD: "+376", AO: "+244",
+  AI: "+1-264", AG: "+1-268", AR: "+54", AM: "+374", AW: "+297", AU: "+61",
+  AT: "+43", AZ: "+994", BS: "+1-242", BH: "+973", BD: "+880", BB: "+1-246",
+  BY: "+375", BE: "+32", BZ: "+501", BJ: "+229", BM: "+1-441", BT: "+975",
+  BO: "+591", BA: "+387", BW: "+267", BR: "+55", BN: "+673", BG: "+359",
+  BF: "+226", BI: "+257", KH: "+855", CM: "+237", CA: "+1", CV: "+238",
+  KY: "+1-345", CF: "+236", TD: "+235", CL: "+56", CN: "+86", CO: "+57",
+  KM: "+269", CG: "+242", CD: "+243", CR: "+506", CI: "+225", HR: "+385",
+  CU: "+53", CY: "+357", CZ: "+420", DK: "+45", DJ: "+253", DM: "+1-767",
+  DO: "+1-809", EC: "+593", EG: "+20", SV: "+503", GQ: "+240", ER: "+291",
+  EE: "+372", ET: "+251", FJ: "+679", FI: "+358", FR: "+33", GA: "+241",
+  GM: "+220", GE: "+995", DE: "+49", GH: "+233", GR: "+30", GD: "+1-473",
+  GT: "+502", GN: "+224", GW: "+245", GY: "+592", HT: "+509", HN: "+504",
+  HK: "+852", HU: "+36", IS: "+354", IN: "+91", ID: "+62", IR: "+98",
+  IQ: "+964", IE: "+353", IL: "+972", IT: "+39", JM: "+1-876", JP: "+81",
+  JO: "+962", KZ: "+7", KE: "+254", KI: "+686", KR: "+82", KW: "+965",
+  KG: "+996", LA: "+856", LV: "+371", LB: "+961", LS: "+266", LR: "+231",
+  LY: "+218", LI: "+423", LT: "+370", LU: "+352", MK: "+389", MG: "+261",
+  MW: "+265", MY: "+60", MV: "+960", ML: "+223", MT: "+356", MH: "+692",
+  MR: "+222", MU: "+230", MX: "+52", FM: "+691", MD: "+373", MC: "+377",
+  MN: "+976", ME: "+382", MA: "+212", MZ: "+258", MM: "+95", NA: "+264",
+  NR: "+674", NP: "+977", NL: "+31", NZ: "+64", NI: "+505", NE: "+227",
+  NG: "+234", NU: "+683", KP: "+850", NO: "+47", OM: "+968", PK: "+92",
+  PW: "+680", PS: "+970", PA: "+507", PG: "+675", PY: "+595", PE: "+51",
+  PH: "+63", PL: "+48", PT: "+351", PR: "+1-787", QA: "+974", RO: "+40",
+  RU: "+7", RW: "+250", KN: "+1-869", LC: "+1-758", VC: "+1-784", WS: "+685",
+  SM: "+378", ST: "+239", SA: "+966", SN: "+221", RS: "+381", SC: "+248",
+  SL: "+232", SG: "+65", SK: "+421", SI: "+386", SB: "+677", SO: "+252",
+  ZA: "+27", SS: "+211", ES: "+34", LK: "+94", SD: "+249", SR: "+597",
+  SZ: "+268", SE: "+46", CH: "+41", SY: "+963", TW: "+886", TJ: "+992",
+  TZ: "+255", TH: "+66", TL: "+670", TG: "+228", TK: "+690", TO: "+676",
+  TT: "+1-868", TN: "+216", TR: "+90", TM: "+993", TV: "+688", UG: "+256",
+  UA: "+380", AE: "+971", GB: "+44", US: "+1", UY: "+598", UZ: "+998",
+  VU: "+678", VA: "+39-06", VE: "+58", VN: "+84", YE: "+967", ZM: "+260",
+  ZW: "+263"
+};
+
 const MAX_FILE_SIZE = 3e9
 
 export function JoinForm() {
@@ -92,16 +149,54 @@ export function JoinForm() {
   const searchParams = useSearchParams() || new URLSearchParams(); 
   const defaultTaxId = searchParams.get("taxID") ?? ""
 
+  // Define VendorType interface
+  interface VendorType {
+    id: number;
+    code: string;
+    nameKo: string;
+    nameEn: string;
+  }
+
+  // Vendor Types state with proper typing
+  const [vendorTypes, setVendorTypes] = React.useState<VendorType[]>([])
+  const [isLoadingVendorTypes, setIsLoadingVendorTypes] = React.useState(true)
+
   // File states
   const [selectedFiles, setSelectedFiles] = React.useState<File[]>([])
 
   const [isSubmitting, setIsSubmitting] = React.useState(false)
 
+  // Fetch vendor types on component mount
+  React.useEffect(() => {
+    async function loadVendorTypes() {
+      setIsLoadingVendorTypes(true)
+      try {
+        const result = await getVendorTypes()
+        if (result.data) {
+          setVendorTypes(result.data)
+        }
+      } catch (error) {
+        console.error("Failed to load vendor types:", error)
+        toast({
+          variant: "destructive",
+          title: "Error",
+          description: "Failed to load vendor types",
+        })
+      } finally {
+        setIsLoadingVendorTypes(false)
+      }
+    }
+    
+    loadVendorTypes()
+  }, [])
+
   // React Hook Form
   const form = useForm<CreateVendorSchema>({
     resolver: zodResolver(createVendorSchema),
     defaultValues: {
       vendorName: "",
+      vendorTypeId: undefined,
+      items: "",
       taxId: defaultTaxId,
       address: "",
       email: "",
@@ -126,7 +221,9 @@ export function JoinForm() {
     mode: "onChange",
   })
   const isFormValid = form.formState.isValid
-
+  console.log("Form errors:", form.formState.errors);
+  console.log("Form values:", form.getValues());
+  console.log("Form valid:", form.formState.isValid);
 
 
   // Field array for contacts
@@ -168,6 +265,8 @@ export function JoinForm() {
 
       const vendorData = {
         vendorName: values.vendorName,
+        vendorTypeId: values.vendorTypeId,
+        items: values.items,
         vendorCode: values.vendorCode,
         website: values.website,
         taxId: values.taxId,
@@ -194,7 +293,7 @@ export function JoinForm() {
           title: "등록 완료",
           description: "회사 등록이 완료되었습니다. (status=PENDING_REVIEW)",
         })
-        router.push("/")
+        router.push("/ko/partners")
       } else {
         toast({
           variant: "destructive",
@@ -214,6 +313,12 @@ export function JoinForm() {
     }
   }
 
+  // Get country code for phone number placeholder
+  const getPhonePlaceholder = (countryCode: string) => {
+    if (!countryCode || !countryDialCodes[countryCode]) return "전화번호";
+    return `${countryDialCodes[countryCode]} 전화번호`;
+  };
+
   // Render
   return (
     <div className="container py-6">
@@ -244,79 +349,123 @@ export function JoinForm() {
               <div className="rounded-md border p-4 space-y-4">
                 <h4 className="text-md font-semibold">기본 정보</h4>
                 <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
-                  {/* vendorName is required in the schema → show * */}
+                  {/* Vendor Type - New Field */}
                   <FormField
                     control={form.control}
-                    name="vendorName"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel className="after:content-['*'] after:ml-0.5 after:text-red-500">
-                          업체명
-                        </FormLabel>
-                        <FormControl>
-                          <Input {...field} disabled={isSubmitting} />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
-                  />
-
-                  {/* Address (optional, no * here) */}
-                  <FormField
-                    control={form.control}
-                    name="address"
-                    render={({ field }) => (
-                      <FormItem>
-                        <FormLabel>주소</FormLabel>
-                        <FormControl>
-                          <Input {...field} disabled={isSubmitting} />
-                        </FormControl>
-                        <FormMessage />
-                      </FormItem>
-                    )}
+                    name="vendorTypeId"
+                    render={({ field }) => {
+                      const selectedType = vendorTypes.find(type => type.id === field.value);
+                      const displayName = lng === "ko" ? 
+                        (selectedType?.nameKo || "") : 
+                        (selectedType?.nameEn || "");
+                        
+                      return (
+                        <FormItem>
+                          <FormLabel className="after:content-['*'] after:ml-0.5 after:text-red-500">
+                            업체유형
+                          </FormLabel>
+                          <Popover>
+                            <PopoverTrigger asChild>
+                              <FormControl>
+                                <Button
+                                  variant="outline"
+                                  role="combobox"
+                                  className={cn(
+                                    "w-full justify-between",
+                                    !field.value && "text-muted-foreground"
+                                  )}
+                                  disabled={isSubmitting || isLoadingVendorTypes}
+                                >
+                                  {isLoadingVendorTypes 
+                                    ? "Loading..." 
+                                    : displayName || "업체유형 선택"}
+                                  <ChevronsUpDown className="ml-2 opacity-50" />
+                                </Button>
+                              </FormControl>
+                            </PopoverTrigger>
+                            <PopoverContent className="w-full p-0">
+                              <Command>
+                                <CommandInput placeholder="업체유형 검색..." />
+                                <CommandList>
+                                  <CommandEmpty>No vendor type found.</CommandEmpty>
+                                  <CommandGroup>
+                                    {vendorTypes.map((type) => (
+                                      <CommandItem
+                                        key={type.id}
+                                        value={lng === "ko" ? type.nameKo : type.nameEn}
+                                        onSelect={() => field.onChange(type.id)}
+                                      >
+                                        <Check
+                                          className={cn(
+                                            "mr-2",
+                                            type.id === field.value
+                                              ? "opacity-100"
+                                              : "opacity-0"
+                                          )}
+                                        />
+                                        {lng === "ko" ? type.nameKo : type.nameEn}
+                                      </CommandItem>
+                                    ))}
+                                  </CommandGroup>
+                                </CommandList>
+                              </Command>
+                            </PopoverContent>
+                          </Popover>
+                          <FormMessage />
+                        </FormItem>
+                      );
+                    }}
                   />
 
+                  {/* vendorName */}
                   <FormField
                     control={form.control}
-                    name="phone"
+                    name="vendorName"
                     render={({ field }) => (
                       <FormItem>
-                        <FormLabel>대표 전화</FormLabel>
+                        <FormLabel className="after:content-['*'] after:ml-0.5 after:text-red-500">
+                          업체명
+                        </FormLabel>
                         <FormControl>
                           <Input {...field} disabled={isSubmitting} />
                         </FormControl>
+                        <FormDescription>
+                          {form.watch("country") === "KR" 
+                            ? "사업자 등록증에 표기된 정확한 회사명을 입력하세요."
+                            : "해외 업체의 경우 영문 회사명을 입력하세요."}
+                        </FormDescription>
                         <FormMessage />
                       </FormItem>
                     )}
                   />
 
-                  {/* email is required → show * */}
+                  {/* Items - New Field */}
                   <FormField
                     control={form.control}
-                    name="email"
+                    name="items"
                     render={({ field }) => (
                       <FormItem>
                         <FormLabel className="after:content-['*'] after:ml-0.5 after:text-red-500">
-                          대표 이메일
+                          공급품목
                         </FormLabel>
                         <FormControl>
                           <Input {...field} disabled={isSubmitting} />
                         </FormControl>
                         <FormDescription>
-                          회사 대표 이메일(관리자 로그인에 사용될 수 있음)
+                          공급 가능한 제품/서비스를 입력하세요
                         </FormDescription>
                         <FormMessage />
                       </FormItem>
                     )}
                   />
 
-                  {/* website optional */}
+                  {/* Address */}
                   <FormField
                     control={form.control}
-                    name="website"
+                    name="address"
                     render={({ field }) => (
                       <FormItem>
-                        <FormLabel>웹사이트</FormLabel>
+                        <FormLabel>주소</FormLabel>
                         <FormControl>
                           <Input {...field} disabled={isSubmitting} />
                         </FormControl>
@@ -325,17 +474,18 @@ export function JoinForm() {
                     )}
                   />
 
+                  {/* Country - Updated with enhanced list */}
                   <FormField
                     control={form.control}
                     name="country"
                     render={({ field }) => {
-                      const selectedCountry = countryArray.find(
+                      const selectedCountry = enhancedCountryArray.find(
                         (c) => c.code === field.value
                       )
                       return (
                         <FormItem>
                           <FormLabel className="after:content-['*'] after:ml-0.5 after:text-red-500">
-                            Country
+                            국가
                           </FormLabel>
                           <Popover>
                             <PopoverTrigger asChild>
@@ -351,18 +501,18 @@ export function JoinForm() {
                                 >
                                   {selectedCountry
                                     ? selectedCountry.label
-                                    : "Select a country"}
+                                    : "국가 선택"}
                                   <ChevronsUpDown className="ml-2 opacity-50" />
                                 </Button>
                               </FormControl>
                             </PopoverTrigger>
                             <PopoverContent className="w-full p-0">
                               <Command>
-                                <CommandInput placeholder="Search country..." />
+                                <CommandInput placeholder="국가 검색..." />
                                 <CommandList>
                                   <CommandEmpty>No country found.</CommandEmpty>
                                   <CommandGroup>
-                                    {countryArray.map((country) => (
+                                    {enhancedCountryArray.map((country) => (
                                       <CommandItem
                                         key={country.code}
                                         value={country.label}
@@ -391,6 +541,62 @@ export function JoinForm() {
                       )
                     }}
                   />
+
+                  {/* Phone - Updated with country code hint */}
+                  <FormField
+                    control={form.control}
+                    name="phone"
+                    render={({ field }) => (
+                      <FormItem>
+                        <FormLabel className="after:content-['*'] after:ml-0.5 after:text-red-500">
+                          대표 전화
+                        </FormLabel>
+                        <FormControl>
+                          <Input 
+                            {...field} 
+                            placeholder={getPhonePlaceholder(form.watch("country"))}
+                            disabled={isSubmitting} 
+                          />
+                        </FormControl>
+                        <FormMessage />
+                      </FormItem>
+                    )}
+                  />
+
+                  {/* Email - Updated with company domain guidance */}
+                  <FormField
+                    control={form.control}
+                    name="email"
+                    render={({ field }) => (
+                      <FormItem>
+                        <FormLabel className="after:content-['*'] after:ml-0.5 after:text-red-500">
+                          대표 이메일
+                        </FormLabel>
+                        <FormControl>
+                          <Input {...field} disabled={isSubmitting} />
+                        </FormControl>
+                        <FormDescription>
+                          회사 도메인 이메일을 사용하세요. (naver.com, gmail.com, daum.net 등의 개인 이메일은 지양해주세요)
+                        </FormDescription>
+                        <FormMessage />
+                      </FormItem>
+                    )}
+                  />
+
+                  {/* Website */}
+                  <FormField
+                    control={form.control}
+                    name="website"
+                    render={({ field }) => (
+                      <FormItem>
+                        <FormLabel>웹사이트</FormLabel>
+                        <FormControl>
+                          <Input {...field} disabled={isSubmitting} />
+                        </FormControl>
+                        <FormMessage />
+                      </FormItem>
+                    )}
+                  />
                 </div>
               </div>
 
@@ -425,7 +631,7 @@ export function JoinForm() {
                       className="bg-muted/10 rounded-md p-4 space-y-4"
                     >
                       <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
-                        {/* contactName → required */}
+                        {/* contactName - All required now */}
                         <FormField
                           control={form.control}
                           name={`contacts.${index}.contactName`}
@@ -442,13 +648,15 @@ export function JoinForm() {
                           )}
                         />
 
-                        {/* contactPosition → optional */}
+                        {/* contactPosition - Now required */}
                         <FormField
                           control={form.control}
                           name={`contacts.${index}.contactPosition`}
                           render={({ field }) => (
                             <FormItem>
-                              <FormLabel>직급 / 부서</FormLabel>
+                              <FormLabel className="after:content-['*'] after:ml-0.5 after:text-red-500">
+                                직급 / 부서
+                              </FormLabel>
                               <FormControl>
                                 <Input {...field} disabled={isSubmitting} />
                               </FormControl>
@@ -457,7 +665,7 @@ export function JoinForm() {
                           )}
                         />
 
-                        {/* contactEmail → required */}
+                        {/* contactEmail */}
                         <FormField
                           control={form.control}
                           name={`contacts.${index}.contactEmail`}
@@ -474,15 +682,21 @@ export function JoinForm() {
                           )}
                         />
 
-                        {/* contactPhone → optional */}
+                        {/* contactPhone - Now required */}
                         <FormField
                           control={form.control}
                           name={`contacts.${index}.contactPhone`}
                           render={({ field }) => (
                             <FormItem>
-                              <FormLabel>전화번호</FormLabel>
+                              <FormLabel className="after:content-['*'] after:ml-0.5 after:text-red-500">
+                                전화번호
+                              </FormLabel>
                               <FormControl>
-                                <Input {...field} disabled={isSubmitting} />
+                                <Input 
+                                  {...field} 
+                                  placeholder={getPhonePlaceholder(form.watch("country"))}
+                                  disabled={isSubmitting} 
+                                />
                               </FormControl>
                               <FormMessage />
                             </FormItem>
@@ -515,7 +729,7 @@ export function JoinForm() {
                 <div className="rounded-md border p-4 space-y-4">
                   <h4 className="text-md font-semibold">한국 사업자 정보</h4>
 
-                  {/* 대표자 등... all optional or whichever you want * for */}
+                  {/* 대표자 등... all now required for Korean companies */}
                   <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                     <FormField
                       control={form.control}
@@ -613,6 +827,9 @@ export function JoinForm() {
                       <FormLabel className="after:content-['*'] after:ml-0.5 after:text-red-500">
                         첨부 파일
                       </FormLabel>
+                      <FormDescription>
+                        사업자등록증, ISO 9001 인증서, 회사 브로셔, 기본 소개자료 등을 첨부해주세요.
+                      </FormDescription>
                       <Dropzone
                         maxSize={MAX_FILE_SIZE}
                         multiple
-- 
cgit v1.2.3

