From 8c916739d0116e9e53e4f209ebb5b14596871453 Mon Sep 17 00:00:00 2001
From: dujinkim <dujin.kim@dtsolution.co.kr>
Date: Fri, 15 Aug 2025 05:20:10 +0000
Subject: (대표님) 파트너 로그인 i18n 처리
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/signup/join-form.tsx | 561 ++++++++++++++++++++++++----------------
 1 file changed, 342 insertions(+), 219 deletions(-)

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

diff --git a/components/signup/join-form.tsx b/components/signup/join-form.tsx
index 2dcde518..71ecbd1c 100644
--- a/components/signup/join-form.tsx
+++ b/components/signup/join-form.tsx
@@ -75,54 +75,102 @@ import { checkEmailExists } from '@/lib/vendor-users/service';
 i18nIsoCountries.registerLocale(enLocale);
 i18nIsoCountries.registerLocale(koLocale);
 
-const locale = "ko";
-const countryMap = i18nIsoCountries.getNames(locale, { select: "official" });
-const countryArray = Object.entries(countryMap).map(([code, label]) => ({
-  code,
-  label,
-}));
-
-const sortedCountryArray = [...countryArray].sort((a, b) => {
-  if (a.code === "KR") return -1;
-  if (b.code === "KR") return 1;
-  return a.label.localeCompare(b.label);
-});
-
-const enhancedCountryArray = sortedCountryArray.map(country => ({
-  ...country,
-  label: locale === "ko" && country.code === "KR"
-    ? "대한민국 (South Korea)"
-    : country.label
-}));
-
-const contactTaskOptions = [
-  { value: "PRESIDENT_DIRECTOR", label: "회사대표 President/Director" },
-  { value: "SALES_MANAGEMENT", label: "영업관리 Sales Management" },
-  { value: "ENGINEERING_DESIGN", label: "설계/기술 Engineering/Design" },
-  { value: "PROCUREMENT", label: "구매 Procurement" },
-  { value: "DELIVERY_CONTROL", label: "납기/출하/운송 Delivery Control" },
-  { value: "PM_MANUFACTURING", label: "PM/생산관리 PM/Manufacturing" },
-  { value: "QUALITY_MANAGEMENT", label: "품질관리 Quality Management" },
-  { value: "SHIPPING_DOC_MANAGEMENT", label: "세금계산서/납품서관리 Shipping Doc. Management" },
-  { value: "AS_MANAGEMENT", label: "A/S 관리 A/S Management" },
-  { value: "FIELD_SERVICE_ENGINEER", label: "FSE(야드작업자) Field Service Engineer" }
-];
+// Types
+interface CountryOption {
+  code: string;
+  label: string;
+}
 
-const MAX_FILE_SIZE = 3e9;
+interface VendorType {
+  id: number;
+  nameKo: string;
+  nameEn: string;
+}
+
+interface ContactTaskOption {
+  value: string;
+  label: string;
+}
+
+interface Contact {
+  contactName: string;
+  contactPosition: string;
+  contactDepartment: string;
+  contactTask: string;
+  contactEmail: string;
+  contactPhone: string;
+}
+
+interface AccountData {
+  name: string;
+  email: string;
+  phone: string;
+  country: string;
+}
+
+interface VendorData {
+  vendorName: string;
+  vendorTypeId?: number;
+  items: string;
+  taxId: string;
+  address: string;
+  email: string;
+  phone: string;
+  country: string;
+  website: string;
+  representativeName: string;
+  representativeBirth: string;
+  representativeEmail: string;
+  representativePhone: string;
+  corporateRegistrationNumber: string;
+  representativeWorkExpirence: boolean;
+  contacts: Contact[];
+}
+
+interface ConsentData {
+  privacy: boolean;
+  terms: boolean;
+  marketing: boolean;
+}
+
+interface PhoneValidation {
+  isValid: boolean;
+  error: string | null;
+  formatted: string;
+  international?: string;
+}
+
+// Country data setup
+const getCountryData = (lng: string): CountryOption[] => {
+  const locale = lng === 'ko' ? "ko" : "en";
+  const countryMap = i18nIsoCountries.getNames(locale, { select: "official" });
+  const countryArray = Object.entries(countryMap).map(([code, label]) => ({
+    code,
+    label,
+  }));
+
+  const sortedCountryArray = [...countryArray].sort((a, b) => {
+    if (a.code === "KR") return -1;
+    if (b.code === "KR") return 1;
+    return a.label.localeCompare(b.label);
+  });
 
-// 스텝 정의
-const STEPS = [
-  { id: 1, title: '약관 동의', description: '서비스 이용 약관 동의', icon: FileText },
-  { id: 2, title: '계정 생성', description: '개인 계정 정보 입력', icon: User },
-  { id: 3, title: '업체 등록', description: '업체 정보 및 서류 제출', icon: Building }
-];
+  return sortedCountryArray.map(country => ({
+    ...country,
+    label: locale === "ko" && country.code === "KR"
+      ? "대한민국 (South Korea)"
+      : country.label
+  }));
+};
+
+const MAX_FILE_SIZE = 3e9;
 
 // ========== 전화번호 처리 유틸리티 함수들 ==========
 
 /**
  * 국가별 전화번호 예시를 가져오는 함수
  */
-function getPhoneExample(countryCode) {
+function getPhoneExample(countryCode: string) {
   if (!countryCode) return null;
   try {
     return getExampleNumber(countryCode, examples);
@@ -134,97 +182,93 @@ function getPhoneExample(countryCode) {
 /**
  * 국가별 전화번호 플레이스홀더를 생성하는 함수
  */
-function getPhonePlaceholder(countryCode) {
-  if (!countryCode) return "국가를 먼저 선택해주세요";
+function getPhonePlaceholder(countryCode: string, t: (key: string) => string): string {
+  if (!countryCode) return t('selectCountryFirst');
 
   const example = getPhoneExample(countryCode);
   if (example) {
-    // 국내 형식으로 표시 (더 친숙함)
     return example.formatNational();
   }
 
-  // 예시가 없는 경우 국가 코드 기반 플레이스홀더
   try {
     const callingCode = getCountryCallingCode(countryCode);
     return `+${callingCode} ...`;
   } catch {
-    return "전화번호를 입력하세요";
+    return t('enterPhoneNumber');
   }
 }
 
 /**
  * 국가별 전화번호 설명을 생성하는 함수
  */
-function getPhoneDescription(countryCode) {
-  if (!countryCode) return "국가를 먼저 선택하여 올바른 전화번호 형식을 확인하세요.";
+function getPhoneDescription(countryCode: string, t: (key: string, options?: any) => string): string {
+  if (!countryCode) return t('selectCountryForPhoneFormat');
 
   const example = getPhoneExample(countryCode);
   if (example) {
-    return `예시: ${example.formatNational()} 또는 ${example.formatInternational()}`;
+    return t('phoneExample', { 
+      national: example.formatNational(),
+      international: example.formatInternational()
+    });
   }
 
   try {
     const callingCode = getCountryCallingCode(countryCode);
-    return `국가 코드: +${callingCode}. 국내 형식 또는 국제 형식으로 입력 가능합니다.`;
+    return t('phoneCountryCode', { code: callingCode });
   } catch {
-    return "올바른 전화번호 형식으로 입력해주세요.";
+    return t('enterValidPhoneFormat');
   }
 }
 
 /**
  * 전화번호 검증 결과를 반환하는 함수
  */
-function validatePhoneNumber(phoneNumber, countryCode) {
+function validatePhoneNumber(phoneNumber: string, countryCode: string, t: (key: string) => string): PhoneValidation {
   if (!phoneNumber || !countryCode) {
     return { isValid: false, error: null, formatted: phoneNumber };
   }
 
   try {
-    // 1. 기본 파싱 시도
     const parsed = parsePhoneNumberFromString(phoneNumber, countryCode);
 
     if (!parsed) {
       return {
         isValid: false,
-        error: "올바른 전화번호 형식이 아닙니다.",
+        error: t('invalidPhoneFormat'),
         formatted: phoneNumber
       };
     }
 
-    // 2. 길이 검증
     const lengthValidation = validatePhoneNumberLength(phoneNumber, countryCode);
     if (lengthValidation !== undefined) {
-      const lengthErrors = {
-        'TOO_SHORT': '전화번호가 너무 짧습니다.',
-        'TOO_LONG': '전화번호가 너무 깁니다.',
-        'INVALID_LENGTH': '전화번호 길이가 올바르지 않습니다.'
+      const lengthErrors: Record<string, string> = {
+        'TOO_SHORT': t('phoneTooShort'),
+        'TOO_LONG': t('phoneTooLong'),
+        'INVALID_LENGTH': t('phoneInvalidLength')
       };
       return {
         isValid: false,
-        error: lengthErrors[lengthValidation] || '전화번호 길이가 올바르지 않습니다.',
+        error: lengthErrors[lengthValidation] || t('phoneInvalidLength'),
         formatted: phoneNumber
       };
     }
 
-    // 3. 가능성 검증
     if (!isPossiblePhoneNumber(phoneNumber, countryCode)) {
       return {
         isValid: false,
-        error: "이 국가에서 가능하지 않은 전화번호 형식입니다.",
+        error: t('phoneNotPossible'),
         formatted: phoneNumber
       };
     }
 
-    // 4. 유효성 검증
     if (!isValidPhoneNumber(phoneNumber, countryCode)) {
       return {
         isValid: false,
-        error: "유효하지 않은 전화번호입니다.",
+        error: t('phoneInvalid'),
         formatted: phoneNumber
       };
     }
 
-    // 모든 검증 통과
     return {
       isValid: true,
       error: null,
@@ -235,7 +279,7 @@ function validatePhoneNumber(phoneNumber, countryCode) {
   } catch (error) {
     return {
       isValid: false,
-      error: "전화번호 형식을 확인해주세요.",
+      error: t('phoneFormatError'),
       formatted: phoneNumber
     };
   }
@@ -244,8 +288,8 @@ function validatePhoneNumber(phoneNumber, countryCode) {
 /**
  * 실시간 전화번호 포맷팅을 위한 커스텀 훅
  */
-function usePhoneFormatter(countryCode) {
-  const [formatter, setFormatter] = useState(null);
+function usePhoneFormatter(countryCode: string) {
+  const [formatter, setFormatter] = useState<AsYouType | null>(null);
 
   useEffect(() => {
     if (countryCode) {
@@ -255,10 +299,8 @@ function usePhoneFormatter(countryCode) {
     }
   }, [countryCode]);
 
-  const formatPhone = useCallback((value) => {
-    if (!formatter) return value;
-
-    // AsYouType은 매번 새로운 인스턴스를 사용해야 함
+  const formatPhone = useCallback((value: string) => {
+    if (!formatter || !countryCode) return value;
     const newFormatter = new AsYouType(countryCode);
     return newFormatter.input(value);
   }, [countryCode, formatter]);
@@ -268,33 +310,42 @@ function usePhoneFormatter(countryCode) {
 
 // ========== 전화번호 입력 컴포넌트 ==========
 
+interface PhoneInputProps {
+  value: string;
+  onChange: (value: string) => void;
+  countryCode: string;
+  placeholder?: string;
+  disabled?: boolean;
+  onBlur?: () => void;
+  className?: string;
+  showValidation?: boolean;
+  t: (key: string, options?: any) => string;
+}
+
 function PhoneInput({
   value,
   onChange,
   countryCode,
   placeholder,
   disabled = false,
-  onBlur = null,
+  onBlur = undefined,
   className = "",
-  showValidation = true
-}) {
+  showValidation = true,
+  t
+}: PhoneInputProps) {
   const [touched, setTouched] = useState(false);
   const [localValue, setLocalValue] = useState(value || '');
   const formatPhone = usePhoneFormatter(countryCode);
 
-  // value prop이 변경될 때 localValue 동기화
   useEffect(() => {
     setLocalValue(value || '');
   }, [value]);
 
-  const validation = validatePhoneNumber(localValue, countryCode);
+  const validation = validatePhoneNumber(localValue, countryCode, t);
 
-  const handleInputChange = (e) => {
+  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
     const inputValue = e.target.value;
-
-    // 실시간 포맷팅 적용
     const formattedValue = countryCode ? formatPhone(inputValue) : inputValue;
-
     setLocalValue(formattedValue);
     onChange(formattedValue);
   };
@@ -314,7 +365,7 @@ function PhoneInput({
         value={localValue}
         onChange={handleInputChange}
         onBlur={handleBlur}
-        placeholder={placeholder || getPhonePlaceholder(countryCode)}
+        placeholder={placeholder || getPhonePlaceholder(countryCode, t)}
         disabled={disabled}
         className={cn(
           className,
@@ -325,22 +376,19 @@ function PhoneInput({
 
       {showValidation && (
         <div className="text-xs space-y-1">
-          {/* 설명 텍스트 */}
           <p className="text-muted-foreground">
-            {getPhoneDescription(countryCode)}
+            {getPhoneDescription(countryCode, t)}
           </p>
 
-          {/* 오류 메시지 */}
           {showError && (
             <p className="text-red-500 font-medium">
               {validation.error}
             </p>
           )}
 
-          {/* 성공 메시지 */}
           {showSuccess && (
             <p className="text-green-600 font-medium">
-              ✓ 올바른 전화번호입니다.
+              ✓ {t('validPhoneNumber')}
               {validation.international && ` (${validation.international})`}
             </p>
           )}
@@ -355,30 +403,30 @@ function PhoneInput({
 export default function JoinForm() {
   const params = useParams() || {};
   const lng = params.lng ? String(params.lng) : "ko";
-  const { t } = useTranslation(lng, "translation");
+  const { t } = useTranslation(lng, "join");
   const router = useRouter();
   const searchParams = useSearchParams() || new URLSearchParams();
   const defaultTaxId = searchParams.get("taxID") ?? "";
   const { toast } = useToast();
 
   const [currentStep, setCurrentStep] = useState(1);
-  const [completedSteps, setCompletedSteps] = useState(new Set());
+  const [completedSteps, setCompletedSteps] = useState(new Set<number>());
 
   // 각 스텝별 데이터
-  const [consentData, setConsentData] = useState({
+  const [consentData, setConsentData] = useState<ConsentData>({
     privacy: false,
     terms: false,
     marketing: false
   });
 
-  const [accountData, setAccountData] = useState({
+  const [accountData, setAccountData] = useState<AccountData>({
     name: '',
     email: '',
     phone: '',
-    country: 'KR' // 기본값을 한국으로 설정
+    country: 'KR'
   });
 
-  const [vendorData, setVendorData] = useState({
+  const [vendorData, setVendorData] = useState<VendorData>({
     vendorName: "",
     vendorTypeId: undefined,
     items: "",
@@ -386,7 +434,7 @@ export default function JoinForm() {
     address: "",
     email: "",
     phone: "",
-    country: "", // 기본값을 빈 문자열로 설정하여 계정 데이터에서 가져오도록 함
+    country: "",
     website: "",
     representativeName: "",
     representativeBirth: "",
@@ -407,19 +455,41 @@ export default function JoinForm() {
   });
 
   // 업체 타입 및 파일 상태
-  const [vendorTypes, setVendorTypes] = useState([]);
+  const [vendorTypes, setVendorTypes] = useState<VendorType[]>([]);
   const [isLoadingVendorTypes, setIsLoadingVendorTypes] = useState(true);
-  const [businessRegistrationFiles, setBusinessRegistrationFiles] = useState([]);
-  const [isoCertificationFiles, setIsoCertificationFiles] = useState([]);
-  const [creditReportFiles, setCreditReportFiles] = useState([]);
-  const [bankAccountFiles, setBankAccountFiles] = useState([]);
+  const [businessRegistrationFiles, setBusinessRegistrationFiles] = useState<File[]>([]);
+  const [isoCertificationFiles, setIsoCertificationFiles] = useState<File[]>([]);
+  const [creditReportFiles, setCreditReportFiles] = useState<File[]>([]);
+  const [bankAccountFiles, setBankAccountFiles] = useState<File[]>([]);
 
-  const [policyVersions, setPolicyVersions] = useState({
+  const [policyVersions] = useState({
     privacy_policy: '1.0',
     terms_of_service: '1.0'
   });
 
+  // 스텝 정의
+  const STEPS = [
+    { id: 1, title: t('consentStep'), description: t('consentStepDesc'), icon: FileText },
+    { id: 2, title: t('accountStep'), description: t('accountStepDesc'), icon: User },
+    { id: 3, title: t('vendorStep'), description: t('vendorStepDesc'), icon: Building }
+  ];
+
   const progress = ((currentStep - 1) / (STEPS.length - 1)) * 100;
+  const enhancedCountryArray = getCountryData(lng);
+
+  // Contact task options
+  const contactTaskOptions: ContactTaskOption[] = [
+    { value: "PRESIDENT_DIRECTOR", label: t('taskPresidentDirector') },
+    { value: "SALES_MANAGEMENT", label: t('taskSalesManagement') },
+    { value: "ENGINEERING_DESIGN", label: t('taskEngineeringDesign') },
+    { value: "PROCUREMENT", label: t('taskProcurement') },
+    { value: "DELIVERY_CONTROL", label: t('taskDeliveryControl') },
+    { value: "PM_MANUFACTURING", label: t('taskPmManufacturing') },
+    { value: "QUALITY_MANAGEMENT", label: t('taskQualityManagement') },
+    { value: "SHIPPING_DOC_MANAGEMENT", label: t('taskShippingDocManagement') },
+    { value: "AS_MANAGEMENT", label: t('taskAsManagement') },
+    { value: "FIELD_SERVICE_ENGINEER", label: t('taskFieldServiceEngineer') }
+  ];
 
   // 정책 버전 및 업체 타입 로드
   useEffect(() => {
@@ -437,22 +507,22 @@ export default function JoinForm() {
       console.error("Failed to load vendor types:", error);
       toast({
         variant: "destructive",
-        title: "Error",
-        description: "Failed to load vendor types",
+        title: t('error'),
+        description: t('failedToLoadVendorTypes'),
       });
     } finally {
       setIsLoadingVendorTypes(false);
     }
   };
 
-  const handleStepComplete = (step) => {
+  const handleStepComplete = (step: number) => {
     setCompletedSteps(prev => new Set([...prev, step]));
     if (step < STEPS.length) {
       setCurrentStep(step + 1);
     }
   };
 
-  const handleStepClick = (stepId) => {
+  const handleStepClick = (stepId: number) => {
     if (stepId <= Math.max(...completedSteps) + 1) {
       setCurrentStep(stepId);
     }
@@ -463,7 +533,7 @@ export default function JoinForm() {
       {/* 진행률 표시 */}
       <div className="mb-8">
         <div className="flex items-center justify-between mb-4">
-          <h1 className="text-2xl font-bold">파트너 등록</h1>
+          <h1 className="text-2xl font-bold">{t('partnerRegistration')}</h1>
           <span className="text-sm text-muted-foreground">
             {currentStep} / {STEPS.length}
           </span>
@@ -530,6 +600,7 @@ export default function JoinForm() {
             data={consentData}
             onChange={setConsentData}
             onNext={() => handleStepComplete(1)}
+            lng={lng} 
           />
         )}
 
@@ -540,6 +611,7 @@ export default function JoinForm() {
             onNext={() => handleStepComplete(2)}
             onBack={() => setCurrentStep(1)}
             enhancedCountryArray={enhancedCountryArray}
+            t={t}
           />
         )}
 
@@ -547,7 +619,6 @@ export default function JoinForm() {
           <VendorStep
             data={{
               ...vendorData,
-              // 업체 국가가 설정되지 않았다면 계정의 국가를 사용
               country: vendorData.country || accountData.country,
             }}
             onChange={setVendorData}
@@ -572,6 +643,7 @@ export default function JoinForm() {
             contactTaskOptions={contactTaskOptions}
             lng={lng}
             policyVersions={policyVersions}
+            t={t}
           />
         )}
       </div>
@@ -580,22 +652,28 @@ export default function JoinForm() {
 }
 
 // Step 2: 계정 생성
+interface AccountStepProps {
+  data: AccountData;
+  onChange: (updater: (prev: AccountData) => AccountData) => void;
+  onNext: () => void;
+  onBack: () => void;
+  enhancedCountryArray: CountryOption[];
+  t: (key: string, options?: any) => string;
+}
+
 function AccountStep({
   data, onChange, onNext, onBack,
-  enhancedCountryArray
-}) {
+  enhancedCountryArray, t
+}: AccountStepProps) {
   const [isLoading, setIsLoading] = useState(false);
   const [emailCheckError, setEmailCheckError] = useState('');
 
-  // 입력 핸들러
-  const handleInputChange = (field, value) => {
+  const handleInputChange = (field: keyof AccountData, value: string) => {
     onChange(prev => ({ ...prev, [field]: value }));
   };
 
-  // 전화번호 validation
-  const phoneValidation = validatePhoneNumber(data.phone, data.country);
+  const phoneValidation = validatePhoneNumber(data.phone, data.country, t);
 
-  // 전체 입력 유효성
   const isValid =
     data.name &&
     data.email &&
@@ -603,7 +681,6 @@ function AccountStep({
     data.phone &&
     phoneValidation.isValid;
 
-  // 이메일 중복체크 + 다음단계
   const handleNext = async () => {
     if (!isValid) return;
 
@@ -612,12 +689,12 @@ function AccountStep({
     try {
       const isUsed = await checkEmailExists(data.email);
       if (isUsed) {
-        setEmailCheckError('이미 사용 중인 이메일입니다.');
+        setEmailCheckError(t('emailAlreadyInUse'));
         return;
       }
       onNext();
     } catch (error) {
-      setEmailCheckError('이메일 확인 중 오류가 발생했습니다.');
+      setEmailCheckError(t('emailCheckError'));
     } finally {
       setIsLoading(false);
     }
@@ -626,20 +703,20 @@ function AccountStep({
   return (
     <div className="space-y-6">
       <div>
-        <h2 className="text-xl font-semibold mb-2">계정 정보 입력</h2>
+        <h2 className="text-xl font-semibold mb-2">{t('accountInfoInput')}</h2>
         <p className="text-gray-600 text-sm">
-          서비스 이용을 위한 개인 계정을 생성합니다.
+          {t('accountInfoDescription')}
         </p>
       </div>
 
       <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
         <div>
           <label className="block text-sm font-medium mb-1">
-            이름 <span className="text-red-500">*</span>
+            {t('name')} <span className="text-red-500">*</span>
           </label>
           <Input
             type="text"
-            placeholder="이름을 입력하세요"
+            placeholder={t('enterName')}
             value={data.name}
             onChange={(e) => handleInputChange('name', e.target.value)}
           />
@@ -647,11 +724,11 @@ function AccountStep({
 
         <div>
           <label className="block text-sm font-medium mb-1">
-            이메일 <span className="text-red-500">*</span>
+            {t('email')} <span className="text-red-500">*</span>
           </label>
           <Input
             type="email"
-            placeholder="이메일을 입력하세요"
+            placeholder={t('enterEmail')}
             value={data.email}
             onChange={(e) => handleInputChange('email', e.target.value)}
           />
@@ -662,7 +739,7 @@ function AccountStep({
 
         <div>
           <label className="block text-sm font-medium mb-1">
-            국가 <span className="text-red-500">*</span>
+            {t('country')} <span className="text-red-500">*</span>
           </label>
           <Popover>
             <PopoverTrigger asChild>
@@ -674,15 +751,15 @@ function AccountStep({
                   !data.country && "text-muted-foreground"
                 )}
               >
-                {enhancedCountryArray.find(c => c.code === data.country)?.label || "국가 선택"}
+                {enhancedCountryArray.find(c => c.code === data.country)?.label || t('selectCountry')}
                 <ChevronsUpDown className="ml-2 opacity-50" />
               </Button>
             </PopoverTrigger>
             <PopoverContent className="w-full p-0">
               <Command>
-                <CommandInput placeholder="국가 검색..." />
+                <CommandInput placeholder={t('searchCountry')} />
                 <CommandList>
-                  <CommandEmpty>No country found.</CommandEmpty>
+                  <CommandEmpty>{t('noCountryFound')}</CommandEmpty>
                   <CommandGroup>
                     {enhancedCountryArray.map((country) => (
                       <CommandItem
@@ -710,23 +787,24 @@ function AccountStep({
 
         <div>
           <label className="block text-sm font-medium mb-1">
-            전화번호 <span className="text-red-500">*</span>
+            {t('phoneNumber')} <span className="text-red-500">*</span>
           </label>
           <PhoneInput
             value={data.phone}
             onChange={(value) => handleInputChange('phone', value)}
             countryCode={data.country}
             showValidation={true}
+            t={t}
           />
         </div>
       </div>
 
       <div className="flex justify-between">
         <Button variant="outline" onClick={onBack}>
-          이전
+          {t('previous')}
         </Button>
         <Button onClick={handleNext} disabled={!isValid || isLoading}>
-          {isLoading ? '확인 중...' : '다음 단계'}
+          {isLoading ? t('checking') : t('nextStep')}
         </Button>
       </div>
     </div>
@@ -734,19 +812,45 @@ function AccountStep({
 }
 
 // Step 3: 업체 등록
-function VendorStep(props) {
+interface VendorStepProps {
+  data: VendorData;
+  onChange: (updater: (prev: VendorData) => VendorData) => void;
+  onBack: () => void;
+  onComplete: () => void;
+  accountData: AccountData;
+  consentData: ConsentData;
+  vendorTypes: VendorType[];
+  isLoadingVendorTypes: boolean;
+  businessRegistrationFiles: File[];
+  setBusinessRegistrationFiles: (files: File[]) => void;
+  isoCertificationFiles: File[];
+  setIsoCertificationFiles: (files: File[]) => void;
+  creditReportFiles: File[];
+  setCreditReportFiles: (files: File[]) => void;
+  bankAccountFiles: File[];
+  setBankAccountFiles: (files: File[]) => void;
+  enhancedCountryArray: CountryOption[];
+  contactTaskOptions: ContactTaskOption[];
+  lng: string;
+  policyVersions: {
+    privacy_policy: string;
+    terms_of_service: string;
+  };
+  t: (key: string, options?: any) => string;
+}
+
+function VendorStep(props: VendorStepProps) {
   return <CompleteVendorForm {...props} />;
 }
 
-// 나머지 CompeleteVendorForm과 FileUploadSection은 기존과 동일하되, 
-// PhoneInput 컴포넌트를 사용하도록 수정
 function CompleteVendorForm({
   data, onChange, onBack, onComplete, accountData, consentData,
   vendorTypes, isLoadingVendorTypes, businessRegistrationFiles, setBusinessRegistrationFiles,
   isoCertificationFiles, setIsoCertificationFiles, creditReportFiles, setCreditReportFiles,
-  bankAccountFiles, setBankAccountFiles, enhancedCountryArray, contactTaskOptions, lng, policyVersions
-}) {
+  bankAccountFiles, setBankAccountFiles, enhancedCountryArray, contactTaskOptions, lng, policyVersions, t
+}: VendorStepProps) {
   const [isSubmitting, setIsSubmitting] = useState(false);
+  const { toast } = useToast();
 
   // 담당자 관리 함수들
   const addContact = () => {
@@ -763,14 +867,14 @@ function CompleteVendorForm({
     }));
   };
 
-  const removeContact = (index) => {
+  const removeContact = (index: number) => {
     onChange(prev => ({
       ...prev,
       contacts: prev.contacts.filter((_, i) => i !== index)
     }));
   };
 
-  const updateContact = (index, field, value) => {
+  const updateContact = (index: number, field: keyof Contact, value: string) => {
     onChange(prev => ({
       ...prev,
       contacts: prev.contacts.map((contact, i) =>
@@ -779,27 +883,26 @@ function CompleteVendorForm({
     }));
   };
 
-  // 폼 입력 변경 핸들러
-  const handleInputChange = (field, value) => {
+  const handleInputChange = (field: keyof VendorData, value: any) => {
     onChange(prev => ({ ...prev, [field]: value }));
   };
 
   // 파일 업로드 핸들러들
-  const createFileUploadHandler = (setFiles, currentFiles) => ({
-    onDropAccepted: (acceptedFiles) => {
+  const createFileUploadHandler = (setFiles: (files: File[]) => void, currentFiles: File[]) => ({
+    onDropAccepted: (acceptedFiles: File[]) => {
       const newFiles = [...currentFiles, ...acceptedFiles];
       setFiles(newFiles);
     },
-    onDropRejected: (fileRejections) => {
+    onDropRejected: (fileRejections: any[]) => {
       fileRejections.forEach((rej) => {
         toast({
           variant: "destructive",
-          title: "File Error",
-          description: `${rej.file.name}: ${rej.errors[0]?.message || "Upload failed"}`,
+          title: t('fileError'),
+          description: `${rej.file.name}: ${rej.errors[0]?.message || t('uploadFailed')}`,
         });
       });
     },
-    removeFile: (index) => {
+    removeFile: (index: number) => {
       const updated = [...currentFiles];
       updated.splice(index, 1);
       setFiles(updated);
@@ -812,34 +915,34 @@ function CompleteVendorForm({
   const bankAccountHandler = createFileUploadHandler(setBankAccountFiles, bankAccountFiles);
 
   // 유효성 검사
-  const validateRequiredFiles = () => {
-    const errors = [];
+  const validateRequiredFiles = (): string[] => {
+    const errors: string[] = [];
 
     if (businessRegistrationFiles.length === 0) {
-      errors.push("사업자등록증을 업로드해주세요.");
+      errors.push(t('uploadBusinessRegistration'));
     }
 
     if (isoCertificationFiles.length === 0) {
-      errors.push("ISO 인증서를 업로드해주세요.");
+      errors.push(t('uploadIsoCertification'));
     }
 
     if (creditReportFiles.length === 0) {
-      errors.push("신용평가보고서를 업로드해주세요.");
+      errors.push(t('uploadCreditReport'));
     }
 
     if (data.country !== "KR" && bankAccountFiles.length === 0) {
-      errors.push("대금지급 통장사본을 업로드해주세요.");
+      errors.push(t('uploadBankAccount'));
     }
 
     return errors;
   };
 
   // 전화번호 검증
-  const vendorPhoneValidation = validatePhoneNumber(data.phone, data.country);
+  const vendorPhoneValidation = validatePhoneNumber(data.phone, data.country, t);
   const contactsValid = data.contacts.length > 0 &&
     data.contacts[0].contactName &&
     data.contacts.every(contact =>
-      contact.contactPhone ? validatePhoneNumber(contact.contactPhone, data.country).isValid : true
+      contact.contactPhone ? validatePhoneNumber(contact.contactPhone, data.country, t).isValid : true
     );
 
   const isFormValid = data.vendorName && data.vendorTypeId && data.items &&
@@ -847,13 +950,13 @@ function CompleteVendorForm({
     contactsValid &&
     validateRequiredFiles().length === 0;
 
-  // 최종 제출 (기존과 동일)
+  // 최종 제출
   const handleSubmit = async () => {
     const fileErrors = validateRequiredFiles();
     if (fileErrors.length > 0) {
       toast({
         variant: "destructive",
-        title: "파일 업로드 필수",
+        title: t('fileUploadRequired'),
         description: fileErrors.join("\n"),
       });
       return;
@@ -914,23 +1017,23 @@ function CompleteVendorForm({
 
       if (response.ok) {
         toast({
-          title: "등록 완료",
-          description: "회원가입 및 업체 등록이 완료되었습니다. 관리자 승인 후 서비스를 이용하실 수 있습니다.",
+          title: t('registrationComplete'),
+          description: t('registrationCompleteDesc'),
         });
         onComplete();
       } else {
         toast({
           variant: "destructive",
-          title: "오류",
-          description: result.error || "등록에 실패했습니다.",
+          title: t('error'),
+          description: result.error || t('registrationFailed'),
         });
       }
     } catch (error) {
       console.error(error);
       toast({
         variant: "destructive",
-        title: "서버 에러",
-        description: error.message || "에러가 발생했습니다.",
+        title: t('serverError'),
+        description: t('errorOccurred'),
       });
     } finally {
       setIsSubmitting(false);
@@ -940,20 +1043,20 @@ function CompleteVendorForm({
   return (
     <div className="space-y-8">
       <div>
-        <h2 className="text-xl font-semibold mb-2">업체 정보 등록</h2>
+        <h2 className="text-xl font-semibold mb-2">{t('vendorInfoRegistration')}</h2>
         <p className="text-gray-600 text-sm">
-          업체 정보와 필요한 서류를 등록해주세요. 모든 정보는 관리자 검토 후 승인됩니다.
+          {t('vendorInfoDescription')}
         </p>
       </div>
 
       {/* 기본 정보 */}
       <div className="rounded-md border p-6 space-y-4">
-        <h4 className="text-md font-semibold">기본 정보</h4>
+        <h4 className="text-md font-semibold">{t('basicInformation')}</h4>
         <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
           {/* 업체 유형 */}
           <div>
             <label className="block text-sm font-medium mb-1">
-              업체유형 <span className="text-red-500">*</span>
+              {t('vendorType')} <span className="text-red-500">*</span>
             </label>
             <Popover>
               <PopoverTrigger asChild>
@@ -967,16 +1070,16 @@ function CompleteVendorForm({
                   disabled={isSubmitting || isLoadingVendorTypes}
                 >
                   {isLoadingVendorTypes
-                    ? "Loading..."
-                    : vendorTypes.find(type => type.id === data.vendorTypeId)?.[lng === "ko" ? "nameKo" : "nameEn"] || "업체유형 선택"}
+                    ? t('loading')
+                    : vendorTypes.find(type => type.id === data.vendorTypeId)?.[lng === "ko" ? "nameKo" : "nameEn"] || t('selectVendorType')}
                   <ChevronsUpDown className="ml-2 opacity-50" />
                 </Button>
               </PopoverTrigger>
               <PopoverContent className="w-full p-0">
                 <Command>
-                  <CommandInput placeholder="업체유형 검색..." />
+                  <CommandInput placeholder={t('searchVendorType')} />
                   <CommandList>
-                    <CommandEmpty>No vendor type found.</CommandEmpty>
+                    <CommandEmpty>{t('noVendorTypeFound')}</CommandEmpty>
                     <CommandGroup>
                       {vendorTypes.map((type) => (
                         <CommandItem
@@ -1005,7 +1108,7 @@ function CompleteVendorForm({
           {/* 업체명 */}
           <div>
             <label className="block text-sm font-medium mb-1">
-              업체명 <span className="text-red-500">*</span>
+              {t('vendorName')} <span className="text-red-500">*</span>
             </label>
             <Input
               value={data.vendorName}
@@ -1014,15 +1117,15 @@ function CompleteVendorForm({
             />
             <p className="text-xs text-gray-500 mt-1">
               {(data.country || accountData.country) === "KR"
-                ? "사업자 등록증에 표기된 정확한 회사명을 입력하세요."
-                : "해외 업체의 경우 영문 회사명을 입력하세요."}
+                ? t('vendorNameHintKorea')
+                : t('vendorNameHintOverseas')}
             </p>
           </div>
 
           {/* 공급품목 */}
           <div>
             <label className="block text-sm font-medium mb-1">
-              공급품목 <span className="text-red-500">*</span>
+              {t('supplyItems')} <span className="text-red-500">*</span>
             </label>
             <Input
               value={data.items}
@@ -1030,14 +1133,14 @@ function CompleteVendorForm({
               disabled={isSubmitting}
             />
             <p className="text-xs text-gray-500 mt-1">
-              공급 가능한 제품/서비스를 입력하세요
+              {t('supplyItemsHint')}
             </p>
           </div>
 
           {/* 사업자등록번호 */}
           <div>
             <label className="block text-sm font-medium mb-1">
-              사업자등록번호 <span className="text-red-500">*</span>
+              {t('businessRegistrationNumber')} <span className="text-red-500">*</span>
             </label>
             <Input
               value={data.taxId}
@@ -1049,7 +1152,7 @@ function CompleteVendorForm({
 
           {/* 주소 */}
           <div>
-            <label className="block text-sm font-medium mb-1">주소</label>
+            <label className="block text-sm font-medium mb-1">{t('address')}</label>
             <Input
               value={data.address}
               onChange={(e) => handleInputChange('address', e.target.value)}
@@ -1060,7 +1163,7 @@ function CompleteVendorForm({
           {/* 국가 */}
           <div>
             <label className="block text-sm font-medium mb-1">
-              국가 <span className="text-red-500">*</span>
+              {t('country')} <span className="text-red-500">*</span>
             </label>
             <Popover>
               <PopoverTrigger asChild>
@@ -1073,15 +1176,15 @@ function CompleteVendorForm({
                   )}
                   disabled={isSubmitting}
                 >
-                  {enhancedCountryArray.find(c => c.code === data.country)?.label || "국가 선택"}
+                  {enhancedCountryArray.find(c => c.code === data.country)?.label || t('selectCountry')}
                   <ChevronsUpDown className="ml-2 opacity-50" />
                 </Button>
               </PopoverTrigger>
               <PopoverContent className="w-full p-0">
                 <Command>
-                  <CommandInput placeholder="국가 검색..." />
+                  <CommandInput placeholder={t('searchCountry')} />
                   <CommandList>
-                    <CommandEmpty>No country found.</CommandEmpty>
+                    <CommandEmpty>{t('noCountryFound')}</CommandEmpty>
                     <CommandGroup>
                       {enhancedCountryArray.map((country) => (
                         <CommandItem
@@ -1110,7 +1213,7 @@ function CompleteVendorForm({
           {/* 대표 전화 - PhoneInput 사용 */}
           <div>
             <label className="block text-sm font-medium mb-1">
-              대표 전화 <span className="text-red-500">*</span>
+              {t('representativePhone')} <span className="text-red-500">*</span>
             </label>
             <PhoneInput
               value={data.phone}
@@ -1118,13 +1221,14 @@ function CompleteVendorForm({
               countryCode={data.country}
               disabled={isSubmitting}
               showValidation={true}
+              t={t}
             />
           </div>
 
           {/* 대표 이메일 */}
           <div>
             <label className="block text-sm font-medium mb-1">
-              대표 이메일 <span className="text-red-500">*</span>
+              {t('representativeEmail')} <span className="text-red-500">*</span>
             </label>
             <Input
               value={data.email}
@@ -1133,13 +1237,13 @@ function CompleteVendorForm({
               placeholder={accountData.email}
             />
             <p className="text-xs text-gray-500 mt-1">
-              비워두면 계정 이메일({accountData.email})을 사용합니다.
+              {t('emailHint', { email: accountData.email })}
             </p>
           </div>
 
           {/* 웹사이트 */}
           <div>
-            <label className="block text-sm font-medium mb-1">웹사이트</label>
+            <label className="block text-sm font-medium mb-1">{t('website')}</label>
             <Input
               value={data.website}
               onChange={(e) => handleInputChange('website', e.target.value)}
@@ -1149,10 +1253,10 @@ function CompleteVendorForm({
         </div>
       </div>
 
-      {/* 담당자 정보 - PhoneInput 사용 */}
+      {/* 담당자 정보 */}
       <div className="rounded-md border p-6 space-y-4">
         <div className="flex items-center justify-between">
-          <h4 className="text-md font-semibold">담당자 정보 (최소 1명)</h4>
+          <h4 className="text-md font-semibold">{t('contactInfo')}</h4>
           <Button
             type="button"
             variant="outline"
@@ -1160,7 +1264,7 @@ function CompleteVendorForm({
             disabled={isSubmitting}
           >
             <Plus className="mr-1 h-4 w-4" />
-            담당자 추가
+            {t('addContact')}
           </Button>
         </div>
 
@@ -1173,7 +1277,7 @@ function CompleteVendorForm({
               <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                 <div>
                   <label className="block text-sm font-medium mb-1">
-                    담당자명 <span className="text-red-500">*</span>
+                    {t('contactName')} <span className="text-red-500">*</span>
                   </label>
                   <Input
                     value={contact.contactName}
@@ -1184,7 +1288,7 @@ function CompleteVendorForm({
 
                 <div>
                   <label className="block text-sm font-medium mb-1">
-                    직급 <span className="text-red-500">*</span>
+                    {t('position')} <span className="text-red-500">*</span>
                   </label>
                   <Input
                     value={contact.contactPosition}
@@ -1195,7 +1299,7 @@ function CompleteVendorForm({
 
                 <div>
                   <label className="block text-sm font-medium mb-1">
-                    부서 <span className="text-red-500">*</span>
+                    {t('department')} <span className="text-red-500">*</span>
                   </label>
                   <Input
                     value={contact.contactDepartment}
@@ -1206,7 +1310,7 @@ function CompleteVendorForm({
 
                 <div>
                   <label className="block text-sm font-medium mb-1">
-                    담당업무 <span className="text-red-500">*</span>
+                    {t('responsibility')} <span className="text-red-500">*</span>
                   </label>
                   <Select
                     value={contact.contactTask}
@@ -1214,7 +1318,7 @@ function CompleteVendorForm({
                     disabled={isSubmitting}
                   >
                     <SelectTrigger>
-                      <SelectValue placeholder="담당업무를 선택하세요" />
+                      <SelectValue placeholder={t('selectResponsibility')} />
                     </SelectTrigger>
                     <SelectContent>
                       {contactTaskOptions.map((option) => (
@@ -1228,7 +1332,7 @@ function CompleteVendorForm({
 
                 <div>
                   <label className="block text-sm font-medium mb-1">
-                    이메일 <span className="text-red-500">*</span>
+                    {t('email')} <span className="text-red-500">*</span>
                   </label>
                   <Input
                     value={contact.contactEmail}
@@ -1239,7 +1343,7 @@ function CompleteVendorForm({
 
                 <div>
                   <label className="block text-sm font-medium mb-1">
-                    전화번호 <span className="text-red-500">*</span>
+                    {t('phoneNumber')} <span className="text-red-500">*</span>
                   </label>
                   <PhoneInput
                     value={contact.contactPhone}
@@ -1247,6 +1351,7 @@ function CompleteVendorForm({
                     countryCode={data.country}
                     disabled={isSubmitting}
                     showValidation={true}
+                    t={t}
                   />
                 </div>
               </div>
@@ -1259,7 +1364,7 @@ function CompleteVendorForm({
                     disabled={isSubmitting}
                   >
                     <X className="mr-1 h-4 w-4" />
-                    삭제
+                    {t('delete')}
                   </Button>
                 </div>
               )}
@@ -1268,14 +1373,14 @@ function CompleteVendorForm({
         </div>
       </div>
 
-      {/* 한국 사업자 정보 - PhoneInput 사용 */}
+      {/* 한국 사업자 정보 */}
       {data.country === "KR" && (
         <div className="rounded-md border p-6 space-y-4">
-          <h4 className="text-md font-semibold">한국 사업자 정보</h4>
+          <h4 className="text-md font-semibold">{t('koreanBusinessInfo')}</h4>
           <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
             <div>
               <label className="block text-sm font-medium mb-1">
-                대표자 이름 <span className="text-red-500">*</span>
+                {t('representativeName')} <span className="text-red-500">*</span>
               </label>
               <Input
                 value={data.representativeName}
@@ -1285,7 +1390,7 @@ function CompleteVendorForm({
             </div>
             <div>
               <label className="block text-sm font-medium mb-1">
-                대표자 생년월일 <span className="text-red-500">*</span>
+                {t('representativeBirth')} <span className="text-red-500">*</span>
               </label>
               <Input
                 placeholder="YYYY-MM-DD"
@@ -1296,7 +1401,7 @@ function CompleteVendorForm({
             </div>
             <div>
               <label className="block text-sm font-medium mb-1">
-                대표자 이메일 <span className="text-red-500">*</span>
+                {t('representativeEmail')} <span className="text-red-500">*</span>
               </label>
               <Input
                 value={data.representativeEmail}
@@ -1306,7 +1411,7 @@ function CompleteVendorForm({
             </div>
             <div>
               <label className="block text-sm font-medium mb-1">
-                대표자 전화번호 <span className="text-red-500">*</span>
+                {t('representativePhone')} <span className="text-red-500">*</span>
               </label>
               <PhoneInput
                 value={data.representativePhone}
@@ -1314,11 +1419,12 @@ function CompleteVendorForm({
                 countryCode="KR"
                 disabled={isSubmitting}
                 showValidation={true}
+                t={t}
               />
             </div>
             <div>
               <label className="block text-sm font-medium mb-1">
-                법인등록번호 <span className="text-red-500">*</span>
+                {t('corporateRegistrationNumber')} <span className="text-red-500">*</span>
               </label>
               <Input
                 value={data.corporateRegistrationNumber}
@@ -1336,7 +1442,7 @@ function CompleteVendorForm({
                 className="h-4 w-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
               />
               <label htmlFor="work-experience" className="text-sm">
-                대표자 삼성중공업 근무이력
+                {t('samsungWorkExperience')}
               </label>
             </div>
           </div>
@@ -1345,63 +1451,67 @@ function CompleteVendorForm({
 
       {/* 필수 첨부 서류 */}
       <div className="rounded-md border p-6 space-y-6">
-        <h4 className="text-md font-semibold">필수 첨부 서류</h4>
+        <h4 className="text-md font-semibold">{t('requiredDocuments')}</h4>
 
         <FileUploadSection
-          title="사업자등록증"
-          description="사업자등록증 스캔본 또는 사진을 업로드해주세요."
+          title={t('businessRegistrationCertificate')}
+          description={t('businessRegistrationDesc')}
           files={businessRegistrationFiles}
           onDropAccepted={businessRegistrationHandler.onDropAccepted}
           onDropRejected={businessRegistrationHandler.onDropRejected}
           removeFile={businessRegistrationHandler.removeFile}
           isSubmitting={isSubmitting}
+          t={t}
         />
 
         <FileUploadSection
-          title="ISO 인증서"
-          description="ISO 9001, ISO 14001 등 품질/환경 관리 인증서를 업로드해주세요."
+          title={t('isoCertificate')}
+          description={t('isoCertificateDesc')}
           files={isoCertificationFiles}
           onDropAccepted={isoCertificationHandler.onDropAccepted}
           onDropRejected={isoCertificationHandler.onDropRejected}
           removeFile={isoCertificationHandler.removeFile}
           isSubmitting={isSubmitting}
+          t={t}
         />
 
         <FileUploadSection
-          title="신용평가보고서"
-          description="신용평가기관에서 발급한 발행 1년 이내의 신용평가보고서를 업로드해주세요."
+          title={t('creditReport')}
+          description={t('creditReportDesc')}
           files={creditReportFiles}
           onDropAccepted={creditReportHandler.onDropAccepted}
           onDropRejected={creditReportHandler.onDropRejected}
           removeFile={creditReportHandler.removeFile}
           isSubmitting={isSubmitting}
+          t={t}
         />
 
         {data.country !== "KR" && (
           <FileUploadSection
-            title="대금지급 통장사본"
-            description="대금 지급용 은행 계좌의 통장 사본 또는 계좌증명서를 업로드해주세요."
+            title={t('bankAccountCopy')}
+            description={t('bankAccountDesc')}
             files={bankAccountFiles}
             onDropAccepted={bankAccountHandler.onDropAccepted}
             onDropRejected={bankAccountHandler.onDropRejected}
             removeFile={bankAccountHandler.removeFile}
             isSubmitting={isSubmitting}
+            t={t}
           />
         )}
       </div>
 
       <div className="flex justify-between">
         <Button variant="outline" onClick={onBack}>
-          이전
+          {t('previous')}
         </Button>
         <Button onClick={handleSubmit} disabled={!isFormValid || isSubmitting}>
           {isSubmitting ? (
             <>
               <Loader2 className="mr-2 h-4 w-4 animate-spin" />
-              등록 중...
+              {t('registering')}
             </>
           ) : (
-            "등록 완료"
+            t('completeRegistration')
           )}
         </Button>
       </div>
@@ -1409,7 +1519,19 @@ function CompleteVendorForm({
   );
 }
 
-// 파일 업로드 섹션 컴포넌트 (기존과 동일)
+// 파일 업로드 섹션 컴포넌트
+interface FileUploadSectionProps {
+  title: string;
+  description: string;
+  files: File[];
+  onDropAccepted: (files: File[]) => void;
+  onDropRejected: (fileRejections: any[]) => void;
+  removeFile: (index: number) => void;
+  isSubmitting: boolean;
+  required?: boolean;
+  t: (key: string, options?: any) => string;
+}
+
 function FileUploadSection({
   title,
   description,
@@ -1418,8 +1540,9 @@ function FileUploadSection({
   onDropRejected,
   removeFile,
   isSubmitting,
-  required = true
-}) {
+  required = true,
+  t
+}: FileUploadSectionProps) {
   return (
     <div className="space-y-4">
       <div>
@@ -1443,10 +1566,10 @@ function FileUploadSection({
             <div className="flex items-center gap-4">
               <DropzoneUploadIcon />
               <div className="grid gap-1">
-                <DropzoneTitle>파일 업로드</DropzoneTitle>
+                <DropzoneTitle>{t('fileUpload')}</DropzoneTitle>
                 <DropzoneDescription>
-                  드래그 또는 클릭
-                  {maxSize ? ` (최대: ${prettyBytes(maxSize)})` : null}
+                  {t('dragOrClick')}
+                  {maxSize ? ` (${t('maxSize')}: ${prettyBytes(maxSize)})` : null}
                 </DropzoneDescription>
               </div>
             </div>
-- 
cgit v1.2.3

