feat: 修改样式
This commit is contained in:
@@ -4,13 +4,12 @@ import { Display } from '@/components/display';
|
||||
import { Empty } from '@/components/empty';
|
||||
import { ProList, ProListActions } from '@/components/pro-list';
|
||||
import { closeOrder, queryOrderList } from '@/services/user/order';
|
||||
import { purchaseCheckout } from '@/services/user/portal';
|
||||
import { AiroButton } from '@workspace/airo-ui/components/AiroButton';
|
||||
import { Card, CardContent } from '@workspace/airo-ui/components/card';
|
||||
import { formatDate } from '@workspace/airo-ui/utils';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Link from 'next/link';
|
||||
import { useRef } from 'react';
|
||||
import { toast } from 'sonner';
|
||||
import OrderDetailDialog from './components/OrderDetailDialog';
|
||||
|
||||
export default function Page() {
|
||||
@@ -19,19 +18,6 @@ export default function Page() {
|
||||
const ref = useRef<ProListActions>(null);
|
||||
const OrderDetailDialogRef = useRef<typeof OrderDetailDialog>(null);
|
||||
|
||||
const handlePayment = async (orderNo) => {
|
||||
const data = await purchaseCheckout({
|
||||
orderNo: orderNo,
|
||||
returnUrl: window.location.href,
|
||||
});
|
||||
if (data.data?.type === 'url' && data.data.checkout_url) {
|
||||
window.open(data.data.checkout_url, '_blank');
|
||||
} else {
|
||||
toast.success(t('paymentSuccess'));
|
||||
ref?.current.reset();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ProList<API.OrderDetail, Record<string, unknown>>
|
||||
@@ -63,14 +49,10 @@ export default function Page() {
|
||||
>
|
||||
{t('cancelOrder')}
|
||||
</AiroButton>
|
||||
<AiroButton
|
||||
variant={'primary'}
|
||||
className={'ml-2'}
|
||||
onClick={() => {
|
||||
handlePayment(item.order_no);
|
||||
}}
|
||||
>
|
||||
{t('payment')}
|
||||
<AiroButton variant={'primary'} className={'ml-2'} asChild>
|
||||
<Link key='payment' href={`/payment?order_no=${item.order_no}`}>
|
||||
{t('payment')}
|
||||
</Link>
|
||||
</AiroButton>
|
||||
</>
|
||||
) : (
|
||||
|
||||
@@ -3,26 +3,18 @@
|
||||
import { Display } from '@/components/display';
|
||||
import StripePayment from '@/components/payment/stripe';
|
||||
import { SubscribeBilling } from '@/components/subscribe/billing';
|
||||
import { SubscribeDetail } from '@/components/subscribe/detail';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { queryOrderDetail } from '@/services/user/order';
|
||||
import { purchaseCheckout } from '@/services/user/portal';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Badge } from '@workspace/airo-ui/components/badge';
|
||||
import { Button } from '@workspace/airo-ui/components/button';
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@workspace/airo-ui/components/card';
|
||||
import { AiroButton } from '@workspace/airo-ui/components/AiroButton';
|
||||
import { Card, CardContent } from '@workspace/airo-ui/components/card';
|
||||
import { Separator } from '@workspace/airo-ui/components/separator';
|
||||
import { Icon } from '@workspace/airo-ui/custom-components/icon';
|
||||
import { formatDate } from '@workspace/airo-ui/utils';
|
||||
import { useCountDown } from 'ahooks';
|
||||
import { addMinutes, format } from 'date-fns';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { QRCodeCanvas } from 'qrcode.react';
|
||||
import { useEffect, useState } from 'react';
|
||||
@@ -88,37 +80,130 @@ export default function Page() {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className='grid gap-4 xl:grid-cols-2'>
|
||||
<Card className='order-2 xl:order-1'>
|
||||
<CardHeader className='bg-muted/50 flex flex-row items-start'>
|
||||
<div className='grid gap-0.5'>
|
||||
<CardTitle className='flex flex-col text-lg'>
|
||||
{t('orderNumber')}
|
||||
<span>{data?.orderNo}</span>
|
||||
</CardTitle>
|
||||
<CardDescription>
|
||||
{t('createdAt')}: {formatDate(data?.created_at)}
|
||||
</CardDescription>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent className='grid gap-3 p-6 text-sm'>
|
||||
<div className='font-semibold'>{t('paymentMethod')}</div>
|
||||
<dl className='grid gap-3'>
|
||||
<div className='flex items-center justify-between'>
|
||||
<dt className='text-muted-foreground'>
|
||||
<Badge>{data?.payment.name || data?.payment.platform}</Badge>
|
||||
</dt>
|
||||
<div className=''>
|
||||
<Card className='border-none shadow-none sm:border sm:shadow'>
|
||||
<CardContent className='grid gap-2 p-6 text-sm'>
|
||||
<div className='relative'>
|
||||
<div className={'absolute flex gap-3'}>
|
||||
<div
|
||||
className={
|
||||
'flex items-center justify-between rounded-md border-2 border-[#225BA9] p-0.5'
|
||||
}
|
||||
>
|
||||
<Image
|
||||
src={data?.payment.icon || `/payment/balance.svg`}
|
||||
width={32}
|
||||
height={32}
|
||||
alt={data?.payment.name}
|
||||
/>
|
||||
</div>
|
||||
<div className={'mt-1 text-sm font-medium text-[#666666]'}>
|
||||
{data?.payment.name || data?.payment.platform}
|
||||
</div>
|
||||
</div>
|
||||
</dl>
|
||||
<Separator />
|
||||
|
||||
{data?.status && [2, 5].includes(data?.status) && (
|
||||
<div className='flex flex-col gap-4 sm:gap-8'>
|
||||
<div className='flex justify-end gap-2'>
|
||||
<AiroButton variant={'primary'} asChild>
|
||||
<Link href='/dashboard'>{t('subscribeNow')}</Link>
|
||||
</AiroButton>
|
||||
<AiroButton variant='outline'>
|
||||
<Link href='/document'>{t('viewDocument')}</Link>
|
||||
</AiroButton>
|
||||
</div>
|
||||
<h3 className='text-xl font-bold tracking-tight text-[#666666]'>
|
||||
{t('paymentSuccess')}
|
||||
</h3>
|
||||
</div>
|
||||
)}
|
||||
{data?.status === 1 && payment?.type === 'url' && (
|
||||
<div className='flex flex-col gap-4 sm:gap-8'>
|
||||
<div className='flex justify-end gap-2'>
|
||||
<AiroButton
|
||||
variant={'primary'}
|
||||
onClick={() => {
|
||||
if (payment?.checkout_url) {
|
||||
window.location.href = payment?.checkout_url;
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t('goToPayment')}
|
||||
</AiroButton>
|
||||
<AiroButton variant='outline'>
|
||||
<Link href='/subscribe'>{t('productList')}</Link>
|
||||
</AiroButton>
|
||||
</div>
|
||||
<div className={'flex items-center'}>
|
||||
<h3 className='text-xl font-bold tracking-tight text-[#666666]'>
|
||||
{t('waitingForPayment')}
|
||||
</h3>
|
||||
<p className='ml-3 flex items-center text-xl font-bold text-[#E22C2E]'>
|
||||
{countdownDisplay}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data?.status === 1 && payment?.type === 'qr' && (
|
||||
<div className='flex flex-col gap-4 sm:gap-8'>
|
||||
<div className='flex justify-end gap-2'>
|
||||
<AiroButton asChild variant={'primary'}>
|
||||
<Link href='/subscribe'>{t('productList')}</Link>
|
||||
</AiroButton>
|
||||
<AiroButton asChild variant='outline'>
|
||||
<Link href='/order'>{t('orderList')}</Link>
|
||||
</AiroButton>
|
||||
</div>
|
||||
<h3 className='text-2xl font-bold tracking-tight'>{t('scanToPay')}</h3>
|
||||
<p className='flex items-center text-3xl font-bold'>{countdownDisplay}</p>
|
||||
<QRCodeCanvas
|
||||
value={payment?.checkout_url || ''}
|
||||
size={208}
|
||||
imageSettings={{
|
||||
src: `/payment/alipay_f2f.svg`,
|
||||
width: 24,
|
||||
height: 24,
|
||||
excavate: true,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data?.status === 1 && payment?.type === 'stripe' && (
|
||||
<div className='flex flex-col items-center gap-4 text-center sm:gap-8'>
|
||||
<h3 className='text-2xl font-bold tracking-tight'>{t('waitingForPayment')}</h3>
|
||||
<p className='ml-3 flex items-center text-3xl font-bold'>{countdownDisplay}</p>
|
||||
{payment.stripe && <StripePayment {...payment.stripe} />}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data?.status && [3, 4].includes(data?.status) && (
|
||||
<div className='flex flex-col gap-4 sm:gap-8'>
|
||||
<div className='flex justify-end gap-2'>
|
||||
<AiroButton variant={'primary'} asChild>
|
||||
<Link href='/subscribe'>{t('productList')}</Link>
|
||||
</AiroButton>
|
||||
<AiroButton asChild variant='outline'>
|
||||
<Link href='/order'>{t('orderList')}</Link>
|
||||
</AiroButton>
|
||||
</div>
|
||||
<h3 className='text-xl font-bold tracking-tight text-[#666666]'>
|
||||
{t('orderClosed')}
|
||||
</h3>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Separator className='mb-3 mt-0 bg-[#225BA9] sm:mt-4' />
|
||||
<div className={'mb-4'}>
|
||||
<div className={'font-bold text-[#666]'}>{t('orderNumber')}</div>
|
||||
<div className={'text-xs text-[#4D4D4D]'}>{data?.order_no}</div>
|
||||
</div>
|
||||
{data?.type && [1, 2].includes(data.type) && (
|
||||
<SubscribeDetail
|
||||
subscribe={{
|
||||
...data?.subscribe,
|
||||
quantity: data?.quantity,
|
||||
}}
|
||||
/>
|
||||
<div>
|
||||
<div className={'font-normal text-[#225BA9]'}>名称</div>
|
||||
<div className={'font-semibold'}>{data?.subscribe?.name}</div>
|
||||
</div>
|
||||
)}
|
||||
{data?.type === 3 && (
|
||||
<>
|
||||
@@ -151,7 +236,11 @@ export default function Page() {
|
||||
</ul>
|
||||
</>
|
||||
)}
|
||||
<Separator />
|
||||
<div>
|
||||
<div className={'font-normal text-[#225BA9]'}>{t('createdAt')}</div>
|
||||
<div className={'font-semibold'}>{formatDate(data?.created_at)}</div>
|
||||
</div>
|
||||
<Separator className='mb-3 mt-4 bg-[#225BA9]' />
|
||||
<SubscribeBilling
|
||||
order={{
|
||||
...data,
|
||||
@@ -160,101 +249,6 @@ export default function Page() {
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<Card className='order-1 flex flex-auto items-center justify-center xl:order-2'>
|
||||
<CardContent className='py-16'>
|
||||
{data?.status && [2, 5].includes(data?.status) && (
|
||||
<div className='flex flex-col items-center gap-8 text-center'>
|
||||
<h3 className='text-2xl font-bold tracking-tight'>{t('paymentSuccess')}</h3>
|
||||
<Icon icon='mdi:success-circle-outline' className='text-7xl text-green-500' />
|
||||
<div className='flex gap-4'>
|
||||
<Button asChild>
|
||||
<Link href='/dashboard'>{t('subscribeNow')}</Link>
|
||||
</Button>
|
||||
<Button variant='outline'>
|
||||
<Link href='/document'>{t('viewDocument')}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{data?.status === 1 && payment?.type === 'url' && (
|
||||
<div className='flex flex-col items-center gap-8 text-center'>
|
||||
<h3 className='text-2xl font-bold tracking-tight'>{t('waitingForPayment')}</h3>
|
||||
<p className='flex items-center text-3xl font-bold'>{countdownDisplay}</p>
|
||||
<Icon icon='mdi:access-time' className='text-muted-foreground text-7xl' />
|
||||
<div className='flex gap-4'>
|
||||
<Button
|
||||
onClick={() => {
|
||||
if (payment?.checkout_url) {
|
||||
window.location.href = payment?.checkout_url;
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t('goToPayment')}
|
||||
</Button>
|
||||
<Button variant='outline'>
|
||||
<Link href='/subscribe'>{t('productList')}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data?.status === 1 && payment?.type === 'qr' && (
|
||||
<div className='flex flex-col items-center gap-8 text-center'>
|
||||
<h3 className='text-2xl font-bold tracking-tight'>{t('scanToPay')}</h3>
|
||||
<p className='flex items-center text-3xl font-bold'>{countdownDisplay}</p>
|
||||
<QRCodeCanvas
|
||||
value={payment?.checkout_url || ''}
|
||||
size={208}
|
||||
imageSettings={{
|
||||
src: `/payment/alipay_f2f.svg`,
|
||||
width: 24,
|
||||
height: 24,
|
||||
excavate: true,
|
||||
}}
|
||||
/>
|
||||
<div className='flex gap-4'>
|
||||
<Button asChild>
|
||||
<Link href='/subscribe'>{t('productList')}</Link>
|
||||
</Button>
|
||||
<Button asChild variant='outline'>
|
||||
<Link href='/order'>{t('orderList')}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data?.status === 1 && payment?.type === 'stripe' && (
|
||||
<div className='flex flex-col items-center gap-8 text-center'>
|
||||
<h3 className='text-2xl font-bold tracking-tight'>{t('waitingForPayment')}</h3>
|
||||
<p className='flex items-center text-3xl font-bold'>{countdownDisplay}</p>
|
||||
{payment.stripe && <StripePayment {...payment.stripe} />}
|
||||
{/* <div className='flex gap-4'>
|
||||
<Button asChild>
|
||||
<Link href='/subscribe'>{t('productList')}</Link>
|
||||
</Button>
|
||||
<Button asChild variant='outline'>
|
||||
<Link href='/order'>{t('orderList')}</Link>
|
||||
</Button>
|
||||
</div> */}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data?.status && [3, 4].includes(data?.status) && (
|
||||
<div className='flex flex-col items-center gap-8 text-center'>
|
||||
<h3 className='text-2xl font-bold tracking-tight'>{t('orderClosed')}</h3>
|
||||
<Icon icon='mdi:cancel' className='text-7xl text-red-500' />
|
||||
<div className='flex gap-4'>
|
||||
<Button asChild>
|
||||
<Link href='/subscribe'>{t('productList')}</Link>
|
||||
</Button>
|
||||
<Button asChild variant='outline'>
|
||||
<Link href='/order'>{t('orderList')}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,11 @@ export function SidebarLeft({ ...props }: React.ComponentProps<typeof Sidebar>)
|
||||
const pathname = usePathname();
|
||||
const { toggleSidebar } = useSidebar();
|
||||
return (
|
||||
<Sidebar side='left' {...props} className={'border-0 bg-transparent md:bg-white'}>
|
||||
<Sidebar
|
||||
side='left'
|
||||
{...props}
|
||||
className={'border-0 bg-transparent pb-8 pt-4 shadow-none md:bg-white md:py-0 md:shadow-lg'}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
'relative ml-2.5 flex h-[calc(100dvh-10px-env(safe-area-inset-top))] flex-col rounded-[30px] bg-[#D9D9D9] px-4 md:ml-0 md:h-full md:rounded-none md:bg-white md:px-8'
|
||||
|
||||
Reference in New Issue
Block a user