feat: 修改代码结构

This commit is contained in:
2025-08-15 09:16:02 -07:00
parent 5524d25d9a
commit 525e305f1d
17 changed files with 256 additions and 63 deletions
@@ -18,8 +18,8 @@ export function Header() {
const pathname = usePathname();
const items = useMemo(() => findNavByUrl(pathname), [pathname]);
return (
<header className='box-content flex h-[84px] items-center justify-between gap-2 px-4 pt-4 md:hidden'>
<SidebarTrigger />
<header className='flex h-[84px] w-full items-center justify-end gap-2 px-4 pt-4 md:hidden'>
<SidebarTrigger className={'fixed left-4'} />
<Breadcrumb>
<BreadcrumbList className={'text-[36px] font-semibold'}>
{items.map((item, index) => {
@@ -75,8 +75,8 @@ export default function Content() {
const { data: orderData } = useQuery({
queryKey: ['orderData'],
queryFn: async () => {
const { data } = await queryOrderList({ status: 5, page: 1, size: 10 });
return data?.[0] ?? {};
const { data } = await queryOrderList({ status: 5, page: 1, size: 1 });
return data?.data?.list?.[0] ?? {};
},
});
@@ -13,8 +13,8 @@ export default async function DashboardLayout({ children }: { children: React.Re
<SidebarLeft className='w-[288px] border-r-0 bg-transparent lg:flex' />
<SidebarInset className='relative flex-grow overflow-hidden'>
{/*<LanguageSwitch />*/}
<Header />
<div className='h-[calc(100vh-84px)] flex-grow gap-4 overflow-auto p-4 pt-0 sm:pt-9'>
<div className='h-screen flex-grow gap-4 overflow-auto p-4 sm:pt-9'>
<Header />
{children}
</div>
</SidebarInset>
@@ -5,6 +5,7 @@ import { updateUserNotify } from '@/services/user/user';
import { zodResolver } from '@hookform/resolvers/zod';
import { Button } from '@workspace/airo-ui/components/button';
import { Card } from '@workspace/airo-ui/components/card';
import { useEffect } from 'react';
import { AiroButton } from '@workspace/airo-ui/components/AiroButton';
import {
@@ -39,6 +40,17 @@ export default function NotifySettings() {
enable_trade_notify: user?.enable_trade_notify ?? false,
},
});
// 监听 user 变化,更新表单
useEffect(() => {
if (user) {
form.reset({
enable_balance_notify: user.enable_balance_notify ?? false,
enable_login_notify: user.enable_login_notify ?? false,
enable_subscribe_notify: user.enable_subscribe_notify ?? false,
enable_trade_notify: user.enable_trade_notify ?? false,
});
}
}, [user, form]);
async function onSubmit(data: z.infer<typeof FormSchema>) {
await updateUserNotify(data);
@@ -0,0 +1,60 @@
import { Display } from '@/components/display';
import { Empty } from '@/components/empty';
import { ProList, ProListActions } from '@/components/pro-list';
import { queryUserBalanceLog } from '@/services/user/user';
import { Card, CardContent } from '@workspace/airo-ui/components/card';
import { formatDate } from '@workspace/airo-ui/utils';
import { useTranslations } from 'next-intl';
import { useRef } from 'react';
const Table: React.FC<{}> = () => {
const ref = useRef<ProListActions>(null);
const t = useTranslations('wallet');
return (
<ProList<API.UserBalanceLog, Record<string, unknown>>
action={ref}
request={async (pagination, filter) => {
const response = await queryUserBalanceLog({ ...pagination, ...filter });
return {
list: response.data.data?.list || [],
total: response.data.data?.total || 0,
};
}}
renderItem={(item) => {
return (
<Card className='rounded-[32px] px-[20px] sm:px-[55px]'>
<CardContent className='px-0 py-3 text-[10px] sm:p-3 sm:text-sm'>
<ul className='grid grid-cols-4 gap-3 *:flex *:flex-col'>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{t('createdAt')}</span>
<time>{formatDate(item.created_at)}</time>
</li>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{t('type.0')}</span>
<span>{t(`type.${item.type}`)}</span>
</li>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{t('amount')}</span>
<span>
<Display type='currency' value={item.amount} />
</span>
</li>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{t('balance')}</span>
<span>
<Display type='currency' value={item.balance} />
</span>
</li>
</ul>
</CardContent>
</Card>
);
}}
empty={<Empty />}
/>
);
};
export default Table;
@@ -0,0 +1,106 @@
import { queryUserBalanceLog } from '@/services/user/user';
import { useQuery } from '@tanstack/react-query';
import { AiroButton } from '@workspace/airo-ui/components/AiroButton';
import { Card, CardContent } from '@workspace/airo-ui/components/card';
import {
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@workspace/airo-ui/components/dialog';
import { default as Airo_Empty } from '@workspace/airo-ui/custom-components/empty';
import { formatDate } from '@workspace/airo-ui/utils';
import { Dialog } from '@workspace/ui/components/dialog';
import { useTranslations } from 'next-intl';
import { useState } from 'react';
import { Display } from '@/components/display';
import Table from '../Table/Table';
const WalletDialog: React.FC<{}> = () => {
const [open, setOpen] = useState(false);
const t = useTranslations('affiliate');
const tWallet = useTranslations('wallet');
const { data } = useQuery({
queryKey: ['walletDialogList'],
queryFn: async () => {
const data = await queryUserBalanceLog({
page: 1,
size: 4,
} as API.QueryUserAffiliateListRequest);
console.log('data', data?.data.data);
return data?.data?.data?.list || [];
},
});
return (
<Card className='order-2 rounded-[20px] border border-[#EAEAEA] bg-gradient-to-b from-white to-[#EAEAEA] p-6 md:order-none'>
<div className='mb-4 flex items-center justify-between'>
<h3 className='font-medium text-[#666666] sm:text-xl'>{tWallet('title')}</h3>
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<AiroButton variant={'dangerLink'} className={'min-w-0 px-1 text-sm text-[#225BA9]'}>
{t('more')}
</AiroButton>
</DialogTrigger>
<DialogContent className='sm:w-[675px]'>
<DialogHeader>
<DialogTitle className='text-left text-2xl sm:text-4xl'>
{tWallet('title')}
</DialogTitle>
</DialogHeader>
<Table />
</DialogContent>
</Dialog>
</div>
<div className='space-y-2 sm:space-y-4'>
{data?.length ? (
<div className='relative space-y-3'>
<div
className={
'absolute bottom-0 left-0 right-0 h-[60px] bg-white/30 backdrop-blur-[1px]'
}
></div>
{data?.map((item) => {
return (
<Card className='rounded-[15px] px-[20px] sm:rounded-[32px] sm:px-[55px]'>
<CardContent className='px-0 py-3 text-[10px] sm:p-3 sm:text-sm'>
<ul className='grid grid-cols-4 gap-3 *:flex *:flex-col'>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{tWallet('createdAt')}</span>
<time>{formatDate(item.created_at)}</time>
</li>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{tWallet('type.0')}</span>
<span>{tWallet(`type.${item.type}`)}</span>
</li>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{tWallet('amount')}</span>
<span>
<Display type='currency' value={item.amount} />
</span>
</li>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{tWallet('balance')}</span>
<span>
<Display type='currency' value={item.balance} />
</span>
</li>
</ul>
</CardContent>
</Card>
);
})}
</div>
) : (
<Airo_Empty className={'py-0'} description={t('noInvitationRecords')} />
)}
</div>
</Card>
);
};
export default WalletDialog;
@@ -1,27 +1,23 @@
'use client';
import { Display } from '@/components/display';
import { ProList, ProListActions } from '@/components/pro-list';
import useGlobalStore from '@/config/use-global';
import { queryUserBalanceLog } from '@/services/user/user';
import { Card, CardContent } from '@workspace/airo-ui/components/card';
import { useTranslations } from 'next-intl';
import { useRef } from 'react';
import { Empty } from '@/components/empty';
import Recharge from '@/components/subscribe/recharge';
import SvgIcon from '@/components/SvgIcon';
import { Button } from '@workspace/airo-ui/components/button';
import { formatDate } from '@workspace/airo-ui/utils';
import Link from 'next/link';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import { toast } from 'sonner';
import Table from './components/Table/Table';
import WalletDialog from './components/WalletDialog/WalletDialog';
export default function Page() {
const t = useTranslations('wallet');
const dashboardT = useTranslations('dashboard');
const { user } = useGlobalStore();
const ref = useRef<ProListActions>(null);
const totalAssets = (user?.balance || 0) + (user?.commission || 0) + (user?.gift_amount || 0);
return (
<>
@@ -92,48 +88,12 @@ export default function Page() {
</div>
</CardContent>
</Card>
<ProList<API.UserBalanceLog, Record<string, unknown>>
action={ref}
request={async (pagination, filter) => {
const response = await queryUserBalanceLog({ ...pagination, ...filter });
return {
list: response.data.data?.list || [],
total: response.data.data?.total || 0,
};
}}
renderItem={(item) => {
return (
<Card className='rounded-[32px] px-[20px] sm:px-[55px]'>
<CardContent className='px-0 py-3 text-[10px] sm:p-3 sm:text-sm'>
<ul className='grid grid-cols-4 gap-3 *:flex *:flex-col'>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{t('createdAt')}</span>
<time>{formatDate(item.created_at)}</time>
</li>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{t('type.0')}</span>
<span>{t(`type.${item.type}`)}</span>
</li>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{t('amount')}</span>
<span>
<Display type='currency' value={item.amount} />
</span>
</li>
<li className='font-semibold'>
<span className='text-[#225BA9]'>{t('balance')}</span>
<span>
<Display type='currency' value={item.balance} />
</span>
</li>
</ul>
</CardContent>
</Card>
);
}}
empty={<Empty />}
/>
<div className={'hidden sm:block'}>
<Table />
</div>
<div className={'mt-2.5 sm:hidden'}>
<WalletDialog />
</div>
</>
);
}