responsive danak-services
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
Reference in New Issue
Block a user