"use client" import { useState, useEffect } from "react" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { CheckIcon, StarIcon, Crown } from "lucide-react" import { useTranslations } from "next-intl" import { useSession } from "next-auth/react" import { useRouter } from "next/navigation" import { toast } from "@/hooks/use-toast" import { useAuth } from "./providers" import { useToast } from "@/components/ui/use-toast" interface PricingSectionProps { locale: string } interface UserInfo { id: string; email: string; username: string | null; isEmailVerified: boolean; credits: number; subscriptionCredits: number; subscriptionStatus: string | null; subscriptionPlan: string | null; subscriptionStartDate: string | null; subscriptionEndDate: string | null; } export default function PricingSection({ locale }: PricingSectionProps) { const t = useTranslations("pricing") const { data: session, status } = useSession() const router = useRouter() const [isSubscribing, setIsSubscribing] = useState(false) const [userInfo, setUserInfo] = useState(null) const [isLoadingUser, setIsLoadingUser] = useState(false) const [isLoading, setIsLoading] = useState(false) const { user, isLoading: isLoadingAuth, refreshUser } = useAuth() const { toast } = useToast() // 获取用户信息包括订阅状态 useEffect(() => { const fetchUserInfo = async () => { // 等待会话状态确定后再执行 if (status === 'loading') { return } if (!session) { setUserInfo(null) return } setIsLoadingUser(true) try { const response = await fetch('/api/auth/me', { method: 'GET', credentials: 'include', }) if (response.ok) { const userData = await response.json() setUserInfo(userData.user) } else { setUserInfo(null) } } catch (error) { console.error('获取用户信息失败:', error) setUserInfo(null) } finally { setIsLoadingUser(false) } } fetchUserInfo() }, [session, status]) // 监听全局认证状态变化事件 useEffect(() => { const handleAuthUpdate = (event: CustomEvent) => { console.log('Pricing component: 收到认证状态更新事件', event.detail); // 当认证状态变化时,重新获取用户信息 if (event.detail.status !== 'loading') { const fetchUserInfo = async () => { if (!event.detail.session) { setUserInfo(null) return } setIsLoadingUser(true) try { const response = await fetch('/api/auth/me', { method: 'GET', credentials: 'include', }) if (response.ok) { const userData = await response.json() setUserInfo(userData.user) } else { setUserInfo(null) } } catch (error) { console.error('获取用户信息失败:', error) setUserInfo(null) } finally { setIsLoadingUser(false) } } fetchUserInfo() } } window.addEventListener('authStatusChanged', handleAuthUpdate as EventListener) return () => { window.removeEventListener('authStatusChanged', handleAuthUpdate as EventListener) } }, []) // 强制刷新用户信息的辅助函数 const forceRefreshUserInfo = async () => { if (status === 'loading') return null; try { const response = await fetch('/api/auth/me', { method: 'GET', credentials: 'include', }) if (response.ok) { const userData = await response.json() setUserInfo(userData.user) return userData.user } return null } catch (error) { console.error('刷新用户信息失败:', error) return null } } const handleSubscribe = async (priceId: string) => { if (isLoadingAuth) { toast({ title: t('checkingAuth'), description: t('pleaseWait'), variant: 'default', }) return } if (!user) { toast({ title: t('loginRequired'), description: t('loginRequiredDesc'), variant: 'destructive', }) router.push(`/${locale}/auth/login`) return } setIsLoading(true) try { const response = await fetch('/api/create-checkout-session', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ priceId, locale, }), }) const data = await response.json() if (data.url) { window.location.href = data.url } else { const errorMessage = data.error === 'alreadySubscribed' ? t('alreadySubscribed') : data.error || t('createSessionFailed'); toast({ title: t('subscriptionFailed'), description: errorMessage, variant: 'destructive', }); console.log('Checkout session data:', data); // 如果已经订阅,刷新用户信息 if (data.error === 'alreadySubscribed') { await refreshUser(); } } } catch (error) { console.error('创建订阅会话失败:', error) toast({ title: t('subscriptionFailed'), description: t('networkError'), variant: 'destructive', }) } finally { setIsLoading(false) } } const handleFreeSignUp = () => { // 跳转到demo页面 router.push(`/${locale}#demo`); }; const handleContactSales = () => { // 新页面打开联系方式页面 window.open(`/${locale}/blog/contact-us`, '_blank'); }; const plans = [ { name: t("free.name"), price: t("free.price"), originalPrice: null, description: t("free.description"), features: [t("free.feature1"), t("free.feature2"), t("free.feature3")], cta: t("free.cta"), popular: false, type: "free" }, { name: t("pro.name"), price: t("pro.price"), originalPrice: t("pro.originalPrice"), description: t("pro.description"), features: [t("pro.feature1"), t("pro.feature2"), t("pro.feature3"), t("pro.feature4")], cta: t("subscribe"), popular: true, type: "pro" }, { name: t("enterprise.name"), price: t("enterprise.price"), originalPrice: null, description: t("enterprise.description"), features: [t("enterprise.feature1"), t("enterprise.feature3")], cta: t("enterprise.cta"), popular: false, type: "enterprise" }, ] const handleButtonClick = (planType: string) => { switch (planType) { case "free": handleFreeSignUp(); break; case "pro": handleSubscribe(planType); break; case "enterprise": handleContactSales(); break; } }; return (

{t("title")}

{t("subtitle")}

{plans.map((plan, index) => ( {plan.popular && (
{t("mostPopular")}
)} {plan.name}
{plan.originalPrice && (
{plan.originalPrice} {t("saveAmount")}
)} {plan.price} {plan.price !== t("enterprise.price") && {t('perMonth')}}

{plan.description}

    {plan.features.map((feature, featureIndex) => (
  • {feature}
  • ))}
))}
) }