// 加载状态组件 import { unitConversion } from '@workspace/airo-ui/utils'; import { useRef } from 'react'; const LoadingState = () => { const t = useTranslations('components.offerDialog'); return (

{t('loading')}

); }; // 错误状态组件 const ErrorState = ({ onRetry }: { onRetry: () => void }) => { const t = useTranslations('components.offerDialog'); return (

{t('loadFailed')}

); }; // 空状态组件 const EmptyState = ({ message }: { message: string }) => (

{message}

); import { useLocale } from 'next-intl'; interface PriceDisplayProps { plan: PlanProps; } interface PlanProps extends API.Subscribe { origin_price: string; discount_price: string; } // 价格显示组件 const PriceDisplay: React.FC = ({ plan }) => { const t = useTranslations('components.offerDialog'); const locale = useLocale(); // 获取当前语言环境 const { common } = useGlobalStore(); const discountItem = plan.discount.find((v) => v.quantity === 12) ?? { discount: 0 }; const discount = locale === 'zh-CN' ? discountItem?.discount / 10 : `${100 - discountItem?.discount}%`; return (
{plan.origin_price && ( {common?.currency?.currency_symbol} {plan.origin_price} )} {common?.currency?.currency_symbol} {plan.discount_price} {t('perYear')}
{plan.origin_price && (

{t('yearlyDiscount', { discount })}

)}
); }; import { useLoginDialog } from '@/app/auth/LoginDialogContext'; import { Display } from '@/components/display'; import Modal, { AlertDialogRef } from '@/components/Modal'; import Purchase from '@/components/subscribe/purchase'; import useGlobalStore from '@/config/use-global'; import { queryUserSubscribe } from '@/services/user/user'; import { AiroButton } from '@workspace/airo-ui/components/AiroButton'; import { useTranslations } from 'next-intl'; import React from 'react'; // 星级评分组件 const StarRating = ({ rating, maxRating = 5 }: { rating: number; maxRating?: number }) => (
{Array.from({ length: Math.min(rating, maxRating) }, (_, i) => ( ))}
); import SvgIcon from '@/components/SvgIcon'; // 功能列表组件 const FeatureList = ({ plan }: { plan: API.Subscribe }) => { const t = useTranslations('subscribe.detail'); const tSubscribe = useTranslations('subscribe'); const tOffer = useTranslations('components.offerDialog'); const features = [ { label: tOffer('availableNodes'), icon: 'feature/Vector (5)', value: plan?.server_count }, ]; return (
); }; // 套餐卡片组件 const PlanCard: React.FC<{ plan: PlanProps; tabValue: string; onSubscribe?: (plan: API.Subscribe) => void; isFirstCard?: boolean; }> = ({ plan, onSubscribe }) => { const { user } = useGlobalStore(); const { openLoginDialog } = useLoginDialog(); const t = useTranslations('components.offerDialog'); const ModalRef = useRef(null); async function handleSubscribe() { if (!user) { // 强制登陆 openLoginDialog(false); return; } // 有生效套餐进行弹窗提示 const { data } = await queryUserSubscribe(); if (data?.data?.list?.[0]?.status === 1) { ModalRef.current?.show(); return; } onSubscribe?.(plan); } return (
{/* 套餐名称 */}

{plan.name}

{/* 价格区域 */}
{/* 订阅按钮 */} {t('subscribe')}
{/* 功能列表 */}
onSubscribe?.(plan)} />
); }; PlanCard.displayName = 'PlanCard'; // 套餐列表组件 export const PlanList = ({ plans, tabValue, isLoading, error, onRetry, emptyMessage, onSubscribe, }: { plans: PlanProps[]; tabValue: string; isLoading: boolean; error: any; onRetry: () => void; emptyMessage: string; onSubscribe?: (plan: API.Subscribe) => void; }) => { if (isLoading) return ; if (error) return ; if (plans.length === 0) return ; return (
{plans.map((plan, index) => ( ))}
); }; interface TabContentProps { tabValue: string; subscribeData: API.Subscribe[]; isLoading: boolean; error: Error | null; onRetry: () => void; firstPlanCardRef?: React.RefObject; } const TabContent: React.FC = ({ tabValue, subscribeData, isLoading, error, onRetry, }) => { const t = useTranslations('components.offerDialog'); // 处理套餐数据的工具函数 const processPlanData = (item: API.Subscribe, isYearly: boolean): PlanProps => { if (isYearly) { const discountItem = item.discount?.find((v) => v.quantity === 12); return { ...item, origin_price: unitConversion('centsToDollars', item.unit_price).toString(), // 原价 discount_price: unitConversion( 'centsToDollars', item.unit_price * ((discountItem?.discount || 100) / 100), ).toString(), // 优惠价格 }; } else { return { ...item, origin_price: '', // 月付没有原价 discount_price: unitConversion('centsToDollars', item.unit_price).toString(), // 月付价格 }; } }; console.log('subscribeData:', subscribeData); let yearlyPlans: PlanProps[] = []; if (Array.isArray(subscribeData)) { yearlyPlans = subscribeData.map((item) => processPlanData(item, true)); } let monthlyPlans: PlanProps[] = []; if (Array.isArray(subscribeData)) { monthlyPlans = subscribeData.map((item) => processPlanData(item, false)); } const PurchaseRef = useRef<{ show: (subscribe: API.Subscribe, tabValue: string) => void; hide: () => void; }>(null); // 处理订阅点击 const handleSubscribe = (plan: API.Subscribe) => { // 这里可以添加订阅逻辑,比如跳转到支付页面或显示确认对话框 PurchaseRef.current?.show(plan, tabValue); }; return (
{tabValue === 'year' && ( )} {tabValue === 'month' && ( )}
); }; export default TabContent;