159 lines
5.2 KiB
TypeScript
159 lines
5.2 KiB
TypeScript
"use client";
|
|
import { Swiper, SwiperSlide } from "swiper/react";
|
|
import { Navigation, Pagination, Thumbs } from "swiper/modules";
|
|
import { useState } from "react";
|
|
import type { Swiper as SwiperType } from "swiper";
|
|
import "swiper/css";
|
|
import "swiper/css/navigation";
|
|
import "swiper/css/pagination";
|
|
import "swiper/css/thumbs";
|
|
import Image from "next/image";
|
|
import { useTranslations } from "next-intl";
|
|
|
|
const navigationPrevEl = ".custom-swiper-prev";
|
|
const navigationNextEl = ".custom-swiper-next";
|
|
|
|
export function SliderComp({ imgs }: { imgs: string[] }) {
|
|
const [thumbsSwiper, setThumbsSwiper] = useState<SwiperType | null>(null);
|
|
const t = useTranslations();
|
|
|
|
// Agar rasm bo'lmasa
|
|
if (!imgs || imgs.length === 0) {
|
|
return (
|
|
<div className="w-full h-96 md:h-125 bg-gray-800 rounded-lg flex items-center justify-center">
|
|
<div className="text-center">
|
|
<svg
|
|
className="w-20 h-20 text-gray-600 mx-auto mb-4"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
|
|
/>
|
|
</svg>
|
|
<p className="text-gray-500">{t("image_not_found")}</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
{/* Main Slider */}
|
|
<div className="relative group">
|
|
<Swiper
|
|
modules={[Navigation, Pagination, Thumbs]}
|
|
thumbs={{
|
|
swiper:
|
|
thumbsSwiper && !thumbsSwiper.destroyed ? thumbsSwiper : null,
|
|
}}
|
|
navigation={{
|
|
prevEl: navigationPrevEl,
|
|
nextEl: navigationNextEl,
|
|
}}
|
|
pagination={{ clickable: true }}
|
|
loop={imgs.length > 1}
|
|
className="w-[90%] h-96 md:h-96 rounded-lg overflow-hidden shadow-xl"
|
|
>
|
|
{imgs.map((image, index) => (
|
|
<SwiperSlide
|
|
key={index}
|
|
className=" flex items-center justify-center"
|
|
>
|
|
<div className="relative w-full h-full p-4 md:p-8">
|
|
<Image
|
|
src={image}
|
|
alt={`Product image ${index + 1}`}
|
|
fill
|
|
className="object-contain"
|
|
sizes="(max-width: 768px) 100vw, 50vw"
|
|
priority={index === 0}
|
|
/>
|
|
</div>
|
|
</SwiperSlide>
|
|
))}
|
|
</Swiper>
|
|
|
|
{/* Navigation Buttons */}
|
|
{imgs.length > 1 && (
|
|
<>
|
|
<button
|
|
className={`${navigationPrevEl.replace(
|
|
".",
|
|
"",
|
|
)} absolute z-10 top-1/2 -translate-y-1/2 left-2 md:left-4 rounded-lg w-10 h-10 md:w-12 md:h-12 bg-red-700/90 hover:bg-red-800 text-white flex items-center justify-center transition opacity-0 group-hover:opacity-100 shadow-lg`}
|
|
>
|
|
<svg
|
|
className="w-6 h-6"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M15 19l-7-7 7-7"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
<button
|
|
className={`${navigationNextEl.replace(
|
|
".",
|
|
"",
|
|
)} absolute z-10 top-1/2 -translate-y-1/2 right-2 md:right-4 rounded-lg w-10 h-10 md:w-12 md:h-12 bg-red-700/90 hover:bg-red-800 text-white flex items-center justify-center transition opacity-0 group-hover:opacity-100 shadow-lg`}
|
|
>
|
|
<svg
|
|
className="w-6 h-6"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
viewBox="0 0 24 24"
|
|
>
|
|
<path
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth={2}
|
|
d="M9 5l7 7-7 7"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
</>
|
|
)}
|
|
</div>
|
|
|
|
{/* Thumbnail Slider */}
|
|
{imgs.length > 1 && (
|
|
<Swiper
|
|
onSwiper={setThumbsSwiper}
|
|
spaceBetween={10}
|
|
slidesPerView={4}
|
|
breakpoints={{
|
|
640: { slidesPerView: 5 },
|
|
768: { slidesPerView: 6 },
|
|
}}
|
|
watchSlidesProgress
|
|
className="w-full"
|
|
>
|
|
{imgs.map((image, index) => (
|
|
<SwiperSlide key={index}>
|
|
<div className="relative h-20 md:h-24 bg-white rounded-lg overflow-hidden cursor-pointer border-2 border-transparent hover:border-red-700 transition">
|
|
<Image
|
|
src={image}
|
|
alt={`Thumbnail ${index + 1}`}
|
|
fill
|
|
className="object-contain p-2"
|
|
sizes="100px"
|
|
/>
|
|
</div>
|
|
</SwiperSlide>
|
|
))}
|
|
</Swiper>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|