responsive danak-services

This commit is contained in:
hamid zarghami
2025-04-15 10:22:38 +03:30
parent 6320cc0784
commit 9bba9156a3
14 changed files with 362 additions and 269 deletions
+12 -12
View File
@@ -9,7 +9,7 @@
"version": "0.1.0",
"dependencies": {
"@tanstack/react-query": "^5.73.3",
"@tanstack/react-query-devtools": "^5.73.3",
"@tanstack/react-query-devtools": "^5.74.3",
"axios": "^1.8.4",
"iconsax-react": "^0.0.8",
"js-cookie": "^3.0.5",
@@ -1119,9 +1119,9 @@
}
},
"node_modules/@tanstack/query-core": {
"version": "5.73.3",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.73.3.tgz",
"integrity": "sha512-LUpsgVT3IkvOECdkQ3QD6esczSH71mAzH/LDZ2cu8j6w430v5W0JB1ulzsG8FFwFBd5fm/ePM2DFpg9TucRMgQ==",
"version": "5.74.3",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.74.3.tgz",
"integrity": "sha512-Mqk+5o3qTuAiZML248XpNH8r2cOzl15+LTbUsZQEwvSvn1GU4VQhvqzAbil36p+MBxpr/58oBSnRzhrBevDhfg==",
"license": "MIT",
"funding": {
"type": "github",
@@ -1139,12 +1139,12 @@
}
},
"node_modules/@tanstack/react-query": {
"version": "5.73.3",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.73.3.tgz",
"integrity": "sha512-umsAEsVsSSnrOZrstX/OlctdqkRZm6vPsetmbl241tdNo0jT3s+0bUoof9kCaTsPr/GopPlbJ1OYlrZj4toKzg==",
"version": "5.74.3",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.74.3.tgz",
"integrity": "sha512-QrycUn0wxjVPzITvQvOxFRdhlAwIoOQSuav7qWD4SWCoKCdLbyRZ2vji2GuBq/glaxbF4wBx3fqcYRDOt8KDTA==",
"license": "MIT",
"dependencies": {
"@tanstack/query-core": "5.73.3"
"@tanstack/query-core": "5.74.3"
},
"funding": {
"type": "github",
@@ -1155,9 +1155,9 @@
}
},
"node_modules/@tanstack/react-query-devtools": {
"version": "5.73.3",
"resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.73.3.tgz",
"integrity": "sha512-5YizhmYep/A9h5Z+aApHZd0rwNH3FQm6JzUQmdH+f8aG5joi2cRAq+3UakDH6wst2kysReEmW4n7PaMxfCEtRQ==",
"version": "5.74.3",
"resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.74.3.tgz",
"integrity": "sha512-H7TsOBB1fRCuuawrBzKMoIszqqILr2IN5oGLYMl7QG7ERJpMdc4hH8OwzBhVxJnmKeGwgtTQgcdKepfoJCWvFg==",
"license": "MIT",
"dependencies": {
"@tanstack/query-devtools": "5.73.3"
@@ -1167,7 +1167,7 @@
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"@tanstack/react-query": "^5.73.3",
"@tanstack/react-query": "^5.74.3",
"react": "^18 || ^19"
}
},
+1 -1
View File
@@ -10,7 +10,7 @@
},
"dependencies": {
"@tanstack/react-query": "^5.73.3",
"@tanstack/react-query-devtools": "^5.73.3",
"@tanstack/react-query-devtools": "^5.74.3",
"axios": "^1.8.4",
"iconsax-react": "^0.0.8",
"js-cookie": "^3.0.5",
+9 -9
View File
@@ -6,7 +6,7 @@ import React from 'react'
const DanakServices: NextPage = () => {
return (
<div className='mt-24'>
<div className='flex items-center justify-between max-w-maxWidth mx-auto'>
<div className='flex gap-y-4 flex-col xl:flex-row xl:items-center justify-between max-w-maxWidth mx-auto'>
<h1 className='text-2xl font-bold'>
خدمات داناک
</h1>
@@ -16,7 +16,7 @@ const DanakServices: NextPage = () => {
</div>
</div>
<div className='mt-20 flex gap-32 max-w-maxWidth mx-auto'>
<div className='mt-20 flex flex-col-reverse xl:flex-row gap-x-32 gap-y-12 max-w-maxWidth mx-auto'>
<div className='flex-1'>
<div className='flex gap-4 items-center'>
<div className="size-12 flex items-center justify-center bg-gradient-to-b from-[#f9fafc] to-[#f1f3f8] rounded-2xl shadow-[inset_4px_4px_6px_#e2e5ec,inset_-4px_-4px_6px_#ffffff] ">
@@ -36,7 +36,7 @@ const DanakServices: NextPage = () => {
</p>
</div>
<div className='flex-1 p-4 bg-white/23 rounded-4xl border-[3px] border-white'>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
@@ -49,13 +49,13 @@ const DanakServices: NextPage = () => {
<div className='w-full xl:py-32 py-20 bg-gradient-to-l from-[#eef0f6] via-[#e2e5ec] to-[#dee1e9] xl:mt-40 mt-12 rounded-4xl'>
<div className='max-w-maxWidth px-4 xl:px-0 mx-auto flex xl:flex-row flex-col items-center xl:gap-32 gap-14'>
<div className='flex-1 p-4 bg-white/23 rounded-4xl border-[3px] border-white'>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
width={300}
height={300}
className='w-full max-h-[300px] h-auto rounded-4xl'
className='min-w-full max-h-[300px] h-auto rounded-4xl'
/>
</div>
@@ -80,7 +80,7 @@ const DanakServices: NextPage = () => {
</div>
</div>
<div className='mt-20 flex gap-32 max-w-maxWidth mx-auto'>
<div className='mt-20 flex flex-col-reverse xl:flex-row gap-x-32 gap-y-12 max-w-maxWidth mx-auto'>
<div className='flex-1'>
<div className='flex gap-4 items-center'>
<div className="size-12 flex items-center justify-center bg-gradient-to-b from-[#f9fafc] to-[#f1f3f8] rounded-2xl shadow-[inset_4px_4px_6px_#e2e5ec,inset_-4px_-4px_6px_#ffffff] ">
@@ -100,7 +100,7 @@ const DanakServices: NextPage = () => {
</p>
</div>
<div className='flex-1 p-4 bg-white/23 rounded-4xl border-[3px] border-white'>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
@@ -113,13 +113,13 @@ const DanakServices: NextPage = () => {
<div className='w-full xl:py-32 py-20 bg-gradient-to-l from-[#eef0f6] via-[#e2e5ec] to-[#dee1e9] xl:mt-40 mt-12 rounded-4xl'>
<div className='max-w-maxWidth px-4 xl:px-0 mx-auto flex xl:flex-row flex-col items-center xl:gap-32 gap-14'>
<div className='flex-1 p-4 bg-white/23 rounded-4xl border-[3px] border-white'>
<div className='flex-1 xl:p-4 p-2 bg-white/23 rounded-4xl border-[3px] border-white'>
<Image
src='https://picsum.photos/seed/picsum/200/300'
alt='service-1'
width={300}
height={300}
className='w-full max-h-[300px] h-auto rounded-4xl'
className='min-w-full max-h-[300px] h-auto rounded-4xl'
/>
</div>
-74
View File
@@ -1,74 +0,0 @@
'use client'
import SectionHeader from '@/components/SectionHeader'
import ServiceItem from '@/components/ServiceItem'
import { clx } from '@/helpers/utils'
import { FC, useState } from 'react'
import { Swiper, SwiperSlide } from 'swiper/react'
import { useGetLanding } from './hooks/useHomeData'
const DanakServices: FC = () => {
const { data } = useGetLanding()
const [categoryId, setCategoryId] = useState<string>('')
return (
<div className='xl:mt-24 mt-12 max-w-maxWidth mx-auto'>
<SectionHeader
title='سرویس های داناک'
/>
<div className='mt-6'>
<Swiper
className='w-full'
spaceBetween={15}
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'>
همه
</div>
</div>
</SwiperSlide>
<SwiperSlide className='max-w-[158px]'>
<div onClick={() => setCategoryId('1')} className={clx(
'h-10 cursor-pointer rounded-full border-2 border-white bg-white/45 flex gap-2 justify-center items-center',
'1' === categoryId && 'bg-white'
)}>
<div className='size-5 rounded-full bg-blue-100'>
</div>
<div className='text-sm'>
ابزارهای کاربردی
</div>
</div>
</SwiperSlide>
</Swiper>
</div>
<div className='xl:mt-16 mt-10 flex flex-wrap gap-8'>
<div className='xl:min-w-[30%] min-w-[70%] flex-1'>
<ServiceItem
isShort
/>
</div>
<div className='xl:min-w-[30%] min-w-[70%] flex-1'>
<ServiceItem
isShort
/>
</div>
<div className='xl:min-w-[30%] min-w-[70%] flex-1'>
<ServiceItem
isShort
/>
</div>
</div>
</div>
)
}
export default DanakServices
-2
View File
@@ -1,14 +1,12 @@
import { useQuery } from "@tanstack/react-query";
import * as api from "../service/HomeService";
// برای client
export const useGetLanding = () =>
useQuery({
queryKey: ["landing"],
queryFn: api.getLanding,
});
// برای server prefetch
export const landingQueryOptions = {
queryKey: ["landing"],
queryFn: api.getLanding,
+2 -1
View File
@@ -1,5 +1,5 @@
import { Blog } from "@/app/blogs/types/BlogTypes";
import { ServiceCategoryType } from "@/app/products/types/ProductTypes";
export interface LandingResponse {
statusCode: number;
success: boolean;
@@ -40,4 +40,5 @@ export interface DanakSuggestService {
link: string;
icon: string;
deletedAt: string | null;
category: ServiceCategoryType;
}
+4
View File
@@ -6,6 +6,8 @@ import "@/assets/fonts/irancell/style.css";
import Header from "@/shared/Header";
import Footer from "@/shared/Footer";
import SideBar from "@/shared/SideBar";
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
import QueryProvider from "@/config/QueryProvider";
const geistSans = Geist({
@@ -40,6 +42,8 @@ export default function RootLayout({
{children}
<Footer />
</div>
<ReactQueryDevtools initialIsOpen={false} />
</QueryProvider>
</body>
</html>
+78
View File
@@ -0,0 +1,78 @@
'use client'
import SectionHeader from '@/components/SectionHeader'
import ServiceItem from '@/components/ServiceItem'
import { clx } from '@/helpers/utils'
import { FC, useState } from 'react'
import { Swiper, SwiperSlide } from 'swiper/react'
import { useGetCategories, useGetServicesByCategory } from './hooks/useProductData'
import Image from 'next/image'
const DanakServices: FC = () => {
const [categoryId, setCategoryId] = useState<string>('')
const { data: categories } = useGetCategories()
const { data } = useGetServicesByCategory(categoryId)
return (
<div className='xl:mt-24 mt-12 max-w-maxWidth mx-auto'>
<SectionHeader
title='سرویس های داناک'
/>
<div className='mt-6'>
<Swiper
className='w-full'
spaceBetween={15}
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'>
همه
</div>
</div>
</SwiperSlide>
{
categories?.data?.categories?.map((item) => {
return (
<SwiperSlide className='max-w-[158px]' key={item.id}>
<div onClick={() => setCategoryId(item.id)} className={clx(
'h-10 cursor-pointer rounded-full border-2 border-white bg-white/45 flex gap-2 justify-center items-center',
item.id === categoryId && 'bg-white'
)}>
<div className='size-5 rounded-full overflow-hidden bg-blue-100'>
<Image src={item.icon} alt={item.title} width={20} height={20} />
</div>
<div className='text-sm'>
{item.title}
</div>
</div>
</SwiperSlide>
)
})
}
</Swiper>
</div>
<div className='xl:mt-16 mt-10 flex flex-wrap gap-8'>
{data?.data?.services?.map((item) => {
return (
<div key={item.id} className='xl:min-w-[30%] min-w-[70%] flex-1'>
<ServiceItem
isShort
item={item}
/>
</div>
)
})}
<div className='xl:min-w-[30%] min-w-[70%] flex-1'></div>
<div className='xl:min-w-[30%] min-w-[70%] flex-1'></div>
</div>
</div>
)
}
export default DanakServices
+173
View File
@@ -0,0 +1,173 @@
'use client'
import { ArrowLeft } from 'iconsax-react'
import Image from 'next/image'
import { Swiper, SwiperSlide } from 'swiper/react'
import DanakSuggestedService from '../home/DanakSuggestedService'
import { FC } from 'react'
import DanakServices from './DanakServices'
const Products: FC = () => {
return (
<div className='max-w-maxWidth mx-auto'>
<div className='flex justify-between mt-20 items-center'>
<h1 className='text-2xl font-bold'>
محصولات
</h1>
<div className='max-w-[320px] text-sm leading-6 hidden xl:block text-center xl:text-right'>
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است
</div>
</div>
<div className='mt-20'>
<Swiper
className='w-full'
spaceBetween={15}
slidesPerView={'auto'}
>
<SwiperSlide className='xl:max-w-[45%] max-w-[90%]'>
<div className='rounded-4xl overflow-hidden relative'>
<Image
src='https://burgeraddict.fr/wp-content/uploads/2024/09/MSG-Smash-Burger-FT-RECIPE0124-d9682401f3554ef683e24311abdf342b.jpg'
alt='product'
width={1080}
height={1080}
className='w-full h-[400px] object-cover'
/>
<div className='absolute bottom-0 left-0 w-full modalGlass3 h-[150px] rounded-b-3xl text-white p-4'>
<div className='flex justify-between items-center'>
<h6 className='text-xs'>
منو دیجیتال رستوران
</h6>
<div className='h-8 bg-black text-white rounded-xl text-sm px-5 flex items-center'>
دسته بندی
</div>
</div>
<div className='mt-6 flex justify-between items-end'>
<div className='flex gap-4'>
<div className='size-14 bg-red-50 rounded-2xl'></div>
<div>
<h2 className='text-xl font-bold'>
دی منو
</h2>
<div className='mt-1'>
<h6 className='text-sm'>
داناک
</h6>
</div>
</div>
</div>
<div className='flex gap-1.5 text-sm items-center'>
<div>جزییات</div>
<ArrowLeft
size={20}
color='white'
/>
</div>
</div>
</div>
</div>
</SwiperSlide>
<SwiperSlide className='xl:max-w-[45%] max-w-[90%]'>
<div className='rounded-4xl overflow-hidden relative'>
<Image
src='https://burgeraddict.fr/wp-content/uploads/2024/09/MSG-Smash-Burger-FT-RECIPE0124-d9682401f3554ef683e24311abdf342b.jpg'
alt='product'
width={1080}
height={1080}
className='w-full h-[400px] object-cover'
/>
<div className='absolute bottom-0 left-0 w-full modalGlass3 h-[150px] rounded-b-3xl text-white p-4'>
<div className='flex justify-between items-center'>
<h6 className='text-xs'>
منو دیجیتال رستوران
</h6>
<div className='h-8 bg-black text-white rounded-xl text-sm px-5 flex items-center'>
دسته بندی
</div>
</div>
<div className='mt-6 flex justify-between items-end'>
<div className='flex gap-4'>
<div className='size-14 bg-red-50 rounded-2xl'></div>
<div>
<h2 className='text-xl font-bold'>
دی منو
</h2>
<div className='mt-1'>
<h6 className='text-sm'>
داناک
</h6>
</div>
</div>
</div>
<div className='flex gap-1.5 text-sm items-center'>
<div>جزییات</div>
<ArrowLeft
size={20}
color='white'
/>
</div>
</div>
</div>
</div>
</SwiperSlide>
<SwiperSlide className='xl:max-w-[45%] max-w-[90%]'>
<div className='rounded-4xl overflow-hidden relative'>
<Image
src='https://burgeraddict.fr/wp-content/uploads/2024/09/MSG-Smash-Burger-FT-RECIPE0124-d9682401f3554ef683e24311abdf342b.jpg'
alt='product'
width={1080}
height={1080}
className='w-full h-[400px] object-cover'
/>
<div className='absolute bottom-0 left-0 w-full modalGlass3 h-[150px] rounded-b-3xl text-white p-4'>
<div className='flex justify-between items-center'>
<h6 className='text-xs'>
منو دیجیتال رستوران
</h6>
<div className='h-8 bg-black text-white rounded-xl text-sm px-5 flex items-center'>
دسته بندی
</div>
</div>
<div className='mt-6 flex justify-between items-end'>
<div className='flex gap-4'>
<div className='size-14 bg-red-50 rounded-2xl'></div>
<div>
<h2 className='text-xl font-bold'>
دی منو
</h2>
<div className='mt-1'>
<h6 className='text-sm'>
داناک
</h6>
</div>
</div>
</div>
<div className='flex gap-1.5 text-sm items-center'>
<div>جزییات</div>
<ArrowLeft
size={20}
color='white'
/>
</div>
</div>
</div>
</div>
</SwiperSlide>
</Swiper>
</div>
<DanakSuggestedService />
<DanakServices />
</div>
)
}
export default Products
+24
View File
@@ -0,0 +1,24 @@
import { useQuery } from "@tanstack/react-query";
import * as api from "../service/ProductService";
export const useGetServicesByCategory = (categoryId?: string) =>
useQuery({
queryKey: ["services", categoryId],
queryFn: () => api.getServicesByCategory(categoryId),
});
export const servicesQueryOptions = {
queryKey: ["services", ""],
queryFn: () => api.getServicesByCategory(undefined),
};
export const useGetCategories = () =>
useQuery({
queryKey: ["service-categories"],
queryFn: () => api.getCategoriesPublic(),
});
export const categoriesQueryOptions = {
queryKey: ["service-categories"],
queryFn: () => api.getCategoriesPublic(),
};
+14 -168
View File
@@ -1,172 +1,18 @@
'use client'
import { ArrowLeft } from 'iconsax-react'
import Image from 'next/image'
import { FC } from 'react'
import { Swiper, SwiperSlide } from 'swiper/react'
import DanakSuggestedService from '../home/DanakSuggestedService'
import DanakServices from '../home/DanakServices'
const Products: FC = () => {
import { NextPage } from 'next'
import { HydrationBoundary } from '@tanstack/react-query'
import { dehydrate } from '@tanstack/react-query'
import { QueryClient } from '@tanstack/react-query'
import { categoriesQueryOptions, servicesQueryOptions } from './hooks/useProductData'
import Products from './Products'
const ProductsPage: NextPage = async () => {
const queryClient = new QueryClient()
await queryClient.prefetchQuery(servicesQueryOptions)
await queryClient.prefetchQuery(categoriesQueryOptions)
return (
<div className='max-w-maxWidth mx-auto'>
<div className='flex justify-between mt-20 items-center'>
<h1 className='text-2xl font-bold'>
محصولات
</h1>
<div className='max-w-[320px] text-sm leading-6 hidden xl:block text-center xl:text-right'>
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است
</div>
</div>
<div className='mt-20'>
<Swiper
className='w-full'
spaceBetween={15}
slidesPerView={'auto'}
>
<SwiperSlide className='xl:max-w-[45%] max-w-[90%]'>
<div className='rounded-4xl overflow-hidden relative'>
<Image
src='https://burgeraddict.fr/wp-content/uploads/2024/09/MSG-Smash-Burger-FT-RECIPE0124-d9682401f3554ef683e24311abdf342b.jpg'
alt='product'
width={1080}
height={1080}
className='w-full h-[400px] object-cover'
/>
<div className='absolute bottom-0 left-0 w-full modalGlass3 h-[150px] rounded-b-3xl text-white p-4'>
<div className='flex justify-between items-center'>
<h6 className='text-xs'>
منو دیجیتال رستوران
</h6>
<div className='h-8 bg-black text-white rounded-xl text-sm px-5 flex items-center'>
دسته بندی
</div>
</div>
<div className='mt-6 flex justify-between items-end'>
<div className='flex gap-4'>
<div className='size-14 bg-red-50 rounded-2xl'></div>
<div>
<h2 className='text-xl font-bold'>
دی منو
</h2>
<div className='mt-1'>
<h6 className='text-sm'>
داناک
</h6>
</div>
</div>
</div>
<div className='flex gap-1.5 text-sm items-center'>
<div>جزییات</div>
<ArrowLeft
size={20}
color='white'
/>
</div>
</div>
</div>
</div>
</SwiperSlide>
<SwiperSlide className='xl:max-w-[45%] max-w-[90%]'>
<div className='rounded-4xl overflow-hidden relative'>
<Image
src='https://burgeraddict.fr/wp-content/uploads/2024/09/MSG-Smash-Burger-FT-RECIPE0124-d9682401f3554ef683e24311abdf342b.jpg'
alt='product'
width={1080}
height={1080}
className='w-full h-[400px] object-cover'
/>
<div className='absolute bottom-0 left-0 w-full modalGlass3 h-[150px] rounded-b-3xl text-white p-4'>
<div className='flex justify-between items-center'>
<h6 className='text-xs'>
منو دیجیتال رستوران
</h6>
<div className='h-8 bg-black text-white rounded-xl text-sm px-5 flex items-center'>
دسته بندی
</div>
</div>
<div className='mt-6 flex justify-between items-end'>
<div className='flex gap-4'>
<div className='size-14 bg-red-50 rounded-2xl'></div>
<div>
<h2 className='text-xl font-bold'>
دی منو
</h2>
<div className='mt-1'>
<h6 className='text-sm'>
داناک
</h6>
</div>
</div>
</div>
<div className='flex gap-1.5 text-sm items-center'>
<div>جزییات</div>
<ArrowLeft
size={20}
color='white'
/>
</div>
</div>
</div>
</div>
</SwiperSlide>
<SwiperSlide className='xl:max-w-[45%] max-w-[90%]'>
<div className='rounded-4xl overflow-hidden relative'>
<Image
src='https://burgeraddict.fr/wp-content/uploads/2024/09/MSG-Smash-Burger-FT-RECIPE0124-d9682401f3554ef683e24311abdf342b.jpg'
alt='product'
width={1080}
height={1080}
className='w-full h-[400px] object-cover'
/>
<div className='absolute bottom-0 left-0 w-full modalGlass3 h-[150px] rounded-b-3xl text-white p-4'>
<div className='flex justify-between items-center'>
<h6 className='text-xs'>
منو دیجیتال رستوران
</h6>
<div className='h-8 bg-black text-white rounded-xl text-sm px-5 flex items-center'>
دسته بندی
</div>
</div>
<div className='mt-6 flex justify-between items-end'>
<div className='flex gap-4'>
<div className='size-14 bg-red-50 rounded-2xl'></div>
<div>
<h2 className='text-xl font-bold'>
دی منو
</h2>
<div className='mt-1'>
<h6 className='text-sm'>
داناک
</h6>
</div>
</div>
</div>
<div className='flex gap-1.5 text-sm items-center'>
<div>جزییات</div>
<ArrowLeft
size={20}
color='white'
/>
</div>
</div>
</div>
</div>
</SwiperSlide>
</Swiper>
</div>
<DanakSuggestedService />
<DanakServices />
</div>
<HydrationBoundary state={dehydrate(queryClient)}>
<Products />
</HydrationBoundary>
)
}
export default Products
export default ProductsPage
@@ -0,0 +1,20 @@
import axios from "@/config/axios";
import { CategoryResponse, ServiceResponse } from "../types/ProductTypes";
export const getServicesByCategory = async (categoryId?: string) => {
let query = ``;
if (categoryId) {
query = `?categoryId=${categoryId}`;
}
const { data } = await axios.get<ServiceResponse>(
`/danak-services/public${query}`
);
return data;
};
export const getCategoriesPublic = async () => {
const { data } = await axios.get<CategoryResponse>(
`/danak-services/categories/public`
);
return data;
};
+23
View File
@@ -0,0 +1,23 @@
import { DanakSuggestService } from "@/app/home/types/HomeTypes";
import { ApiResponse } from "@/shared/types/SharedTypes";
export type ServiceResponse = ApiResponse<{
services: DanakSuggestService[];
nextPage: boolean;
}>;
export type CategoryResponse = ApiResponse<{
categories: ServiceCategoryType[];
}>;
export type ServiceCategoryType = {
id: string;
createdAt: string;
updatedAt: string;
title: string;
icon: string;
isActive: boolean;
order: number;
parentId: string | null;
deletedAt: string | null;
};
+1 -1
View File
@@ -16,7 +16,7 @@ const ServiceItem: FC<Props> = (props) => {
<Image src={props.item.icon} className='size-full object-cover' alt={props.item.name} width={65} height={65} />
</div>
<div className='h-8 bg-primary text-white px-4 rounded-2xl text-sm flex items-center'>
دسته بندی
{props.item.category?.title}
</div>
</div>