diff options
| author | joonhoekim <26rote@gmail.com> | 2025-08-20 03:38:55 +0000 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-08-20 03:38:55 +0000 |
| commit | 1c653c940fba07fa91db5fff8de22ac95d51c272 (patch) | |
| tree | 9f6d3c2bceb4c7568f8b4fd4b4e1973f012ed3a6 /components | |
| parent | 8077419e40368dc703f94d558fc746b73fbc6702 (diff) | |
(김준회) reset-password i18n 처리, vendorData 측 잘못된 unique 제약조건 삭제 (내부망DB에는 이미 삭제되어 있음)
Diffstat (limited to 'components')
| -rw-r--r-- | components/login/reset-password.tsx | 55 |
1 files changed, 28 insertions, 27 deletions
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> |
