api ulandi
This commit is contained in:
@@ -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} />)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user