feat: 修改样式
This commit is contained in:
parent
265519a03d
commit
612829375b
@ -75,7 +75,7 @@ export default function Content() {
|
|||||||
const { data: orderData } = useQuery({
|
const { data: orderData } = useQuery({
|
||||||
queryKey: ['orderData'],
|
queryKey: ['orderData'],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data } = await queryOrderList({ status: 5 });
|
const { data } = await queryOrderList({ status: 5, page: 1, size: 10 });
|
||||||
return data?.[0] ?? {};
|
return data?.[0] ?? {};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { Dialog, DialogContent } from '@workspace/airo-ui/components/dialog';
|
import { Dialog, DialogContent, DialogTitle } from '@workspace/airo-ui/components/dialog';
|
||||||
import { Separator } from '@workspace/airo-ui/components/separator';
|
import { Separator } from '@workspace/airo-ui/components/separator';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
@ -63,6 +63,9 @@ const OrderDetailDialog = forwardRef<OrderDetailDialogRef, OrderDetailDialogProp
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onOpenChange={setOpen}>
|
<Dialog open={open} onOpenChange={setOpen}>
|
||||||
|
<DialogTitle>
|
||||||
|
<div className={'sr-only'}>order detail</div>
|
||||||
|
</DialogTitle>
|
||||||
<DialogContent className='sm:w-[675px]'>
|
<DialogContent className='sm:w-[675px]'>
|
||||||
<div className='text-4xl font-bold text-[#0F2C53] sm:mb-8 sm:text-center sm:text-4xl'>
|
<div className='text-4xl font-bold text-[#0F2C53] sm:mb-8 sm:text-center sm:text-4xl'>
|
||||||
{t('orderDetail')}
|
{t('orderDetail')}
|
||||||
@ -75,7 +78,7 @@ const OrderDetailDialog = forwardRef<OrderDetailDialogRef, OrderDetailDialogProp
|
|||||||
<Separator className='mb-3 mt-2 h-[2px] bg-[#225BA9]' />
|
<Separator className='mb-3 mt-2 h-[2px] bg-[#225BA9]' />
|
||||||
<div className='text-[15px] text-[#225BA9]'>
|
<div className='text-[15px] text-[#225BA9]'>
|
||||||
<div>{t('paymentMethod')}</div>
|
<div>{t('paymentMethod')}</div>
|
||||||
<div className='font-light text-[#666]'>{t('walletBalance')}</div>
|
<div className='font-light text-[#666]'>{data?.payment?.name}</div>
|
||||||
</div>
|
</div>
|
||||||
<Separator className='mb-3 mt-4 bg-[#225BA9]' />
|
<Separator className='mb-3 mt-4 bg-[#225BA9]' />
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -39,7 +39,7 @@ export default function Page() {
|
|||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data } = await queryOrderDetail({ order_no: orderNo! });
|
const { data } = await queryOrderDetail({ order_no: orderNo! });
|
||||||
if (data?.data?.status !== 1) {
|
if (data?.data?.status !== 1) {
|
||||||
getUserInfo();
|
await getUserInfo();
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
}
|
}
|
||||||
return data?.data;
|
return data?.data;
|
||||||
|
|||||||
@ -175,7 +175,7 @@ const PlanCard = forwardRef<
|
|||||||
|
|
||||||
// 有生效套餐进行弹窗提示
|
// 有生效套餐进行弹窗提示
|
||||||
const { data } = await queryUserSubscribe();
|
const { data } = await queryUserSubscribe();
|
||||||
if (data?.data?.list?.[0].status === 1) {
|
if (data?.data?.list?.[0]?.status === 1) {
|
||||||
ModalRef.current.show();
|
ModalRef.current.show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,55 +1,3 @@
|
|||||||
/*
|
|
||||||
'use client';
|
|
||||||
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@workspace/ui/components/card';
|
|
||||||
import { Separator } from '@workspace/ui/components/separator';
|
|
||||||
import { useTranslations } from 'next-intl';
|
|
||||||
|
|
||||||
export function SubscribeBilling({ order }: { order: API.Order }) {
|
|
||||||
const t = useTranslations('subscribe.billing');
|
|
||||||
const t_c = useTranslations('components.billing');
|
|
||||||
return (
|
|
||||||
<Card>
|
|
||||||
<CardHeader>
|
|
||||||
<CardTitle>{t('billingTitle')}</CardTitle>
|
|
||||||
</CardHeader>
|
|
||||||
<CardContent>
|
|
||||||
<div className={'grid gap-4'}>
|
|
||||||
<div className={'flex items-center justify-between'}>
|
|
||||||
<span className={'text-muted-foreground'}>{t('productDiscount')}</span>
|
|
||||||
<span className={''}>-¥ {order?.discount_amount}</span>
|
|
||||||
</div>
|
|
||||||
<div className={'flex items-center justify-between'}>
|
|
||||||
<span className={'text-muted-foreground'}>{t('couponDiscount')}</span>
|
|
||||||
<span className={''}>-¥ {order?.coupon_discount_amount}</span>
|
|
||||||
</div>
|
|
||||||
<div className={'flex items-center justify-between'}>
|
|
||||||
<span className={'text-muted-foreground'}>{t_c('planDuration')}</span>
|
|
||||||
<span className={''}>
|
|
||||||
{order?.quantity === 1 ? t_c('30days') : ''}
|
|
||||||
{order?.quantity === 12 ? t_c('365days') : ''}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className={'flex items-center justify-between'}>
|
|
||||||
<span className={'text-muted-foreground'}>{t('gift')}</span>
|
|
||||||
<span className={''}>-¥ {order?.gift_balance_deduction_amount}</span>
|
|
||||||
</div>
|
|
||||||
<div className={'flex items-center justify-between'}>
|
|
||||||
<span className={'text-muted-foreground'}>{t('fee')}</span>
|
|
||||||
<span className={''}>¥ {order?.fee}</span>
|
|
||||||
</div>
|
|
||||||
<Separator />
|
|
||||||
<div className={'flex items-center justify-between font-medium'}>
|
|
||||||
<span className={'text-muted-foreground'}>{t('total')}</span>
|
|
||||||
<span className={''}>¥ {order?.total_amount}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CardContent>
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Display } from '@/components/display';
|
import { Display } from '@/components/display';
|
||||||
@ -81,14 +29,6 @@ export function SubscribeBilling({ order }: Readonly<SubscribeBillingProps>) {
|
|||||||
{order?.quantity === 12 ? t_c('365days') : ''}
|
{order?.quantity === 12 ? t_c('365days') : ''}
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
{order?.type && [1, 2].includes(order?.type) && (
|
|
||||||
<li>
|
|
||||||
<span className=''>{t('billing.duration')}</span>
|
|
||||||
<span>
|
|
||||||
{order?.quantity || 1} {t(order?.unit_time || 'Month')}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
<li>
|
<li>
|
||||||
<span className=''>{t('billing.price')}</span>
|
<span className=''>{t('billing.price')}</span>
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@ -7,64 +7,71 @@ import { RadioGroup, RadioGroupItem } from '@workspace/airo-ui/components/radio-
|
|||||||
import { cn } from '@workspace/airo-ui/lib/utils';
|
import { cn } from '@workspace/airo-ui/lib/utils';
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import React, { memo } from 'react';
|
import React, { memo, useState } from 'react';
|
||||||
|
|
||||||
interface PaymentMethodsProps {
|
interface PaymentMethodsProps {
|
||||||
value: number;
|
value: number;
|
||||||
onChange: (value: number) => void;
|
onChange: (value: number) => void;
|
||||||
balance?: boolean;
|
balance?: boolean;
|
||||||
|
titleClassName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PaymentMethods: React.FC<PaymentMethodsProps> = ({ value, onChange, balance = true }) => {
|
const PaymentMethods: React.FC<PaymentMethodsProps> = ({
|
||||||
|
value,
|
||||||
|
onChange,
|
||||||
|
balance = true,
|
||||||
|
titleClassName,
|
||||||
|
}) => {
|
||||||
const t = useTranslations('subscribe');
|
const t = useTranslations('subscribe');
|
||||||
|
const [methods, setMethods] = useState({});
|
||||||
const { data } = useQuery({
|
const { data } = useQuery({
|
||||||
queryKey: ['getAvailablePaymentMethods', { balance }],
|
queryKey: ['getAvailablePaymentMethods', { balance }],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data } = await getAvailablePaymentMethods();
|
const { data } = await getAvailablePaymentMethods();
|
||||||
const list = data.data?.list || [];
|
const list = data.data?.list || [];
|
||||||
const methods = balance ? list : list.filter((item) => item.id !== -1);
|
const methods = balance ? list : list.filter((item) => item.id !== -1);
|
||||||
const defaultMethod = methods.find((item) => item.id)?.id;
|
const defaultMethod = methods.find((item) => item.id);
|
||||||
if (defaultMethod) onChange(defaultMethod);
|
if (defaultMethod?.id) {
|
||||||
|
onChange(defaultMethod?.id);
|
||||||
|
setMethods(defaultMethod);
|
||||||
|
}
|
||||||
return methods;
|
return methods;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className='font-semibold'>{t('paymentMethod')}</div>
|
<div className='mb-2 flex items-center font-semibold'>
|
||||||
|
<span className={titleClassName}>{t('paymentMethod')}</span>
|
||||||
|
<span className={'ml-4 text-sm font-medium text-[#666]'}>{methods.name}</span>
|
||||||
|
</div>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
className='grid grid-cols-2 gap-2 md:grid-cols-5'
|
className='flex flex-wrap gap-2'
|
||||||
value={String(value)}
|
value={String(value)}
|
||||||
onValueChange={(val) => {
|
onValueChange={(item) => {
|
||||||
console.log(val);
|
setMethods(item);
|
||||||
onChange(Number(val));
|
onChange(Number(item.id));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{data?.map((item) => (
|
{data?.map((item) => (
|
||||||
<div key={item.id} className='relative'>
|
<div key={item.id} className='relative size-10'>
|
||||||
<RadioGroupItem
|
<RadioGroupItem
|
||||||
value={String(item.id)}
|
value={item}
|
||||||
id={String(item.id)}
|
id={String(item.id)}
|
||||||
className='absolute inset-0 z-10 h-full w-full cursor-pointer opacity-0'
|
className='absolute inset-0 z-10 h-full w-full cursor-pointer opacity-0'
|
||||||
/>
|
/>
|
||||||
<Label
|
<Label
|
||||||
htmlFor={String(item.id)}
|
htmlFor={String(item.id)}
|
||||||
className={cn(
|
className={cn(
|
||||||
'border-muted bg-popover hover:bg-accent hover:text-accent-foreground flex flex-col items-center justify-between rounded-md border-2 py-2',
|
'border-muted bg-popover hover:bg-accent hover:text-accent-foreground flex size-10 flex-col items-center justify-center rounded-md border-2',
|
||||||
String(value) === String(item.id) ? 'border-primary' : '',
|
String(value) === String(item.id) ? 'border-primary' : '',
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className='mb-3 size-12'>
|
<Image
|
||||||
<Image
|
src={item.icon || `/payment/balance.svg`}
|
||||||
src={item.icon || `/payment/balance.svg`}
|
width={32}
|
||||||
width={48}
|
height={32}
|
||||||
height={48}
|
alt={item.name}
|
||||||
alt={item.name}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<span className='w-full overflow-hidden text-ellipsis whitespace-nowrap text-center'>
|
|
||||||
{item.name}
|
|
||||||
</span>
|
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
import PaymentMethods from '@/components/subscribe/payment-methods';
|
||||||
import useGlobalStore from '@/config/use-global';
|
import useGlobalStore from '@/config/use-global';
|
||||||
import { preCreateOrder, purchase } from '@/services/user/order';
|
import { preCreateOrder, purchase } from '@/services/user/order';
|
||||||
import { purchaseCheckout } from '@/services/user/portal';
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
import { Button } from '@workspace/airo-ui/components/button';
|
import { Button } from '@workspace/airo-ui/components/button';
|
||||||
import {
|
import {
|
||||||
@ -24,7 +24,6 @@ import {
|
|||||||
useState,
|
useState,
|
||||||
useTransition,
|
useTransition,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { toast } from 'sonner';
|
|
||||||
import { SubscribeBilling } from './billing';
|
import { SubscribeBilling } from './billing';
|
||||||
import { SubscribeDetail } from './detail';
|
import { SubscribeDetail } from './detail';
|
||||||
|
|
||||||
@ -109,17 +108,8 @@ const Purchase = forwardRef<PurchaseDialogRef, PurchaseProps>((props, ref) => {
|
|||||||
const response = await purchase(params as API.PurchaseOrderRequest);
|
const response = await purchase(params as API.PurchaseOrderRequest);
|
||||||
const orderNo = response.data.data?.order_no;
|
const orderNo = response.data.data?.order_no;
|
||||||
if (orderNo) {
|
if (orderNo) {
|
||||||
const data = await purchaseCheckout({
|
|
||||||
orderNo: orderNo,
|
|
||||||
returnUrl: window.location.href,
|
|
||||||
});
|
|
||||||
await getUserInfo();
|
await getUserInfo();
|
||||||
if (data.data?.type === 'url' && data.data.checkout_url) {
|
router.push(`/payment?order_no=${orderNo}`);
|
||||||
window.open(data.data.checkout_url, '_blank');
|
|
||||||
} else {
|
|
||||||
toast.success(t('paymentSuccess'));
|
|
||||||
router.push(`/dashboard`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
/* empty */
|
/* empty */
|
||||||
@ -193,10 +183,13 @@ const Purchase = forwardRef<PurchaseDialogRef, PurchaseProps>((props, ref) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Separator className='mb-3 mt-4 bg-[#225BA9]' />
|
<Separator className='mb-3 mt-4 bg-[#225BA9]' />
|
||||||
<div className='flex items-center justify-between text-[15px] text-[#225BA9]'>
|
<PaymentMethods
|
||||||
<div>{t('paymentMethod')}</div>
|
titleClassName={'text-[15px] text-[#225BA9]'}
|
||||||
<div className='font-light text-[#666]'>{t('walletBalance')}</div>
|
value={params.payment!}
|
||||||
</div>
|
onChange={(value) => {
|
||||||
|
handleChange('payment', value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='mt-8 flex items-center justify-center'>
|
<div className='mt-8 flex items-center justify-center'>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import { ButtonProps } from '@workspace/airo-ui/components/button';
|
|||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
DialogDescription,
|
|
||||||
DialogHeader,
|
DialogHeader,
|
||||||
DialogTitle,
|
DialogTitle,
|
||||||
DialogTrigger,
|
DialogTrigger,
|
||||||
@ -43,13 +42,12 @@ export default function Recharge(props: Readonly<ButtonProps>) {
|
|||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className='flex h-full flex-col overflow-hidden md:h-auto'>
|
<DialogContent className='flex h-full flex-col overflow-hidden md:h-auto'>
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle className={'text-4xl'}>{t('balanceRecharge')}</DialogTitle>
|
<DialogTitle className={'text-3xl'}>{t('balanceRecharge')}</DialogTitle>
|
||||||
<DialogDescription>{t('rechargeDescription')}</DialogDescription>
|
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className='mt-8 flex flex-col justify-between text-sm'>
|
<div className='mt-6 flex flex-col justify-between text-sm'>
|
||||||
<div className='grid gap-3'>
|
<div className='grid gap-3'>
|
||||||
<div className='font-semibold'>{t('rechargeAmount')}</div>
|
<div className='font-semibold'>{t('rechargeAmount')}</div>
|
||||||
<div className='mb-8 flex'>
|
<div className='mb-6 flex'>
|
||||||
<EnhancedInput
|
<EnhancedInput
|
||||||
type='number'
|
type='number'
|
||||||
placeholder={t('enterAmount')}
|
placeholder={t('enterAmount')}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user