164 lines
6.6 KiB
TypeScript
164 lines
6.6 KiB
TypeScript
"use client";
|
||
|
||
import { Card, CardContent, CardHeader } from "@/components/ui/card";
|
||
import { Button } from "@/components/ui/button";
|
||
import Image from "next/image";
|
||
import Icon from "@/components/ui/icon";
|
||
import Link from "next/link";
|
||
import FeaturedYacht from "./FeaturedYacht";
|
||
import useApiClient from "@/hooks/useApiClient";
|
||
import { useEffect, useState } from "react";
|
||
import {
|
||
formatMinCost,
|
||
formatSpeed,
|
||
formatWidth,
|
||
getImageUrl,
|
||
} from "@/lib/utils";
|
||
|
||
export default function YachtGrid() {
|
||
const client = useApiClient();
|
||
|
||
const [featuredYacht, setFeaturedYacht] =
|
||
useState<CatalogItemShortDto | null>(null);
|
||
const [yachtCatalog, setYachtCatalog] = useState<
|
||
CatalogItemShortDto[] | null
|
||
>(null);
|
||
|
||
useEffect(() => {
|
||
(async () => {
|
||
const response = await client.get<MainPageCatalogResponseDto>(
|
||
"/catalog/main-page/"
|
||
);
|
||
setFeaturedYacht(response.data.featuredYacht);
|
||
setYachtCatalog(response.data.restYachts);
|
||
})();
|
||
}, []);
|
||
|
||
return (
|
||
<section className="text-white">
|
||
<div className="container max-w-6xl mx-auto px-4 mt-6 md:mt-12">
|
||
{/* Header Section */}
|
||
<div className="mb-6">
|
||
<h1 className="text-3xl md:text-4xl font-bold mb-4 text-black">
|
||
Яхты и катера в аренду
|
||
</h1>
|
||
<h2 className="text-l text-black font-bold mb-2">
|
||
Онлайн бронирование яхт и катеров
|
||
</h2>
|
||
<p className="text-gray-700 max-w-3xl leading-relaxed">
|
||
Каталог лучших яхт Балаклавы разных ценовых сегментах.
|
||
</p>
|
||
<p className="text-gray-700 leading-relaxed">
|
||
Проверенные лодки с лицензией на перевозки, опытные капитаны.
|
||
Выбирайте удобную дату, время и бронируйте.
|
||
</p>
|
||
</div>
|
||
|
||
{/* Featured Yacht Block */}
|
||
{featuredYacht && <FeaturedYacht yacht={featuredYacht} />}
|
||
|
||
{/* Yacht Grid */}
|
||
{yachtCatalog && (
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-6">
|
||
{yachtCatalog.map((yacht) => (
|
||
<Link
|
||
key={yacht.id}
|
||
href={`/catalog/${yacht.id ?? 0}`}
|
||
className="block"
|
||
>
|
||
<Card className="overflow-hidden bg-white text-gray-900 cursor-pointer transition-all duration-200 hover:shadow-lg">
|
||
<CardHeader className="p-0 relative">
|
||
<div className="relative">
|
||
{/* Best Offer Badge - над карточкой */}
|
||
{yacht.topText && (
|
||
<div className="w-full flex justify-center">
|
||
<div
|
||
className="flex w-full items-center justify-center text-white px-4 py-2 text-sm font-medium bg-cover bg-center bg-no-repeat"
|
||
style={{
|
||
backgroundImage:
|
||
"url('/images/best-yacht-bg.jpg')",
|
||
}}
|
||
>
|
||
<span>{yacht.topText}</span>
|
||
</div>
|
||
</div>
|
||
)}
|
||
<Image
|
||
src={getImageUrl(yacht.mainImageUrl)}
|
||
alt={yacht.name}
|
||
width={400}
|
||
height={250}
|
||
className="w-full h-48 object-cover"
|
||
/>
|
||
{/* Badge Overlay */}
|
||
{!yacht.hasQuickRent && !yacht.topText && (
|
||
<>
|
||
<div className="absolute top-3 left-3">
|
||
<div className="flex items-center justify-center bg-black/40 text-white px-3 py-1 rounded-lg text-sm flex items-center gap-1">
|
||
<Icon size={16} name="restart" />
|
||
<span>По запросу</span>
|
||
</div>
|
||
</div>
|
||
</>
|
||
)}
|
||
</div>
|
||
</CardHeader>
|
||
<CardContent className="p-4">
|
||
<div className="flex justify-between gap-4">
|
||
{/* Левая колонка - название и длина */}
|
||
<div className="space-y-2">
|
||
<h3 className="font-bold text-l">{yacht.name}</h3>
|
||
<div className="flex items-center gap-1 text-sm">
|
||
<Icon size={16} name="width" />
|
||
<span>{formatWidth(yacht.length)}</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Правая колонка - цена и футы */}
|
||
<div className="flex flex-col justify-between">
|
||
<div className="w-fit">
|
||
{yacht.isBestOffer ? (
|
||
<p
|
||
style={{
|
||
background:
|
||
"linear-gradient(90deg, #008299 0%, #7E8FFF 100%)",
|
||
}}
|
||
className="text-l font-bold text-white pl-2 pr-3 rounded-t-[5px] rounded-bl-[10px] rounded-br-[30px] whitespace-nowrap"
|
||
>
|
||
{formatMinCost(yacht.minCost)} / час
|
||
</p>
|
||
) : (
|
||
<p className="w-fit text-l whitespace-nowrap">
|
||
{formatMinCost(yacht.minCost)} / час
|
||
</p>
|
||
)}
|
||
</div>
|
||
<div className="flex items-center gap-1 text-sm">
|
||
<Icon size={16} name="anchor" />
|
||
<span>{formatSpeed(yacht.speed)}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</Link>
|
||
))}
|
||
</div>
|
||
)}
|
||
|
||
{/* Call to Action Button */}
|
||
<div className="text-center">
|
||
<Link href="/catalog">
|
||
<Button
|
||
size="lg"
|
||
className="bg-white text-gray-900 hover:bg-gray-100 px-8 py-3 h-[56px] w-[336px] text-lg font-bold"
|
||
>
|
||
Каталог яхт
|
||
</Button>
|
||
</Link>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
);
|
||
}
|