plan info
This commit is contained in:
@@ -0,0 +1,46 @@
|
|||||||
|
import { AddCircle } from 'iconsax-react'
|
||||||
|
import { FC, useState, useRef, useEffect } from 'react'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
title: string
|
||||||
|
content: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const Accordion: FC<Props> = ({ title, content }) => {
|
||||||
|
const [isOpen, setIsOpen] = useState(false)
|
||||||
|
const contentRef = useRef<HTMLDivElement>(null)
|
||||||
|
const [contentHeight, setContentHeight] = useState(0)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (contentRef.current) {
|
||||||
|
setContentHeight(isOpen ? contentRef.current.scrollHeight : 0)
|
||||||
|
}
|
||||||
|
}, [isOpen])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='bg-white rounded-xl p-3 flex-1 h-fit'>
|
||||||
|
<div className='flex gap-2 justify-between items-center cursor-pointer accordion-trigger' onClick={() => setIsOpen(!isOpen)}>
|
||||||
|
<div className='font-bold xl:text-sm text-xs'>
|
||||||
|
{title}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<AddCircle
|
||||||
|
size={24}
|
||||||
|
color='black'
|
||||||
|
className={`transition-transform duration-300 accordion-icon ${isOpen ? 'rotate-45' : 'rotate-0'}`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
ref={contentRef}
|
||||||
|
className='overflow-hidden transition-all duration-300 accordion-content'
|
||||||
|
style={{ maxHeight: `${contentHeight}px` }}
|
||||||
|
>
|
||||||
|
<p className='text-sm leading-6 py-2 text-[#7D818C]'>
|
||||||
|
{content}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Accordion
|
||||||
@@ -27,7 +27,7 @@ const Tabs: FC<Props> = (props: Props) => {
|
|||||||
spaceBetween={30}
|
spaceBetween={30}
|
||||||
className='px-10 max-w-full w-fit items-center text-description mx-auto backdrop-blur-md border-2 border-white gap-10 flex h-[80px] rounded-[32px] bg-white bg-opacity-45'>
|
className='px-10 max-w-full w-fit items-center text-description mx-auto backdrop-blur-md border-2 border-white gap-10 flex h-[80px] rounded-[32px] bg-white bg-opacity-45'>
|
||||||
{
|
{
|
||||||
props.items?.map((item: Item, index: number) => {
|
props.items?.length > 0 && props.items?.map((item: Item, index: number) => {
|
||||||
return (
|
return (
|
||||||
<SwiperSlide style={SWIPER_SLIDE_STYLE} onClick={() => props.onChange(item.value)} key={item.value} className={clx(
|
<SwiperSlide style={SWIPER_SLIDE_STYLE} onClick={() => props.onChange(item.value)} key={item.value} className={clx(
|
||||||
'flex flex-col max-w-fit mt-[15px] items-center gap-2 cursor-pointer',
|
'flex flex-col max-w-fit mt-[15px] items-center gap-2 cursor-pointer',
|
||||||
|
|||||||
@@ -38,5 +38,6 @@ export const Pages = {
|
|||||||
financial: "/financial",
|
financial: "/financial",
|
||||||
support: {
|
support: {
|
||||||
index: "/support",
|
index: "/support",
|
||||||
|
info: "/support/info",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Helmet } from 'react-helmet-async'
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import SidebarHint from './components/SidebarHint'
|
import SidebarHint from './components/SidebarHint'
|
||||||
import SupportImage from '../../assets/images/support.png'
|
import SupportImage from '../../assets/images/support.png'
|
||||||
import { Building, CloseCircle, Component, Crown, TickCircle } from 'iconsax-react'
|
import { ArrowLeft, Building, CloseCircle, Component, Crown, TickCircle } from 'iconsax-react'
|
||||||
import Tabs from '../../components/Tabs'
|
import Tabs from '../../components/Tabs'
|
||||||
import { useGetSupportPlans } from './hooks/useSupportData'
|
import { useGetSupportPlans } from './hooks/useSupportData'
|
||||||
import { NumberFormat } from '../../config/func'
|
import { NumberFormat } from '../../config/func'
|
||||||
@@ -12,6 +12,8 @@ import SupportSkeleton from './components/SupportSkeleton'
|
|||||||
import SupportIcon from './components/SupportIcon'
|
import SupportIcon from './components/SupportIcon'
|
||||||
import { SupportPlanFeatureKey } from './enum/SupportEnum'
|
import { SupportPlanFeatureKey } from './enum/SupportEnum'
|
||||||
import BuyPlan from './components/BuyPlan'
|
import BuyPlan from './components/BuyPlan'
|
||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import { Pages } from '../../config/Pages'
|
||||||
|
|
||||||
const Support: FC = () => {
|
const Support: FC = () => {
|
||||||
const { data, isLoading } = useGetSupportPlans()
|
const { data, isLoading } = useGetSupportPlans()
|
||||||
@@ -36,8 +38,15 @@ const Support: FC = () => {
|
|||||||
داناک | {t('support.title')}
|
داناک | {t('support.title')}
|
||||||
</title>
|
</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<div>
|
<div className='flex justify-between items-center'>
|
||||||
{t('support.title')}
|
{t('support.title')}
|
||||||
|
|
||||||
|
<Link to={Pages.support.info}>
|
||||||
|
<div className='flex gap-2 items-center'>
|
||||||
|
<div className='text-sm'>بیشتر بدانید</div>
|
||||||
|
<ArrowLeft size={18} color='#000' />
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='xl:hidden mt-5'>
|
<div className='xl:hidden mt-5'>
|
||||||
@@ -142,8 +151,8 @@ const Support: FC = () => {
|
|||||||
<div className='text-center mb-6'>
|
<div className='text-center mb-6'>
|
||||||
<div className='font-bold text-lg'>{plan.name}</div>
|
<div className='font-bold text-lg'>{plan.name}</div>
|
||||||
<div className='text-sm text-[#595C67] mt-2'>سالیانه</div>
|
<div className='text-sm text-[#595C67] mt-2'>سالیانه</div>
|
||||||
<div className='font-bold text-sm mt-1'>{NumberFormat(plan.price)}</div>
|
<div className='font-bold text-sm mt-1'>{plan.price === 0 ? 'رایگان' : NumberFormat(plan.price)}</div>
|
||||||
<div className='mt-1 text-sm'>تومان</div>
|
<div className='mt-1 text-sm'>{plan.price === 0 ? ' ' : 'تومان'}</div>
|
||||||
<BuyPlan
|
<BuyPlan
|
||||||
id={plan.id}
|
id={plan.id}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -0,0 +1,204 @@
|
|||||||
|
import { FC, useEffect, useState } from 'react'
|
||||||
|
import { Helmet } from 'react-helmet-async'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { useGetSupportPlans } from './hooks/useSupportData'
|
||||||
|
import { Building, Component } from 'iconsax-react'
|
||||||
|
import { PlanItemType } from './types/SupportTypes'
|
||||||
|
import { Crown } from 'iconsax-react'
|
||||||
|
import SupportImage from '../../assets/images/support.png'
|
||||||
|
import { NumberFormat } from '../../config/func'
|
||||||
|
import { featureItemType } from './types/SupportTypes'
|
||||||
|
import SupportIcon from './components/SupportIcon'
|
||||||
|
import { TickCircle, CloseCircle } from 'iconsax-react'
|
||||||
|
import SidebarHint from './components/SidebarHint'
|
||||||
|
import { SupportPlanFeatureKey } from './enum/SupportEnum'
|
||||||
|
import Accordion from '../../components/Accordion'
|
||||||
|
import Tabs from '../../components/Tabs'
|
||||||
|
import SupportSkeleton from './components/SupportSkeleton'
|
||||||
|
|
||||||
|
const SupportInfo: FC = () => {
|
||||||
|
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
const { data, isPending } = useGetSupportPlans()
|
||||||
|
const [activeTab, setActiveTab] = useState<string>('')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data?.data?.supportPlans?.length > 0 && !activeTab) {
|
||||||
|
setActiveTab(data.data.supportPlans[0].id)
|
||||||
|
}
|
||||||
|
}, [data, activeTab])
|
||||||
|
|
||||||
|
if (isPending || !data?.data) {
|
||||||
|
return <SupportSkeleton />
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='mt-4'>
|
||||||
|
<Helmet>
|
||||||
|
<title>
|
||||||
|
داناک | {t('support.title')}
|
||||||
|
</title>
|
||||||
|
</Helmet>
|
||||||
|
|
||||||
|
<div className='font-bold'>
|
||||||
|
خدمات پشتیبانی داناک
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className='mt-5 text-sm text-description'>
|
||||||
|
با استفاده از خدمات پشتیبانی داناک میتوانید در کمترین زمان ایرادهای فنی زیر ساخت های نرم افزاری خود را رفع نمایید.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className='xl:hidden mt-5'>
|
||||||
|
<Tabs
|
||||||
|
items={data?.data?.supportPlans?.map((plan: PlanItemType, index: number) => ({
|
||||||
|
icon: index === 0 ? <Component color={activeTab === plan.id ? 'black' : '#8C90A3'} size={22} /> : index === 1 ? <Crown color={activeTab === plan.id ? 'black' : '#8C90A3'} size={22} /> : <Building 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 flex flex-col flex-1 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'>
|
||||||
|
{item.price === 0 ? 'رایگان' : NumberFormat(item.price)}
|
||||||
|
</div>
|
||||||
|
<div className='mt-1 text-sm'>
|
||||||
|
{item.price === 0 ? ' ' : 'تومان'}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* <div className='flex-1 flex items-end'>
|
||||||
|
<BuyPlan
|
||||||
|
id={item.id}
|
||||||
|
/>
|
||||||
|
</div> */}
|
||||||
|
</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 key={row.featureKey} 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}
|
||||||
|
{row.featureKey === 'ticket_limit' && ' (روزانه)'}
|
||||||
|
</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'>{plan.price === 0 ? 'رایگان' : NumberFormat(plan.price)}</div>
|
||||||
|
<div className='mt-1 text-sm'>{plan.price === 0 ? ' ' : 'تومان'}</div>
|
||||||
|
{/* <BuyPlan
|
||||||
|
id={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'>
|
||||||
|
<SupportIcon keySupport={row.featureKey as SupportPlanFeatureKey} />
|
||||||
|
</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}
|
||||||
|
{row.featureKey === 'ticket_limit' && ' (روزانه)'}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<SidebarHint />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex flex-col gap-4 mt-10'>
|
||||||
|
<Accordion title='آیا امکان ارتقای بستهی پشتیبانی به پلنهای بالاتر وجود دارد؟' content='بله، شما میتوانید با انتخاب بستههای بالاتر به طیف گستردهتری از خدمات پشتیبانی داناک مانند: پاسخگویی در کمتر از ۲ ساعت، دسترسی به متخصصین فنی و … دسترسی داشته باشید.' />
|
||||||
|
<Accordion title='آیا امکان بازگشت به بستههای پایینتر وجود دارد؟' content='بستههای مختلف خدمات پشتیبانی بهشکل سالیانه ارایه می شوند و شما از تاریخ خرید یا فعالسازی پلن خود، تا ابتدای سال بعد امکان بازگشت به بستهی پایینتر را نخواهید داشت.' />
|
||||||
|
<Accordion title='آیا خدمات پشتیبانی منطبق با سازمان من ارایه میشود؟' content='بله، شما با استفاده از خدمات سازمانی داناک میتوانید به طیف گستردهای از خدمات پشتیبانی دسترسی داشته باشید و در کمترین زمان ممکن مشکلات و چالشهای نرم افزاری کسبوکار خود را برطرف کنید. ' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SupportInfo
|
||||||
@@ -30,6 +30,7 @@ import MyDiscountList from '../pages/discounts/List'
|
|||||||
import LearningDetail from '../pages/learning/Detail'
|
import LearningDetail from '../pages/learning/Detail'
|
||||||
import BuyService from '../pages/service/BuyService'
|
import BuyService from '../pages/service/BuyService'
|
||||||
import Support from '../pages/support/Support'
|
import Support from '../pages/support/Support'
|
||||||
|
import SupportInfo from '../pages/support/SupportInfo'
|
||||||
|
|
||||||
const MainRouter: FC = () => {
|
const MainRouter: FC = () => {
|
||||||
return (
|
return (
|
||||||
@@ -42,6 +43,7 @@ const MainRouter: FC = () => {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route path={Pages.dashboard} element={<Home />} />
|
<Route path={Pages.dashboard} element={<Home />} />
|
||||||
<Route path={Pages.support.index} element={<Support />} />
|
<Route path={Pages.support.index} element={<Support />} />
|
||||||
|
<Route path={Pages.support.info} element={<SupportInfo />} />
|
||||||
<Route path={Pages.services.mine} element={<MyServices />} />
|
<Route path={Pages.services.mine} element={<MyServices />} />
|
||||||
<Route path={Pages.services.other} element={<OtherServices />} />
|
<Route path={Pages.services.other} element={<OtherServices />} />
|
||||||
<Route path={Pages.services.detail + ':id'} element={<DetailService />} />
|
<Route path={Pages.services.detail + ':id'} element={<DetailService />} />
|
||||||
|
|||||||
Reference in New Issue
Block a user