This commit is contained in:
hamid zarghami
2025-02-23 15:43:04 +03:30
parent 5916ab100d
commit bc3d068dfd
24 changed files with 278 additions and 121 deletions
+2
View File
@@ -12,6 +12,7 @@ import { IApiErrorRepsonse } from './types/error.types'
import MainRouter from './router/Main'
import AuthRouter from './router/Auth'
import { Pages } from './config/Pages'
import useConvertNumbers from './hooks/useConvertNumbers';
i18next.init({
interpolation: { escapeValue: false },
@@ -43,6 +44,7 @@ const queryClient = new QueryClient({
const App: FC = () => {
// useNumberFont()
useConvertNumbers()
const [isLogin, setIsLogin] = useState<'checking' | 'isLogin' | 'isNotLogin'>('checking')
useEffect(() => {
+1 -1
View File
@@ -27,7 +27,7 @@ const DefaulModal: FC<Props> = (props: Props) => {
props.open && (
<Fragment>
<div style={{ maxWidth: props.width }} className='xl:justify-center xl:items-center items-end flex overflow-x-hidden overflow-y-auto fixed inset-0 z-[60] h-auto top-0 bottom-0 m-auto outline-none focus:outline-none xl:max-w-xl mx-auto'>
<div className='relative xl:h-full h-[80%] bottom-0 left-0 flex xl:items-center sm:h-auto w-full xl:my-6 xl:p-2'>
<div className='relative xl:h-full max-h-[80%] bottom-0 left-0 flex xl:items-center sm:h-auto w-full xl:my-6 xl:p-2'>
<div className='border-0 h-auto p-5 lg:min-w-full overflow-y-auto rounded-3xl rounded-b-none xl:rounded-b-3xl relative flex flex-col w-full modalGlass2 outline-none focus:outline-none'>
+1 -4
View File
@@ -27,9 +27,6 @@ const ServiceItem: FC<Props> = (props: Props) => {
</div>
<div className='mt-4 text-xs'>
<div className='font-extralight'>{item.description} </div>
<p dangerouslySetInnerHTML={{ __html: item.metaDescription }} className='text-description mt-2'>
</p>
</div>
<div className='mt-4'>
@@ -38,7 +35,7 @@ const ServiceItem: FC<Props> = (props: Props) => {
className='h-8 w-fit px-5 text-xs text-black bg-description bg-opacity-20 rounded-xl'
>
<div className='flex gap-2'>
<div>{t('service.buy')}</div>
<div>{t('service.detail')}</div>
<ArrowLeft color='black' size={16} />
</div>
</Button>
+1 -1
View File
@@ -9,7 +9,7 @@ const ServiceSection: FC<Props> = (props: Props) => {
const { item } = props
return (
<div className='flex gap-4'>
<div className='size-10 rounded-xl'>
<div className='size-10 min-w-10 rounded-xl'>
<img src={item.icon} alt={item.name} className='w-full h-full' />
</div>
<div>
+1
View File
@@ -28,6 +28,7 @@ export const Pages = {
learning: "/learning",
setting: "/setting",
wallet: "/wallet",
callback: "/wallet/callback/",
profile: "/profile",
discounts: "/discounts",
financial: "/financial",
+34
View File
@@ -0,0 +1,34 @@
import { useEffect } from "react";
const toPersianDigits = (text: string): string => {
return text.replace(/\d/g, (d) => "۰۱۲۳۴۵۶۷۸۹"[parseInt(d, 10)]);
};
const convertNumbersInDOM = (node: Node): void => {
if (node.nodeType === Node.TEXT_NODE) {
node.nodeValue = toPersianDigits(node.nodeValue || "");
} else if (node.nodeType === Node.ELEMENT_NODE) {
node.childNodes.forEach(convertNumbersInDOM);
}
};
const useConvertNumbers = (): void => {
useEffect(() => {
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === "childList") {
mutation.addedNodes.forEach(convertNumbersInDOM);
}
});
});
observer.observe(document.body, { childList: true, subtree: true });
// اجرای اولیه روی کل صفحه
convertNumbersInDOM(document.body);
return () => observer.disconnect();
}, []);
};
export default useConvertNumbers;
+21 -5
View File
@@ -39,7 +39,9 @@
"login_with_otp": "ورود با رمز عبور یکبار مصرف",
"otp_sent": "کد تایید ارسال شد",
"mobile_number": "شماره موبایل",
"enter_mobile_number": "شماره موبایل خود را وارد کنید"
"enter_mobile_number": "شماره موبایل خود را وارد کنید",
"try_again": "ارسال مجدد",
"toast_resend_code": "کد جدیدی برای شما ارسال شد"
},
"errors": {
"required": "این فیلد اجباری می باشد",
@@ -85,13 +87,17 @@
"add_access": "دسترسی سریع تازه ایجاد کنید.",
"danak_learning": "آموزش داناک",
"see_all": "دیدن همه",
"create_new_access": "ایجاد دسترسی سریع"
"create_new_access": "ایجاد دسترسی سریع",
"receip": "صورتحساب پرداخت نشده دارید",
"balance": "موجودی",
"cannot_find_service": "سرویسی پیدا نشد",
"not_active_service": "شما هنوز سرویس فعالی ندارید"
},
"all": "همه",
"service": {
"my_service": "سرویس های من",
"search": "جستجو در سرویس ها",
"active_menu": "منو فعال",
"active_menu": "سرویس فعال",
"selected_danak": "انتخاب داناک",
"buy": "خرید",
"other_services": "سایر سرویس ها",
@@ -115,7 +121,8 @@
"enter_title_comment": "عنوان نظر خود را وارد کنید",
"your_comment": "نظر شما",
"write_your_comment": "نظر خود را راجع به این سرویس بنویسید",
"users_comments": "نظرات کاربران"
"users_comments": "نظرات کاربران",
"detail": "جزییات بیشتر"
},
"loading": "در حال بارگذاری",
"footer": {
@@ -173,6 +180,7 @@
},
"date": "تاریخ",
"receip": {
"receip": "صورتحساب",
"receip_list": "لیست صورتحساب ها",
"dont_pay": "پرداخت نشده",
"dont_confrim": "تایید نشده",
@@ -400,5 +408,13 @@
},
"man": "مرد",
"woman": "زن",
"success": "عملیات با موفقیت انجام شد"
"success": "عملیات با موفقیت انجام شد",
"callback": {
"title_success": "پرداخت موفق بود!",
"desc_success": "پرداخت شما با موفقیت انجام شد. از خرید شما متشکریم!",
"order_number": "شماره سفارش",
"amount": "مبلغ پرداختی",
"date": "تاریخ",
"back": "بازگشت"
}
}
+31 -6
View File
@@ -9,7 +9,7 @@ import OTPInput from 'react-otp-input'
import { useCountDown } from '../../../hooks/useCountDown'
// import ArrowLeftIcon from '../../../assets/images/arrow-left.svg'
import { Pages } from '../../../config/Pages'
import { useOtpVerify } from '../hooks/useAuthData'
import { useLoginWithOtp, useOtpVerify } from '../hooks/useAuthData'
import { ErrorType } from '../../../helpers/types'
import { toast } from 'react-toastify'
@@ -17,8 +17,9 @@ const LoginStep2: FC = () => {
const { t } = useTranslation('global')
const { phone, setStepLogin } = useAuthStore()
const { value } = useCountDown(2, true)
const { value, reset } = useCountDown(2, true)
const otpVerify = useOtpVerify()
const loginWithOtp = useLoginWithOtp()
const formik = useFormik<OtpVerifyType>({
initialValues: {
@@ -69,6 +70,18 @@ const LoginStep2: FC = () => {
return () => ac.abort();
}, []);
const reSend = () => {
loginWithOtp.mutate({ phone: phone }, {
onSuccess: () => {
reset()
toast.success(t('auth.toast_resend_code'))
},
onError: (error: ErrorType) => {
toast.error(error.response?.data?.error.message[0])
}
})
}
return (
<div>
<div className='mt-5'>
@@ -103,6 +116,7 @@ const LoginStep2: FC = () => {
renderInput={(props) =>
<input
{...props}
type='tel'
autoComplete="one-time-code"
inputMode="numeric"
className='w-full h-[50px] flex-1 mx-2 bg-white border rounded-2.5' />
@@ -116,10 +130,21 @@ const LoginStep2: FC = () => {
}
<div className='flex mt-4 justify-end'>
<div className='flex gap-1 text-description text-xs'>
<div>{value}</div>
<div>{t('auth.counter_otp')}</div>
</div>
{
value !== '00:00' ?
<div className='flex gap-1 text-description text-xs'>
<div>{value}</div>
<div>{t('auth.counter_otp')}</div>
</div>
:
<div onClick={reSend} className='flex cursor-pointer gap-1 pl-2 text-black text-sm'>
<div className=''>
{t('auth.try_again')}
</div>
</div>
}
</div>
</div>
+1 -1
View File
@@ -26,7 +26,7 @@ const Financial: FC = () => {
},
{
icon: <ProfileCircle color={activeTab === 'personal' ? 'black' : '#8C90A3'} size={22} />,
label: t('financial.legal'),
label: t('financial.personal'),
value: 'personal'
},
]}
+9 -9
View File
@@ -1,6 +1,6 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { ArrowLeft, Element3, Messages3, NotificationStatus, Teacher } from 'iconsax-react'
import { ArrowLeft, Element3, Messages3, NotificationStatus, Receipt21 } from 'iconsax-react'
import ItemDashboard from './components/ItemDashboard'
import TitleLine from '../../components/TitleLine'
import AccessbilityImage from '../../assets/images/accessbility.jpg'
@@ -73,6 +73,14 @@ const Home: FC = () => {
description={t('home.unread_messages')}
/>
<ItemDashboard
title={t('receip.receip')}
icon={<Receipt21 size={20} color='black' />}
color='#0047FF'
count={4}
description={t('home.receip')}
/>
<ItemDashboard
title={t('home.announcement')}
icon={<NotificationStatus size={20} color='black' />}
@@ -81,14 +89,6 @@ const Home: FC = () => {
description={t('home.unread_announcement')}
/>
<ItemDashboard
title={t('home.learnings')}
icon={<Teacher size={20} color='black' />}
color='#0047FF'
count={4}
description={t('home.learning')}
/>
</div>
<div className='w-full mt-8'>
@@ -3,13 +3,17 @@ import { FC, useState } from 'react'
import DefaulModal from '../../../components/DefaulModal'
import { useTranslation } from 'react-i18next'
import Input from '../../../components/Input'
import Select from '../../../components/Select'
import SwitchComponent from '../../../components/Switch'
import { useGetMyServices } from '../../service/hooks/useServiceData'
import { MyServicesItem } from '../../service/types/ServiecTypes'
import PageLoading from '../../../components/PageLoading'
const BoxNewAccessbility: FC = () => {
const [search, setSearch] = useState<string>('')
const [open, setOpen] = useState<boolean>(false)
const { t } = useTranslation('global')
const getMyservices = useGetMyServices(search)
return (
<>
@@ -63,80 +67,58 @@ const BoxNewAccessbility: FC = () => {
<Input
variant='search'
className='bg-opacity-25 bg-white'
onChangeSearchFinal={setSearch}
/>
</div>
<Select
items={[
{ value: '1', label: '1' },
{ value: '2', label: '2' },
{ value: '3', label: '3' },
]}
placeholder={t('all')}
className='bg-opacity-25 bg-white w-[100px]'
/>
</div>
<div className='mt-6 flex flex-wrap gap-6'>
<div className='flex-1 xl:min-w-[40%] min-w-full flex justify-between items-center border-b border-[#8C90A3] border-opacity-30 py-2'>
<div className='flex gap-4'>
<div className='size-10 rounded-xl bg-red-300'></div>
<div>
<div className='text-sm'>
دی منو
</div>
<div className='text-xs text-description'>
منو رستوران
</div>
</div>
{
getMyservices.isPending ?
<div className='mt-6'>
<PageLoading />
</div>
<div>
<SwitchComponent
active
onChange={() => { }}
/>
:
<div className='mt-6 flex flex-wrap gap-6'>
{
getMyservices.data?.data?.subscriptions?.length === 0 ?
<div className='text-center w-full mt-4'>
{
search === '' ?
t('home.not_active_service')
:
t('home.cannot_find_service')
}
</div>
:
getMyservices.data?.data?.subscriptions?.map((item: MyServicesItem) => {
return (
<div key={item.id} className='flex-1 xl:min-w-[40%] min-w-full flex justify-between items-center border-b border-[#8C90A3] border-opacity-30 py-2'>
<div className='flex gap-4'>
<div className='size-10 rounded-xl overflow-hidden'>
<img src={item.plan?.service?.icon} className='size-full' />
</div>
<div>
<div className='text-sm'>
{item.plan.service?.name}
</div>
<div className='text-xs text-description'>
{item.plan.service?.title}
</div>
</div>
</div>
<div>
<SwitchComponent
active
onChange={() => { }}
/>
</div>
</div>
)
})
}
<div className='flex-1 min-w-[40%]'></div>
</div>
</div>
<div className='flex-1 xl:min-w-[40%] min-w-full flex justify-between items-center border-b border-[#8C90A3] border-opacity-30 py-2'>
<div className='flex gap-4'>
<div className='size-10 rounded-xl bg-blue-300'></div>
<div>
<div className='text-sm'>
دی منو
</div>
<div className='text-xs text-description'>
منو رستوران
</div>
</div>
</div>
<div>
<SwitchComponent
active
onChange={() => { }}
/>
</div>
</div>
<div className='flex-1 xl:min-w-[40%] min-w-full flex justify-between items-center border-b border-[#8C90A3] border-opacity-30 py-2'>
<div className='flex gap-4'>
<div className='size-10 rounded-xl bg-green-300'></div>
<div>
<div className='text-sm'>
دی منو
</div>
<div className='text-xs text-description'>
منو رستوران
</div>
</div>
</div>
<div>
<SwitchComponent
active
onChange={() => { }}
/>
</div>
</div>
<div className='flex-1 min-w-[40%]'></div>
</div>
}
</div>
</DefaulModal>
</>
+1 -1
View File
@@ -210,7 +210,7 @@ const DetailService: FC = () => {
{
getAdsLeft.isSuccess && getAdsLeft.data.data.ads[0] &&
<a href={getAdsLeft.data?.data?.ads[0].link} target='_blank' className='bg-white w-sidebar h-fit hidden xl:block rounded-3xl overflow-hidden relative'>
<a href={getAdsLeft.data?.data?.ads[0].link} target='_blank' className='bg-white w-sidebar h-fit hidden xl:block rounded-3xl overflow-hidden sticky top-4'>
<img
src={getAdsLeft.data.data.ads[0].imageUrl}
className='w-full backdrop-blur-[100px] h-[550px] object-cover'
+1 -1
View File
@@ -89,7 +89,7 @@ const MyServices: FC = () => {
{
getAdsLeft.isSuccess && getAdsLeft.data.data.ads[0] &&
<a href={getAdsLeft.data?.data?.ads[0].link} target='_blank' className='bg-white w-sidebar h-fit hidden xl:block rounded-3xl overflow-hidden relative'>
<a href={getAdsLeft.data?.data?.ads[0].link} target='_blank' className='bg-white w-sidebar h-fit hidden xl:block rounded-3xl overflow-hidden sticky top-0'>
<img
src={getAdsLeft.data.data.ads[0].imageUrl}
className='w-full backdrop-blur-[100px] h-[550px] object-cover'
+1 -1
View File
@@ -96,7 +96,7 @@ const OtherServices: FC = () => {
</div>
{
getAdsLeft.isSuccess && getAdsLeft.data.data.ads[0] &&
<a href={getAdsLeft.data?.data?.ads[0].link} target='_blank' className='bg-white w-sidebar h-fit hidden xl:block rounded-3xl overflow-hidden relative'>
<a href={getAdsLeft.data?.data?.ads[0].link} target='_blank' className='bg-white w-sidebar h-fit hidden xl:block rounded-3xl overflow-hidden sticky top-0'>
<img
src={getAdsLeft.data.data.ads[0].imageUrl}
className='w-full backdrop-blur-[100px] h-[550px] object-cover'
@@ -68,7 +68,7 @@ const OtherServicesComponent: FC = () => {
getServices.data?.data?.category?.danakServices?.map((item: ItemServiceType) => {
return (
<div className='flex-1 min-w-full xl:min-w-0 bg-white rounded-3xl py-4 px-6'>
<div className='flex justify-between items-center'>
<div className='flex gap-2 justify-between items-center'>
<ServiceSection
item={item}
/>
@@ -77,7 +77,7 @@ const OtherServicesComponent: FC = () => {
className='h-8 w-fit px-2 text-xs text-black bg-description bg-opacity-20 rounded-xl'
>
<div className='flex gap-2'>
<div>{t('service.buy')}</div>
<div className='whitespace-nowrap'>{t('service.detail')}</div>
<ArrowLeft color='black' size={16} />
</div>
</Button>
+3 -4
View File
@@ -88,7 +88,6 @@ const TicketDetail: FC = () => {
<div className='mt-4'>
<div className='flex gap-1'>
<div>{t('ticket.ticket_number')}</div>
<div>12312</div>
</div>
{
getMessages.isPending ?
@@ -115,7 +114,7 @@ const TicketDetail: FC = () => {
{
getMessages.data?.data?.messages.map((item: any) => {
if (item?.author?.role?.name === 'user') {
if (item?.author?.roles[0]?.name === 'user') {
return (
<div key={item.id} className='mt-6 xl:text-sm text-xs bg-[#F6F7FA] p-6 rounded-3xl rounded-tr-none xl:max-w-[70%] max-w-[90%]'>
<div className='leading-7'>
@@ -154,8 +153,8 @@ const TicketDetail: FC = () => {
<div className='leading-7 mt-4'>
{item.content}
</div>
<div className='flex justify-end mt-6 text-xs text-description'>
10:07 | 1403/09/30
<div className='flex dltr end mt-6 text-xs text-description'>
{moment(item.createdAt).format('jYYYY-jMM-jDD HH:mm')}
</div>
</div>
+6 -6
View File
@@ -12,7 +12,7 @@ import moment from 'moment-jalaali'
const TicketList: FC = () => {
const { t } = useTranslation('global')
const [activeTab, setActiveTab] = useState<'ANSWERED' | 'PENDING' | 'CLOSED'>('ANSWERED')
const [activeTab, setActiveTab] = useState<'ANSWERED' | 'PENDING' | 'CLOSED'>('PENDING')
const getTickets = useGetTickets(activeTab)
return (
@@ -40,16 +40,16 @@ const TicketList: FC = () => {
<Tabs
active={activeTab}
items={[
{
icon: <MessageTick color={activeTab === 'ANSWERED' ? 'black' : '#8C90A3'} size={22} />,
label: t('ticket.answered'),
value: 'ANSWERED'
},
{
icon: <MessageTime color={activeTab === 'PENDING' ? 'black' : '#8C90A3'} size={22} />,
label: t('ticket.checking'),
value: 'PENDING'
},
{
icon: <MessageTick color={activeTab === 'ANSWERED' ? 'black' : '#8C90A3'} size={22} />,
label: t('ticket.answered'),
value: 'ANSWERED'
},
// {
// icon: <Message2 color={activeTab === 'wating' ? 'black' : '#8C90A3'} size={22} />,
// label: t('ticket.wait_answered'),
+9
View File
@@ -56,7 +56,16 @@ export const useAddMessageTicket = (id: string) => {
};
export const useCloseTicket = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (id: string) => api.closeTicket(id),
onSuccess: () => {
queryClient.refetchQueries({
queryKey: ["tickets"],
});
queryClient.refetchQueries({
queryKey: ["ticket-messages"],
});
},
});
};
+1 -1
View File
@@ -105,7 +105,7 @@ const TransactionList: FC = () => {
<tr key={item.id}>
<Td text={item.numericId + ''} />
<Td text={item.description} />
<Td text={item.amount} />
<Td text={NumberFormat(+item.amount)} />
<Td text={moment(item.createdAt).format('jYYYY-jMM-jDD')} />
<Td text={''}>
<Detail />
+61
View File
@@ -0,0 +1,61 @@
import { TickCircle } from 'iconsax-react'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { NumberFormat } from '../../config/func'
import Button from '../../components/Button'
const CallBack: FC = () => {
const { t } = useTranslation('global')
return (
<div className='flex mt-10 flex-col justify-center items-center flex-1 h-full'>
<TickCircle
size={64}
color='#00712D'
/>
<div className='mt-7 text-xl'>
{t('callback.title_success')}
</div>
<div className='mt-7'>
{t('callback.desc_success')}
</div>
<div className='mt-16 xl:min-w-[560px] bg-[#FBFBFD] p-8 text-sm'>
<div className='flex justify-between'>
<div>
{t('callback.order_number')}
</div>
<div>
#1234
</div>
</div>
<div className='flex justify-between mt-6'>
<div>
{t('callback.amount')}
</div>
<div>
{NumberFormat(200000) + ' ' + t('toman')}
</div>
</div>
<div className='flex justify-between mt-6'>
<div>
{t('callback.date')}
</div>
<div>
۲۹ بهمن ۱۴۰۳
</div>
</div>
</div>
<Button
label={t('callback.back')}
className='xl:max-w-[560px] mt-8'
/>
</div>
)
}
export default CallBack
@@ -11,6 +11,7 @@ import { DepositTransferType } from '../types/WalletTypes'
import * as Yup from 'yup'
import { useSingleUpload } from '../../ticket/hooks/useTicketData'
import { toast } from 'react-toastify'
import { ErrorType } from '../../../helpers/types'
const CardtoCard: FC = () => {
@@ -42,6 +43,9 @@ const CardtoCard: FC = () => {
formik.resetForm()
setFile(undefined)
toast.success(t('wallet.successful_transfer'))
},
onError: (error: ErrorType) => {
toast.error(error.response?.data?.error.message[0])
}
})
}
+4
View File
@@ -11,6 +11,7 @@ import { DepositTransferType } from '../types/WalletTypes'
import * as Yup from 'yup'
import { useSingleUpload } from '../../ticket/hooks/useTicketData'
import { toast } from 'react-toastify'
import { ErrorType } from '../../../helpers/types'
const CardtoCard: FC = () => {
@@ -43,6 +44,9 @@ const CardtoCard: FC = () => {
setFile(undefined)
toast.success(t('wallet.successful_transfer'))
window.location.reload()
},
onError: (error: ErrorType) => {
toast.error(error.response?.data?.error.message[0])
}
})
}
+3 -1
View File
@@ -25,6 +25,7 @@ import TicketList from '../pages/ticket/TicketList'
import CreateTicket from '../pages/ticket/CreateTicket'
import TicketDetail from '../pages/ticket/Detail'
import Financial from '../pages/financial/Financial'
import CallBack from '../pages/wallet/CallBack'
const MainRouter: FC = () => {
return (
@@ -33,7 +34,7 @@ const MainRouter: FC = () => {
<Header />
<div className='flex-1 xl:ms-[269px] mt-[68px] xl:mt-[81px]'>
<div className={`overflow-auto w-[${window.innerWidth}] max-h-[calc(100vh-113px)]`}>
<div>
<div className='pb-16'>
<Routes>
<Route path={Pages.dashboard} element={<Home />} />
<Route path={Pages.services.mine} element={<MyServices />} />
@@ -51,6 +52,7 @@ const MainRouter: FC = () => {
<Route path={Pages.learning} element={<LearningList />} />
<Route path={Pages.setting} element={<Setting />} />
<Route path={Pages.wallet} element={<Wallet />} />
<Route path={Pages.callback + ':id'} element={<CallBack />} />
<Route path={Pages.profile} element={<Profile />} />
<Route path={Pages.financial} element={<Financial />} />
</Routes>
+29 -8
View File
@@ -10,6 +10,8 @@ import { useSharedStore } from './store/sharedStore'
import { useGetProfile } from '../pages/profile/hooks/useProfileData'
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/react'
import SideBarItem from './SideBarItem'
import { useGetWalletBalance } from '../pages/wallet/hooks/useWalletData'
import { NumberFormat } from '../config/func'
const Header: FC = () => {
@@ -18,6 +20,7 @@ const Header: FC = () => {
const { t } = useTranslation('global')
const { setOpenSidebar, openSidebar } = useSharedStore()
const { data } = useGetProfile()
const getWalletBalance = useGetWalletBalance()
useEffect(() => {
setPopoverKey((prevKey) => prevKey + 1);
@@ -40,9 +43,19 @@ const Header: FC = () => {
<Link to={Pages.services.other}>
<Element3 color='black' className='xl:size-[18px] size-[17px]' />
</Link>
<Link to={Pages.wallet}>
<Link className='xl:hidden' to={Pages.wallet}>
<Wallet className='xl:size-[18px] size-[17px]' color='black' />
</Link>
<Link className='hidden xl:block' to={Pages.wallet}>
<div className='flex items-center h-8 pl-2 rounded-full bg-[#EEF0F7]'>
<div className='px-3 text-xs'>
{NumberFormat(getWalletBalance.data?.data?.balance) + ' ' + t('toman')}
</div>
<div className='size-[26px] flex justify-center items-center bg-white rounded-xl'>
<Wallet className='xl:size-[18px] size-[17px]' color='black' />
</div>
</div>
</Link>
<Notifications />
{
data && (
@@ -80,13 +93,21 @@ const Header: FC = () => {
</div>
<div className='pb-6 px-6 border-b border-[#EAEDF5]'>
<SideBarItem
icon={<Wallet size={20} color='black' />}
title={t('header.wallet')}
link={Pages.wallet}
isActive
isWithoutLine
/>
<div className='flex justify-between items-center'>
<SideBarItem
icon={<Wallet size={20} color='black' />}
title={t('header.wallet')}
link={Pages.wallet}
isActive
isWithoutLine
/>
<div className='flex items-center mt-4 h-8 pl-2 rounded-full bg-[#EEF0F7]'>
<div className='ps-3'>{t('home.balance')}</div>
<div className='px-3 text-xs'>
{NumberFormat(getWalletBalance.data?.data?.balance) + ' ' + t('toman')}
</div>
</div>
</div>
<SideBarItem
icon={<Card color={'black'} size={20} />}