fix: 样式修改

This commit is contained in:
2025-07-30 23:55:34 -07:00
parent c1aa738154
commit 816df42bc3
15 changed files with 310 additions and 331 deletions
@@ -1,142 +1,112 @@
'use client';
import { Display } from '@/components/display';
import { querySubscribeGroupList, querySubscribeList } from '@/services/user/subscribe';
import { querySubscribeList } from '@/services/user/subscribe';
import { useQuery } from '@tanstack/react-query';
import { Button } from '@workspace/ui/components/button';
import { Card, CardContent, CardFooter, CardHeader } from '@workspace/ui/components/card';
import { Separator } from '@workspace/ui/components/separator';
import { Tabs, TabsList, TabsTrigger } from '@workspace/ui/components/tabs';
import { Icon } from '@workspace/ui/custom-components/icon';
import { cn } from '@workspace/ui/lib/utils';
import { useTranslations } from 'next-intl';
import { useState } from 'react';
import { useMemo, useState } from 'react';
import { Empty } from '@/components/empty';
import { SubscribeDetail } from '@/components/subscribe/detail';
import { TabContent } from '@/components/main/OfferDialog/TabContent';
import { ProcessedPlanData } from '@/components/main/OfferDialog/types';
import Purchase from '@/components/subscribe/purchase';
import { unitConversion } from '@workspace/ui/utils';
export default function Page() {
const t = useTranslations('subscribe');
const [subscribe, setSubscribe] = useState<API.Subscribe>();
const [subscribe, setSubscribe] = useState<API.Subscribe | undefined>();
const [tabValue, setTabValue] = useState<'year' | 'month'>('year');
const [group, setGroup] = useState<string>('');
const { data: groups } = useQuery({
queryKey: ['querySubscribeGroupList'],
queryFn: async () => {
const { data } = await querySubscribeGroupList();
return data.data?.list || [];
},
});
const { data } = useQuery({
const { data, isLoading, error, refetch } = useQuery({
queryKey: ['querySubscribeList'],
queryFn: async () => {
const { data } = await querySubscribeList();
return data.data?.list || [];
return data.data?.list?.filter((v) => v.unit_time === 'Month') || [];
},
});
// 处理套餐数据的工具函数
const processPlanData = (item: API.Subscribe, isYearly: boolean): ProcessedPlanData => {
if (isYearly) {
const discountItem = item.discount?.find((v) => v.quantity === 12);
return {
...item,
origin_price: unitConversion('centsToDollars', item.unit_price * 12).toString(), // 原价
discount_price: unitConversion(
'centsToDollars',
item.unit_price * ((discountItem?.discount || 100) / 100) * 12,
).toString(), // 优惠价格
};
} else {
return {
...item,
origin_price: '', // 月付没有原价
discount_price: unitConversion('centsToDollars', item.unit_price).toString(), // 月付价格
};
}
};
// 使用 useMemo 优化数据处理性能
const yearlyPlans: ProcessedPlanData[] = useMemo(
() => (data || []).map((item) => processPlanData(item, true)),
[data],
);
const monthlyPlans: ProcessedPlanData[] = useMemo(
() => (data || []).map((item) => processPlanData(item, false)),
[data],
);
// 处理订阅点击
const handleSubscribe = (plan: ProcessedPlanData) => {
console.log('用户选择了套餐:', plan);
// 这里可以添加订阅逻辑,比如跳转到支付页面或显示确认对话框
setSubscribe(plan);
};
return (
<>
<Tabs value={group} onValueChange={setGroup} className='space-y-4'>
{groups && groups.length > 0 && (
<>
<h1 className='text-muted-foreground w-full'>{t('category')}</h1>
<TabsList>
<TabsTrigger value=''>{t('all')}</TabsTrigger>
{groups.map((group) => (
<TabsTrigger key={group.id} value={String(group.id)}>
{group.name}
</TabsTrigger>
))}
</TabsList>
<h2 className='text-muted-foreground w-full'>{t('products')}</h2>
</>
)}
<div className='grid gap-4 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3'>
{data
?.filter((item) => item.show)
?.filter((item) => (group ? item.group_id === Number(group) : true))
?.map((item) => (
<Card className='flex flex-col' key={item.id}>
<CardHeader className='bg-muted/50 text-xl font-medium'>{item.name}</CardHeader>
<CardContent className='flex flex-grow flex-col gap-3 p-6 *:!text-sm'>
{/* <div className='font-semibold'>{t('productDescription')}</div> */}
<ul className='flex flex-grow flex-col gap-3'>
{(() => {
let parsedDescription;
try {
parsedDescription = JSON.parse(item.description);
} catch {
parsedDescription = { description: '', features: [] };
}
const { description, features } = parsedDescription;
return (
<>
{description && <li className='text-muted-foreground'>{description}</li>}
{features?.map(
(
feature: {
icon: string;
label: string;
type: 'default' | 'success' | 'destructive';
},
index: number,
) => (
<li
className={cn('flex items-center gap-1', {
'text-muted-foreground line-through':
feature.type === 'destructive',
})}
key={index}
>
{feature.icon && (
<Icon
icon={feature.icon}
className={cn('text-primary size-5', {
'text-green-500': feature.type === 'success',
'text-destructive': feature.type === 'destructive',
})}
/>
)}
{feature.label}
</li>
),
)}
</>
);
})()}
</ul>
<SubscribeDetail
subscribe={{
...item,
name: undefined,
}}
/>
</CardContent>
<Separator />
<CardFooter className='relative mt-2 flex flex-col gap-2'>
<h2 className='pb-5 text-2xl font-semibold sm:text-3xl'>
<Display type='currency' value={item.unit_price} />
<span className='text-base font-medium'>/{t(item.unit_time || 'Month')}</span>
</h2>
<Button
className='absolute bottom-0 w-full rounded-b-xl rounded-t-none'
onClick={() => {
setSubscribe(item);
}}
>
{t('buy')}
</Button>
</CardFooter>
</Card>
))}
</div>
{data?.length === 0 && <Empty />}
</Tabs>
<div className={'text-4xl font-bold text-[#0F2C53] md:mb-4 md:text-center md:text-5xl'}>
</div>
<div className={'text-lg font-medium text-[#666666] md:text-center'}>
</div>
<div>
<Tabs
defaultValue='year'
className={'mt-8 text-center md:mt-16'}
value={tabValue}
onValueChange={(value) => setTabValue(value as 'year' | 'month')}
>
<TabsList className='mb-8 h-[74px] flex-wrap rounded-full bg-[#EAEAEA] p-2.5 md:mb-16'>
<TabsTrigger
className={
'rounded-full px-10 py-3.5 text-xl data-[state=active]:bg-[#0F2C53] data-[state=active]:text-white md:px-12'
}
value='year'
>
</TabsTrigger>
<TabsTrigger
className={
'rounded-full px-10 py-3.5 text-xl data-[state=active]:bg-[#0F2C53] data-[state=active]:text-white md:px-12'
}
value='month'
>
</TabsTrigger>
</TabsList>
</Tabs>
<TabContent
tabValue={tabValue}
yearlyPlans={yearlyPlans}
monthlyPlans={monthlyPlans}
isLoading={isLoading}
error={error}
onRetry={refetch}
onSubscribe={handleSubscribe}
/>
</div>
<Purchase subscribe={subscribe} setSubscribe={setSubscribe} />
</>
);