plan
This commit is contained in:
@@ -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'>
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user