This commit is contained in:
hamid zarghami
2025-05-06 12:32:06 +03:30
parent 817327519a
commit 3b409a3c56
6 changed files with 104 additions and 52 deletions
+7 -34
View File
@@ -3,27 +3,20 @@ 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 { 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'
import BuyPlan from './components/BuyPlan'
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) {
@@ -31,20 +24,6 @@ const Support: FC = () => {
}
}, [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 />
@@ -92,17 +71,14 @@ const Support: FC = () => {
ماهیانه
</div>
<div className='font-bold text-sm mt-1'>
{NumberFormat(item.price)}
{item.price === 0 ? 'رایگان' : 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}
<BuyPlan
id={item.id}
/>
</div>
</div>
@@ -163,11 +139,8 @@ const Support: FC = () => {
<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}
<BuyPlan
id={plan.id}
/>
</div>
<div className='space-y-4'>
+65
View File
@@ -0,0 +1,65 @@
import { FC, useEffect, useState } from 'react'
import { useBuySupportPlan, useGetUserSupportPlan, useUpgradeSupportPlan } from '../hooks/useSupportData'
import { toast } from '../../../components/Toast'
import { Pages } from '../../../config/Pages'
import { useNavigate } from 'react-router-dom'
import { ErrorType } from '../../../helpers/types'
import Button from '../../../components/Button'
import { clx } from '../../../helpers/utils'
type Props = {
id: string,
}
const BuyPlan: FC<Props> = ({ id }) => {
const navigate = useNavigate()
const [isActive, setIsActive] = useState(false)
const [isCanUpgrade, setIsCanUpgrade] = useState(false)
const { data: userSupportPlan } = useGetUserSupportPlan()
const { mutate: buySupportPlan, isPending } = useBuySupportPlan()
const { mutate: upgradeSupportPlan, isPending: isUpgradePending } = useUpgradeSupportPlan()
useEffect(() => {
setIsActive(userSupportPlan?.data?.userSupportPlan?.supportPlan?.id === id)
setIsCanUpgrade(userSupportPlan?.data?.userSupportPlan ? true : false)
}, [userSupportPlan])
const handleUpgrade = () => {
upgradeSupportPlan(id, {
onSuccess: (data) => {
toast(data?.data?.message, 'success')
navigate(Pages.receipts.detail + data?.data?.invoice?.id)
},
onError: (error: ErrorType) => {
toast(error?.response?.data?.error.message[0], 'error')
}
})
}
const handleBuy = (planId: string) => {
buySupportPlan(planId, {
onSuccess: (data) => {
toast(data?.data?.message, 'success')
navigate(Pages.receipts.detail + data?.data?.invoice?.id)
},
onError: (error: ErrorType) => {
toast(error?.response?.data?.error.message[0], 'error')
}
})
}
return (
<Button
label={isActive ? 'پلن فعال' : isCanUpgrade ? 'تغییر پلن' : 'خرید پلن'}
className={clx(
'mt-4 mx-auto w-fit px-5',
isActive && 'bg-[#01A560] text-white'
)}
onClick={() => isActive ? undefined : isCanUpgrade ? handleUpgrade() : handleBuy(id)}
isLoading={isPending || isUpgradePending}
/>
)
}
export default BuyPlan
+1 -1
View File
@@ -3,7 +3,7 @@ import { FC } from 'react'
const SidebarHint: FC = () => {
return (
<div className='bg-white w-sidebar xl:block hidden py-10 px-5 h-fit rounded-3xl'>
<div className='bg-white w-sidebar xl:hidden hidden py-10 px-5 h-fit rounded-3xl'>
<div className='text-sm'>
جهت انتخاب بهتر به مسائل زیر توجه بفرمایید:
</div>
@@ -11,7 +11,7 @@ const SupportSkeleton: FC = () => {
<div className='w-[160px] h-[160px] bg-gray-200 rounded-xl animate-pulse' />
</div>
{[1, 2].map((item) => (
{[1, 2, 3].map((item) => (
<div key={item} className='flex-1 flex flex-col items-center'>
<div className='text-center w-full'>
<div className='h-6 w-32 bg-gray-200 rounded-lg animate-pulse mx-auto' />
@@ -35,7 +35,7 @@ const SupportSkeleton: FC = () => {
</div>
))}
</div>
{[1, 2].map((item) => (
{[1, 2, 3].map((item) => (
<div key={item} className='flex-1 flex flex-col'>
{[1, 2, 3, 4, 5].map((feature) => (
<div key={feature} className='flex h-16 px-4 plan items-center justify-center'>
@@ -71,20 +71,6 @@ const SupportSkeleton: FC = () => {
</div>
</div>
</div>
<div className='xl:block hidden w-[300px]'>
<div className='bg-white p-6 rounded-3xl'>
<div className='h-6 w-32 bg-gray-200 rounded-lg animate-pulse mb-4' />
<div className='space-y-3'>
{[1, 2, 3].map((item) => (
<div key={item} className='flex items-center gap-2'>
<div className='size-6 bg-gray-200 rounded-full animate-pulse' />
<div className='h-4 w-40 bg-gray-200 rounded-lg animate-pulse' />
</div>
))}
</div>
</div>
</div>
</div>
</div>
)
+19 -1
View File
@@ -1,5 +1,10 @@
import { useQuery, useMutation } from "@tanstack/react-query";
import { getSupportPlans, buySupportPlan } from "../service/SupportService";
import {
getSupportPlans,
buySupportPlan,
getUserSupportPlan,
upgradeSupportPlan,
} from "../service/SupportService";
export const useGetSupportPlans = () => {
return useQuery({ queryKey: ["support-plans"], queryFn: getSupportPlans });
@@ -10,3 +15,16 @@ export const useBuySupportPlan = () => {
mutationFn: (planId: string) => buySupportPlan(planId),
});
};
export const useGetUserSupportPlan = () => {
return useQuery({
queryKey: ["user-support-plan"],
queryFn: getUserSupportPlan,
});
};
export const useUpgradeSupportPlan = () => {
return useMutation({
mutationFn: (id: string) => upgradeSupportPlan(id),
});
};
@@ -9,3 +9,13 @@ export const buySupportPlan = async (planId: string) => {
const { data } = await axios.post(`/support-plans/${planId}/subscribe`);
return data;
};
export const getUserSupportPlan = async () => {
const { data } = await axios.get(`/support-plans/user`);
return data;
};
export const upgradeSupportPlan = async (id: string) => {
const { data } = await axios.post(`/support-plans/${id}/upgrade`);
return data;
};