150 lines
4.2 KiB
TypeScript
150 lines
4.2 KiB
TypeScript
"use client";
|
||
|
||
import { Swiper, SwiperSlide } from "swiper/react";
|
||
import { Navigation } from "swiper/modules";
|
||
import "swiper/css";
|
||
import "swiper/css/navigation";
|
||
import Title from "../lib_components/title";
|
||
import SliderCard from "../cards/sliderCard";
|
||
import { useEffect, useState } from "react";
|
||
import { ProductTypes } from "@/types";
|
||
import { usePathname } from "next/navigation";
|
||
import Text from "../lib_components/text";
|
||
import { LoadingSkeleton } from "../loadingProduct";
|
||
import { baseUrl } from "@/data/url";
|
||
|
||
// The custom CSS selectors for navigation
|
||
const navigationPrevEl = ".custom-swiper-prev";
|
||
const navigationNextEl = ".custom-swiper-next";
|
||
|
||
function getRandomItems(arr: any[], count: number) {
|
||
const shuffled = [...arr];
|
||
|
||
for (let i = shuffled.length - 1; i > 0; i--) {
|
||
const j = Math.floor(Math.random() * (i + 1));
|
||
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
||
}
|
||
|
||
return shuffled.slice(0, count);
|
||
}
|
||
|
||
export default function CustomSlider() {
|
||
const [cars, setCars] = useState<ProductTypes[]>([]);
|
||
const [loading, setLoading] = useState(true);
|
||
const [error, setError] = useState<string | null>(null);
|
||
const pathname = usePathname();
|
||
const lang = pathname.split("/")[1];
|
||
useEffect(() => {
|
||
const fetchProducts = async () => {
|
||
try {
|
||
setLoading(true);
|
||
setError(null);
|
||
|
||
const response = await fetch(baseUrl, {
|
||
headers: {
|
||
"Accept-Language": lang,
|
||
},
|
||
});
|
||
|
||
if (!response.ok) {
|
||
throw new Error("Server xatosi");
|
||
}
|
||
|
||
const data = await response.json();
|
||
console.log("backend Data slider: ", data?.data);
|
||
|
||
if (data?.data && data.data.length > 0) {
|
||
const dataSlider = getRandomItems(data.data, 6);
|
||
const formattedData = dataSlider.map((item) => ({
|
||
id: item.id,
|
||
truck_name: item.name,
|
||
desc: "news-title1",
|
||
image: item.image || "",
|
||
}));
|
||
setCars(formattedData);
|
||
} else {
|
||
setCars([]);
|
||
}
|
||
} catch (error) {
|
||
console.log("Xatolik: ", error);
|
||
setError(error instanceof Error ? error.message : "Noma'lum xatolik");
|
||
} finally {
|
||
setLoading(false);
|
||
}
|
||
};
|
||
|
||
fetchProducts();
|
||
}, [lang]);
|
||
|
||
if (error) {
|
||
return (
|
||
<div className="mb-4 p-4 bg-red-50 border border-red-200 rounded-lg">
|
||
<p className="text-red-600 text-center">
|
||
<Text txt="downloadError" /> : {error}
|
||
</p>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
if (loading) {
|
||
return <LoadingSkeleton />;
|
||
}
|
||
return (
|
||
<div
|
||
dir="ltr"
|
||
className="max-w-[1400px] w-full mx-auto relative my-20 px-4"
|
||
>
|
||
{/* Title */}
|
||
<div className="my-10 mb-20 flex items-center justify-between ">
|
||
<div className="">
|
||
<Title text="news-h2" />
|
||
</div>
|
||
|
||
{/* Custom buttons */}
|
||
<div className="flex gap-2 items-center justify-center">
|
||
<button
|
||
className={`${navigationPrevEl.replace(
|
||
".",
|
||
"",
|
||
)} w-10 h-10 p-0 bg-primary text-[30px] text-center text-white flex items-center justify-center hover:bg-secondary hover:cursor-pointer transition`}
|
||
>
|
||
‹
|
||
</button>
|
||
<button
|
||
className={`${navigationNextEl.replace(
|
||
".",
|
||
"",
|
||
)} w-10 h-10 bg-primary text-[30px] text-center text-white flex items-center justify-center hover:bg-secondary hover:cursor-pointer transition `}
|
||
>
|
||
›
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Swiper */}
|
||
<Swiper
|
||
modules={[Navigation]}
|
||
slidesPerView={3}
|
||
spaceBetween={30}
|
||
loop={true}
|
||
navigation={{
|
||
// Pass the class selectors here
|
||
prevEl: navigationPrevEl,
|
||
nextEl: navigationNextEl,
|
||
}}
|
||
breakpoints={{
|
||
0: { slidesPerView: 1 },
|
||
768: { slidesPerView: 2 },
|
||
1024: { slidesPerView: 3 },
|
||
}}
|
||
>
|
||
{cars.map((item, index) => (
|
||
<SwiperSlide key={index}>
|
||
<SliderCard data={item} />
|
||
</SwiperSlide>
|
||
))}
|
||
</Swiper>
|
||
</div>
|
||
);
|
||
}
|