complated order

This commit is contained in:
Samandar Turgunboyev
2026-02-04 18:29:55 +05:00
parent 4d22e3441c
commit 2535913eb2
19 changed files with 176 additions and 144 deletions

View File

@@ -1,4 +1,4 @@
import Product from '@/features/category/ui/Product'; import SubCategory from '@/features/category/ui/SubCategory';
import { category_api } from '@/shared/config/api/category/api'; import { category_api } from '@/shared/config/api/category/api';
import { BASE_URL } from '@/shared/config/api/URLs'; import { BASE_URL } from '@/shared/config/api/URLs';
import { Metadata } from 'next'; import { Metadata } from 'next';
@@ -13,7 +13,7 @@ interface Params {
const fetchCategory = async (categoryId: string) => { const fetchCategory = async (categoryId: string) => {
try { try {
const res = await category_api.getCategory({ page: 1, page_size: 99 }); const res = await category_api.getCategory({ page: 1, page_size: 99 });
return res.data.results.find((c) => c.id.toString() === categoryId); return res.data.find((c) => c.id.toString() === categoryId);
} catch { } catch {
return null; return null;
} }
@@ -60,7 +60,7 @@ export async function generateMetadata({ params }: Params): Promise<Metadata> {
const Page = () => { const Page = () => {
return ( return (
<Suspense> <Suspense>
<Product /> <SubCategory />
</Suspense> </Suspense>
); );
}; };

View File

@@ -7,7 +7,7 @@ import { Suspense } from 'react';
const fetchCategoryData = async () => { const fetchCategoryData = async () => {
try { try {
const res = await category_api.getCategory({ page: 1, page_size: 99 }); const res = await category_api.getCategory({ page: 1, page_size: 99 });
return res.data.results; return res.data;
} catch { } catch {
return []; return [];
} }

View File

@@ -165,7 +165,9 @@ const CartPage = () => {
<Image <Image
src={ src={
item.product.images.length > 0 item.product.images.length > 0
? BASE_URL + item.product.images[0].image ? item.product.images[0].image.includes(BASE_URL)
? item.product.images[0].image
: BASE_URL + item.product.images[0].image
: ProductBanner : ProductBanner
} }
alt={item.product.name} alt={item.product.name}

View File

@@ -36,7 +36,6 @@ import {
ZoomControl, ZoomControl,
} from '@pbe/react-yandex-maps'; } from '@pbe/react-yandex-maps';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { AxiosError } from 'axios';
import { format } from 'date-fns'; import { format } from 'date-fns';
import { uz } from 'date-fns/locale'; import { uz } from 'date-fns/locale';
import { import {
@@ -106,20 +105,17 @@ const OrderPage = () => {
queryClinet.refetchQueries({ queryKey: ['cart_items'] }); queryClinet.refetchQueries({ queryKey: ['cart_items'] });
} else { } else {
toast.error(t('Xatolik yuz berdi'), { toast.error(t('Xatolik yuz berdi: Mahsulot omborxonada yetarli emas'), {
richColors: true, richColors: true,
position: 'top-center', position: 'top-center',
}); });
} }
}, },
onError: (error: AxiosError) => { onError: () => {
( toast.error(t('Xatolik yuz berdi: Mahsulot omborxoda yetarli emas'), {
error.response?.data as { items: { non_field_errors: string[] }[] } richColors: true,
).items position: 'top-center',
?.flatMap((i) => i.non_field_errors || []) });
.forEach((msg: string) =>
toast.error(msg, { richColors: true, position: 'top-center' }),
);
}, },
}); });
@@ -281,19 +277,19 @@ const OrderPage = () => {
order_quant: item.quantity, order_quant: item.quantity,
price_type_code: item.product.prices![0].price_type.code, price_type_code: item.product.prices![0].price_type.code,
product_price: item.product.prices![0].price, product_price: item.product.prices![0].price,
warehouse_code: 'wh1', warehouse_code: process.env.NEXT_PUBLIC_WARHOUSES_CODE!,
})); }));
if (user) { if (user) {
mutate({ mutate({
order: [ order: [
{ {
filial_code: process.env.NEXT_FILIAL_CODE!, filial_code: process.env.NEXT_PUBLIC_FILIAL_CODE!,
delivery_date: formatDate.format(deliveryDate, 'DD.MM.YYYY'), delivery_date: formatDate.format(deliveryDate, 'DD.MM.YYYY'),
room_code: process.env.NEXT_ROOM_CODE!, room_code: process.env.NEXT_PUBLIC_ROOM_CODE!,
deal_time: formatDate.format(deliveryDate, 'DD.MM.YYYY'), deal_time: formatDate.format(deliveryDate, 'DD.MM.YYYY'),
robot_code: process.env.NEXT_ROBOT_CODE!, robot_code: process.env.NEXT_PUBLIC_ROBOT_CODE!,
status: 'B#N', status: 'B#N',
sales_manager_code: process.env.NEXT_SALES_MANAGER_CODE!, sales_manager_code: process.env.NEXT_PUBLIC_SALES_MANAGER_CODE!,
person_code: user?.username, person_code: user?.username,
currency_code: '860', currency_code: '860',
owner_person_code: user?.username, owner_person_code: user?.username,
@@ -565,7 +561,9 @@ const OrderPage = () => {
unoptimized unoptimized
src={ src={
item.product.images.length !== 0 item.product.images.length !== 0
? BASE_URL + item.product.images[0].image ? item.product.images[0].image.includes(BASE_URL)
? item.product.images[0].image
: BASE_URL + item.product.images[0].image
: LogosProduct : LogosProduct
} }
alt={item.product.name} alt={item.product.name}

View File

@@ -14,7 +14,7 @@ const Category = () => {
queryKey: ['category_list'], queryKey: ['category_list'],
queryFn: () => category_api.getCategory({ page: 1, page_size: 99 }), queryFn: () => category_api.getCategory({ page: 1, page_size: 99 }),
select(data) { select(data) {
return data.data.results; return data.data;
}, },
}); });

View File

@@ -15,7 +15,8 @@ import { useEffect, useState } from 'react';
const PAGE_SIZE = 36; const PAGE_SIZE = 36;
const Product = () => { const Product = () => {
const { categoryId } = useParams(); const { subId } = useParams();
const router = useRouter(); const router = useRouter();
const pathname = usePathname(); const pathname = usePathname();
const searchParams = useSearchParams(); const searchParams = useSearchParams();
@@ -32,18 +33,19 @@ const Product = () => {
isLoading, isLoading,
isError, isError,
} = useQuery({ } = useQuery({
queryKey: ['product_list', categoryId, page], queryKey: ['product_list', subId, page],
queryFn: () => { queryFn: () => {
if (!categoryId) throw new Error('Category ID is required'); if (!subId) throw new Error('Category ID is required');
return product_api.listGetCategoryId({ return product_api.list({
category_id: categoryId.toString(), page,
params: { page, page_size: PAGE_SIZE }, page_size: PAGE_SIZE,
product_type_id: Number(subId),
}); });
}, },
select(data) { select(data) {
return data.data; return data.data;
}, },
enabled: !!categoryId, enabled: !!subId,
}); });
const handleBack = () => { const handleBack = () => {

View File

@@ -1,30 +1,43 @@
'use client'; 'use client';
import { category_api } from '@/shared/config/api/category/api';
import { useRouter } from '@/shared/config/i18n/navigation'; import { useRouter } from '@/shared/config/i18n/navigation';
import { categoryList } from '@/widgets/welcome/lib/data'; import { useQuery } from '@tanstack/react-query';
import { ChevronRight } from 'lucide-react'; import { ChevronRight } from 'lucide-react';
import { useParams } from 'next/navigation'; import { useParams } from 'next/navigation';
const SubCategory = () => { const SubCategory = () => {
const { categoryId } = useParams(); const { categoryId } = useParams();
const router = useRouter(); const { data: category } = useQuery({
const category = queryKey: ['category_list'],
categoryList.find((cat) => cat.name === categoryId) || categoryList[0]; queryFn: () => category_api.getCategory({ page: 1, page_size: 99 }),
select(data) {
return data.data;
},
});
const handleSubCategoryClick = (subCategory: { name: string }) => { const router = useRouter();
router.push(`/category/${categoryId}/${subCategory.name}`); const categorys = category?.find((cat) => cat.id === Number(categoryId));
const handleSubCategoryClick = (subCategory: {
name: string;
id: number;
}) => {
router.push(`/category/${categoryId}/${subCategory.id}`);
}; };
console.log(categorys);
return ( return (
<div className="custom-container"> <div className="custom-container">
<> <>
<h1 className="text-2xl font-semibold text-gray-900 mb-6"> <h1 className="text-2xl font-semibold text-gray-900 mb-6">
{category.name} {categorys?.name}
</h1> </h1>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3"> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
{category.subCategories.map((subCategory, index) => ( {categorys?.product_types.map((subCategory, index) => (
<button <button
key={index} key={index}
onClick={() => handleSubCategoryClick(subCategory)} onClick={() => handleSubCategoryClick(subCategory)}

View File

@@ -175,7 +175,9 @@ const ProductDetail = () => {
height={500} height={500}
src={ src={
data?.images?.length data?.images?.length
? BASE_URL + data.images[selectedImage]?.image ? data.images[selectedImage]?.image?.includes(BASE_URL)
? data.images[selectedImage]?.image
: BASE_URL + data.images[selectedImage]?.image
: '/placeholder.svg' : '/placeholder.svg'
} }
alt={data?.name || 'logo'} alt={data?.name || 'logo'}

View File

@@ -1,13 +1,13 @@
import { AxiosResponse } from 'axios'; import { AxiosResponse } from 'axios';
import httpClient from '../httpClient'; import httpClient from '../httpClient';
import { API_URLS } from '../URLs'; import { API_URLS } from '../URLs';
import { Category } from './type'; import { CategoryResult } from './type';
export const category_api = { export const category_api = {
async getCategory(params: { async getCategory(params: {
page: number; page: number;
page_size: number; page_size: number;
}): Promise<AxiosResponse<Category>> { }): Promise<AxiosResponse<CategoryResult[]>> {
const res = await httpClient.get(API_URLS.Category, { params }); const res = await httpClient.get(API_URLS.Category, { params });
return res; return res;
}, },

View File

@@ -9,7 +9,12 @@ export interface Category {
} }
export interface CategoryResult { export interface CategoryResult {
id: string; id: number;
name: string; name: string;
image: string | null; image: string | null;
product_types: ProductTypes[];
}
export interface ProductTypes {
id: number;
name: string;
} }

View File

@@ -12,6 +12,8 @@ export const product_api = {
async list(params: { async list(params: {
page: number; page: number;
page_size: number; page_size: number;
product_type_id?: number;
category_id?: number;
}): Promise<AxiosResponse<ProductList>> { }): Promise<AxiosResponse<ProductList>> {
const res = await httpClient.get(`${API_URLS.Product}list/`, { params }); const res = await httpClient.get(`${API_URLS.Product}list/`, { params });
return res; return res;

View File

@@ -204,5 +204,8 @@
"Tez-tez So'raladigan Savollar": "Часто задаваемые вопросы", "Tez-tez So'raladigan Savollar": "Часто задаваемые вопросы",
"Gastro Market haqida eng ko'p so'raladigan savollarga javoblar": "Ответы на самые часто задаваемые вопросы о Gastro Market", "Gastro Market haqida eng ko'p so'raladigan savollarga javoblar": "Ответы на самые часто задаваемые вопросы о Gastro Market",
"Barcha mahsulotlar": "Все товары" "Barcha mahsulotlar": "Все товары",
"Xatolik yuz berdi: Mahsulot omborxonada yetarli emas": "Произошла ошибка: недостаточно товаров на складе",
"Bu kategoriyada hozircha mahsulot yoq": "В этой категории пока нет товаров",
"Tez orada qoshiladi": "Скоро будет добавлено"
} }

View File

@@ -204,5 +204,8 @@ declare const messages: {
"Gastro Market haqida eng ko'p so'raladigan savollarga javoblar": "Gastro Market haqida eng ko'p so'raladigan savollarga javoblar"; "Gastro Market haqida eng ko'p so'raladigan savollarga javoblar": "Gastro Market haqida eng ko'p so'raladigan savollarga javoblar";
'Barcha mahsulotlar': 'Barcha mahsulotlar'; 'Barcha mahsulotlar': 'Barcha mahsulotlar';
'Xatolik yuz berdi: Mahsulot omborxonada yetarli emas': 'Xatolik yuz berdi: Mahsulot omborxonada yetarli emas';
'Bu kategoriyada hozircha mahsulot yoq': 'Bu kategoriyada hozircha mahsulot yoq';
'Tez orada qoshiladi': 'Tez orada qoshiladi';
}; };
export default messages; export default messages;

View File

@@ -200,5 +200,8 @@
"Tez-tez So'raladigan Savollar": "Tez-tez So'raladigan Savollar", "Tez-tez So'raladigan Savollar": "Tez-tez So'raladigan Savollar",
"Gastro Market haqida eng ko'p so'raladigan savollarga javoblar": "Gastro Market haqida eng ko'p so'raladigan savollarga javoblar", "Gastro Market haqida eng ko'p so'raladigan savollarga javoblar": "Gastro Market haqida eng ko'p so'raladigan savollarga javoblar",
"Barcha mahsulotlar": "Barcha mahsulotlar" "Barcha mahsulotlar": "Barcha mahsulotlar",
"Xatolik yuz berdi: Mahsulot omborxonada yetarli emas": "Xatolik yuz berdi: Mahsulot omborxonada yetarli emas",
"Bu kategoriyada hozircha mahsulot yoq": "Bu kategoriyada hozircha mahsulot yoq",
"Tez orada qoshiladi": "Tez orada qoshiladi"
} }

View File

@@ -1,6 +1,6 @@
'use client'; 'use client';
import { CategoryResult } from '@/shared/config/api/category/type'; import { ProductTypes } from '@/shared/config/api/category/type';
import { product_api } from '@/shared/config/api/product/api'; import { product_api } from '@/shared/config/api/product/api';
import { useRouter } from '@/shared/config/i18n/navigation'; import { useRouter } from '@/shared/config/i18n/navigation';
import { cn } from '@/shared/lib/utils'; import { cn } from '@/shared/lib/utils';
@@ -18,7 +18,7 @@ import { ChevronLeft, ChevronRight } from 'lucide-react';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { ProductCard } from './product-card'; import { ProductCard } from './product-card';
export function CategoryCarousel({ category }: { category: CategoryResult }) { export function CategoryCarousel({ category }: { category: ProductTypes }) {
const router = useRouter(); const router = useRouter();
const [api, setApi] = useState<CarouselApi>(); const [api, setApi] = useState<CarouselApi>();
const [canScrollPrev, setCanScrollPrev] = useState(false); const [canScrollPrev, setCanScrollPrev] = useState(false);
@@ -57,9 +57,10 @@ export function CategoryCarousel({ category }: { category: CategoryResult }) {
const { data: product, isLoading } = useQuery({ const { data: product, isLoading } = useQuery({
queryKey: ['product_list', category], queryKey: ['product_list', category],
queryFn: () => queryFn: () =>
product_api.listGetCategoryId({ product_api.list({
category_id: category.id, page: 1,
params: { page: 1, page_size: 16 }, page_size: 16,
product_type_id: category.id,
}), }),
select(data) { select(data) {
return data.data; return data.data;

View File

@@ -14,7 +14,7 @@ const Footer = () => {
queryKey: ['category_list'], queryKey: ['category_list'],
queryFn: () => category_api.getCategory({ page: 1, page_size: 12 }), queryFn: () => category_api.getCategory({ page: 1, page_size: 12 }),
select(data) { select(data) {
return data.data.results; return data.data;
}, },
}); });

View File

@@ -1,13 +1,13 @@
import { CategoryType } from '@/widgets/welcome/lib/data'; import { CategoryResult } from '@/shared/config/api/category/type';
import { create } from 'zustand'; import { create } from 'zustand';
type Category = { type Category = {
active: CategoryType | null; active: CategoryResult | null;
openToolbar: boolean; openToolbar: boolean;
}; };
type Actions = { type Actions = {
setActive: (active: CategoryType | null) => void; setActive: (active: CategoryResult | null) => void;
setOpenToolbar: (openToolbar: boolean) => void; setOpenToolbar: (openToolbar: boolean) => void;
setCloseToolbar: (openToolbar: boolean) => void; setCloseToolbar: (openToolbar: boolean) => void;
}; };
@@ -15,7 +15,7 @@ type Actions = {
const useCategoryActive = create<Category & Actions>((set) => ({ const useCategoryActive = create<Category & Actions>((set) => ({
active: null, active: null,
openToolbar: false, openToolbar: false,
setActive: (active: CategoryType | null) => set(() => ({ active })), setActive: (active: CategoryResult | null) => set(() => ({ active })),
setOpenToolbar: () => set(() => ({ openToolbar: true })), setOpenToolbar: () => set(() => ({ openToolbar: true })),
setCloseToolbar: () => set(() => ({ openToolbar: false })), setCloseToolbar: () => set(() => ({ openToolbar: false })),
})); }));

View File

@@ -1,6 +1,7 @@
'use client'; 'use client';
import { cart_api } from '@/features/cart/lib/api'; import { cart_api } from '@/features/cart/lib/api';
import { category_api } from '@/shared/config/api/category/api';
import { Link, useRouter } from '@/shared/config/i18n/navigation'; import { Link, useRouter } from '@/shared/config/i18n/navigation';
import { useCartId } from '@/shared/hooks/cartId'; import { useCartId } from '@/shared/hooks/cartId';
import formatPhone from '@/shared/lib/formatPhone'; import formatPhone from '@/shared/lib/formatPhone';
@@ -18,7 +19,6 @@ import {
SheetTrigger, SheetTrigger,
} from '@/shared/ui/sheet'; } from '@/shared/ui/sheet';
import { banner_api } from '@/widgets/welcome/lib/api'; import { banner_api } from '@/widgets/welcome/lib/api';
import { categoryList } from '@/widgets/welcome/lib/data';
import { userStore } from '@/widgets/welcome/lib/hook'; import { userStore } from '@/widgets/welcome/lib/hook';
import { PopoverTrigger } from '@radix-ui/react-popover'; import { PopoverTrigger } from '@radix-ui/react-popover';
import { useMutation, useQuery } from '@tanstack/react-query'; import { useMutation, useQuery } from '@tanstack/react-query';
@@ -27,6 +27,7 @@ import {
Facebook, Facebook,
Heart, Heart,
Instagram, Instagram,
LayoutGrid,
Mail, Mail,
MenuIcon, MenuIcon,
Phone, Phone,
@@ -35,6 +36,7 @@ import {
ShoppingCart, ShoppingCart,
Twitter, Twitter,
User, User,
XIcon,
} from 'lucide-react'; } from 'lucide-react';
import { useTranslations } from 'next-intl'; import { useTranslations } from 'next-intl';
import Image from 'next/image'; import Image from 'next/image';
@@ -69,6 +71,14 @@ const Navbar = () => {
queryFn: () => banner_api.getMe(), queryFn: () => banner_api.getMe(),
}); });
const { data: category } = useQuery({
queryKey: ['category_list'],
queryFn: () => category_api.getCategory({ page: 1, page_size: 99 }),
select(data) {
return data.data;
},
});
useEffect(() => { useEffect(() => {
if (me) { if (me) {
setUser(me.data); setUser(me.data);
@@ -392,7 +402,7 @@ const Navbar = () => {
</Sheet> </Sheet>
</div> </div>
<div className="flex-1 flex gap-3"> <div className="flex-1 flex gap-3">
{/* <Button <Button
variant={'outline'} variant={'outline'}
className="h-10 max-lg:hidden cursor-pointer" className="h-10 max-lg:hidden cursor-pointer"
onClick={() => { onClick={() => {
@@ -409,7 +419,7 @@ const Navbar = () => {
<LayoutGrid className="size-4 text-foreground" /> <LayoutGrid className="size-4 text-foreground" />
)} )}
<p className="text-foreground">Kataloglar</p> <p className="text-foreground">Kataloglar</p>
</Button> */} </Button>
<div className="relative w-full max-lg:hidden"> <div className="relative w-full max-lg:hidden">
<Input <Input
@@ -483,54 +493,58 @@ const Navbar = () => {
<div /> <div />
</PopoverTrigger> </PopoverTrigger>
<PopoverContent <PopoverContent
className="w-[100vw] !p-0 h-[100vh] rounded-b-xl border-t-2 border-blue-500" className="w-[100vw] !p-0 h-[100vh] rounded-b-xl"
onInteractOutside={() => setOpenToolbar(false)} onInteractOutside={() => setOpenToolbar(false)}
> >
<div className="flex h-[90vh]"> <div className="flex h-[90vh]">
<div className="border-r border-slate-200 w-[20%] py-3 flex flex-col gap-2 px-3 overflow-y-auto scrollbar-thin bg-slate-50"> <div className="border-r border-slate-200 w-[20%] py-3 flex flex-col gap-2 px-3 overflow-y-auto scrollbar-thin bg-slate-50">
{categoryList.map((e, index) => { {category &&
const isActive = active?.name === e.name; category.map((e, index) => {
const isActive = active?.name === e.name;
return ( return (
<Button <Button
key={index} key={index}
variant="secondary" variant="secondary"
onMouseEnter={() => setActive(e)} onMouseEnter={() => setActive(e)}
onClick={() => setActive(e)} onClick={() => setActive(e)}
className={`flex justify-between items-center cursor-pointer px-4 h-14 rounded-xl transition-all duration-300 ${ className={`flex justify-between items-center cursor-pointer px-4 h-14 rounded-xl transition-all duration-300 ${
isActive
? 'bg-blue-100 border border-blue-400'
: 'hover:bg-slate-100 border border-transparent'
}`}
>
<div className="flex gap-3 items-center">
<div
className={`p-1.5 rounded-lg ${isActive ? 'bg-white' : 'bg-white'}`}
>
<Image
src={e.image || '/placeholder.svg'}
alt={e.name}
unoptimized
className="w-5 h-5 object-contain"
/>
</div>
<p
className={`text-sm font-medium ${isActive ? 'text-blue-700' : 'text-slate-700'}`}
>
{e.name}
</p>
</div>
<ChevronRight
className={`size-5 transition-transform duration-300 ${
isActive isActive
? 'rotate-90 text-blue-600' ? 'bg-blue-100 border border-blue-400'
: 'text-slate-400' : 'hover:bg-slate-100 border border-transparent'
}`} }`}
/> >
</Button> <div className="flex gap-3 items-center min-w-0">
); <div className={`p-1.5 rounded-lg bg-white shrink-0`}>
})} <Image
src={e.image || '/placeholder.svg'}
alt={e.name}
width={500}
height={500}
unoptimized
className="w-5 h-5 object-contain"
/>
</div>
<p
className={`text-sm font-medium truncate ${
isActive ? 'text-blue-700' : 'text-slate-700'
}`}
>
{e.name}
</p>
</div>
<ChevronRight
className={`size-5 transition-transform duration-300 ${
isActive
? 'rotate-90 text-blue-600'
: 'text-slate-400'
}`}
/>
</Button>
);
})}
</div> </div>
<div className="w-[80%] overflow-y-auto p-8 scrollbar-thin bg-white"> <div className="w-[80%] overflow-y-auto p-8 scrollbar-thin bg-white">
@@ -538,21 +552,30 @@ const Navbar = () => {
{active?.name} {active?.name}
</h3> </h3>
<div className="grid grid-cols-3 gap-4"> {active && active?.product_types?.length > 0 ? (
{active?.subCategories.map((sub, index) => ( <div className="grid grid-cols-3 gap-4">
<Button {active.product_types.map((sub, index) => (
key={index} <Button
onClick={() => { key={index}
setCloseToolbar(false); onClick={() => {
router.push(`/category/${active.name}/${sub.name}`); setCloseToolbar(false);
}} router.push(`/category/${active.id}/${sub.id}`);
variant="outline" }}
className="justify-start h-12 cursor-pointer border border-slate-200 hover:border-blue-400 hover:bg-blue-50 transition-all text-slate-700 hover:text-blue-700 font-medium rounded-xl bg-transparent" variant="outline"
> className="justify-start h-12 border border-slate-200 hover:border-blue-400 hover:bg-blue-50 transition-all rounded-xl"
{sub.name} >
</Button> {sub.name}
))} </Button>
</div> ))}
</div>
) : (
<div className="flex flex-col items-center justify-center h-[50vh] text-slate-400">
<p className="text-lg font-medium">
{t('Bu kategoriyada hozircha mahsulot yoq')}
</p>
<p className="text-sm mt-1">{t('Tez orada qoshiladi')}</p>
</div>
)}
</div> </div>
</div> </div>
</PopoverContent> </PopoverContent>

View File

@@ -31,7 +31,6 @@ const Welcome = () => {
const [apiPro, setApiPro] = useState<CarouselApi>(); const [apiPro, setApiPro] = useState<CarouselApi>();
const [canScrollPrev, setCanScrollPrev] = useState(false); const [canScrollPrev, setCanScrollPrev] = useState(false);
const [canScrollNext, setCanScrollNext] = useState(false); const [canScrollNext, setCanScrollNext] = useState(false);
const [apiCat, setApiCat] = useState<CarouselApi>();
const router = useRouter(); const router = useRouter();
const t = useTranslations(); const t = useTranslations();
@@ -77,7 +76,7 @@ const Welcome = () => {
queryKey: ['category_list'], queryKey: ['category_list'],
queryFn: () => category_api.getCategory({ page: 1, page_size: 99 }), queryFn: () => category_api.getCategory({ page: 1, page_size: 99 }),
select(data) { select(data) {
return data.data.results; return data.data;
}, },
}); });
@@ -89,10 +88,6 @@ const Welcome = () => {
} }
}; };
const scrollPrevCar = () => {
apiCat?.scrollPrev();
};
const scrollNext = () => { const scrollNext = () => {
if (api?.canScrollNext()) { if (api?.canScrollNext()) {
api?.scrollNext(); api?.scrollNext();
@@ -101,10 +96,6 @@ const Welcome = () => {
} }
}; };
const scrollNextCat = () => {
apiCat?.scrollNext();
};
const { data: product, isLoading: productLoading } = useQuery({ const { data: product, isLoading: productLoading } = useQuery({
queryKey: ['list'], queryKey: ['list'],
queryFn: () => queryFn: () =>
@@ -172,7 +163,7 @@ const Welcome = () => {
</CarouselContent> </CarouselContent>
</Carousel> </Carousel>
<Carousel className="w-full mt-5" setApi={setApiCat}> <Carousel className="w-full mt-5">
<CarouselContent className="py-2 px-1 pr-[12%]"> <CarouselContent className="py-2 px-1 pr-[12%]">
{category && {category &&
category.map((banner, index) => ( category.map((banner, index) => (
@@ -200,24 +191,6 @@ const Welcome = () => {
</CarouselItem> </CarouselItem>
))} ))}
</CarouselContent> </CarouselContent>
<Button
onClick={scrollNextCat}
className="absolute max-lg:w-8 max-lg:h-8 top-1/2 -translate-y-1/2 -right-2 cursor-pointer"
variant={'secondary'}
size={'icon'}
aria-label="next images"
>
<ChevronRight className="size-6 max-lg:size-6" />
</Button>
<Button
onClick={scrollPrevCar}
className="absolute max-lg:w-8 max-lg:h-8 top-1/2 -translate-y-1/2 -left-2 cursor-pointer"
variant={'secondary'}
size={'icon'}
aria-label="prev images"
>
<ChevronLeft className="size-6 max-lg:size-6" />
</Button>
</Carousel> </Carousel>
</div> </div>
<section className="relative custom-container mt-5 justify-center items-center border-b border-slate-200"> <section className="relative custom-container mt-5 justify-center items-center border-b border-slate-200">
@@ -300,9 +273,11 @@ const Welcome = () => {
</section> </section>
{category && {category &&
category category.map((e) =>
.slice(0, 6) e.product_types.map((c) => (
.map((e) => <CategoryCarousel category={e} key={e.id} />)} <CategoryCarousel category={c} key={c.id} />
)),
)}
</> </>
); );
}; };