summaryrefslogtreecommitdiff
path: root/components/signup/conset-step.tsx
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-08-15 05:20:10 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-08-15 05:20:10 +0000
commit8c916739d0116e9e53e4f209ebb5b14596871453 (patch)
tree95da967f5804c7d3bc50451670fa07c2c56d5080 /components/signup/conset-step.tsx
parent49d236df3bd2bd976ebc424644f34f5affa1074f (diff)
(대표님) 파트너 로그인 i18n 처리
Diffstat (limited to 'components/signup/conset-step.tsx')
-rw-r--r--components/signup/conset-step.tsx79
1 files changed, 49 insertions, 30 deletions
diff --git a/components/signup/conset-step.tsx b/components/signup/conset-step.tsx
index 3260a7b7..4d0a544f 100644
--- a/components/signup/conset-step.tsx
+++ b/components/signup/conset-step.tsx
@@ -5,6 +5,7 @@ import { Separator } from '@/components/ui/separator';
import { ChevronDown, ChevronUp, FileText, Shield, Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';
import { getCurrentPolicies } from '@/lib/polices/service';
+import { useTranslation } from '@/i18n/client';
// ✅ 정책 데이터 타입 개선
interface PolicyData {
@@ -30,9 +31,12 @@ interface ConsentStepProps {
};
onChange: (updater: (prev: any) => any) => void;
onNext: () => void;
+ lng: string; // 언어 코드 추가
}
-export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps) {
+export default function ConsentStep({ data, onChange, onNext, lng }: ConsentStepProps) {
+ const { t } = useTranslation(lng, 'consent');
+
const [policyData, setPolicyData] = useState<PolicyVersions | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
@@ -58,11 +62,11 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
console.log('Policy data loaded:', result.data);
setPolicyData(result.data);
} else {
- setError(result.error || '정책 데이터를 불러올 수 없습니다.');
+ setError(result.error || t('policyLoadError'));
console.error('Failed to fetch policy data:', result.error);
}
} catch (error) {
- const errorMessage = '정책 데이터를 불러오는 중 오류가 발생했습니다.';
+ const errorMessage = t('policyFetchError');
setError(errorMessage);
console.error('Failed to fetch policy data:', error);
} finally {
@@ -100,7 +104,7 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
// ✅ 정책 미리보기 텍스트 생성
const renderPolicyPreview = (policy: PolicyData, maxLength = 200): string => {
- if (!policy?.content) return '내용 없음';
+ if (!policy?.content) return t('noContent');
const textContent = stripHtmlTags(policy.content);
return textContent.length > maxLength
@@ -114,7 +118,7 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
<div className="flex items-center justify-center p-8">
<div className="flex items-center gap-2 text-gray-600">
<Loader2 className="h-4 w-4 animate-spin" />
- 정책 내용을 불러오는 중...
+ {t('loadingPolicies')}
</div>
</div>
);
@@ -125,10 +129,10 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
return (
<div className="text-center p-8">
<div className="text-red-600 mb-4">
- {error || '정책 내용을 불러올 수 없습니다.'}
+ {error || t('policyLoadError')}
</div>
<Button onClick={fetchPolicyData} variant="outline">
- 다시 시도
+ {t('retryButton')}
</Button>
</div>
);
@@ -139,11 +143,11 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
return (
<div className="text-center p-8">
<div className="text-amber-600 mb-4">
- 일부 정책이 설정되지 않았습니다. 관리자에게 문의해주세요.
+ {t('policiesNotConfigured')}
</div>
<div className="text-sm text-gray-500">
- {!policyData.privacy_policy && '개인정보 처리방침이 없습니다.'}<br />
- {!policyData.terms_of_service && '이용약관이 없습니다.'}
+ {!policyData.privacy_policy && t('missingPrivacyPolicy')}<br />
+ {!policyData.terms_of_service && t('missingTermsOfService')}
</div>
</div>
);
@@ -152,9 +156,9 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
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('consentTitle')}</h2>
<p className="text-gray-600 text-sm">
- 서비스 이용을 위해 다음 약관에 동의해주세요. 각 항목을 클릭하여 상세 내용을 확인할 수 있습니다.
+ {t('consentDescription')}
</p>
</div>
@@ -169,11 +173,13 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
policy={policyData.privacy_policy}
isRequired={true}
icon={<Shield className="w-4 h-4" />}
- title="개인정보 처리방침"
- description="개인정보 수집, 이용, 보관 및 파기에 관한 정책입니다."
+ title={t('privacyPolicyTitle')}
+ description={t('privacyPolicyDescription')}
expanded={expandedSections.privacy}
onToggleExpand={() => toggleSection('privacy')}
onShowModal={() => setShowPrivacyModal(true)}
+ t={t}
+ lng={lng}
/>
)}
@@ -189,15 +195,16 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
policy={policyData.terms_of_service}
isRequired={true}
icon={<FileText className="w-4 h-4" />}
- title="이용약관"
- description="서비스 이용 시 준수해야 할 규칙과 조건입니다."
+ title={t('termsOfServiceTitle')}
+ description={t('termsOfServiceDescription')}
expanded={expandedSections.terms}
onToggleExpand={() => toggleSection('terms')}
onShowModal={() => setShowTermsModal(true)}
+ t={t}
+ lng={lng}
/>
)}
-
{/* ✅ 전체 동의 */}
<div className="pt-4 border-t bg-gray-50 p-4 rounded-lg">
<div className="flex items-center space-x-3">
@@ -216,7 +223,7 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
className="h-5 w-5 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
/>
<label htmlFor="all-consent" className="text-base font-medium cursor-pointer">
- 위 내용에 모두 동의합니다
+ {t('agreeToAll')}
</label>
</div>
</div>
@@ -224,7 +231,7 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
<div className="flex justify-end">
<Button onClick={onNext} disabled={!isValid} size="lg">
- 다음 단계로
+ {t('nextStep')}
</Button>
</div>
@@ -237,6 +244,8 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
onChange(prev => ({ ...prev, privacy: true }));
setShowPrivacyModal(false);
}}
+ t={t}
+ lng={lng}
/>
)}
@@ -249,6 +258,8 @@ export default function ConsentStep({ data, onChange, onNext }: ConsentStepProps
onChange(prev => ({ ...prev, terms: true }));
setShowTermsModal(false);
}}
+ t={t}
+ lng={lng}
/>
)}
</div>
@@ -269,15 +280,17 @@ interface PolicyConsentSectionProps {
expanded: boolean;
onToggleExpand: () => void;
onShowModal: () => void;
+ t: (key: string, options?: any) => string;
+ lng: string;
}
function PolicyConsentSection({
id, type, checked, onChange, policy, isRequired, icon, title, description,
- expanded, onToggleExpand, onShowModal
+ expanded, onToggleExpand, onShowModal, t, lng
}: PolicyConsentSectionProps) {
// ✅ HTML에서 텍스트 추출
const renderPolicyPreview = (content: string, maxLength = 300): string => {
- if (!content) return '내용 없음';
+ if (!content) return t('noContent');
const textContent = content
.replace(/<[^>]*>/g, '') // HTML 태그 제거
@@ -311,7 +324,7 @@ function PolicyConsentSection({
{icon}
<label htmlFor={id} className="text-sm font-medium cursor-pointer">
<span className={isRequired ? "text-red-500" : "text-blue-500"}>
- [{isRequired ? "필수" : "선택"}]
+ [{isRequired ? t('required') : t('optional')}]
</span> {title} (v{policy.version})
</label>
</div>
@@ -331,7 +344,7 @@ function PolicyConsentSection({
className="flex items-center space-x-1 text-blue-600 hover:underline"
>
{expanded ? <ChevronUp className="w-3 h-3" /> : <ChevronDown className="w-3 h-3" />}
- <span>{expanded ? '간략히' : '더보기'}</span>
+ <span>{expanded ? t('showLess') : t('showMore')}</span>
</button>
<span className="text-gray-400">|</span>
<button
@@ -339,11 +352,13 @@ function PolicyConsentSection({
onClick={onShowModal}
className="text-blue-600 hover:underline"
>
- 전문보기
+ {t('viewFullText')}
</button>
<span className="text-gray-400">|</span>
<span className="text-gray-500">
- 시행일: {new Date(policy.effectiveDate).toLocaleDateString('ko-KR')}
+ {t('effectiveDate')}: {new Date(policy.effectiveDate).toLocaleDateString(
+ lng === 'ko' ? 'ko-KR' : 'en-US'
+ )}
</span>
</div>
</div>
@@ -357,11 +372,13 @@ interface PolicyModalProps {
policy: PolicyData;
onClose: () => void;
onAgree: () => void;
+ t: (key: string, options?: any) => string;
+ lng: string;
}
-function PolicyModal({ policy, onClose, onAgree }: PolicyModalProps) {
+function PolicyModal({ policy, onClose, onAgree, t, lng }: PolicyModalProps) {
const getPolicyTitle = (policyType: string): string => {
- return policyType === 'privacy_policy' ? '개인정보 처리방침' : '이용약관';
+ return policyType === 'privacy_policy' ? t('privacyPolicyTitle') : t('termsOfServiceTitle');
};
return (
@@ -374,7 +391,9 @@ function PolicyModal({ policy, onClose, onAgree }: PolicyModalProps) {
{getPolicyTitle(policy.policyType)}
</h3>
<p className="text-sm text-gray-600 mt-1">
- 버전 {policy.version} | 시행일: {new Date(policy.effectiveDate).toLocaleDateString('ko-KR')}
+ {t('version')} {policy.version} | {t('effectiveDate')}: {new Date(policy.effectiveDate).toLocaleDateString(
+ lng === 'ko' ? 'ko-KR' : 'en-US'
+ )}
</p>
</div>
<button
@@ -400,13 +419,13 @@ function PolicyModal({ policy, onClose, onAgree }: PolicyModalProps) {
onClick={onClose}
className="flex-1"
>
- 닫기
+ {t('close')}
</Button>
<Button
onClick={onAgree}
className="flex-1"
>
- 동의하고 닫기
+ {t('agreeAndClose')}
</Button>
</div>
</div>