'use client';
/**
* SubscriptionClient — 대체 구독관리 컴포넌트 (SubscriptionManagement.tsx 사용 권장)
* 기존 호환성 유지를 위해 보존
*/
import { useState, useCallback } from 'react';
import { CreditCard, Download, AlertTriangle } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { ConfirmDialog } from '@/components/ui/confirm-dialog';
import { PageLayout } from '@/components/organisms/PageLayout';
import { PageHeader } from '@/components/organisms/PageHeader';
import { toast } from 'sonner';
import { usePermission } from '@/hooks/usePermission';
import { cancelSubscription, requestDataExport } from './actions';
import type { SubscriptionInfo } from './types';
import { SUBSCRIPTION_STATUS_LABELS } from './types';
import { formatKrw, getProgressColor } from './utils';
import { formatAmountWon as formatCurrency } from '@/lib/utils/amount';
interface SubscriptionClientProps {
initialData: SubscriptionInfo;
}
const formatDate = (dateStr: string | null): string => {
if (!dateStr) return '-';
const date = new Date(dateStr);
if (isNaN(date.getTime())) return '-';
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
};
function ColoredProgress({ value }: { value: number }) {
const color = getProgressColor(value);
const clamped = Math.min(value, 100);
return (
);
}
export function SubscriptionClient({ initialData }: SubscriptionClientProps) {
const { canExport } = usePermission();
const [subscription, setSubscription] = useState(initialData);
const [showCancelDialog, setShowCancelDialog] = useState(false);
const [isExporting, setIsExporting] = useState(false);
const [isCancelling, setIsCancelling] = useState(false);
const handleExportData = useCallback(async () => {
setIsExporting(true);
try {
const result = await requestDataExport('all');
if (result.success) toast.success('내보내기 요청이 등록되었습니다.');
else toast.error(result.error || '내보내기 요청에 실패했습니다.');
} catch { toast.error('서버 오류가 발생했습니다.'); }
finally { setIsExporting(false); }
}, []);
const handleCancelService = useCallback(async () => {
if (!subscription.id) { toast.error('구독 정보를 찾을 수 없습니다.'); setShowCancelDialog(false); return; }
setIsCancelling(true);
try {
const result = await cancelSubscription(subscription.id, '사용자 요청');
if (result.success) { toast.success('서비스가 해지되었습니다.'); setSubscription(prev => ({ ...prev, status: 'cancelled' })); }
else toast.error(result.error || '서비스 해지에 실패했습니다.');
} catch { toast.error('서버 오류가 발생했습니다.'); }
finally { setIsCancelling(false); setShowCancelDialog(false); }
}, [subscription.id]);
const userPercentage = subscription.userLimit ? (subscription.userCount / subscription.userLimit) * 100 : 30;
return (
<>
{canExport && (
)}
}
/>
요금제
{subscription.planName}
시작: {formatDate(subscription.startedAt)}
구독 상태
{SUBSCRIPTION_STATUS_LABELS[subscription.status] || subscription.status}
{subscription.remainingDays != null && subscription.remainingDays > 0 && (
남은 일: {subscription.remainingDays}일
)}
구독 금액
{formatCurrency(subscription.monthlyFee)}/월
종료: {formatDate(subscription.endedAt)}
리소스 사용량
사용자
{subscription.userCount}명 / {subscription.userLimit ? `${subscription.userLimit}명` : '무제한'}
저장 공간
{subscription.storageUsedFormatted} / {subscription.storageLimitFormatted}
AI 토큰
{formatKrw(subscription.aiTokens.costKrw)}
서비스 해지}
description={<>모든 데이터가 삭제되며 복구할 수 없습니다.
정말 서비스를 해지하시겠습니까?>}
confirmText="확인"
loading={isCancelling}
/>
>
);
}