"use client"; import { useEffect, useState } from "react"; import { useSession } from "next-auth/react"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Crown, Check, X, Loader2, AlertTriangle, CheckCircle } from "lucide-react"; import { api } from "@/lib/api"; interface PlanFeature { name: string; included: boolean; } interface PlanDetail { id: string; name: string; price: number; max_queries: number; features: PlanFeature[]; } interface SubscriptionData { id: string; plan: string; status: string; start_date: string; end_date: string; amount: number | null; payment_method: string | null; created_at: string; } function ProfileTab() { const { data: session, update } = useSession(); const [name, setName] = useState(session?.user?.name || ""); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); const [success, setSuccess] = useState(false); const handleSave = async (e: React.FormEvent) => { e.preventDefault(); if (!session?.accessToken) return; setLoading(true); setError(""); setSuccess(false); try { await api.auth.updateProfile(session.accessToken, { name }); await update({ name }); setSuccess(true); } catch (err: unknown) { const message = err instanceof Error ? err.message : "保存失败"; setError(message); } finally { setLoading(false); } }; return (
{error &&

{error}

} {success &&

个人资料已更新

}
setName(e.target.value)} placeholder="请输入用户名" />
); } function PasswordTab() { const { data: session } = useSession(); const [oldPassword, setOldPassword] = useState(""); const [newPassword, setNewPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); const [success, setSuccess] = useState(false); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(""); setSuccess(false); if (newPassword.length < 8) { setError("新密码至少需要 8 位"); return; } if (newPassword !== confirmPassword) { setError("两次输入的新密码不一致"); return; } if (!session?.accessToken) { setError("登录已过期,请重新登录"); return; } setLoading(true); try { await api.auth.changePassword(session.accessToken, oldPassword, newPassword); setSuccess(true); setOldPassword(""); setNewPassword(""); setConfirmPassword(""); } catch (err: unknown) { const message = err instanceof Error ? err.message : "修改失败"; setError(message); } finally { setLoading(false); } }; return (
{error &&

{error}

} {success &&

密码修改成功

}
setOldPassword(e.target.value)} required />
setNewPassword(e.target.value)} required />
setConfirmPassword(e.target.value)} required />
); } function SubscriptionTab() { const { data: session } = useSession(); const [plans, setPlans] = useState([]); const [currentSub, setCurrentSub] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(null); const [dialogOpen, setDialogOpen] = useState(false); const [dialogType, setDialogType] = useState<"subscribe" | "cancel">("subscribe"); const [selectedPlan, setSelectedPlan] = useState(""); const [actionLoading, setActionLoading] = useState(false); const token = session?.accessToken; const currentPlan = currentSub?.plan || "free"; useEffect(() => { loadData(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [token]); async function loadData() { setLoading(true); setError(null); try { const plansData = await api.subscriptions.getPlans(); setPlans(plansData); if (token) { try { const subData = await api.subscriptions.getCurrent(token); setCurrentSub(subData); } catch { // 暂无订阅记录,保持 null setCurrentSub(null); } } } catch (err) { setError(err instanceof Error ? err.message : "加载失败"); } finally { setLoading(false); } } function openSubscribeDialog(planId: string) { setSelectedPlan(planId); setDialogType("subscribe"); setDialogOpen(true); } function openCancelDialog() { setDialogType("cancel"); setDialogOpen(true); } async function handleConfirm() { if (!token) return; setActionLoading(true); setSuccess(null); try { if (dialogType === "subscribe") { await api.subscriptions.subscribe(token, selectedPlan); setSuccess("订阅成功"); } else { await api.subscriptions.cancel(token); setSuccess("订阅已取消"); } await loadData(); setDialogOpen(false); setTimeout(() => setSuccess(null), 3000); } catch (err) { setError(err instanceof Error ? err.message : "操作失败"); setDialogOpen(false); } finally { setActionLoading(false); } } const currentPlanName = plans.find((p) => p.id === currentPlan)?.name || currentPlan; return (
{error && (
{error}
)} {success && (
{success}
)} 当前套餐

{currentPlanName}

当前套餐 {currentSub?.status && ( 状态: {currentSub.status === "active" ? "生效中" : currentSub.status} )}
{currentPlan !== "free" && currentSub && (

有效期: {currentSub.start_date} 至 {currentSub.end_date}

{currentSub.amount &&

金额: ¥{currentSub.amount}

}
)} {currentPlan !== "free" && ( )}

套餐对比

{loading ? (
) : (
{plans.map((plan) => { const isCurrent = plan.id === currentPlan; const canUpgrade = plan.id !== currentPlan; return ( {plan.name} ¥{plan.price} /月
    {plan.features.map((feature, idx) => (
  • {feature.included ? ( ) : ( )} {feature.name}
  • ))}
{isCurrent ? ( 当前套餐 ) : canUpgrade ? ( ) : null}
); })}
)}
{dialogType === "subscribe" ? "确认订阅" : "取消订阅"} {dialogType === "subscribe" ? `确认使用模拟支付订阅「${plans.find((p) => p.id === selectedPlan)?.name || selectedPlan}」套餐?` : "确认取消当前订阅?取消后将在当前计费周期结束后恢复为免费版。"}
); } export default function SettingsPage() { return (

设置

管理您的账户和订阅信息

个人资料 密码修改 订阅管理 个人资料 管理您的基本信息 密码修改 更改您的登录密码
); }