summaryrefslogtreecommitdiff
path: root/components/polices/policy-page-client.tsx
diff options
context:
space:
mode:
author0-Zz-ang <s1998319@gmail.com>2025-09-25 15:57:18 +0900
committer0-Zz-ang <s1998319@gmail.com>2025-09-25 15:57:18 +0900
commitd6d3bbc55a557acde7d1f07c3bd4813e367d4e86 (patch)
treedb94f330abda7fee103c050fea3e880309bcef98 /components/polices/policy-page-client.tsx
parent4c2d4c235bd80368e31cae9c375e9a585f6a6844 (diff)
(박서영)동의관련 언어설정 추가
Diffstat (limited to 'components/polices/policy-page-client.tsx')
-rw-r--r--components/polices/policy-page-client.tsx281
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>
+ )
+}