api ulandi
This commit is contained in:
112
src/pages/site-banner/ui/BannerCarousel.tsx
Normal file
112
src/pages/site-banner/ui/BannerCarousel.tsx
Normal file
@@ -0,0 +1,112 @@
|
||||
"use client";
|
||||
|
||||
import { getBanner } from "@/pages/site-banner/lib/api";
|
||||
import { Card } from "@/shared/ui/card";
|
||||
import {
|
||||
Carousel,
|
||||
CarouselContent,
|
||||
CarouselItem,
|
||||
CarouselNext,
|
||||
CarouselPrevious,
|
||||
} from "@/shared/ui/carousel";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { AlertTriangle, Loader2, MoveRightIcon } from "lucide-react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
const BannerCarousel = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
// 🧠 Bannerlarni backenddan olish
|
||||
const { data, isLoading, isError, refetch } = useQuery({
|
||||
queryKey: ["all_banner"],
|
||||
queryFn: () => getBanner(),
|
||||
select: (res) =>
|
||||
res.data.data.results.filter((b) => b.position === "banner1"),
|
||||
});
|
||||
|
||||
const colors = ["#EDF5C7", "#F5DCC7"];
|
||||
|
||||
if (isLoading)
|
||||
return (
|
||||
<div className="flex items-center justify-center min-h-[400px]">
|
||||
<Loader2 className="animate-spin text-blue-500 w-8 h-8" />
|
||||
</div>
|
||||
);
|
||||
|
||||
if (isError)
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-[400px] text-white">
|
||||
<AlertTriangle className="text-red-500 w-8 h-8 mb-2" />
|
||||
<p>{t("Ma'lumotlarni yuklashda xatolik yuz berdi.")}</p>
|
||||
<button
|
||||
onClick={() => refetch()}
|
||||
className="mt-3 bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg"
|
||||
>
|
||||
{t("Qayta urinish")}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
if (!data || data.length === 0)
|
||||
return (
|
||||
<div className="flex items-center justify-center text-gray-400 min-h-[400px]">
|
||||
{t("Hozircha bannerlar mavjud emas")}
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="mt-10 max-lg:hidden custom-container">
|
||||
<Carousel opts={{ loop: true, align: "start" }}>
|
||||
<CarouselContent>
|
||||
{data.map((banner, index) => (
|
||||
<CarouselItem
|
||||
key={banner.id}
|
||||
className="basis-full md:basis-[80%] shrink-0"
|
||||
>
|
||||
<div className="h-[500px]">
|
||||
<Card className="h-full !rounded-[50px] flex border-none items-center justify-start relative overflow-hidden">
|
||||
{/* <BannerCircle
|
||||
color={colors[index % colors.length]}
|
||||
className="w-[60%] h-full absolute z-10"
|
||||
/> */}
|
||||
|
||||
{/* Matn qismi */}
|
||||
<div className="flex flex-col gap-6 w-96 z-20 absolute left-14 top-1/2 -translate-y-1/2">
|
||||
<p className="text-4xl font-semibold text-[#232325]">
|
||||
{banner.title}
|
||||
</p>
|
||||
<p className="text-[#212122] font-medium">
|
||||
{banner.description}
|
||||
</p>
|
||||
<Link
|
||||
to={banner.link || "#"}
|
||||
className="bg-white text-[#212122] font-semibold flex gap-4 px-8 py-4 shadow-sm !rounded-4xl w-fit"
|
||||
>
|
||||
<p>{t("Batafsil")}</p>
|
||||
<MoveRightIcon />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Rasm qismi */}
|
||||
<div className="absolute right-0 w-[50%] h-full">
|
||||
<img
|
||||
src={banner.image}
|
||||
alt={banner.title}
|
||||
className="object-cover w-full h-full"
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</CarouselItem>
|
||||
))}
|
||||
</CarouselContent>
|
||||
|
||||
<CarouselPrevious className="absolute left-2 top-1/2 -translate-y-1/2 bg-white/80 hover:bg-white p-2 size-10 rounded-full shadow z-10" />
|
||||
<CarouselNext className="absolute right-2 top-1/2 -translate-y-1/2 bg-white/80 hover:bg-white p-2 rounded-full size-10 shadow z-10" />
|
||||
</Carousel>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default BannerCarousel;
|
||||
Reference in New Issue
Block a user