pixel perfect
This commit is contained in:
@@ -17,7 +17,7 @@ const ServiceSection: FC<Props> = (props: Props) => {
|
|||||||
{item.name}
|
{item.name}
|
||||||
</div>
|
</div>
|
||||||
<div className='text-xs text-description'>
|
<div className='text-xs text-description'>
|
||||||
{item.description}
|
{item.title}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -225,3 +225,13 @@ tbody tr {
|
|||||||
animation: shimmer 5s infinite;
|
animation: shimmer 5s infinite;
|
||||||
content: "";
|
content: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
scrollbar-width: none; /* برای فایرفاکس */
|
||||||
|
-ms-overflow-style: none; /* برای اینترنت اکسپلورر و اج */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* برای Webkit (کروم، سافاری و اپرا) */
|
||||||
|
*::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ const Home: FC = () => {
|
|||||||
getAds.data?.data?.ads?.map((item: AdsItemType) => {
|
getAds.data?.data?.ads?.map((item: AdsItemType) => {
|
||||||
return (
|
return (
|
||||||
<div key={item.id} className='relative drtl'>
|
<div key={item.id} className='relative drtl'>
|
||||||
<img src={item.imageUrl} className='w-full max-h-[300px] h-full object-cover rounded-3xl' />
|
<img src={item.imageUrl} className='w-full min-h-[190px] max-h-[300px] h-full object-cover rounded-3xl' />
|
||||||
<div className='absolute bg-black bg-opacity-20 size-full top-0 right-0 py-6 px-8 flex flex-col justify-between'>
|
<div className='absolute bg-black bg-opacity-20 size-full top-0 right-0 py-6 px-8 flex flex-col justify-between'>
|
||||||
<button className="px-8 w-fit py-1.5 bg-white bg-opacity-10 text-white text-sm rounded-full shadow-md ">
|
<button className="px-8 w-fit py-1.5 bg-white bg-opacity-10 text-white text-sm rounded-full shadow-md ">
|
||||||
{t('home.new')}
|
{t('home.new')}
|
||||||
@@ -120,9 +120,9 @@ const Home: FC = () => {
|
|||||||
<div className='mt-8 flex flex-wrap gap-6 items-stretch'>
|
<div className='mt-8 flex flex-wrap gap-6 items-stretch'>
|
||||||
{
|
{
|
||||||
getQuikAccess?.data?.data?.quickAccesses?.length === 0 &&
|
getQuikAccess?.data?.data?.quickAccesses?.length === 0 &&
|
||||||
<div className='flex-1 min-w-[40%] xl:min-w-[20%] min-h-[152px] rounded-3xl bg-white flex flex-col gap-4 justify-center items-center'>
|
<div className='flex-1 min-w-[40%] xl:!min-w-[20%] xl:p-6 p-4 min-h-[152px] rounded-3xl bg-white flex flex-col gap-4 justify-center items-center'>
|
||||||
<img src={AccessbilityImage} className='w-10' />
|
<img src={AccessbilityImage} className='w-10' />
|
||||||
<div className='text-xs'>
|
<div className='text-xs text-center'>
|
||||||
{t('home.add_access')}
|
{t('home.add_access')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ const CallBack: FC = () => {
|
|||||||
<div>
|
<div>
|
||||||
{t('callback.order_number')}
|
{t('callback.order_number')}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className='text-left'>
|
||||||
{params.id}
|
{params.id}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ const BuyService: FC = () => {
|
|||||||
}),
|
}),
|
||||||
onSubmit: (values) => {
|
onSubmit: (values) => {
|
||||||
buyService.mutate(values, {
|
buyService.mutate(values, {
|
||||||
onSuccess: () => {
|
onSuccess: (data) => {
|
||||||
toast.success(t('success'))
|
toast.success(t('success'))
|
||||||
navigate(Pages.receipts.index)
|
navigate(Pages.receipts.detail + data?.data?.invoice?.id)
|
||||||
},
|
},
|
||||||
onError: (error: ErrorType) => {
|
onError: (error: ErrorType) => {
|
||||||
toast.error(error.response?.data?.error.message[0])
|
toast.error(error.response?.data?.error.message[0])
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const OtherServices: FC = () => {
|
|||||||
getAds.data?.data?.ads?.map((item: AdsItemType) => {
|
getAds.data?.data?.ads?.map((item: AdsItemType) => {
|
||||||
return (
|
return (
|
||||||
<a target='_blank' key={item.id} className='relative drtl'>
|
<a target='_blank' key={item.id} className='relative drtl'>
|
||||||
<img src={item.imageUrl} className='w-full max-h-[300px] h-full object-cover rounded-3xl' />
|
<img src={item.imageUrl} className='w-full min-h-[190px] max-h-[300px] h-full object-cover rounded-3xl' />
|
||||||
<div className='absolute bg-black bg-opacity-20 size-full top-0 right-0 py-6 px-8 flex flex-col justify-between'>
|
<div className='absolute bg-black bg-opacity-20 size-full top-0 right-0 py-6 px-8 flex flex-col justify-between'>
|
||||||
<button className="px-8 w-fit py-1.5 bg-white bg-opacity-10 text-white text-sm rounded-full shadow-md ">
|
<button className="px-8 w-fit py-1.5 bg-white bg-opacity-10 text-white text-sm rounded-full shadow-md ">
|
||||||
{t('home.new')}
|
{t('home.new')}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ const HeaderBuy: FC<Props> = ({ data, planId }) => {
|
|||||||
const { t } = useTranslation('global')
|
const { t } = useTranslation('global')
|
||||||
const [planSelected] = useState<string>(planId ? planId : '')
|
const [planSelected] = useState<string>(planId ? planId : '')
|
||||||
const [price, setPrice] = useState<number>(data?.subscriptionPlans[0]?.price)
|
const [price, setPrice] = useState<number>(data?.subscriptionPlans[0]?.price)
|
||||||
const [finalPrice, setFinalPrice] = useState<number>(0)
|
|
||||||
const [planText, setPlanText] = useState<string>('')
|
const [planText, setPlanText] = useState<string>('')
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -25,7 +24,6 @@ const HeaderBuy: FC<Props> = ({ data, planId }) => {
|
|||||||
const plan = data?.subscriptionPlans.find((item) => item.id === planSelected)
|
const plan = data?.subscriptionPlans.find((item) => item.id === planSelected)
|
||||||
|
|
||||||
setPlanText(plan.name)
|
setPlanText(plan.name)
|
||||||
setFinalPrice(plan.finalPrice)
|
|
||||||
setPrice(plan?.price)
|
setPrice(plan?.price)
|
||||||
|
|
||||||
}, [data])
|
}, [data])
|
||||||
@@ -68,13 +66,13 @@ const HeaderBuy: FC<Props> = ({ data, planId }) => {
|
|||||||
<div className='flex gap-4 mt-5 xl:mt-0 items-center justify-between xl:justify-normal'>
|
<div className='flex gap-4 mt-5 xl:mt-0 items-center justify-between xl:justify-normal'>
|
||||||
<div className='text-xs whitespace-nowrap flex gap-1 items-center'>
|
<div className='text-xs whitespace-nowrap flex gap-1 items-center'>
|
||||||
<div className='flex gap-2'>
|
<div className='flex gap-2'>
|
||||||
{
|
{/* {
|
||||||
finalPrice !== price &&
|
finalPrice !== price &&
|
||||||
<div className='line-through text-xs text-description'>
|
<div className='line-through text-xs text-description'>
|
||||||
{NumberFormat(Number(price))}
|
{NumberFormat(Number(price))}
|
||||||
</div>
|
</div>
|
||||||
}
|
} */}
|
||||||
<div>{NumberFormat(Number(finalPrice))}</div>
|
<div>{NumberFormat(Number(price))}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { FC, useEffect, useState } from 'react'
|
import { FC, useState } from 'react'
|
||||||
import TitleLine from '../../../components/TitleLine'
|
import TitleLine from '../../../components/TitleLine'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useGetCategoriesPublic, useGetServicesByCategory } from '../hooks/useServiceData'
|
import { useGetCategoriesPublic, useGetServicesByCategory } from '../hooks/useServiceData'
|
||||||
@@ -18,19 +18,6 @@ const OtherServicesComponent: FC = () => {
|
|||||||
const getCategory = useGetCategoriesPublic()
|
const getCategory = useGetCategoriesPublic()
|
||||||
const getServices = useGetServicesByCategory(categoryId)
|
const getServices = useGetServicesByCategory(categoryId)
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
|
|
||||||
if (getCategory.data) {
|
|
||||||
setCategoryId(getCategory?.data?.data?.categories[0]?.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
}, [getCategory.data])
|
|
||||||
|
|
||||||
console.log('services', getServices.data?.data?.category?.danakServices
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className='w-full mt-8'>
|
<div className='w-full mt-8'>
|
||||||
@@ -43,6 +30,14 @@ const OtherServicesComponent: FC = () => {
|
|||||||
spaceBetween={15} // فاصله پیشفرض بین اسلایدها
|
spaceBetween={15} // فاصله پیشفرض بین اسلایدها
|
||||||
slidesPerView='auto'
|
slidesPerView='auto'
|
||||||
>
|
>
|
||||||
|
<SwiperSlide className='max-w-[158px]'>
|
||||||
|
<div onClick={() => setCategoryId('')} className={clx(
|
||||||
|
'h-10 cursor-pointer rounded-full border-2 border-white bg-white/45 flex gap-2 justify-center items-center',
|
||||||
|
'' === categoryId && 'bg-white'
|
||||||
|
)}>
|
||||||
|
<div className='text-sm'>{t('all')}</div>
|
||||||
|
</div>
|
||||||
|
</SwiperSlide>
|
||||||
{
|
{
|
||||||
getCategory.data?.data?.categories?.map((item: CategoryItemType) => {
|
getCategory.data?.data?.categories?.map((item: CategoryItemType) => {
|
||||||
return (
|
return (
|
||||||
@@ -65,7 +60,7 @@ const OtherServicesComponent: FC = () => {
|
|||||||
<div className='flex w-full gap-6 items-center'>
|
<div className='flex w-full gap-6 items-center'>
|
||||||
<div className='flex w-full flex-wrap xl:gap-6 gap-4 items-center mt-8'>
|
<div className='flex w-full flex-wrap xl:gap-6 gap-4 items-center mt-8'>
|
||||||
{
|
{
|
||||||
getServices.data?.data?.category?.danakServices?.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'>
|
<div className='flex-1 min-w-full xl:min-w-0 bg-white rounded-3xl py-4 px-6'>
|
||||||
<div className='flex gap-2 justify-between items-center'>
|
<div className='flex gap-2 justify-between items-center'>
|
||||||
@@ -77,7 +72,7 @@ const OtherServicesComponent: FC = () => {
|
|||||||
className='h-8 w-fit px-2 text-xs text-black bg-description bg-opacity-20 rounded-xl'
|
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='flex gap-2'>
|
||||||
<div className='whitespace-nowrap'>{t('service.detail')}</div>
|
<div className='whitespace-nowrap'>{t('service.buy')}</div>
|
||||||
<ArrowLeft color='black' size={16} />
|
<ArrowLeft color='black' size={16} />
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const ServiceHeader: FC<Props> = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<div className='w-full p-6 bg-white rounded-3xl flex xl:flex-row flex-col items-end xl:justify-between'>
|
<div className='w-full p-6 bg-white rounded-3xl flex xl:flex-row flex-col items-end xl:justify-between'>
|
||||||
<div className='flex xl:gap-8 gap-4'>
|
<div className='flex xl:gap-8 gap-4'>
|
||||||
<div className='xl:size-[70px] size-[50px] rounded-xl'>
|
<div className='xl:size-[70px] min-w-[50px] size-[50px] rounded-xl'>
|
||||||
<img src={data?.icon} className='w-full h-full rounded-xl' />
|
<img src={data?.icon} className='w-full h-full rounded-xl' />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -66,7 +66,7 @@ const ServiceHeader: FC<Props> = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='flex flex-col justify-between xl:items-end'>
|
<div className='flex w-full flex-col justify-between xl:items-end'>
|
||||||
<div className='xl:hidden flex gap-5 mt-5'>
|
<div className='xl:hidden flex gap-5 mt-5'>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
items={data?.subscriptionPlans?.map((item) => {
|
items={data?.subscriptionPlans?.map((item) => {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ export const useGetServicesByCategory = (categoryId: string) => {
|
|||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ["services-category", categoryId],
|
queryKey: ["services-category", categoryId],
|
||||||
queryFn: () => api.getServicesByCategory(categoryId),
|
queryFn: () => api.getServicesByCategory(categoryId),
|
||||||
enabled: !!categoryId,
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,11 @@ export const getCategoriesPublic = async () => {
|
|||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
export const getServicesByCategory = async (categoryId: string) => {
|
export const getServicesByCategory = async (categoryId: string) => {
|
||||||
const { data } = await axios.get(
|
let query = ``;
|
||||||
`/danak-services/categories/${categoryId}/services`
|
if (categoryId) {
|
||||||
);
|
query = `?categoryId=${categoryId}`;
|
||||||
|
}
|
||||||
|
const { data } = await axios.get(`/danak-services/public${query}`);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export type ItemServiceType = {
|
|||||||
softwareLanguage: string;
|
softwareLanguage: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
userCount: number;
|
userCount: number;
|
||||||
|
title: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CategoryItemType = {
|
export type CategoryItemType = {
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ const MainRouter: FC = () => {
|
|||||||
<Header />
|
<Header />
|
||||||
<div className='flex-1 xl:ms-[269px] mt-[68px] xl:mt-[81px]'>
|
<div className='flex-1 xl:ms-[269px] mt-[68px] xl:mt-[81px]'>
|
||||||
<div className={`overflow-auto w-[${window.innerWidth}] max-h-[calc(100vh-113px)]`}>
|
<div className={`overflow-auto w-[${window.innerWidth}] max-h-[calc(100vh-113px)]`}>
|
||||||
<div className='pb-20'>
|
<div className='xl:pb-20 pb-32'>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path={Pages.dashboard} element={<Home />} />
|
<Route path={Pages.dashboard} element={<Home />} />
|
||||||
<Route path={Pages.services.mine} element={<MyServices />} />
|
<Route path={Pages.services.mine} element={<MyServices />} />
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const Footer: FC = () => {
|
|||||||
return (
|
return (
|
||||||
<div className='xl:hidden'>
|
<div className='xl:hidden'>
|
||||||
<div className='h-[60px] '></div>
|
<div className='h-[60px] '></div>
|
||||||
<div className='fixed z-50 bottom-2 right-3 left-3 bg-white h-[60px] rounded-2xl flex justify-between items-center px-3'>
|
<div className='fixed z-10 bottom-2 right-3 left-3 bg-white h-[60px] rounded-2xl flex justify-between items-center px-3'>
|
||||||
<Link to={Pages.dashboard}>
|
<Link to={Pages.dashboard}>
|
||||||
<div className={`text-description w-[70px] flex flex-col items-center gap-1.5 ${isActive(Pages.dashboard) ? 'text-black' : ''}`}>
|
<div className={`text-description w-[70px] flex flex-col items-center gap-1.5 ${isActive(Pages.dashboard) ? 'text-black' : ''}`}>
|
||||||
<Home2
|
<Home2
|
||||||
|
|||||||
Reference in New Issue
Block a user