travelmarine-frontend/src/app/catalog/[id]/components/YachtGallery.tsx

111 lines
4.2 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import Image from "next/image";
import Icon from "@/components/ui/icon";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
type CarouselApi,
} from "@/components/ui/carousel";
interface YachtGalleryProps {
images: string[];
badge?: string;
}
export function YachtGallery({ images, badge }: YachtGalleryProps) {
const [api, setApi] = useState<CarouselApi>();
const [current, setCurrent] = useState(0);
useEffect(() => {
if (!api) {
return;
}
setCurrent(api.selectedScrollSnap());
api.on("select", () => {
setCurrent(api.selectedScrollSnap());
});
}, [api]);
const scrollTo = (index: number) => {
api?.scrollTo(index);
};
return (
<div className="space-y-4">
{/* Main Image Carousel */}
<div className="relative">
<Carousel
setApi={setApi}
opts={{
align: "start",
loop: false,
}}
className="w-full"
>
<CarouselContent>
{images.map((img, index) => (
<CarouselItem key={index}>
<div className="relative w-full h-[60vh] lg:h-[592px] rounded-0 lg:rounded-[24px] overflow-hidden">
<Image
src={img}
alt={`Yacht image ${index + 1}`}
fill
className="object-cover"
priority={index === 0}
/>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious className="left-2 lg:left-4 bg-white/80 hover:bg-white border-gray-300 w-10 h-10 lg:w-12 lg:h-12 rounded-full" />
<CarouselNext className="right-2 lg:right-4 bg-white/80 hover:bg-white border-gray-300 w-10 h-10 lg:w-12 lg:h-12 rounded-full" />
</Carousel>
{/* Badge - поверх слайдера, не скроллится */}
{badge && (
<div className="absolute bottom-4 left-4 z-20 pointer-events-none">
<div className="flex items-center justify-center bg-black/40 text-white px-3 py-1 rounded-lg text-sm gap-1">
<Icon size={16} name="restart" />
<span>{badge}</span>
</div>
</div>
)}
{/* Photo counter - поверх слайдера, не скроллится */}
<div className="absolute bottom-4 right-4 z-20 pointer-events-none">
<div className="bg-black/40 text-white px-3 py-1 rounded-lg text-sm">
{current + 1}/{images.length}
</div>
</div>
</div>
{/* Thumbnails - скрыты на мобильных */}
<div className="hidden lg:flex gap-2 overflow-x-auto pb-2">
{images.map((img, index) => (
<button
key={index}
onClick={() => scrollTo(index)}
className={`relative flex-shrink-0 w-17 h-14 rounded-lg overflow-hidden border-2 transition-all ${
current === index
? "border-[#008299] opacity-100"
: "border-transparent opacity-60 hover:opacity-100"
}`}
>
<Image
src={img}
alt={`Thumbnail ${index + 1}`}
fill
className="object-cover"
/>
</button>
))}
</div>
</div>
);
}