box services

This commit is contained in:
hamid zarghami
2025-03-04 10:16:47 +03:30
parent 23d19208b9
commit 002e420d85
6 changed files with 85 additions and 78 deletions
+20 -6
View File
@@ -9,7 +9,8 @@ import { ItemServiceType } from '../pages/service/types/ServiecTypes'
type Props = { type Props = {
item: ItemServiceType, item: ItemServiceType,
className?: string, className?: string,
isLinkPanel?: boolean isLinkPanel?: boolean,
businessName?: string
} }
const ServiceItem: FC<Props> = (props: Props) => { const ServiceItem: FC<Props> = (props: Props) => {
@@ -18,13 +19,21 @@ const ServiceItem: FC<Props> = (props: Props) => {
const { item } = props const { item } = props
return ( return (
<div className={`flex-1 min-w-[45%] xl:min-w-[30%] bg-white rounded-3xl xl:p-6 p-4 ${props.className}`}> <div className={`flex-1 flex flex-col self-stretch min-w-[45%] xl:min-w-[30%] bg-white rounded-3xl xl:p-6 p-4 ${props.className}`}>
<div className='flex gap-2 items-center'> <div className='flex gap-2 items-center'>
<div className='xl:size-[50px] size-10 overflow-hidden rounded-xl'> <div className='xl:size-[50px] size-10 overflow-hidden rounded-xl'>
<img src={item.icon} alt={item.name} className='w-full h-full' /> <img src={item.icon} alt={item.name} className='w-full h-full' />
</div> </div>
<div className='xl:text-base text-sm'> <div className='flex flex-col'>
{item.name} <div className='xl:text-base text-sm'>
{item.name}
</div>
{
props.isLinkPanel &&
<div className='text-xs text-description'>
{props.businessName}
</div>
}
</div> </div>
</div> </div>
<div className='mt-4 text-xs'> <div className='mt-4 text-xs'>
@@ -32,12 +41,17 @@ const ServiceItem: FC<Props> = (props: Props) => {
</div> </div>
<div className='mt-4 flex-1 flex items-end'> <div className='mt-4 flex-1 flex items-end'>
<Link to={Pages.services.detail + item.id}> <Link target={props.isLinkPanel ? '_blank' : ''} to={props.isLinkPanel ? item.link : Pages.services.detail + item.id}>
<Button <Button
className='h-8 w-fit px-5 text-xs text-black bg-description bg-opacity-20 rounded-xl' className='h-8 w-fit px-5 text-xs text-black bg-description bg-opacity-20 rounded-xl'
> >
<div className='flex gap-2 whitespace-nowrap'> <div className='flex gap-2 whitespace-nowrap'>
<div>{t('service.detail')}</div> {
props.isLinkPanel ?
t('panel_service')
:
t('service.detail')
}
<ArrowLeft color='black' size={16} /> <ArrowLeft color='black' size={16} />
</div> </div>
</Button> </Button>
+3 -2
View File
@@ -94,6 +94,7 @@
"not_active_service": "شما هنوز سرویس فعالی ندارید", "not_active_service": "شما هنوز سرویس فعالی ندارید",
"detail": "جزییات بیشتر" "detail": "جزییات بیشتر"
}, },
"panel_service": "پنل سرویس",
"all": "همه", "all": "همه",
"service": { "service": {
"my_service": "سرویس های من", "my_service": "سرویس های من",
@@ -206,11 +207,11 @@
"company_name": "نام شرکت/ سازمان :", "company_name": "نام شرکت/ سازمان :",
"registration_number": "شماره ثبت :", "registration_number": "شماره ثبت :",
"tel_company": "تلفن شرکت :", "tel_company": "تلفن شرکت :",
"national_code": "کد ملی نماینده :", "national_code": " شناسه ملی :",
"postal_code": "کد پستی :", "postal_code": "کد پستی :",
"state": "استان :", "state": "استان :",
"city": "شهر :", "city": "شهر :",
"address": "آدرس :", "address": "آدرس ثبتی :",
"detail_receip": "مشخصات صورتحساب", "detail_receip": "مشخصات صورتحساب",
"not_paid": "پرداخت نشده", "not_paid": "پرداخت نشده",
"description": "توضیحات", "description": "توضیحات",
+6 -3
View File
@@ -144,9 +144,12 @@ const Notifications: FC = () => {
{ {
posts.map((item: NotificationItemType) => ( posts.map((item: NotificationItemType) => (
<div onClick={() => handleRedirect(item.type)} className="bg-white cursor-pointer h-fit gap-4 items-start rounded-xl bg-opacity-60 p-3 mb-4 flex" key={item.id}> <div onClick={() => handleRedirect(item.type)} className="bg-white cursor-pointer h-fit gap-4 items-start rounded-xl bg-opacity-60 p-3 mb-4 flex" key={item.id}>
<div className="mt-1"> {
<StatusCircle color="#00BA4B" /> !item.isRead &&
</div> <div className="mt-1">
<StatusCircle color="#00BA4B" />
</div>
}
<div> <div>
<div className="truncate max-w-[200px]">{item.message}</div> <div className="truncate max-w-[200px]">{item.message}</div>
<div className="mt-2 flex gap-2 text-[10px] text-description"> <div className="mt-2 flex gap-2 text-[10px] text-description">
+7 -43
View File
@@ -1,15 +1,13 @@
import { FC, useState } from 'react' import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import Input from '../../components/Input' import Input from '../../components/Input'
import ServiceSection from '../../components/ServiceSection'
import StatusCircle from '../../components/StatusCircle'
import { useGetMyServices } from './hooks/useServiceData' import { useGetMyServices } from './hooks/useServiceData'
import { MyServicesItem } from './types/ServiecTypes' import { MyServicesItem } from './types/ServiecTypes'
import { useGetAds } from '../ads/hooks/useAdsData' import { useGetAds } from '../ads/hooks/useAdsData'
import { AdsDisplayLocation } from '../ads/types/AdsTypes' import { AdsDisplayLocation } from '../ads/types/AdsTypes'
import { Helmet } from 'react-helmet-async' import { Helmet } from 'react-helmet-async'
import ServiceItemSkeleton from './components/ServiceItemSkeleton' import ServiceItemSkeleton from './components/ServiceItemSkeleton'
import { clx } from '../../helpers/utils' import ServiceItem from '../../components/ServiceItem'
const MyServices: FC = () => { const MyServices: FC = () => {
@@ -59,46 +57,12 @@ const MyServices: FC = () => {
: :
getServices.data?.data?.subscriptions?.map((item: MyServicesItem) => { getServices.data?.data?.subscriptions?.map((item: MyServicesItem) => {
return ( return (
<a target='_blank' key={item.id} href={item.status === 'ACTIVE' ? item.plan.service.link + item.id : '#'} className={clx( <ServiceItem
'flex-1 min-w-[40%] xl:min-w-[20%] bg-white rounded-3xl p-6 flex flex-col items-center self-stretch', key={item.id}
item.status === 'INACTIVE' && 'opacity-50' item={item.plan.service}
)}> isLinkPanel
<div className="flex-grow"> businessName={item.businessName}
<ServiceSection />
item={{
author: item.plan.service.author,
createDate: item.plan?.service?.createDate,
createdAt: item.createdAt,
description: item.plan?.service?.title,
icon: item.plan?.service.icon,
id: item.plan.service.id,
isActive: item.plan.isActive,
isDanakSuggest: item.plan.service.isDanakSuggest,
link: item.plan.service.link,
metaDescription: item.plan.service.metaDescription,
name: item.plan.service.name,
serviceLanguage: item.plan.service.serviceLanguage,
softwareLanguage: item.plan.service.softwareLanguage,
updatedAt: item.plan.service.updatedAt,
userCount: item.plan.service?.userCount,
title: item.plan.service.title,
}}
/>
</div>
<div className='mt-6 flex gap-1 items-center'>
<StatusCircle
color={item.status === 'ACTIVE' ? '#00BA4B' : '#FF0000'}
/>
<div className='text-xs text-description'>
{
item.status === 'ACTIVE' ?
t('active')
:
t('inactive')
}
</div>
</div>
</a>
) )
}) })
} }
+48 -24
View File
@@ -5,11 +5,7 @@ import { useGetCategoriesPublic, useGetServicesByCategory } from '../hooks/useSe
import { SwiperSlide, Swiper } from 'swiper/react' import { SwiperSlide, Swiper } from 'swiper/react'
import { CategoryItemType, ItemServiceType } from '../types/ServiecTypes' import { CategoryItemType, ItemServiceType } from '../types/ServiecTypes'
import { clx } from '../../../helpers/utils' import { clx } from '../../../helpers/utils'
import ServiceSection from '../../../components/ServiceSection' import ServiceItem from '../../../components/ServiceItem'
import { Link } from 'react-router-dom'
import Button from '../../../components/Button'
import { ArrowLeft } from 'iconsax-react'
import { Pages } from '../../../config/Pages'
const OtherServicesComponent: FC = () => { const OtherServicesComponent: FC = () => {
@@ -62,31 +58,59 @@ const OtherServicesComponent: FC = () => {
{ {
getServices.data?.data?.services?.map((item: ItemServiceType) => { getServices.data?.data?.services?.map((item: ItemServiceType) => {
return ( return (
<div className='flex-1 min-w-full xl:min-w-0 bg-white rounded-3xl py-4 px-6 '> <ServiceItem
<div className='flex flex-col gap-2 justify-between items-center'> key={item.id}
<ServiceSection item={item}
item={item} />
/>
<Link to={Pages.services.detail + item.id}>
<Button
className='h-8 w-fit px-2 text-xs text-black bg-description bg-opacity-20 rounded-xl'
>
<div className='flex gap-2'>
<div className='whitespace-nowrap'>{t('service.buy')}</div>
<ArrowLeft color='black' size={16} />
</div>
</Button>
</Link>
</div>
</div>
) )
}) })
} }
<div className='flex-1 min-w-[40%] xl:min-w-[30%] xl:p-6 p-4'></div>
</div> </div>
</div> </div>
</div>
{/* <a target='_blank' key={item.id} href={item.status === 'ACTIVE' ? item.plan.service.link + item.id : '#'} className={clx(
'flex-1 min-w-[40%] xl:min-w-[20%] bg-white rounded-3xl p-6 flex flex-col items-center self-stretch',
item.status === 'INACTIVE' && 'opacity-50'
)}>
<div className="flex-grow">
<ServiceSection
item={{
author: item.plan.service.author,
createDate: item.plan?.service?.createDate,
createdAt: item.createdAt,
description: item.plan?.service?.title,
icon: item.plan?.service.icon,
id: item.plan.service.id,
isActive: item.plan.isActive,
isDanakSuggest: item.plan.service.isDanakSuggest,
link: item.plan.service.link,
metaDescription: item.plan.service.metaDescription,
name: item.plan.service.name,
serviceLanguage: item.plan.service.serviceLanguage,
softwareLanguage: item.plan.service.softwareLanguage,
updatedAt: item.plan.service.updatedAt,
userCount: item.plan.service?.userCount,
title: item.plan.service.title,
}}
/>
</div>
<div className='mt-6 flex gap-1 items-center'>
<StatusCircle
color={item.status === 'ACTIVE' ? '#00BA4B' : '#FF0000'}
/>
<div className='text-xs text-description'>
{
item.status === 'ACTIVE' ?
t('active')
:
t('inactive')
}
</div>
</div>
</a> */}
</div >
) )
} }
+1
View File
@@ -81,6 +81,7 @@ export type MyServicesItem = {
endDate: string; endDate: string;
id: string; id: string;
isCanceled: boolean; isCanceled: boolean;
businessName: string;
plan: { plan: {
id: string; id: string;
createdAt: string; createdAt: string;