feat: 完成代码编写
@ -18,9 +18,8 @@ export function Header() {
|
||||
const pathname = usePathname();
|
||||
const items = useMemo(() => findNavByUrl(pathname), [pathname]);
|
||||
return (
|
||||
<header className='flex h-[84px] w-full items-center justify-between gap-2 sm:hidden'>
|
||||
<header className='flex h-[84px] w-full items-center justify-between gap-2 md:hidden'>
|
||||
<SidebarTrigger />
|
||||
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList className={'text-[36px] font-semibold'}>
|
||||
{items.map((item, index) => {
|
||||
|
||||
@ -39,11 +39,11 @@ export const Popup = ({ ref }: PopupProps) => {
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogContent className='max-h-[350px] min-h-[220px] max-w-[80%] rounded-[25px] sm:max-w-[425px]'>
|
||||
<DialogContent className='flex max-h-[350px] min-h-[420px] max-w-[80%] flex-col justify-center rounded-[25px] sm:max-w-[425px]'>
|
||||
<DialogHeader>
|
||||
<DialogTitle className={'sr-only'}>{data.title}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className={'pt-[30%]'}>
|
||||
<div className={'font-light'}>
|
||||
<div className={'mb-4 text-xl'}>{data.title}</div>
|
||||
<Markdown>{data.content}</Markdown>
|
||||
</div>
|
||||
|
||||
@ -30,6 +30,7 @@ import {
|
||||
PopupRef,
|
||||
} from '@/app/(main)/(content)/(user)/dashboard/components/Announcement/Popup';
|
||||
import { Empty } from '@/components/empty';
|
||||
import SvgIcon from '@/components/SvgIcon';
|
||||
import { queryAnnouncement } from '@/services/user/announcement';
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@workspace/airo-ui/components/popover';
|
||||
import {
|
||||
@ -46,6 +47,7 @@ import {
|
||||
import { Tabs, TabsList, TabsTrigger } from '@workspace/ui/components/tabs';
|
||||
import { differenceInDays, formatDate } from '@workspace/ui/utils';
|
||||
import { QRCodeCanvas } from 'qrcode.react';
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
|
||||
const platforms: (keyof API.ApplicationPlatform)[] = [
|
||||
'windows',
|
||||
@ -351,12 +353,12 @@ export default function Content() {
|
||||
onValueChange={setProtocol}
|
||||
className='w-full max-w-full md:w-auto'
|
||||
>
|
||||
<TabsList className='flex h-full flex-wrap gap-2 bg-transparent p-0 *:flex-auto'>
|
||||
<TabsList className='flex h-full flex-wrap gap-2 bg-transparent p-0'>
|
||||
{['all', ...(data?.protocol || [])].map((item) => (
|
||||
<TabsTrigger
|
||||
value={item === 'all' ? '' : item}
|
||||
key={item}
|
||||
className='un rounded-full bg-[#EAEAEA] px-6 py-1 text-[10px] uppercase text-[#66666673] shadow-[inset_0px_0px_4px_0px_rgba(0,0,0,0.25)] data-[state=active]:bg-[#225BA9] data-[state=active]:text-white'
|
||||
className='rounded-full bg-[#EAEAEA] px-6 py-1 text-[10px] uppercase text-[#66666673] shadow-[inset_0px_0px_4px_0px_rgba(0,0,0,0.25)] data-[state=active]:bg-[#225BA9] data-[state=active]:text-white'
|
||||
>
|
||||
{item}
|
||||
</TabsTrigger>
|
||||
@ -399,20 +401,32 @@ export default function Content() {
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
<div className='flex-1 rounded-full bg-white px-3 py-1 text-[10px] leading-tight text-[#225BA9] shadow-[inset_0px_0px_7.6px_0px_rgba(0,0,0,0.25)] sm:rounded-[16px] sm:p-3 sm:text-xs'>
|
||||
<div className={'line-clamp-2 break-all text-[10px] sm:text-base'}>
|
||||
{userSubscribeProtocolCurrent}
|
||||
<div className='flex-1 rounded-full bg-white px-3 py-1 text-[10px] leading-tight text-[#225BA9] shadow-[inset_0px_0px_7.6px_0px_rgba(0,0,0,0.25)] sm:rounded-[16px] sm:text-xs'>
|
||||
<div className={'flex items-center gap-4 py-1 text-[10px] sm:text-[16px]'}>
|
||||
<div className={'line-clamp-2 flex-1 break-all'}>
|
||||
{userSubscribeProtocolCurrent}
|
||||
</div>
|
||||
<CopyToClipboard
|
||||
text={userSubscribeProtocolCurrent}
|
||||
onCopy={(text, result) => {
|
||||
if (result) {
|
||||
toast.success(t('copySuccess'));
|
||||
}
|
||||
}}
|
||||
>
|
||||
<span className={'cursor-pointer p-1'}>
|
||||
<SvgIcon name={'copy'}></SvgIcon>
|
||||
</span>
|
||||
</CopyToClipboard>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Popover>
|
||||
<PopoverTrigger asChild>
|
||||
<div
|
||||
className={
|
||||
'ml-3 h-[40px] w-[40px] flex-shrink-0 cursor-pointer rounded-lg bg-black'
|
||||
}
|
||||
></div>
|
||||
<div className={'size-10'}>
|
||||
<SvgIcon name={'qrcode'} width={'100%'} height={'100%'}></SvgIcon>
|
||||
</div>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className='w-auto rounded-xl p-4' align='end'>
|
||||
<div className='flex flex-col items-center gap-2'>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
'use client';
|
||||
import SvgIcon from '@/components/SvgIcon';
|
||||
import { UserNav } from '@/components/user-nav';
|
||||
import { navs } from '@/config/navs';
|
||||
import {
|
||||
@ -10,9 +11,8 @@ import {
|
||||
SidebarMenuItem,
|
||||
useSidebar,
|
||||
} from '@workspace/airo-ui/components/sidebar';
|
||||
import { Icon } from '@workspace/ui/custom-components/icon';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import Image from 'next/legacy/image';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
|
||||
@ -21,18 +21,21 @@ export function SidebarLeft({ ...props }: React.ComponentProps<typeof Sidebar>)
|
||||
const pathname = usePathname();
|
||||
const { toggleSidebar } = useSidebar();
|
||||
return (
|
||||
<Sidebar side='left' {...props} className={'border-0 bg-transparent sm:bg-white'}>
|
||||
<Sidebar side='left' {...props} className={'border-0 bg-transparent md:bg-white'}>
|
||||
<div
|
||||
className={
|
||||
'relative ml-2.5 flex h-[calc(100dvh-10px-env(safe-area-inset-top))] flex-col rounded-[30px] bg-[#D9D9D9] px-4 sm:ml-0 sm:h-full sm:rounded-none sm:bg-white'
|
||||
'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'
|
||||
}
|
||||
>
|
||||
<div className={'absolute -right-3 top-6'} onClick={toggleSidebar}>
|
||||
<Image src={'shrink.png'} height={30} width={30} alt='close' unoptimized></Image>
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
'absolute -left-2.5 top-2.5 -z-10 h-full w-full rounded-[30px] bg-[#225BA9] sm:hidden'
|
||||
'absolute -left-2.5 top-2.5 -z-10 h-full w-full rounded-[30px] bg-[#225BA9] md:hidden'
|
||||
}
|
||||
></div>
|
||||
<div className='pb-7 pl-4 pt-5 sm:pt-12'>
|
||||
<div className='pb-7 pl-4 pt-5 md:pt-12'>
|
||||
<Link href={'/dashboard'}>
|
||||
<Image
|
||||
className={'cursor-pointer'}
|
||||
@ -45,25 +48,27 @@ export function SidebarLeft({ ...props }: React.ComponentProps<typeof Sidebar>)
|
||||
</Link>
|
||||
</div>
|
||||
<SidebarContent className={''}>
|
||||
<SidebarMenu className={'gap-1 sm:gap-2.5'}>
|
||||
<SidebarMenu className={'gap-1 md:gap-2.5'}>
|
||||
{navs
|
||||
.filter((v) => !v.hidden)
|
||||
.map((nav, navIndex) => (
|
||||
<SidebarMenu
|
||||
key={navIndex}
|
||||
className={navIndex === 0 ? 'mb-4 sm:mb-[42px]' : 'mb-0'}
|
||||
className={navIndex === 0 ? 'mb-4 md:mb-[42px]' : 'mb-0'}
|
||||
>
|
||||
<SidebarMenuItem key={nav.title} className={''}>
|
||||
<SidebarMenuButton
|
||||
className={
|
||||
'h-[40px] rounded-full bg-[#EAEAEA] px-5 font-medium hover:bg-[#EAEAEA] hover:text-[#0F2C53] focus-visible:!outline-none focus-visible:!ring-0 active:bg-[#EAEAEA] active:text-[#0F2C53] data-[active=true]:bg-[#0F2C53] sm:h-[60px] sm:bg-white sm:text-xl sm:font-normal'
|
||||
'h-[40px] rounded-full bg-[#EAEAEA] px-5 font-medium hover:bg-[#EAEAEA] hover:text-[#0F2C53] focus-visible:!outline-none focus-visible:!ring-0 active:bg-[#EAEAEA] active:text-[#0F2C53] data-[active=true]:bg-[#0F2C53] md:h-[60px] md:bg-white md:text-xl md:font-normal'
|
||||
}
|
||||
asChild
|
||||
tooltip={t(nav.title)}
|
||||
isActive={nav.url === pathname}
|
||||
>
|
||||
<Link href={nav.url} onClick={toggleSidebar} className={'gap-4 sm:gap-0.5'}>
|
||||
{nav.icon && <Icon className={'!size-4 sm:!size-6'} icon={nav.icon} />}
|
||||
<Link href={nav.url} onClick={toggleSidebar} className={'gap-4'}>
|
||||
<div className={'relative size-4 md:!size-6'}>
|
||||
<SvgIcon name={nav.image} />
|
||||
</div>
|
||||
<span>{t(nav.title)}</span>
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
@ -73,7 +78,7 @@ export function SidebarLeft({ ...props }: React.ComponentProps<typeof Sidebar>)
|
||||
</SidebarMenu>
|
||||
</SidebarContent>
|
||||
|
||||
<SidebarFooter className={'mt-4'}>
|
||||
<SidebarFooter className={'mt-4 px-0'}>
|
||||
<UserNav from='profile' />
|
||||
</SidebarFooter>
|
||||
</div>
|
||||
|
||||
@ -10,15 +10,16 @@ import { useRef } from 'react';
|
||||
|
||||
import { Empty } from '@/components/empty';
|
||||
import Recharge from '@/components/subscribe/recharge';
|
||||
import SvgIcon from '@/components/SvgIcon';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import { formatDate } from '@workspace/ui/utils';
|
||||
import { Copy } from 'lucide-react';
|
||||
import Link from 'next/link';
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
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);
|
||||
@ -44,7 +45,7 @@ export default function Page() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='grid grid-cols-2 gap-2 sm:grid-cols-4 sm:gap-6'>
|
||||
<div className='grid grid-cols-2 gap-2 sm:grid-cols-2 sm:gap-6 md:grid-cols-4'>
|
||||
<div className='col-span-2 rounded-[20px] bg-[#EAEAEA] p-4 shadow-sm transition-all duration-300 hover:shadow-md sm:col-span-1'>
|
||||
<p className='text-sm font-medium text-[#666] opacity-80 sm:mb-3'>账户余额</p>
|
||||
<p className='text-xl font-bold text-[#225BA9] sm:text-2xl'>
|
||||
@ -80,12 +81,12 @@ export default function Page() {
|
||||
text={`${location?.origin}/?invite=${user?.refer_code}`}
|
||||
onCopy={(text, result) => {
|
||||
if (result) {
|
||||
toast.success(t('copySuccess'));
|
||||
toast.success(dashboardT('copySuccess'));
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Button variant='secondary' size='sm' className='gap-2'>
|
||||
<Copy className='h-4 w-4' />
|
||||
<Button variant='link' size='sm' className='h-auto p-0 px-0 [&_svg]:size-5'>
|
||||
<SvgIcon name={'copy'}></SvgIcon>
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
</p>
|
||||
|
||||
33
apps/user/components/SvgIcon.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
const SvgIcon = ({ name, ...props }) => {
|
||||
const [Icon, setIcon] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
|
||||
import(`public/svg-icon/${name}.svg`)
|
||||
.then((module) => {
|
||||
if (isMounted) {
|
||||
setIcon(() => module.default);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (isMounted) {
|
||||
setIcon(null);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, [name]);
|
||||
|
||||
if (!Icon) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <Icon {...props} />;
|
||||
};
|
||||
|
||||
export default SvgIcon;
|
||||
@ -6,13 +6,13 @@ import {
|
||||
} from '@/components/affiliate/components/AffiliateDialog';
|
||||
import { Display } from '@/components/display';
|
||||
import { Empty } from '@/components/empty';
|
||||
import SvgIcon from '@/components/SvgIcon';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { queryUserAffiliate, queryUserAffiliateList } from '@/services/user/user';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
import { Card, CardContent } from '@workspace/ui/components/card';
|
||||
import { formatDate } from '@workspace/ui/utils';
|
||||
import { Copy } from 'lucide-react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useRef, useState } from 'react';
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
@ -58,7 +58,7 @@ export default function Affiliate() {
|
||||
<div className={'mb-3 text-xl font-bold text-[#091B33] sm:text-[32px]'}>
|
||||
历史推荐用户:7
|
||||
</div>
|
||||
<div className={'grid grid-cols-2 gap-[10px] sm:gap-5'}>
|
||||
<div className={'grid grid-cols-2 gap-[10px] sm:grid-cols-1 sm:gap-5 lg:grid-cols-2'}>
|
||||
<div className='rounded-[20px] bg-[#EAEAEA] px-4 py-2 shadow-sm transition-all duration-300 hover:shadow-md sm:py-4'>
|
||||
<p className='font-medium text-[#666] opacity-80 sm:mb-3 sm:text-sm'>佣金总额</p>
|
||||
<p className='text-xl font-bold text-[#225BA9] sm:text-2xl'>
|
||||
@ -67,21 +67,23 @@ export default function Affiliate() {
|
||||
</div>
|
||||
<div className='rounded-[20px] border-2 border-[#D9D9D9] px-4 py-2 shadow-sm transition-all duration-300 hover:shadow-md sm:py-4'>
|
||||
<p className='flex justify-between font-medium text-[#666] opacity-80 sm:mb-3 sm:text-sm'>
|
||||
<span className={'flex'}>
|
||||
返佣邀请码
|
||||
<CopyToClipboard
|
||||
text={`${location?.origin}/?invite=${user?.refer_code}`}
|
||||
onCopy={(text, result) => {
|
||||
if (result) {
|
||||
toast.success(t('copySuccess'));
|
||||
}
|
||||
}}
|
||||
返佣邀请码
|
||||
<CopyToClipboard
|
||||
text={`${location?.origin}/?invite=${user?.refer_code}`}
|
||||
onCopy={(text, result) => {
|
||||
if (result) {
|
||||
toast.success(t('copySuccess'));
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
variant='link'
|
||||
size='sm'
|
||||
className='h-auto p-0 px-0 sm:hidden [&_svg]:size-5'
|
||||
>
|
||||
<Button variant='secondary' size='sm' className='px-0 sm:hidden'>
|
||||
<Copy className='h-4 w-4' />
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
</span>
|
||||
<SvgIcon name={'copy'}></SvgIcon>
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
</p>
|
||||
<p className='flex justify-between text-xl font-bold text-[#225BA9] sm:text-2xl'>
|
||||
<span> {user?.refer_code}</span>
|
||||
@ -93,8 +95,12 @@ export default function Affiliate() {
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Button variant='secondary' size='sm' className='hidden gap-2 sm:block'>
|
||||
<Copy className='h-4 w-4' />
|
||||
<Button
|
||||
variant='link'
|
||||
size='sm'
|
||||
className='hidden gap-2 p-0 sm:block [&_svg]:size-5'
|
||||
>
|
||||
<SvgIcon name={'copy'}></SvgIcon>
|
||||
</Button>
|
||||
</CopyToClipboard>
|
||||
</p>
|
||||
@ -105,7 +111,10 @@ export default function Affiliate() {
|
||||
<Card className='rounded-[20px] border border-[#EAEAEA] bg-gradient-to-b from-white to-[#EAEAEA] p-6'>
|
||||
<div className='mb-4 flex items-center justify-between'>
|
||||
<h3 className='font-medium text-[#666666] sm:text-xl'>邀请记录</h3>
|
||||
<span className='text-sm text-[#225BA9]' onClick={() => dialogRef.current.open()}>
|
||||
<span
|
||||
className='cursor-pointer text-sm text-[#225BA9]'
|
||||
onClick={() => dialogRef.current.open()}
|
||||
>
|
||||
更多
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
'use client';
|
||||
|
||||
import SvgIcon from '@/components/SvgIcon.tsx';
|
||||
import useGlobalStore from '@/config/use-global';
|
||||
import { Logout } from '@/utils/common';
|
||||
import { useSidebar } from '@workspace/airo-ui/components/sidebar';
|
||||
import { useIsMobile } from '@workspace/airo-ui/hooks/use-mobile';
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@workspace/ui/components/avatar';
|
||||
import {
|
||||
DropdownMenu,
|
||||
@ -20,29 +22,30 @@ export function UserNav({ from = '' }: { from?: string }) {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const { toggleSidebar } = useSidebar();
|
||||
const isMobile = useIsMobile();
|
||||
if (user) {
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
{from === 'profile' ? (
|
||||
<div className='mb-3 flex cursor-pointer items-center gap-2 rounded-full bg-[#EAEAEA] p-1 pr-6'>
|
||||
<Avatar className='h-[34px] w-[34px] sm:h-[52px] sm:w-[52px]'>
|
||||
<Avatar className='h-[34px] w-[34px] md:h-[52px] md:w-[52px]'>
|
||||
<AvatarImage
|
||||
alt={user?.avatar ?? ''}
|
||||
src={user?.avatar ?? ''}
|
||||
className='object-cover'
|
||||
/>
|
||||
<AvatarFallback className='to-primary text-background bg-[#0F2C53] bg-gradient-to-br text-[28px] font-bold sm:text-[40px]'>
|
||||
<AvatarFallback className='to-primary text-background bg-[#0F2C53] bg-gradient-to-br text-[28px] font-bold md:text-[40px]'>
|
||||
{user?.auth_methods?.[0]?.auth_identifier.toUpperCase().charAt(0)}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className='flex flex-1 items-center justify-between text-xs sm:text-base'>
|
||||
<div className='flex flex-1 items-center justify-between text-xs md:text-base'>
|
||||
{user?.auth_methods?.[0]?.auth_identifier.split('@')[0]}
|
||||
</div>
|
||||
<Icon icon='lucide:ellipsis' className='text-muted-foreground !size-6' />
|
||||
</div>
|
||||
) : (
|
||||
<Avatar className='h-14 w-14 cursor-pointer sm:h-16 sm:w-16'>
|
||||
<Avatar className='h-14 w-14 cursor-pointer md:h-16 md:w-16'>
|
||||
<AvatarImage
|
||||
alt={user?.avatar ?? ''}
|
||||
src={user?.auth_methods?.[0]?.auth_identifier ?? ''}
|
||||
@ -57,25 +60,28 @@ export function UserNav({ from = '' }: { from?: string }) {
|
||||
<DropdownMenuContent
|
||||
forceMount
|
||||
align='end'
|
||||
side={from === 'profile' ? 'right' : undefined}
|
||||
className='flex w-64 flex-col gap-1 rounded-[42px] p-3 sm:gap-3'
|
||||
side={from === 'profile' ? (isMobile ? 'top' : 'right') : undefined}
|
||||
className='flex w-[var(--sidebar-width)] flex-col gap-1 rounded-[42px] border-0 bg-transparent pl-[26px] pr-4 shadow-none md:w-64 md:gap-3 md:border md:bg-white md:p-3 md:shadow-md'
|
||||
style={{
|
||||
'--sidebar-width': '14rem',
|
||||
}}
|
||||
>
|
||||
<div className='flex items-center justify-start gap-2 rounded-full bg-[#EAEAEA] p-1'>
|
||||
<Avatar className='h-[34px] w-[34px] sm:h-[52px] sm:w-[52px]'>
|
||||
<div className='flex items-center justify-start gap-2 rounded-full bg-white p-1 md:bg-[#EAEAEA]'>
|
||||
<Avatar className='h-[34px] w-[34px] md:h-[52px] md:w-[52px]'>
|
||||
<AvatarImage
|
||||
alt={user?.avatar ?? ''}
|
||||
src={user?.avatar ?? ''}
|
||||
className='object-cover'
|
||||
/>
|
||||
<AvatarFallback className='to-primary text-background bg-[#225BA9] bg-gradient-to-br text-[18px] font-bold sm:text-2xl'>
|
||||
<AvatarFallback className='to-primary text-background bg-[#225BA9] bg-gradient-to-br text-[18px] font-bold md:text-2xl'>
|
||||
{user?.auth_methods?.[0]?.auth_identifier.toUpperCase().charAt(0)}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className='flex flex-col space-y-0.5'>
|
||||
<p className='text-xs font-medium leading-none sm:text-xl'>
|
||||
<p className='text-xs font-medium leading-none md:text-xl'>
|
||||
{user?.auth_methods?.[0]?.auth_identifier.split('@')[0]}
|
||||
</p>
|
||||
<p className='text-muted-foreground text-[10px] sm:text-xs'>
|
||||
<p className='text-muted-foreground text-[10px] md:text-xs'>
|
||||
{user?.auth_methods?.[0]?.auth_identifier}
|
||||
</p>
|
||||
</div>
|
||||
@ -84,7 +90,7 @@ export function UserNav({ from = '' }: { from?: string }) {
|
||||
{
|
||||
title: 'profile',
|
||||
url: '/profile',
|
||||
icon: 'uil:dashboard',
|
||||
icon: 'profile',
|
||||
},
|
||||
].map((item) => (
|
||||
<DropdownMenuItem
|
||||
@ -95,9 +101,9 @@ export function UserNav({ from = '' }: { from?: string }) {
|
||||
toggleSidebar();
|
||||
router.push(`${item.url}`);
|
||||
}}
|
||||
className='flex cursor-pointer items-center gap-3 rounded-full px-5 py-2 text-base font-medium focus:bg-[#0F2C53] focus:text-white data-[active=true]:bg-[#0F2C53] data-[active=true]:text-white sm:text-xl'
|
||||
className='flex cursor-pointer items-center gap-3 rounded-full bg-white px-5 py-2 text-base font-medium focus:bg-[#0F2C53] focus:text-white data-[active=true]:bg-[#0F2C53] data-[active=true]:text-white md:text-xl'
|
||||
>
|
||||
<Icon className='!size-4 flex-none sm:!size-6' icon={item.icon!} />
|
||||
<SvgIcon className='!size-4 flex-none md:!size-6' name={item.icon} />
|
||||
<span className='flex-grow truncate'>{t(item.title)}</span>
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
@ -106,9 +112,14 @@ export function UserNav({ from = '' }: { from?: string }) {
|
||||
Logout();
|
||||
setUser();
|
||||
}}
|
||||
className='flex cursor-pointer items-center gap-3 rounded-full px-5 py-2 text-base font-medium text-[#0F2C53] focus:bg-[#E22C2E] focus:text-white sm:text-xl'
|
||||
className='flex cursor-pointer items-center gap-3 rounded-full bg-[#E22C2E] px-5 py-2 text-base font-medium text-white focus:bg-[#E22C2E] focus:text-white md:bg-white md:text-xl md:text-[#0F2C53]'
|
||||
>
|
||||
<Icon className='!size-4 flex-none sm:!size-6' icon='uil:exit' />
|
||||
<SvgIcon
|
||||
className='!size-4 flex-none md:!size-6'
|
||||
width='99'
|
||||
height='100'
|
||||
name={'exit'}
|
||||
/>
|
||||
<span className='flex-grow'>{t('logout')}</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
|
||||
@ -3,42 +3,50 @@ export const navs = [
|
||||
title: 'dashboard',
|
||||
url: '/dashboard',
|
||||
icon: 'uil:dashboard',
|
||||
image: 'dashboard',
|
||||
},
|
||||
{
|
||||
url: '/subscribe',
|
||||
icon: 'uil:shop',
|
||||
title: 'subscribe',
|
||||
image: 'shop',
|
||||
},
|
||||
{
|
||||
url: '/order',
|
||||
icon: 'uil:notes',
|
||||
title: 'order',
|
||||
image: 'notes',
|
||||
},
|
||||
{
|
||||
url: '/wallet',
|
||||
icon: 'uil:wallet',
|
||||
title: 'wallet',
|
||||
image: 'wallet',
|
||||
},
|
||||
{
|
||||
url: '/affiliate',
|
||||
icon: 'uil:users-alt',
|
||||
title: 'affiliate',
|
||||
image: 'affiliate',
|
||||
},
|
||||
{
|
||||
url: '/document',
|
||||
icon: 'uil:book-alt',
|
||||
title: 'document',
|
||||
image: 'document',
|
||||
},
|
||||
{
|
||||
url: '/profile',
|
||||
icon: 'uil:megaphone',
|
||||
title: 'profile',
|
||||
hidden: true,
|
||||
image: 'profile',
|
||||
},
|
||||
{
|
||||
url: '/ticket',
|
||||
icon: 'uil:message',
|
||||
title: 'ticket',
|
||||
image: 'ticket',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import createNextIntlPlugin from 'next-intl/plugin';
|
||||
const withNextIntl = createNextIntlPlugin('./locales/request.ts');
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
transpilePackages: ['@workspace/ui'],
|
||||
transpilePackages: ['@workspace/ui', '@workspace/airo-ui'],
|
||||
output: 'standalone',
|
||||
images: {
|
||||
remotePatterns: [
|
||||
@ -18,6 +18,14 @@ const nextConfig: NextConfig = {
|
||||
},
|
||||
],
|
||||
},
|
||||
turbopack: {
|
||||
rules: {
|
||||
'./public/svg-icon/*.svg': {
|
||||
loaders: ['@svgr/webpack'],
|
||||
as: '*.js',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default withNextIntl(nextConfig);
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
"zustand": "^5.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@svgr/webpack": "^8.1.0",
|
||||
"@types/node": "^22.10.5",
|
||||
"@types/react": "^19.0.4",
|
||||
"@types/react-copy-to-clipboard": "^5.0.7",
|
||||
|
||||
BIN
apps/user/public/list.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
apps/user/public/shrink.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
3
apps/user/public/svg-icon/affiliate.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 25 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.07812 20.0312C6.58594 20.0312 7.8125 21.2578 7.8125 22.7656V24.3281C7.8125 24.9766 7.28906 25.5 6.64062 25.5H1.17188C0.523438 25.5 0 24.9766 0 24.3281V22.7656C0 21.2578 1.22656 20.0312 2.73438 20.0312H5.07812ZM22.2656 20.0312C23.7734 20.0312 25 21.2578 25 22.7656V24.3281C25 24.9766 24.4766 25.5 23.8281 25.5H18.3594C17.7109 25.5 17.1875 24.9766 17.1875 24.3281V22.7656C17.1875 21.2578 18.4141 20.0312 19.9219 20.0312H22.2656ZM12.5 14.5625C13.1484 14.5625 13.6719 15.0859 13.6719 15.7344V19.1562L15.6719 21.1562C16.1328 21.6172 16.1328 22.3516 15.6719 22.8125C15.2109 23.2734 14.4766 23.2734 14.0156 22.8125L12.5 21.2969L10.9844 22.8125C10.5234 23.2734 9.78906 23.2734 9.32812 22.8125C8.86719 22.3516 8.86719 21.6172 9.32812 21.1562L11.3281 19.1562V15.7344C11.3281 15.0859 11.8516 14.5625 12.5 14.5625ZM2.73438 22.375C2.51562 22.375 2.34375 22.5547 2.34375 22.7656V23.1562H5.46875V22.7656C5.46875 22.5547 5.29688 22.375 5.07812 22.375H2.73438ZM19.9219 22.375C19.7031 22.375 19.5312 22.5547 19.5312 22.7656V23.1562H22.6562V22.7656C22.6562 22.5547 22.4844 22.375 22.2656 22.375H19.9219ZM3.90625 12.6094C5.63281 12.6094 7.03125 14.0078 7.03125 15.7344C7.03125 17.4609 5.63281 18.8594 3.90625 18.8594C2.17969 18.8594 0.78125 17.4609 0.78125 15.7344C0.78125 14.0078 2.17969 12.6094 3.90625 12.6094ZM21.0938 12.6094C22.8203 12.6094 24.2188 14.0078 24.2188 15.7344C24.2188 17.4609 22.8203 18.8594 21.0938 18.8594C19.3672 18.8594 17.9688 17.4609 17.9688 15.7344C17.9688 14.0078 19.3672 12.6094 21.0938 12.6094ZM3.90625 14.9531C3.47656 14.9531 3.125 15.3047 3.125 15.7344C3.125 16.1641 3.47656 16.5156 3.90625 16.5156C4.33594 16.5156 4.6875 16.1641 4.6875 15.7344C4.6875 15.3047 4.33594 14.9531 3.90625 14.9531ZM21.0938 14.9531C20.6641 14.9531 20.3125 15.3047 20.3125 15.7344C20.3125 16.1641 20.6641 16.5156 21.0938 16.5156C21.5234 16.5156 21.875 16.1641 21.875 15.7344C21.875 15.3047 21.5234 14.9531 21.0938 14.9531ZM14.8438 7.53125C16.3516 7.53125 17.5781 8.75781 17.5781 10.2656V12.2188C17.5781 12.8672 17.0547 13.3906 16.4062 13.3906H8.59375C7.94531 13.3906 7.42188 12.8672 7.42188 12.2188V10.2656C7.42188 8.75781 8.64844 7.53125 10.1562 7.53125H14.8438ZM10.1562 9.875C9.9375 9.875 9.76562 10.0547 9.76562 10.2656V11.0469H15.2344V10.2656C15.2344 10.0547 15.0625 9.875 14.8438 9.875H10.1562ZM12.5 0.5C14.2266 0.5 15.625 1.89844 15.625 3.625C15.625 5.35156 14.2266 6.75 12.5 6.75C10.7734 6.75 9.375 5.35156 9.375 3.625C9.375 1.89844 10.7734 0.5 12.5 0.5ZM12.5 2.84375C12.0703 2.84375 11.7188 3.19531 11.7188 3.625C11.7188 4.05469 12.0703 4.40625 12.5 4.40625C12.9297 4.40625 13.2812 4.05469 13.2812 3.625C13.2812 3.19531 12.9297 2.84375 12.5 2.84375Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
10
apps/user/public/svg-icon/copy.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="16" height="18" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1190_2247)">
|
||||
<path d="M16 9V15.6973C16 16.9672 14.9878 18 13.7433 18H5.53748C4.72615 18 3.99754 17.57 3.58597 16.8506C3.41465 16.5512 3.51311 16.1674 3.80652 15.9926C4.09994 15.8178 4.47606 15.9203 4.64738 16.2177C4.83643 16.5472 5.16726 16.7441 5.53551 16.7441H13.7413C14.3065 16.7441 14.7673 16.2739 14.7673 15.6973V9C14.7673 8.62425 14.5743 8.28667 14.2513 8.09377C13.9579 7.91895 13.8594 7.53315 14.0308 7.23577C14.2021 6.93637 14.5802 6.8359 14.8716 7.01072C15.5766 7.43068 15.998 8.17415 15.998 9.00201L16 9ZM10.4606 14.6504H2.25674C1.01218 14.6504 0 13.6175 0 12.3476V2.30275C0 1.03282 1.01218 0 2.25674 0H8.82018C8.98363 0 9.1392 0.0663095 9.25538 0.182853L12.5381 3.53248C12.6543 3.65104 12.7173 3.80978 12.7173 3.97656V12.3496C12.7173 13.6196 11.7051 14.6524 10.4606 14.6524V14.6504ZM9.43655 3.13865C9.43655 3.25318 9.52911 3.34762 9.64135 3.34762H10.6181L9.43655 2.142V3.13865ZM2.25674 13.3945H10.4625C11.0277 13.3945 11.4885 12.9243 11.4885 12.3476V4.60348H9.64135C8.84972 4.60348 8.20578 3.94642 8.20578 3.13865V1.25586H2.25674C1.69157 1.25586 1.23077 1.72605 1.23077 2.30275V12.3496C1.23077 12.9263 1.69157 13.3965 2.25674 13.3965V13.3945ZM9.64135 10.0469H3.07594C2.73526 10.0469 2.46154 10.3282 2.46154 10.6738C2.46154 11.0194 2.73723 11.3007 3.07594 11.3007H9.63939C9.98006 11.3007 10.2538 11.0194 10.2538 10.6738C10.2538 10.3282 9.97809 10.0469 9.63939 10.0469H9.64135ZM9.64135 6.69725H3.07594C2.73526 6.69725 2.46154 6.97857 2.46154 7.32619C2.46154 7.67381 2.73723 7.95311 3.07594 7.95311H9.63939C9.98006 7.95311 10.2538 7.6718 10.2538 7.32619C10.2538 6.98058 9.97809 6.69926 9.63939 6.69926L9.64135 6.69725ZM3.07791 4.60348H6.36062C6.70129 4.60348 6.97502 4.32217 6.97502 3.97656C6.97502 3.63094 6.69932 3.34963 6.36062 3.34963H3.07791C2.73723 3.34963 2.46351 3.63094 2.46351 3.97656C2.46351 4.32217 2.7392 4.60348 3.07791 4.60348Z" fill="#225BA9"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1190_2247">
|
||||
<rect width="16" height="18" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
3
apps/user/public/svg-icon/dashboard.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 25 20" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21.4844 0.625C23.4219 0.625 25 2.20312 25 4.14062V15.8594C25 17.7969 23.4219 19.375 21.4844 19.375H3.51562C1.57812 19.375 0 17.7969 0 15.8594V4.14062C0 2.20312 1.57812 0.625 3.51562 0.625H21.4844ZM3.51562 2.96875C2.86719 2.96875 2.34375 3.49219 2.34375 4.14062V15.8594C2.34375 16.5078 2.86719 17.0312 3.51562 17.0312H21.4844C22.1328 17.0312 22.6562 16.5078 22.6562 15.8594V4.14062C22.6562 3.49219 22.1328 2.96875 21.4844 2.96875H3.51562ZM8.59375 10.3906C11.0078 10.3906 13.0859 12.0469 13.6406 14.4219C13.7891 15.0469 13.3984 15.6797 12.7656 15.8281C12.1328 15.9766 11.5078 15.5781 11.3594 14.9531C11.0547 13.6484 9.91406 12.7344 8.59375 12.7344C7.27344 12.7344 6.13281 13.6484 5.82812 14.9531C5.67969 15.5859 5.05469 15.9766 4.42188 15.8281C3.78906 15.6797 3.39844 15.0469 3.54688 14.4219C4.10156 12.0469 6.17969 10.3906 8.59375 10.3906ZM18.75 10.7812C19.3984 10.7812 19.9219 11.3047 19.9219 11.9531C19.9219 12.6016 19.3984 13.125 18.75 13.125H15.625C14.9766 13.125 14.4531 12.6016 14.4531 11.9531C14.4531 11.3047 14.9766 10.7812 15.625 10.7812H18.75ZM8.59375 4.14062C10.1016 4.14062 11.3281 5.36719 11.3281 6.875C11.3281 8.38281 10.1016 9.60938 8.59375 9.60938C7.08594 9.60938 5.85938 8.38281 5.85938 6.875C5.85938 5.36719 7.08594 4.14062 8.59375 4.14062ZM20.3125 6.875C20.9609 6.875 21.4844 7.39844 21.4844 8.04688C21.4844 8.69531 20.9609 9.21875 20.3125 9.21875H15.625C14.9766 9.21875 14.4531 8.69531 14.4531 8.04688C14.4531 7.39844 14.9766 6.875 15.625 6.875H20.3125ZM8.59375 6.48438C8.38281 6.48438 8.20312 6.65625 8.20312 6.875C8.20312 7.09375 8.38281 7.26562 8.59375 7.26562C8.80469 7.26562 8.98438 7.09375 8.98438 6.875C8.98438 6.65625 8.80469 6.48438 8.59375 6.48438Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
10
apps/user/public/svg-icon/document.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg viewBox="0 0 23 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1289_877)">
|
||||
<path d="M21.8105 0.5C22.4687 0.500107 23 1.0235 23 1.67188V18.8594C23 19.5077 22.4687 20.0311 21.8105 20.0312H3.96582C3.09341 20.0312 2.37891 20.7344 2.37891 21.5938C2.37891 22.4531 3.09341 23.1562 3.96582 23.1562H21.8105C22.4687 23.1564 23 23.6798 23 24.3281C23 24.9765 22.4687 25.4999 21.8105 25.5H3.96582C1.77685 25.5 0 23.75 0 21.5938V4.40625C0 2.25 1.77685 0.5 3.96582 0.5H21.8105ZM3.96582 2.84375C3.09341 2.84375 2.37891 3.54688 2.37891 4.40625V18.0156C2.8627 17.8047 3.40272 17.6875 3.96582 17.6875H20.6211V2.84375H3.96582ZM10.6592 14.5156C11.1033 14.0781 11.9046 14.0781 12.3408 14.5156C12.8008 14.9766 12.8087 15.7109 12.3408 16.1719C11.8729 16.6328 11.1192 16.625 10.6592 16.1719C10.1914 15.711 10.1914 14.9687 10.6592 14.5156ZM9.20801 4.83594C10.017 4.16409 11.0878 3.89063 12.1426 4.07031C13.586 4.32037 14.7677 5.48443 15.0215 6.90625C15.2832 8.39843 14.5609 9.89063 13.2285 10.6172C12.9035 10.7892 12.6973 11.1955 12.6973 11.6406V11.8281C12.6973 12.4766 12.1661 13 11.5078 13C10.8496 12.9999 10.3184 12.4765 10.3184 11.8281V11.6406C10.3184 10.3281 10.9925 9.14844 12.0791 8.5625C12.4201 8.37497 12.7848 7.93743 12.6738 7.3125C12.5945 6.85171 12.1982 6.46111 11.7305 6.38281C11.3656 6.3125 11.0159 6.40625 10.7383 6.63281C10.4608 6.85937 10.3105 7.18758 10.3105 7.53125C10.3105 8.17955 9.77918 8.70291 9.12109 8.70312C8.46282 8.70312 7.93067 8.17969 7.93066 7.53125C7.93066 6.48438 8.39904 5.50781 9.20801 4.83594Z" fill="currentColor"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1289_877">
|
||||
<rect width="23" height="25" fill="white" transform="translate(0 0.5)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
3
apps/user/public/svg-icon/exit.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 25 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.83594 0.5C7.48413 0.500238 8.00684 1.02358 8.00684 1.67188C8.00684 2.32017 7.48413 2.84351 6.83594 2.84375H4.19531C3.17194 2.84375 2.34375 3.67188 2.34375 4.69531V21.3047C2.34375 22.3281 3.17975 23.1562 4.19531 23.1562H6.83594C7.48413 23.1565 8.00684 23.6798 8.00684 24.3281C8.00684 24.9764 7.48413 25.4998 6.83594 25.5H4.19531C1.88296 25.5 3.5586e-07 23.6172 0 21.3047V4.69531C0 2.38281 1.88296 0.5 4.19531 0.5H6.83594ZM14.4521 4.79688C14.4521 3.75781 15.7178 3.23438 16.4521 3.96875L24.6543 12.1719C25.1152 12.6328 25.1152 13.3672 24.6543 13.8281L16.4521 22.0312C15.7178 22.7656 14.4521 22.25 14.4521 21.2031V17.2969H5.07812C4.42973 17.2969 3.90625 16.7734 3.90625 16.125V9.48438C3.90625 9.17188 4.03126 8.875 4.25 8.65625C4.46872 8.43758 4.76571 8.3125 5.07812 8.3125H14.4521V4.79688ZM16.7959 9.48438C16.7959 10.1328 16.2724 10.6562 15.624 10.6562H6.25V14.9531H15.624C16.2724 14.9531 16.7959 15.4766 16.7959 16.125V18.375L22.1709 13L16.7959 7.625V9.48438Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
3
apps/user/public/svg-icon/notes.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 21 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.4023 0.500037C12.4414 0.500056 12.4805 0.50785 12.5195 0.50785C12.8164 0.507875 13.1133 0.61734 13.332 0.835975L19.9824 7.47855C20.2325 7.72863 20.3496 8.07318 20.3184 8.40922V22.7647C20.3184 24.273 19.0913 25.5 17.583 25.5H2.73535C1.22708 25.5 0 24.273 0 22.7647V3.22758C4.19046e-05 1.71934 1.22711 0.492222 2.73535 0.500037H12.4023ZM2.73535 2.83695C2.51656 2.83695 2.34477 3.0088 2.34473 3.22758V22.7647C2.34473 22.9757 2.51654 23.1553 2.73535 23.1553H17.583C17.8018 23.1553 17.9746 22.9757 17.9746 22.7647V9.47953H14.0664C12.5583 9.47933 11.332 8.25233 11.332 6.74418V2.83695H2.73535ZM13.2852 18.0762C13.9338 18.0762 14.457 18.5995 14.457 19.2481C14.457 19.8967 13.9338 20.42 13.2852 20.42H4.68848C4.04005 20.4197 3.5166 19.8966 3.5166 19.2481C3.51663 18.5996 4.04007 18.0765 4.68848 18.0762H13.2852ZM15.6299 14.168C16.2785 14.1681 16.8018 14.6923 16.8018 15.3409C16.8017 15.9894 16.2784 16.5127 15.6299 16.5127H4.68848C4.0401 16.5125 3.51668 15.9893 3.5166 15.3409C3.5166 14.6924 4.04005 14.1682 4.68848 14.168H15.6299ZM13.6758 6.74418C13.6758 6.95506 13.8478 7.1346 14.0664 7.1348H16.3174L13.6758 4.4932V6.74418Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
3
apps/user/public/svg-icon/profile.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 25 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12.5 0.5C5.60938 0.5 0 6.10938 0 13C0 19.8906 5.67188 25.5 12.5 25.5C19.3281 25.5 25 19.8672 25 13C25 6.13281 19.3906 0.5 12.5 0.5ZM5.88281 20.6875C6.14844 17.2656 9.00781 14.5625 12.5 14.5625C15.9922 14.5625 18.8516 17.2656 19.1172 20.6875C17.3359 22.2188 15.0312 23.1562 12.5 23.1562C9.96875 23.1562 7.66406 22.2266 5.88281 20.6875ZM12.5 12.2109C10.9922 12.2109 9.76562 10.9844 9.76562 9.47656C9.76562 7.96875 10.9922 6.74219 12.5 6.74219C14.0078 6.74219 15.2344 7.96875 15.2344 9.47656C15.2344 10.9844 14.0078 12.2109 12.5 12.2109ZM21.0547 18.4609C20.2734 16.0234 18.4688 14.0391 16.1562 13.0078C17.0391 12.0938 17.5859 10.8516 17.5859 9.49219C17.5859 6.69531 15.3125 4.41406 12.5078 4.41406C9.70312 4.41406 7.42969 6.6875 7.42969 9.49219C7.42969 10.8594 7.97656 12.1016 8.85938 13.0078C6.53906 14.0469 4.74219 16.0234 3.95312 18.4609C2.94531 16.8828 2.35156 15.0156 2.35156 13C2.35156 7.39844 6.90625 2.84375 12.5078 2.84375C18.1094 2.84375 22.6641 7.39844 22.6641 13C22.6641 15.0078 22.0703 16.8828 21.0625 18.4609H21.0547Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
12
apps/user/public/svg-icon/qrcode.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="40" height="40" rx="10" fill="#D9D9D9"/>
|
||||
<rect x="1" y="1" width="38" height="38" rx="9" stroke="#848484" stroke-opacity="0.28" stroke-width="2"/>
|
||||
<g clip-path="url(#clip0_795_3268)">
|
||||
<path d="M8.75 8C8.3375 8 8 8.3375 8 8.75V17.75C8 18.1625 8.3375 18.5 8.75 18.5H17.75C18.1625 18.5 18.5 18.1625 18.5 17.75V8.75C18.5 8.3375 18.1625 8 17.75 8H8.75ZM22.25 8C21.8375 8 21.5 8.3375 21.5 8.75V17.75C21.5 18.1625 21.8375 18.5 22.25 18.5H31.25C31.6625 18.5 32 18.1625 32 17.75V8.75C32 8.3375 31.6625 8 31.25 8H22.25ZM9.5 9.5H17V17H9.5V9.5ZM23 9.5H30.5V17H23V9.5ZM11 11V15.5H15.5V11H11ZM24.5 11V15.5H29V11H24.5ZM8.75 21.5C8.3375 21.5 8 21.8375 8 22.25V31.25C8 31.6625 8.3375 32 8.75 32H17.75C18.1625 32 18.5 31.6625 18.5 31.25V22.25C18.5 21.8375 18.1625 21.5 17.75 21.5H8.75ZM22.25 21.5C21.8375 21.5 21.5 21.8375 21.5 22.25V26H23V23H26V21.5H22.25ZM28.25 21.5C27.8375 21.5 27.5 21.8375 27.5 22.25V26H29V23H32V21.5H28.25ZM9.5 23H17V30.5H9.5V23ZM11 24.5V29H15.5V24.5H11ZM24.5 26V27.5H23.75C23.3375 27.5 23 27.8375 23 28.25V32H24.5V29H26V32H27.5V28.25C27.5 27.8375 27.1625 27.5 26.75 27.5H26V26H24.5ZM30.5 26V32H32V26H30.5Z" fill="#848484"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_795_3268">
|
||||
<rect width="24" height="24" fill="white" transform="translate(8 8)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
3
apps/user/public/svg-icon/shop.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 25 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M6.64062 18.4688C8.57823 18.4688 10.1572 20.0469 10.1572 21.9844C10.1572 23.9219 8.57823 25.5 6.64062 25.5C4.70316 25.4998 3.125 23.9218 3.125 21.9844C3.125 20.047 4.70316 18.4689 6.64062 18.4688ZM18.3604 18.4688C20.2979 18.4688 21.876 20.0469 21.876 21.9844C21.876 23.9219 20.2979 25.5 18.3604 25.5C16.4228 25.5 14.8447 23.9219 14.8447 21.9844C14.8447 20.0469 16.4228 18.4688 18.3604 18.4688ZM6.64062 20.8125C5.99229 20.8127 5.46875 21.336 5.46875 21.9844C5.46875 22.6327 5.99229 23.1561 6.64062 23.1562C7.2891 23.1562 7.8125 22.6328 7.8125 21.9844C7.8125 21.3359 7.2891 20.8125 6.64062 20.8125ZM18.3604 20.8125C17.7119 20.8125 17.1885 21.3359 17.1885 21.9844C17.1885 22.6328 17.7119 23.1562 18.3604 23.1562C19.0088 23.1562 19.5322 22.6328 19.5322 21.9844C19.5322 21.336 19.0088 20.8125 18.3604 20.8125ZM5.07812 0.5C5.7266 0.5 6.25 1.02344 6.25 1.67188V14.9531H19.9854L22.7822 9.35156C23.0713 8.77352 23.7744 8.53924 24.3525 8.82812C24.9307 9.11719 25.1651 9.82031 24.876 10.3984L21.751 16.6484C21.5556 17.0468 21.1494 17.2969 20.7041 17.2969H5.07812C4.42978 17.2967 3.90625 16.7733 3.90625 16.125V2.84375H1.17188C0.523432 2.84372 0 2.32029 0 1.67188C0 1.02346 0.523432 0.500033 1.17188 0.5H5.07812ZM16.3994 0.5C17.0478 0.500099 17.5713 1.0235 17.5713 1.67188V5.96875H19.5244C20.001 5.96876 20.4307 6.25783 20.6104 6.69531C20.79 7.14062 20.6885 7.64062 20.3525 7.97656L14.8838 13.4453C14.4229 13.9062 13.6885 13.9061 13.2275 13.4453L7.75781 7.97656C7.42983 7.64065 7.32821 7.13271 7.50781 6.69531C7.69527 6.25012 8.11732 5.9689 8.59375 5.96875H10.5469V1.67188C10.5469 1.02344 11.0713 0.5 11.7197 0.5H16.3994ZM12.8916 2.84375V7.14062C12.8916 7.78892 12.368 8.31227 11.7197 8.3125H11.4229L14.0635 10.9531L16.7041 8.3125H16.4072C15.7588 8.3125 15.2354 7.78906 15.2354 7.14062V2.84375H12.8916Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
10
apps/user/public/svg-icon/ticket.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg viewBox="0 0 25 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_1289_704)">
|
||||
<path d="M23.8281 0.5C24.4766 0.5 25 1.02344 25 1.67188V17.2969C25 17.9453 24.4766 18.4688 23.8281 18.4688H8.6875L2 25.1562C1.26562 25.8906 0 25.375 0 24.3281V1.67188C0 1.02344 0.523438 0.5 1.17188 0.5H23.8281ZM2.34375 21.5L7.375 16.4688C7.59375 16.25 7.89062 16.125 8.20312 16.125H22.6562V2.84375H2.34375V21.5ZM11.3281 8.70312C11.3281 7.15625 13.6719 7.15625 13.6719 8.70312V13.7812C13.6719 14.4297 13.1484 14.9531 12.5 14.9531C11.8516 14.9531 11.3281 14.4297 11.3281 13.7812V8.70312ZM11.6719 4.38281C12.1016 3.94532 12.8906 3.94532 13.3281 4.38281C13.7891 4.84375 13.7812 5.58594 13.3281 6.03906C12.875 6.49218 12.1328 6.49999 11.6719 6.03906C11.2188 5.58594 11.2109 4.84375 11.6719 4.38281Z" fill="currentColor"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_1289_704">
|
||||
<rect width="25" height="25" fill="white" transform="translate(0 0.5)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 971 B |
3
apps/user/public/svg-icon/wallet.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg viewBox="0 0 25 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20.7031 0.234375C22.2109 0.234375 23.4375 1.46094 23.4375 2.96875V5.3125H23.8281C24.4766 5.3125 25 5.83594 25 6.48438V13.5156C25 14.1641 24.4766 14.6875 23.8281 14.6875H23.4375V17.0312C23.4375 18.5391 22.2109 19.7656 20.7031 19.7656H2.73438C1.22656 19.7656 0 18.5391 0 17.0312V2.96875C0 1.46094 1.22656 0.234375 2.73438 0.234375H20.7031ZM2.73438 2.57812C2.51562 2.57812 2.34375 2.75 2.34375 2.96875V17.0312C2.34375 17.2422 2.52344 17.4219 2.73438 17.4219H20.7031C20.9219 17.4219 21.0938 17.2422 21.0938 17.0312V14.6875H19.1406C16.5547 14.6875 14.4531 12.5859 14.4531 10C14.4531 7.41406 16.5547 5.3125 19.1406 5.3125H21.0938V2.96875C21.0938 2.75 20.9219 2.57812 20.7031 2.57812H2.73438ZM19.1406 7.65625C16.0391 7.65625 16.0469 12.3438 19.1406 12.3438H22.6562V7.65625H19.1406ZM18.3125 9.17188C18.75 8.73438 19.5391 8.73438 19.9766 9.17188C20.4219 9.63281 20.4219 10.3672 19.9766 10.8281C19.4922 11.2891 18.7656 11.2812 18.3125 10.8281C17.8516 10.3672 17.8516 9.625 18.3125 9.17188Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -2,7 +2,7 @@
|
||||
|
||||
import { Slot } from '@radix-ui/react-slot';
|
||||
import { VariantProps, cva } from 'class-variance-authority';
|
||||
import { PanelLeft } from 'lucide-react';
|
||||
import Image from 'next/image';
|
||||
import * as React from 'react';
|
||||
|
||||
import { Button } from '@workspace/airo-ui/components/button';
|
||||
@ -270,14 +270,14 @@ const SidebarTrigger = React.forwardRef<
|
||||
data-sidebar='trigger'
|
||||
variant='ghost'
|
||||
size='icon'
|
||||
className={cn('h-7 w-7', className)}
|
||||
className={cn('size-14', className)}
|
||||
onClick={(event) => {
|
||||
onClick?.(event);
|
||||
toggleSidebar();
|
||||
}}
|
||||
{...props}
|
||||
>
|
||||
<PanelLeft />
|
||||
<Image src={'list.png'} width={61} height={61} unoptimized />
|
||||
<span className='sr-only'>Toggle Sidebar</span>
|
||||
</Button>
|
||||
);
|
||||
|
||||