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}
|
||||
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 (
|
||||
<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',
|
||||
|
||||
@@ -38,5 +38,6 @@ export const Pages = {
|
||||
financial: "/financial",
|
||||
support: {
|
||||
index: "/support",
|
||||
info: "/support/info",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Helmet } from 'react-helmet-async'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import SidebarHint from './components/SidebarHint'
|
||||
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 { useGetSupportPlans } from './hooks/useSupportData'
|
||||
import { NumberFormat } from '../../config/func'
|
||||
@@ -12,6 +12,8 @@ import SupportSkeleton from './components/SupportSkeleton'
|
||||
import SupportIcon from './components/SupportIcon'
|
||||
import { SupportPlanFeatureKey } from './enum/SupportEnum'
|
||||
import BuyPlan from './components/BuyPlan'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Pages } from '../../config/Pages'
|
||||
|
||||
const Support: FC = () => {
|
||||
const { data, isLoading } = useGetSupportPlans()
|
||||
@@ -36,8 +38,15 @@ const Support: FC = () => {
|
||||
داناک | {t('support.title')}
|
||||
</title>
|
||||
</Helmet>
|
||||
<div>
|
||||
<div className='flex justify-between items-center'>
|
||||
{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 className='xl:hidden mt-5'>
|
||||
@@ -142,8 +151,8 @@ const Support: FC = () => {
|
||||
<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>
|
||||
<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}
|
||||
/>
|
||||
|
||||
@@ -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 BuyService from '../pages/service/BuyService'
|
||||
import Support from '../pages/support/Support'
|
||||
import SupportInfo from '../pages/support/SupportInfo'
|
||||
|
||||
const MainRouter: FC = () => {
|
||||
return (
|
||||
@@ -42,6 +43,7 @@ const MainRouter: FC = () => {
|
||||
<Routes>
|
||||
<Route path={Pages.dashboard} element={<Home />} />
|
||||
<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.other} element={<OtherServices />} />
|
||||
<Route path={Pages.services.detail + ':id'} element={<DetailService />} />
|
||||
|
||||
Reference in New Issue
Block a user