travelmarine-frontend/src/app/components/FeaturedYacht.tsx

215 lines
11 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel";
import Image from "next/image";
import Icon from "@/components/ui/icon";
import { useState } from "react";
import { GuestDatePicker } from "@/components/form/guest-date-picker";
const yacht = {
name: "Яхта",
length: "12 метров",
price: "от 18 000 ₽",
perTime: "/ час",
feet: "7 Футов",
mainImage: "/images/featured-yacht/featured1.png",
thumbnails: [
"/images/featured-yacht/featured1.png",
"/images/featured-yacht/featured2.png",
"/images/featured-yacht/featured3.png",
"/images/featured-yacht/featured4.png",
"/images/featured-yacht/featured5.png",
"/images/featured-yacht/featured6.png",
"/images/featured-yacht/featured7.png",
"/images/featured-yacht/featured8.png",
"/images/featured-yacht/featured9.png",
"/images/featured-yacht/featured10.png",
],
isPromoted: true,
totalPrice: "0 ₽",
};
export default function FeaturedYacht() {
const [selectedImage, setSelectedImage] = useState(yacht.mainImage);
const handleThumbnailClick = (imageSrc: string) => {
setSelectedImage(imageSrc);
};
return (
<div className="mb-10">
<Card className="overflow-hidden bg-white text-gray-900">
<CardContent className="p-0">
<div className="flex flex-col lg:flex-row gap-11 px-6 py-10">
{/* Left side - Yacht details and images */}
<div className="flex-1">
{/* Promoted banner - Mobile only */}
<div
className="text-white flex items-center justify-center py-2 rounded-full text-center mb-6 relative lg:hidden"
style={{
backgroundImage:
"url(/images/badge-bg.jpg)",
backgroundSize: "cover",
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
}}
>
<span className="text-xs font-medium relative z-10">
Заметнее других бронируют быстрее
</span>
</div>
{/* Header with yacht name and length */}
<div className="flex items-center justify-between mb-6">
<h2 className="text-3xl font-bold">
{yacht.name}
</h2>
<div className="flex items-center gap-2 text-gray-600">
<Icon size={16} name="width" />
<span className="text-lg">
{yacht.length}
</span>
</div>
</div>
{/* Main yacht image */}
<div className="relative mb-6">
<Image
src={selectedImage}
alt={yacht.name}
width={600}
height={400}
className="w-full h-80 object-cover rounded-[24px]"
/>
</div>
{/* Thumbnail images carousel */}
<div className="relative mb-6">
<Carousel
opts={{
align: "start",
loop: false,
slidesToScroll: 2,
}}
className="w-full"
>
<CarouselContent className="-ml-2 md:-ml-4">
{yacht.thumbnails.map((thumb, idx) => (
<CarouselItem
key={idx}
className="pl-2 md:pl-4 basis-auto"
>
<div className="relative">
<Image
src={thumb}
alt={`${
yacht.name
} view ${idx + 1}`}
width={80}
height={60}
className={`w-20 h-16 object-cover rounded-[8px] cursor-pointer border-2 transition-all ${
selectedImage ===
thumb
? "border-[#008299]"
: "border-gray-200 hover:border-gray-400"
}`}
onClick={() =>
handleThumbnailClick(
thumb
)
}
/>
</div>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious className="absolute left-2 top-1/2 -translate-y-1/2 bg-white hover:bg-gray-50 shadow-lg z-10" />
<CarouselNext className="absolute right-2 top-1/2 -translate-y-1/2 bg-white hover:bg-gray-50 shadow-lg z-10" />
</Carousel>
</div>
{/* Promoted badge */}
{yacht.isPromoted && (
<div className="flex items-center gap-2 text-sm text-gray-400">
<Icon className="min-w-[21px] min-h-[21px]" size={21} name="ad" />
<span>
Это объявление продвигается.{" "}
<span className="underline cursor-pointer">
Хотите так же?
</span>
</span>
</div>
)}
</div>
{/* Right side - Booking form */}
<div className="min-w-[296px] flex-0 flex flex-col justify-between">
<div>
{/* Promoted banner - Desktop only */}
<div
className="text-white flex items-center justify-center py-2 rounded-full text-center mb-6 relative hidden lg:flex"
style={{
backgroundImage:
"url(/images/badge-bg.jpg)",
backgroundSize: "cover",
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
}}
>
<span className="text-xs font-medium relative z-10">
Заметнее других бронируют быстрее
</span>
</div>
<div className="border rounded-[16px] p-6 pb-8 border-gray-200 pt-6">
{/* Price */}
<div className="mb-6">
<p className="text-3xl font-bold">
{yacht.price}
<span className="text-sm font-normal text-gray-500">
{yacht.perTime}
</span>
</p>
</div>
{/* Booking form */}
<div className="mb-8">
<div>
<GuestDatePicker />
</div>
</div>
{/* Book button */}
<Button
variant="gradient"
className="font-bold text-white h-[64px] w-full px-8"
>
Забронировать
</Button>
{/* Total price */}
<div className="flex justify-between items-center text-l mt-6 font-bold text-gray-800">
<span className="font-normal">
Итого:
</span>
<span>{yacht.totalPrice}</span>
</div>
</div>
</div>
</div>
</div>
</CardContent>
</Card>
</div>
);
}