feat: 修改翻译
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { useTranslations } from 'next-intl';
|
||||
import React from 'react';
|
||||
import { PlanList } from './index';
|
||||
import { ProcessedPlanData } from './types';
|
||||
@@ -23,6 +24,7 @@ export const TabContent: React.FC<TabContentProps> = ({
|
||||
onSubscribe,
|
||||
firstPlanCardRef,
|
||||
}) => {
|
||||
const t = useTranslations('components.offerDialog');
|
||||
return (
|
||||
<div>
|
||||
{tabValue === 'year' && (
|
||||
@@ -32,7 +34,7 @@ export const TabContent: React.FC<TabContentProps> = ({
|
||||
tabValue={tabValue}
|
||||
error={error}
|
||||
onRetry={onRetry}
|
||||
emptyMessage='暂无年付套餐'
|
||||
emptyMessage={t('noYearlyPlan')}
|
||||
onSubscribe={onSubscribe}
|
||||
firstPlanCardRef={firstPlanCardRef}
|
||||
/>
|
||||
@@ -44,7 +46,7 @@ export const TabContent: React.FC<TabContentProps> = ({
|
||||
isLoading={isLoading}
|
||||
error={error}
|
||||
onRetry={onRetry}
|
||||
emptyMessage='暂无月付套餐'
|
||||
emptyMessage={t('noMonthlyPlan')}
|
||||
onSubscribe={onSubscribe}
|
||||
firstPlanCardRef={firstPlanCardRef}
|
||||
/>
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import CloseSvg from '@/components/CustomIcon/icons/close.svg';
|
||||
import { getSubscription } from '@/services/user/portal';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Dialog, DialogContent, DialogTitle } from '@workspace/airo-ui/components/dialog';
|
||||
import { ScrollArea } from '@workspace/airo-ui/components/scroll-area';
|
||||
import { Tabs, TabsList, TabsTrigger } from '@workspace/airo-ui/components/tabs';
|
||||
import { unitConversion } from '@workspace/airo-ui/utils';
|
||||
import Image from 'next/image';
|
||||
import {
|
||||
forwardRef,
|
||||
useCallback,
|
||||
@@ -20,25 +18,31 @@ import { TabContent } from './TabContent';
|
||||
import { ProcessedPlanData } from './types';
|
||||
|
||||
// 加载状态组件
|
||||
const LoadingState = () => (
|
||||
<div className='py-12 text-center'>
|
||||
<div className='mx-auto h-12 w-12 animate-spin rounded-full border-b-2 border-[#0F2C53]'></div>
|
||||
<p className='mt-4 text-gray-600'>加载中...</p>
|
||||
</div>
|
||||
);
|
||||
const LoadingState = () => {
|
||||
const t = useTranslations('components.offerDialog');
|
||||
return (
|
||||
<div className='py-12 text-center'>
|
||||
<div className='mx-auto h-12 w-12 animate-spin rounded-full border-b-2 border-[#0F2C53]'></div>
|
||||
<p className='mt-4 text-gray-600'>{t('loading')}</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// 错误状态组件
|
||||
const ErrorState = ({ onRetry }: { onRetry: () => void }) => (
|
||||
<div className='py-12 text-center'>
|
||||
<p className='text-lg text-red-500'>加载失败,请重试</p>
|
||||
<button
|
||||
onClick={onRetry}
|
||||
className='mt-4 rounded-lg bg-[#0F2C53] px-6 py-2 text-white transition-colors hover:bg-[#0A2C47]'
|
||||
>
|
||||
重新加载
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
const ErrorState = ({ onRetry }: { onRetry: () => void }) => {
|
||||
const t = useTranslations('components.offerDialog');
|
||||
return (
|
||||
<div className='py-12 text-center'>
|
||||
<p className='text-lg text-red-500'>{t('loadFailed')}</p>
|
||||
<button
|
||||
onClick={onRetry}
|
||||
className='mt-4 rounded-lg bg-[#0F2C53] px-6 py-2 text-white transition-colors hover:bg-[#0A2C47]'
|
||||
>
|
||||
{t('reload')}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// 空状态组件
|
||||
const EmptyState = ({ message }: { message: string }) => (
|
||||
@@ -48,34 +52,41 @@ const EmptyState = ({ message }: { message: string }) => (
|
||||
);
|
||||
|
||||
// 价格显示组件
|
||||
const PriceDisplay = ({ plan }: { plan: ProcessedPlanData }) => (
|
||||
<div className='mb-2 sm:mb-4'>
|
||||
<div className='mb-1 flex items-baseline gap-2'>
|
||||
{plan.origin_price && (
|
||||
<span className='text-2xl font-bold leading-[1.125em] text-[#666666] line-through'>
|
||||
${plan.origin_price}
|
||||
const PriceDisplay = ({ plan }: { plan: ProcessedPlanData }) => {
|
||||
const t = useTranslations('components.offerDialog');
|
||||
return (
|
||||
<div className='mb-2 sm:mb-4'>
|
||||
<div className='mb-1 flex items-baseline gap-2'>
|
||||
{plan.origin_price && (
|
||||
<span className='text-2xl font-bold leading-[1.125em] text-[#666666] line-through'>
|
||||
${plan.origin_price}
|
||||
</span>
|
||||
)}
|
||||
<span className='text-2xl font-bold leading-[1.125em] text-[#091B33]'>
|
||||
${plan.discount_price}
|
||||
</span>
|
||||
<span className='text-sm font-normal leading-[1.8em] text-[#4D4D4D] sm:text-[15px]'>
|
||||
{t('perYear')}
|
||||
</span>
|
||||
</div>
|
||||
{plan.origin_price && (
|
||||
<p className='text-left text-[10px] font-normal text-black'>{t('yearlyDiscount')}</p>
|
||||
)}
|
||||
<span className='text-2xl font-bold leading-[1.125em] text-[#091B33]'>
|
||||
${plan.discount_price}
|
||||
</span>
|
||||
<span className='text-sm font-normal leading-[1.8em] text-[#4D4D4D] sm:text-[15px]'>/年</span>
|
||||
</div>
|
||||
{plan.origin_price && (
|
||||
<p className='text-left text-[10px] font-normal text-black'>年付享受8折优惠</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
import { useLoginDialog } from '@/app/auth/LoginDialogContext';
|
||||
import { Display } from '@/components/display';
|
||||
import Purchase from '@/components/subscribe/purchase';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
// 订阅按钮组件
|
||||
const SubscribeButton = ({ onClick }: { onClick?: () => void }) => {
|
||||
const { user } = useGlobalStore();
|
||||
const { openLoginDialog } = useLoginDialog();
|
||||
const t = useTranslations('components.offerDialog');
|
||||
|
||||
function handleClick() {
|
||||
console.log('click', user);
|
||||
@@ -92,7 +103,7 @@ const SubscribeButton = ({ onClick }: { onClick?: () => void }) => {
|
||||
onClick={handleClick}
|
||||
className='h-10 w-full rounded-full bg-[#0F2C53] text-sm font-medium text-white shadow-md transition-all duration-300 hover:bg-[#225BA9] sm:h-10 sm:text-sm md:h-[40px] md:text-[14px]'
|
||||
>
|
||||
订阅
|
||||
{t('subscribe')}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
@@ -111,7 +122,8 @@ const StarRating = ({ rating, maxRating = 5 }: { rating: number; maxRating?: num
|
||||
// 功能列表组件
|
||||
const FeatureList = ({ plan }: { plan: ProcessedPlanData }) => {
|
||||
const t = useTranslations('subscribe.detail');
|
||||
const features = [{ label: '可用节点', value: plan.features?.nodes || '11' }];
|
||||
const tOffer = useTranslations('components.offerDialog');
|
||||
const features = [{ label: tOffer('availableNodes'), value: plan.features?.nodes || '11' }];
|
||||
|
||||
return (
|
||||
<div className='mt-6 space-y-0 sm:mt-6'>
|
||||
@@ -154,7 +166,7 @@ const FeatureList = ({ plan }: { plan: ProcessedPlanData }) => {
|
||||
<li className='py-1'>
|
||||
<div className={'flex items-start justify-between'}>
|
||||
<span className='text-xs font-light leading-[1.8461538461538463em] text-black sm:text-[13px]'>
|
||||
网络稳定指数:
|
||||
{tOffer('networkStabilityIndex')}
|
||||
</span>
|
||||
<StarRating rating={plan.features?.stability || 4} />
|
||||
</div>
|
||||
@@ -246,6 +258,7 @@ export interface OfferDialogRef {
|
||||
}
|
||||
|
||||
const OfferDialog = forwardRef<OfferDialogRef>((props, ref) => {
|
||||
const t = useTranslations('components.offerDialog');
|
||||
const [open, setOpen] = useState(false);
|
||||
const [tabValue, setTabValue] = useState('year');
|
||||
const [selectedPlan, setSelectedPlan] = useState<ProcessedPlanData | null>(null);
|
||||
@@ -379,17 +392,13 @@ const OfferDialog = forwardRef<OfferDialogRef>((props, ref) => {
|
||||
<DialogContent
|
||||
ref={dialogRef}
|
||||
className='rounded-0 !container h-full w-full gap-0 px-8 py-8 sm:h-auto sm:!rounded-[32px] sm:px-12 sm:py-12 md:w-[1000px]'
|
||||
closeIcon={<Image src={CloseSvg} alt={'close'} />}
|
||||
closeClassName={
|
||||
'right-6 top-6 font-bold text-black opacity-100 focus:ring-0 focus:ring-offset-0'
|
||||
}
|
||||
>
|
||||
<DialogTitle className={'sr-only'}></DialogTitle>
|
||||
<div className={'text-4xl font-bold text-[#0F2C53] md:mb-4 md:text-center md:text-5xl'}>
|
||||
选择套餐
|
||||
{t('selectPlan')}
|
||||
</div>
|
||||
<div className={'text-lg font-medium text-[#666666] md:text-center'}>
|
||||
选择最适合您的服务套餐
|
||||
{t('selectYourPlan')}
|
||||
</div>
|
||||
<div>
|
||||
<Tabs
|
||||
@@ -421,7 +430,7 @@ const OfferDialog = forwardRef<OfferDialogRef>((props, ref) => {
|
||||
}
|
||||
value='year'
|
||||
>
|
||||
年付套餐
|
||||
{t('yearlyPlan')}
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
className={
|
||||
@@ -429,7 +438,7 @@ const OfferDialog = forwardRef<OfferDialogRef>((props, ref) => {
|
||||
}
|
||||
value='month'
|
||||
>
|
||||
月付套餐
|
||||
{t('monthlyPlan')}
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
|
||||
Reference in New Issue
Block a user