diff options
| author | 0-Zz-ang <s1998319@gmail.com> | 2025-09-25 15:57:18 +0900 |
|---|---|---|
| committer | 0-Zz-ang <s1998319@gmail.com> | 2025-09-25 15:57:18 +0900 |
| commit | d6d3bbc55a557acde7d1f07c3bd4813e367d4e86 (patch) | |
| tree | db94f330abda7fee103c050fea3e880309bcef98 /components/polices/policy-page-client.tsx | |
| parent | 4c2d4c235bd80368e31cae9c375e9a585f6a6844 (diff) | |
(박서영)동의관련 언어설정 추가
Diffstat (limited to 'components/polices/policy-page-client.tsx')
| -rw-r--r-- | components/polices/policy-page-client.tsx | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/components/polices/policy-page-client.tsx b/components/polices/policy-page-client.tsx new file mode 100644 index 00000000..ccc87c31 --- /dev/null +++ b/components/polices/policy-page-client.tsx @@ -0,0 +1,281 @@ +'use client' + +import { useState } from 'react' +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' +import { FileText, Shield, Clock, Calendar, User } from 'lucide-react' +import { PolicyManagementClient } from '@/components/polices/policy-management-client' + +interface Policy { + id: number + policyType: string + locale: string + version: string + content: string + effectiveDate: string + isCurrent: boolean + createdAt: string +} + +interface PolicyPageClientProps { + data: { + currentPolicies: { + ko: Record<string, Policy> + en: Record<string, Policy> + } + allPolicies: { + ko: { + privacy_policy: Policy[] + terms_of_service: Policy[] + } + en: { + privacy_policy: Policy[] + terms_of_service: Policy[] + } + } + stats: { + totalVersions: number + koVersions: { + privacy: number + terms: number + } + enVersions: { + privacy: number + terms: number + } + lastUpdate: string | null + } + } +} + +// 선택된 locale의 가장 최근 업데이트 날짜를 가져오는 함수 +function getLastUpdateForLocale(data: PolicyPageClientProps['data'], locale: 'ko' | 'en'): string | null { + const allPolicies = [ + ...(data.allPolicies[locale]?.privacy_policy || []), + ...(data.allPolicies[locale]?.terms_of_service || []) + ] + + if (allPolicies.length === 0) return null + + // 가장 최근 createdAt 날짜 찾기 + const sortedPolicies = allPolicies.sort((a, b) => + new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime() + ) + + return sortedPolicies[0]?.createdAt || null +} + +export function PolicyPageClient({ data }: PolicyPageClientProps) { + const [selectedLocale, setSelectedLocale] = useState<'ko' | 'en'>('ko') + + // 선택된 locale에 맞는 데이터 필터링 + const filteredData = { + currentPolicies: { + privacy_policy: data.currentPolicies[selectedLocale]?.privacy_policy || null, + terms_of_service: data.currentPolicies[selectedLocale]?.terms_of_service || null + }, + allPolicies: { + privacy_policy: data.allPolicies[selectedLocale]?.privacy_policy || [], + terms_of_service: data.allPolicies[selectedLocale]?.terms_of_service || [] + }, + stats: { + totalVersions: data.stats[`${selectedLocale}Versions`].privacy + data.stats[`${selectedLocale}Versions`].terms, + privacyVersions: data.stats[`${selectedLocale}Versions`].privacy, + termsVersions: data.stats[`${selectedLocale}Versions`].terms, + lastUpdate: getLastUpdateForLocale(data, selectedLocale) + } + } + + return ( + <div className="container mx-auto py-6 space-y-6"> + {/* 헤더 */} + <div className="flex items-center justify-between"> + <div> + <h2 className="text-2xl font-bold tracking-tight">정책 관리</h2> + <p className="text-muted-foreground"> + 개인정보 처리방침과 이용약관을 버전별로 관리합니다 + </p> + </div> + + {/* 전역 locale 토글 */} + <div className="flex items-center gap-3"> + <div className="flex bg-muted rounded-lg p-1"> + <button + className={`px-3 py-1 rounded-md text-sm font-medium transition-colors ${ + selectedLocale === 'ko' + ? 'bg-background shadow-sm' + : 'text-muted-foreground hover:text-foreground' + }`} + onClick={() => setSelectedLocale('ko')} + > + KO + </button> + <button + className={`px-3 py-1 rounded-md text-sm font-medium transition-colors ${ + selectedLocale === 'en' + ? 'bg-background shadow-sm' + : 'text-muted-foreground hover:text-foreground' + }`} + onClick={() => setSelectedLocale('en')} + > + EN + </button> + </div> + </div> + </div> + + {/* 통계 카드들 */} + <div className="grid gap-4 md:grid-cols-4"> + <Card> + <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> + <CardTitle className="text-sm font-medium">총 버전 수</CardTitle> + <FileText className="h-4 w-4 text-muted-foreground" /> + </CardHeader> + <CardContent> + <div className="text-2xl font-bold">{filteredData.stats.totalVersions}</div> + <p className="text-xs text-muted-foreground"> + 전체 정책 버전 + </p> + </CardContent> + </Card> + + <Card> + <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> + <CardTitle className="text-sm font-medium">개인정보 정책</CardTitle> + <Shield className="h-4 w-4 text-muted-foreground" /> + </CardHeader> + <CardContent> + <div className="text-2xl font-bold">{filteredData.stats.privacyVersions}</div> + <p className="text-xs text-muted-foreground"> + 버전 수 + </p> + </CardContent> + </Card> + + <Card> + <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> + <CardTitle className="text-sm font-medium">이용약관</CardTitle> + <FileText className="h-4 w-4 text-muted-foreground" /> + </CardHeader> + <CardContent> + <div className="text-2xl font-bold">{filteredData.stats.termsVersions}</div> + <p className="text-xs text-muted-foreground"> + 버전 수 + </p> + </CardContent> + </Card> + + <Card> + <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> + <CardTitle className="text-sm font-medium">최근 업데이트</CardTitle> + <Clock className="h-4 w-4 text-muted-foreground" /> + </CardHeader> + <CardContent> + <div className="text-2xl font-bold"> + {filteredData.stats.lastUpdate + ? new Date(filteredData.stats.lastUpdate).toLocaleDateString('ko-KR').split('.').slice(1, 3).join('.') + : 'N/A' + } + </div> + <p className="text-xs text-muted-foreground"> + 마지막 정책 변경 + </p> + </CardContent> + </Card> + </div> + + {/* 현재 활성 정책들 */} + <div className="grid gap-6 md:grid-cols-2"> + <Card> + <CardHeader> + <CardTitle className="flex items-center gap-2"> + <Shield className="h-5 w-5" /> + 개인정보 처리방침 + </CardTitle> + <CardDescription> + {filteredData.currentPolicies.privacy_policy ? + `현재 활성 정책 • 시행일: ${new Date(filteredData.currentPolicies.privacy_policy.effectiveDate).toLocaleDateString('ko-KR')}` : + `아직 등록된 ${selectedLocale === 'ko' ? '한국어' : '영어'} 개인정보 정책이 없습니다` + } + </CardDescription> + </CardHeader> + <CardContent> + <div className="space-y-3"> + <div className="text-sm"> + <strong>정책 내용 미리보기:</strong> + </div> + <div className="bg-muted/50 p-3 rounded-md text-sm max-h-32 overflow-hidden"> + <div className="line-clamp-4"> + {filteredData.currentPolicies.privacy_policy ? + filteredData.currentPolicies.privacy_policy.content?.replace(/#{1,6}\s+/g, '').replace(/\*\*(.*?)\*\*/g, '$1').substring(0, 200) + '...' : + `아직 등록된 ${selectedLocale === 'ko' ? '한국어' : '영어'} 개인정보 정책이 없습니다` + } + </div> + </div> + + {/* 메타 정보 */} + <div className="flex items-center justify-between text-xs text-muted-foreground"> + <div className="flex items-center gap-1"> + <Calendar className="h-3 w-3" /> + 생성: {filteredData.currentPolicies.privacy_policy?.createdAt ? new Date(filteredData.currentPolicies.privacy_policy.createdAt).toLocaleDateString('ko-KR') : 'N/A'} + </div> + <div className="flex items-center gap-1"> + <User className="h-3 w-3" /> + 관리자 + </div> + </div> + </div> + </CardContent> + </Card> + + <Card> + <CardHeader> + <CardTitle className="flex items-center gap-2"> + <FileText className="h-5 w-5" /> + 이용약관 + </CardTitle> + <CardDescription> + {filteredData.currentPolicies.terms_of_service ? + `현재 활성 정책 • 시행일: ${new Date(filteredData.currentPolicies.terms_of_service.effectiveDate).toLocaleDateString('ko-KR')}` : + `아직 등록된 ${selectedLocale === 'ko' ? '한국어' : '영어'} 이용약관이 없습니다` + } + </CardDescription> + </CardHeader> + <CardContent> + <div className="space-y-3"> + <div className="text-sm"> + <strong>정책 내용 미리보기:</strong> + </div> + <div className="bg-muted/50 p-3 rounded-md text-sm max-h-32 overflow-hidden"> + <div className="line-clamp-4"> + {filteredData.currentPolicies.terms_of_service ? + filteredData.currentPolicies.terms_of_service.content?.replace(/#{1,6}\s+/g, '').replace(/\*\*(.*?)\*\*/g, '$1').substring(0, 200) + '...' : + `아직 등록된 ${selectedLocale === 'ko' ? '한국어' : '영어'} 이용약관이 없습니다` + } + </div> + </div> + + {/* 메타 정보 */} + <div className="flex items-center justify-between text-xs text-muted-foreground"> + <div className="flex items-center gap-1"> + <Calendar className="h-3 w-3" /> + 생성: {filteredData.currentPolicies.terms_of_service?.createdAt ? new Date(filteredData.currentPolicies.terms_of_service.createdAt).toLocaleDateString('ko-KR') : 'N/A'} + </div> + <div className="flex items-center gap-1"> + <User className="h-3 w-3" /> + 관리자 + </div> + </div> + </div> + </CardContent> + </Card> + </div> + + {/* 정책 편집 부분 - 선택된 locale의 데이터만 표시 */} + <PolicyManagementClient + key={selectedLocale} + initialData={filteredData} + currentLocale={selectedLocale} + /> + </div> + ) +} |
