support plan

This commit is contained in:
hamid zarghami
2025-05-05 16:59:48 +03:30
parent b945ffb0a3
commit f45273fc96
25 changed files with 552 additions and 9 deletions
+209
View File
@@ -0,0 +1,209 @@
import { FC, useEffect, useState } from 'react'
import { Helmet } from 'react-helmet-async'
import { useTranslation } from 'react-i18next'
import SidebarHint from './components/SidebarHint'
import SupportImage from '../../assets/images/support.png'
import Button from '../../components/Button'
import { CloseCircle, Document, Element3, TickCircle } from 'iconsax-react'
import Tabs from '../../components/Tabs'
import { useBuySupportPlan, useGetSupportPlans } from './hooks/useSupportData'
import { NumberFormat } from '../../config/func'
import { PlanItemType, featureItemType } from './types/SupportTypes'
import SupportSkeleton from './components/SupportSkeleton'
import SupportIcon from './components/SupportIcon'
import { SupportPlanFeatureKey } from './enum/SupportEnum'
import { toast } from '../../components/Toast'
import { ErrorType } from '../../helpers/types'
import { useNavigate } from 'react-router-dom'
import { Pages } from '../../config/Pages'
const Support: FC = () => {
const { data, isLoading } = useGetSupportPlans()
const { t } = useTranslation('global')
const [activeTab, setActiveTab] = useState<string>('')
const [loadingPlanId, setLoadingPlanId] = useState<string>('')
const { mutate: buySupportPlan } = useBuySupportPlan()
const navigate = useNavigate()
useEffect(() => {
if (data?.data?.supportPlans?.length > 0 && !activeTab) {
setActiveTab(data.data.supportPlans[0].id)
}
}, [data, activeTab])
const handleBuy = (planId: string) => {
setLoadingPlanId(planId)
buySupportPlan(planId, {
onSuccess: (data) => {
toast(data?.data?.message, 'success')
navigate(Pages.receipts.detail + data?.data?.invoice?.id)
setLoadingPlanId('')
},
onError: (error: ErrorType) => {
toast(error?.response?.data?.error.message[0], 'error')
setLoadingPlanId('')
}
})
}
if (isLoading || !data?.data) {
return <SupportSkeleton />
}
return (
<div className='mt-4'>
<Helmet>
<title>
داناک | {t('support.title')}
</title>
</Helmet>
<div>
{t('support.title')}
</div>
<div className='xl:hidden mt-5'>
<Tabs
items={data?.data?.supportPlans?.map((plan: PlanItemType) => ({
icon: <Element3 color={activeTab === plan.id ? 'black' : '#8C90A3'} size={22} />,
label: plan.name,
value: plan.id
}))}
active={activeTab}
onChange={setActiveTab}
/>
</div>
<div className='flex gap-6 xl:mt-8 mt-4'>
<div className='flex-1 bg-white py-8 xl:px-10 px-4 rounded-3xl'>
<div className='xl:flex hidden justify-between mt-10'>
<div className='flex-1 flex justify-center'>
<img src={SupportImage} alt='support' className='w-[160px]' />
</div>
{
data?.data?.supportPlans?.map((item: PlanItemType) => {
return (
<div key={item.id} className='flex-1 flex flex-col items-center'>
<div className='text-center w-full'>
<div className='font-bold'>
{item.name}
</div>
<div className='text-sm text-[#595C67] mt-4'>
ماهیانه
</div>
<div className='font-bold text-sm mt-1'>
{NumberFormat(item.price)}
</div>
<div className='mt-1 text-sm'>
تومان
</div>
<Button
label='ثبت پلن'
className='mt-4 mx-auto w-fit px-5'
onClick={() => handleBuy(item.id)}
isLoading={loadingPlanId === item.id}
/>
</div>
</div>
)
})
}
</div>
<div className='xl:flex hidden flex-1 mt-5'>
<div className='flex-1 flex flex-col'>
{
data?.data?.supportPlans?.[0]?.features.map((row: featureItemType) => (
<div className='flex h-16 px-4 plan items-center justify-between'>
<div className='flex-1 flex items-center gap-2'>
<div className='size-8 rounded-2.5 bg-[#EEF0F7] flex items-center justify-center'>
<SupportIcon keySupport={row.featureKey as SupportPlanFeatureKey} />
</div>
<div className='text-xs'>{t(`support.${row.featureKey}`)}</div>
</div>
</div>
))
}
</div>
{
data?.data?.supportPlans?.map((item: PlanItemType) => (
<div className='flex-1 flex flex-col'>
{
item.features.map((row) => (
<div className='flex h-16 px-4 plan items-center justify-center'>
{
row.featureType === 'boolean' ?
row.featureValue === 'true' ?
<TickCircle className='xl:size-8 size-6' color='#01A560' variant='Bold' />
:
<CloseCircle className='xl:size-8 size-6' color='#D50303' variant='Bold' />
:
<div className='text-xs'>{row.featureValue}</div>
}
</div>
))
}
</div>
))
}
</div>
{/* Mobile View */}
<div className='xl:hidden block mt-5'>
{
data?.data?.supportPlans?.map((plan: PlanItemType) => (
activeTab === plan.id && (
<div key={plan.id}>
<div className='flex justify-center mb-6'>
<img src={SupportImage} alt='support' className='w-[120px]' />
</div>
<div className='text-center mb-6'>
<div className='font-bold text-lg'>{plan.name}</div>
<div className='text-sm text-[#595C67] mt-2'>ماهیانه</div>
<div className='font-bold text-sm mt-1'>{NumberFormat(plan.price)}</div>
<div className='mt-1 text-sm'>تومان</div>
<Button
label='ثبت پلن'
className='mt-4 w-fit px-5 mx-auto'
onClick={() => handleBuy(plan.id)}
isLoading={loadingPlanId === plan.id}
/>
</div>
<div className='space-y-4'>
{
plan.features.map((row: featureItemType) => (
<div className='flex items-center justify-between p-4 bg-gray-50 rounded-xl'>
<div className='flex items-center gap-2'>
<div className='size-8 rounded-2.5 bg-[#EEF0F7] flex items-center justify-center'>
<Document size={16} color='#595C67' variant='Bold' />
</div>
<div className='text-xs'>{t(`support.${row.featureKey}`)}</div>
</div>
{
row.featureType === 'boolean' ?
row.featureValue === 'true' ?
<TickCircle className='size-6' color='#01A560' variant='Bold' />
:
<CloseCircle className='size-6' color='#D50303' variant='Bold' />
:
<div className='text-sm'>{row.featureValue}</div>
}
</div>
))
}
</div>
</div>
)
))
}
</div>
</div>
<SidebarHint />
</div>
</div>
)
}
export default Support