// apps/admin/src/app/(admin)/users/[id]/page.tsx // 유저 상세 — 프로필 + 구독 + 30일 사용량 import { Box, Grid } from '@mui/material' import { MetalCard, PhosphorText } from '@d3ro/ui/components/ds' import { d3roPalette, d3roFontMono, d3roTypo } from '@d3ro/ui/theme' import { getSupabaseServerClient } from '@/lib/supabase-server' import { notFound } from 'next/navigation' interface PageProps { params: Promise<{ id: string }> } export default async function AdminUserDetailPage({ params }: PageProps): Promise { const { id } = await params const supabase = await getSupabaseServerClient() const [profileRes, subRes, usageRes] = await Promise.all([ supabase.from('profiles').select('*').eq('id', id).maybeSingle(), supabase.from('subscriptions').select('*').eq('user_id', id).maybeSingle(), supabase.from('daily_usage').select('*') .eq('user_id', id) .gte('date', new Date(Date.now() - 30 * 86400000).toISOString().split('T')[0]) .order('date', { ascending: false }), ]) const profile = profileRes.data as Record | null if (!profile) notFound() const sub = subRes.data as Record | null const usage = (usageRes.data ?? []) as Array> const tier = (profile.tier as string) ?? 'free' const tierColor = tier === 'pro_plus' ? d3roPalette.tag.purple : tier === 'pro' ? d3roPalette.tag.green : d3roPalette.accent.amber return ( USER DETAIL PROFILE SUBSCRIPTION {sub ? ( ) : ( No subscription )} USAGE (30 DAYS) {usage.length === 0 ? ( No usage data ) : ( DATEFEATURECOUNT {usage.map((row, i) => ( {row.date as string} {row.feature as string} {row.count as number} ))} )} ) } function Row({ label, value, valueColor }: { label: string; value: string; valueColor?: string }): React.ReactElement { return ( {label} {value} ) }