import { useState } from 'react'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { User as UserIcon, Crown, Coins, History, KeyRound, ShoppingBag, Loader2, ChevronLeft, ChevronRight, Mail, Phone, CalendarDays, type LucideIcon, } from 'lucide-react'; import { useProfile, useProfileBalance, useProfileMembership, useProfileLoginLogs, useProfileApiKeys, useProfilePurchasedApps, } from '@/hooks/useApi'; function StatCard({ icon: Icon, label, value, hint, accent, }: { icon: LucideIcon; label: string; value: string; hint?: string; accent: string; }) { return (
{label}
{value}
{hint &&

{hint}

}
); } function formatNumber(n: number): string { return n.toLocaleString('zh-CN'); } function formatTime(iso: string | null): string { if (!iso) return '—'; const d = new Date(iso); if (isNaN(d.getTime())) return iso; return d.toLocaleString('zh-CN', { hour12: false }); } function InfoRow({ icon: Icon, label, value }: { icon: LucideIcon; label: string; value: string }) { return (
{label} {value}
); } export function ProfilePage() { const [logPage, setLogPage] = useState(1); const logPageSize = 8; const { data: profile, isLoading: pLoading } = useProfile(); const { data: balance, isLoading: bLoading } = useProfileBalance(); const { data: membership } = useProfileMembership(); const { data: loginLogs, isLoading: logsLoading, isFetching: logsFetching } = useProfileLoginLogs( logPage, logPageSize ); const { data: apiKeys, isLoading: keysLoading } = useProfileApiKeys(); const { data: purchasedApps, isLoading: appsLoading } = useProfilePurchasedApps(); const logTotal = loginLogs?.total ?? 0; const logItems = loginLogs?.items ?? []; const logTotalPages = Math.max(1, Math.ceil(logTotal / logPageSize)); const isExpired = membership?.is_expired ?? false; const hasMembership = membership?.has_membership ?? false; return (
{/* Header */}

个人中心

管理账户资料、会员状态、余额与 API 密钥

{profile?.created_at && ( 注册于 {formatTime(profile.created_at).split(' ')[0]} )}
{/* Profile card + membership */}
{/* Profile identity */} 账户资料 当前登录账户的基础信息
{profile?.username?.[0]?.toUpperCase() ?? '—'}

{pLoading ? '加载中…' : profile?.username ?? '—'}

{profile?.role ?? 'user'} · {profile?.status ?? 'active'}

{/* Membership */} 会员状态 当前订阅与有效期 {!hasMembership ? (

尚未开通会员

) : ( <>
套餐 {isExpired ? '已过期' : '生效中'}
计划 ID {membership?.plan_id ?? '—'}
生效 {formatTime(membership?.start_at ?? null).split(' ')[0]}
到期 {formatTime(membership?.expire_at ?? null).split(' ')[0]}
)}
{/* Balance stat row */}
{/* Login logs */}
登录记录 最近账户登录 IP 与设备信息
{logsLoading ? ( ) : logItems.length === 0 ? ( ) : ( logItems.map((log) => ( )) )}
时间 IP User Agent
暂无登录记录
{formatTime(log.login_at)} {log.ip} {log.user_agent}
{/* Pagination */}
第 {logPage} / {logTotalPages} 页 · 共 {formatNumber(logTotal)} 条
{/* Two-column: API keys + purchased apps */}
{/* API Keys */} API 密钥 用于第三方集成的访问凭证 {keysLoading ? (
) : !apiKeys || apiKeys.length === 0 ? (
尚未创建密钥
) : ( apiKeys.map((k) => (

{k.name}

{k.key_preview}

{k.status === 'active' ? '启用' : k.status}
)) )}
{/* Purchased apps */} 已购应用 已下单的应用服务列表 {appsLoading ? (
) : !purchasedApps || purchasedApps.length === 0 ? (
暂无已购应用
) : ( purchasedApps.map((app) => (
{app.app_icon ? ( ) : (
)}

{app.app_name}

{app.app_type} · {formatTime(app.purchased_at).split(' ')[0]}

¥{formatNumber(app.price)}
)) )}
); } export default ProfilePage;