api ulandi

This commit is contained in:
Samandar Turgunboyev
2025-12-22 11:35:55 +05:00
parent 37c7120d1b
commit 9978b4e3fe
75 changed files with 10255 additions and 11924 deletions

View File

@@ -1,8 +1,8 @@
'use client';
import Banner from '@/assets/gemma-c-stpjHJGqZyw-unsplash.jpg';
import Banner_Two from '@/assets/photo-1506617420156-8e4536971650.jpg';
import Banner_Three from '@/assets/pngtree-supermarket-aisle-with-empty-shopping-cart-at-grocery-store-retail-business-image_15646095.jpg';
import { category_api } from '@/shared/config/api/category/api';
import { BASE_URL } from '@/shared/config/api/URLs';
import { Link } from '@/shared/config/i18n/navigation';
import { AspectRatio } from '@/shared/ui/aspect-ratio';
import { Button } from '@/shared/ui/button';
import {
@@ -11,19 +11,34 @@ import {
CarouselItem,
type CarouselApi,
} from '@/shared/ui/carousel';
import useCategoryActive from '@/widgets/navbar/lib/openCategory';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { Skeleton } from '@/shared/ui/skeleton';
import { CategoryCarousel } from '@/widgets/categories/ui/category-carousel';
import { useQuery } from '@tanstack/react-query';
import { AlertCircle, ChevronLeft, ChevronRight } from 'lucide-react';
import Image from 'next/image';
import { useState } from 'react';
import 'swiper/css';
import { Swiper, SwiperSlide } from 'swiper/react';
import { categoryList } from '../lib/data';
const banner = [Banner, Banner_Two, Banner_Three];
import { banner_api } from '../lib/api';
const Welcome = () => {
const { setActive, setOpenToolbar } = useCategoryActive();
const [api, setApi] = useState<CarouselApi>();
const [apiCat, setApiCat] = useState<CarouselApi>();
const { data, isLoading, isError } = useQuery({
queryKey: ['banner_list'],
queryFn: () => banner_api.getBanner(),
select(data) {
return data.data;
},
});
const { data: category } = useQuery({
queryKey: ['category_list'],
queryFn: () => category_api.getCategory({ page: 1, page_size: 99 }),
select(data) {
return data.data.results;
},
});
const scrollPrev = () => {
if (api?.canScrollPrev()) {
@@ -33,6 +48,10 @@ const Welcome = () => {
}
};
const scrollPrevCar = () => {
apiCat?.scrollPrev();
};
const scrollNext = () => {
if (api?.canScrollNext()) {
api?.scrollNext();
@@ -41,78 +60,110 @@ const Welcome = () => {
}
};
return (
<div className="custom-container">
<Carousel className="w-full" setApi={setApi}>
<CarouselContent className="!pr-[15%] lg:!pr-[8%] sm:pr-0">
{banner.map((e, index) => (
<CarouselItem key={index} className="relative">
<AspectRatio ratio={16 / 8}>
<div className="relative w-full h-full">
<Image
src={e || '/placeholder.svg'}
alt="Banner"
fill
className="rounded-2xl object-cover shadow-lg border border-slate-200"
priority
/>
</div>
</AspectRatio>
<Button
onClick={scrollNext}
className="absolute bottom-5 right-5 max-lg:hidden cursor-pointer"
variant={'secondary'}
size={'icon'}
>
<ChevronRight className="size-6" />
</Button>
<Button
onClick={scrollPrev}
className="absolute bottom-5 right-16 cursor-pointer max-lg:hidden"
variant={'secondary'}
size={'icon'}
>
<ChevronLeft className="size-6" />
</Button>
</CarouselItem>
))}
</CarouselContent>
</Carousel>
const scrollNextCat = () => {
apiCat?.scrollNext();
};
{/* Category Slider */}
<div className="mx-auto mt-5 max-lg:hidden">
<Swiper
spaceBetween={4}
slidesPerView={4}
breakpoints={{
320: { slidesPerView: 1 },
640: { slidesPerView: 2 },
1024: { slidesPerView: 4 },
}}
>
{categoryList.map((item, index) => (
<SwiperSlide key={index} className="py-3 px-1">
<div
className="flex gap-1 items-center justify-center bg-gray-100/60 p-3 rounded-lg shadow-sm cursor-pointer space-x-3"
onClick={() => {
setOpenToolbar(true);
setActive(item);
}}
>
<Image
src={item.image}
alt={item.name}
className="w-7 h-7 object-contain"
/>
<p className="text-sm font-bold truncate line-clamp-2 leading-tight text-slate-700">
{item.name}
</p>
</div>
</SwiperSlide>
))}
</Swiper>
return (
<>
<div className="custom-container">
<Carousel className="w-full" setApi={setApi}>
<CarouselContent>
{isLoading && (
<CarouselItem className="relative">
<Skeleton className="w-full h-full" />
</CarouselItem>
)}
{isError && (
<CarouselItem className="relative gap-2 bg-gray-300/20 rounded-xl flex flex-col justify-center items-center">
<AlertCircle className="size-10 text-red-500" />
<p className="text-red-500">Banner yuklanmadi. Xatolik yuz</p>
</CarouselItem>
)}
{data &&
data.map((banner, index) => (
<CarouselItem key={index} className="relative">
<AspectRatio
ratio={16 / 7}
className="relative overflow-hidden rounded-2xl"
>
<Image
src={BASE_URL + banner.banner || '/placeholder.svg'}
alt={banner.id}
fill
className="object-cover"
priority={index === 0}
/>
</AspectRatio>
<Button
onClick={scrollNext}
className="absolute max-lg:w-6 max-lg:h-6 top-1/2 -translate-y-1/2 right-2 cursor-pointer"
variant={'secondary'}
size={'icon'}
>
<ChevronRight className="size-6 max-lg:size-5" />
</Button>
<Button
onClick={scrollPrev}
className="absolute max-lg:w-6 max-lg:h-6 top-1/2 -translate-y-1/2 left-5 cursor-pointer"
variant={'secondary'}
size={'icon'}
>
<ChevronLeft className="size-6 max-lg:size-5" />
</Button>
</CarouselItem>
))}
</CarouselContent>
</Carousel>
<Carousel className="w-full mt-5" setApi={setApiCat}>
<CarouselContent className="py-2 px-1 pr-[12%]">
{category &&
category.map((banner, index) => (
<CarouselItem
key={index}
className="basis-1/5 max-lg:basis-1/3 max-md:basis-1/2 max-xs:basis-1/1"
>
<Link href={`/category/${banner.id}`}>
<div className="flex flex-col gap-1 items-center justify-start bg-white p-3 rounded-lg shadow-md cursor-pointer space-x-3">
<Image
src={BASE_URL + banner.image}
alt={banner.name}
width={500}
height={500}
className="w-full h-16 object-contain"
/>
<p className="text-sm font-bold line-clamp-1 leading-tight text-slate-700">
{banner.name}
</p>
</div>
</Link>
</CarouselItem>
))}
</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'}
>
<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'}
>
<ChevronLeft className="size-6 max-lg:size-6" />
</Button>
</Carousel>
</div>
</div>
{category &&
category
.slice(0, 6)
.map((e) => <CategoryCarousel category={e} key={e.id} />)}
</>
);
};