fix: 홈 로또 카드 가격/플랜명 수정, 관리자 구독자 통계/구독 현황 추가

- 홈 카드: 월 4,900원 → 900원~, 플랜명 골드/플래티넘/다이아로 수정
- 관리자 대시보드: 활성 구독자 수 카드 추가
- 관리자 회원 목록: 구독 현황(플랜명, 만료일) 컬럼 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-16 03:51:18 +09:00
parent 16fa4f4c98
commit b250d4b50c
5 changed files with 43 additions and 9 deletions

View File

@@ -7,6 +7,7 @@ interface Stats {
totalOrders: number;
totalRevenue: number;
pendingContacts: number;
activeSubscribers: number;
monthlyChart: Array<{ month: string; revenue: number }>;
}
@@ -53,7 +54,7 @@ export default function AdminDashboard() {
) : (
<>
{/* 통계 카드 */}
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
<div className="grid grid-cols-2 lg:grid-cols-5 gap-4 mb-6">
<StatCard
label="총 회원 수"
value={`${stats?.totalMembers ?? 0}`}
@@ -87,6 +88,17 @@ export default function AdminDashboard() {
</svg>
}
/>
<StatCard
label="활성 구독자"
value={`${stats?.activeSubscribers ?? 0}`}
color="bg-amber-500/20 text-amber-400"
icon={
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
d="M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" />
</svg>
}
/>
<StatCard
label="미처리 문의"
value={`${stats?.pendingContacts ?? 0}`}

View File

@@ -9,8 +9,15 @@ interface Member {
created_at: string;
orderCount: number;
totalPaid: number;
activeSub: { product_id: string; status: string; expires_at: string } | null;
}
const PLAN_LABELS: Record<string, string> = {
lotto_gold: '🥇 골드',
lotto_platinum: '💎 플래티넘',
lotto_diamond: '👑 다이아',
};
export default function AdminMembersPage() {
const [members, setMembers] = useState<Member[]>([]);
const [loading, setLoading] = useState(true);
@@ -65,6 +72,7 @@ export default function AdminMembersPage() {
<th className="text-left px-5 py-3 text-slate-400 font-medium"></th>
<th className="text-left px-5 py-3 text-slate-400 font-medium"></th>
<th className="text-left px-5 py-3 text-slate-400 font-medium"></th>
<th className="text-left px-5 py-3 text-slate-400 font-medium"></th>
<th className="text-right px-5 py-3 text-slate-400 font-medium"> </th>
<th className="text-right px-5 py-3 text-slate-400 font-medium"> </th>
</tr>
@@ -72,7 +80,7 @@ export default function AdminMembersPage() {
<tbody>
{filtered.length === 0 ? (
<tr>
<td colSpan={5} className="text-center py-12 text-slate-500">
<td colSpan={6} className="text-center py-12 text-slate-500">
</td>
</tr>
@@ -84,6 +92,16 @@ export default function AdminMembersPage() {
<td className="px-5 py-3 text-slate-400">
{new Date(m.created_at).toLocaleDateString('ko-KR')}
</td>
<td className="px-5 py-3">
{m.activeSub ? (
<div>
<span className="text-xs font-semibold text-amber-400">{PLAN_LABELS[m.activeSub.product_id] ?? m.activeSub.product_id}</span>
<div className="text-xs text-slate-500">{new Date(m.activeSub.expires_at).toLocaleDateString('ko-KR')} </div>
</div>
) : (
<span className="text-xs text-slate-600">-</span>
)}
</td>
<td className="px-5 py-3 text-right">
<span className={`px-2 py-0.5 rounded-full text-xs ${m.orderCount > 0 ? 'bg-green-900/40 text-green-400' : 'bg-slate-700 text-slate-500'}`}>
{m.orderCount}