From 1c653c940fba07fa91db5fff8de22ac95d51c272 Mon Sep 17 00:00:00 2001
From: joonhoekim <26rote@gmail.com>
Date: Wed, 20 Aug 2025 03:38:55 +0000
Subject: (김준회) reset-password i18n 처리, vendorData 측 잘못된 unique
 제약조건 삭제 (내부망DB에는 이미 삭제되어 있음)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 components/login/reset-password.tsx | 55 +++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 27 deletions(-)

(limited to 'components/login/reset-password.tsx')

diff --git a/components/login/reset-password.tsx b/components/login/reset-password.tsx
index f68018d9..cc09f4fb 100644
--- a/components/login/reset-password.tsx
+++ b/components/login/reset-password.tsx
@@ -1,7 +1,6 @@
 'use client';
 
 import { useState, useEffect } from 'react';
-import { useRouter } from 'next/navigation';
 import { useFormState } from 'react-dom';
 import { useToast } from '@/hooks/use-toast';
 import { Button } from '@/components/ui/button';
@@ -12,6 +11,7 @@ import Link from 'next/link';
 import SuccessPage from './SuccessPage';
 import { PasswordPolicy } from '@/lib/users/auth/passwordUtil';
 import { PasswordValidationResult, resetPasswordAction, validatePasswordAction } from '@/lib/users/auth/partners-auth';
+import { useTranslation } from '@/i18n/client';
 
 interface PasswordRequirement {
   text: string;
@@ -23,11 +23,12 @@ interface Props {
   token: string;
   userId: number;
   passwordPolicy: PasswordPolicy;
+  lng?: string;
 }
 
-export default function ResetPasswordForm({ token, userId, passwordPolicy }: Props) {
-  const router = useRouter();
+export default function ResetPasswordForm({ token, userId, passwordPolicy, lng = 'ko' }: Props) {
   const { toast } = useToast();
+  const { t } = useTranslation(lng, 'login');
   
   // 상태 관리
   const [showPassword, setShowPassword] = useState(false);
@@ -75,12 +76,12 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
   useEffect(() => {
     if (resetState.error) {
       toast({
-        title: '오류',
+        title: t('error'),
         description: resetState.error,
         variant: 'destructive',
       });
     }
-  }, [resetState, toast]);
+  }, [resetState, toast, t]);
 
   // 패스워드 요구사항 생성
   const getPasswordRequirements = (): PasswordRequirement[] => {
@@ -89,7 +90,7 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
     const { strength } = passwordValidation;
     const requirements: PasswordRequirement[] = [
       {
-        text: `${passwordPolicy.minLength}자 이상`,
+        text: `${passwordPolicy.minLength}${t('passwordRequirementLength')}`,
         met: strength.length >= passwordPolicy.minLength,
         type: 'length'
       }
@@ -97,7 +98,7 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
 
     if (passwordPolicy.requireUppercase) {
       requirements.push({
-        text: '대문자 포함',
+        text: t('passwordRequirementUppercase'),
         met: strength.hasUppercase,
         type: 'uppercase'
       });
@@ -105,7 +106,7 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
 
     if (passwordPolicy.requireLowercase) {
       requirements.push({
-        text: '소문자 포함',
+        text: t('passwordRequirementLowercase'),
         met: strength.hasLowercase,
         type: 'lowercase'
       });
@@ -113,7 +114,7 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
 
     if (passwordPolicy.requireNumbers) {
       requirements.push({
-        text: '숫자 포함',
+        text: t('passwordRequirementNumbers'),
         met: strength.hasNumbers,
         type: 'number'
       });
@@ -121,7 +122,7 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
 
     if (passwordPolicy.requireSymbols) {
       requirements.push({
-        text: '특수문자 포함',
+        text: t('passwordRequirementSymbols'),
         met: strength.hasSymbols,
         type: 'symbol'
       });
@@ -144,11 +145,11 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
 
   const getStrengthText = (score: number) => {
     switch (score) {
-      case 1: return '매우 약함';
-      case 2: return '약함';
-      case 3: return '보통';
-      case 4: return '강함';
-      case 5: return '매우 강함';
+      case 1: return t('passwordStrengthVeryWeak');
+      case 2: return t('passwordStrengthWeak');
+      case 3: return t('passwordStrengthMedium');
+      case 4: return t('passwordStrengthStrong');
+      case 5: return t('passwordStrengthVeryStrong');
       default: return '';
     }
   };
@@ -170,9 +171,9 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
           <Ship className="w-6 h-6 text-blue-600" />
           <span className="text-xl font-bold">eVCP</span>
         </div>
-        <CardTitle className="text-2xl">새 비밀번호 설정</CardTitle>
+        <CardTitle className="text-2xl">{t('resetPasswordTitle')}</CardTitle>
         <CardDescription>
-          계정 보안을 위해 강력한 비밀번호를 설정해주세요.
+          {t('resetPasswordDescription')}
         </CardDescription>
       </CardHeader>
       
@@ -183,7 +184,7 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
           {/* 새 비밀번호 */}
           <div className="space-y-2">
             <label htmlFor="newPassword" className="text-sm font-medium text-gray-700">
-              새 비밀번호
+              {t('newPassword')}
             </label>
             <div className="relative">
               <Input
@@ -192,7 +193,7 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
                 type={showPassword ? "text" : "password"}
                 value={newPassword}
                 onChange={(e) => setNewPassword(e.target.value)}
-                placeholder="새 비밀번호를 입력하세요"
+                placeholder={t('newPasswordPlaceholder')}
                 required
               />
               <button
@@ -209,7 +210,7 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
               <div className="mt-2 space-y-2">
                 <div className="flex items-center space-x-2">
                   <Shield className="h-4 w-4 text-gray-500" />
-                  <span className="text-xs text-gray-600">강도:</span>
+                  <span className="text-xs text-gray-600">{t('passwordStrength')}:</span>
                   <span className={`text-xs font-medium ${getStrengthColor(passwordValidation.strength.score)}`}>
                     {getStrengthText(passwordValidation.strength.score)}
                   </span>
@@ -258,7 +259,7 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
                 <div className="flex items-center space-x-2 text-xs">
                   <XCircle className="h-3 w-3 text-red-500" />
                   <span className="text-red-700">
-                    최근 {passwordPolicy.historyCount}개 비밀번호와 달라야 합니다
+                    {t('passwordHistoryError', { count: passwordPolicy.historyCount })}
                   </span>
                 </div>
               </div>
@@ -292,7 +293,7 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
           {/* 비밀번호 확인 */}
           <div className="space-y-2">
             <label htmlFor="confirmPassword" className="text-sm font-medium text-gray-700">
-              비밀번호 확인
+              {t('confirmPassword')}
             </label>
             <div className="relative">
               <Input
@@ -301,7 +302,7 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
                 type={showConfirmPassword ? "text" : "password"}
                 value={confirmPassword}
                 onChange={(e) => setConfirmPassword(e.target.value)}
-                placeholder="비밀번호를 다시 입력하세요"
+                placeholder={t('confirmPasswordPlaceholder')}
                 required
               />
               <button
@@ -319,12 +320,12 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
                 {passwordsMatch ? (
                   <>
                     <CheckCircle className="h-3 w-3 text-green-500" />
-                    <span className="text-green-700">비밀번호가 일치합니다</span>
+                    <span className="text-green-700">{t('passwordsMatch')}</span>
                   </>
                 ) : (
                   <>
                     <XCircle className="h-3 w-3 text-red-500" />
-                    <span className="text-red-700">비밀번호가 일치하지 않습니다</span>
+                    <span className="text-red-700">{t('passwordsNotMatch')}</span>
                   </>
                 )}
               </div>
@@ -336,13 +337,13 @@ export default function ResetPasswordForm({ token, userId, passwordPolicy }: Pro
             className="w-full"
             disabled={!canSubmit}
           >
-            {isValidatingPassword ? '검증 중...' : '비밀번호 변경하기'}
+            {isValidatingPassword ? t('validating') : t('changePassword')}
           </Button>
         </form>
 
         <div className="mt-6 text-center">
           <Link href="/partners" className="text-sm text-blue-600 hover:text-blue-500">
-            로그인 페이지로 돌아가기
+            {t('backToLogin')}
           </Link>
         </div>
       </CardContent>
-- 
cgit v1.2.3

