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
+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])
}
})
}