Доработки по главной странице, итерация 3

This commit is contained in:
Sergey Bolshakov 2025-10-26 14:47:50 +03:00
parent 6ee8a8f624
commit 0987860f54
9 changed files with 278 additions and 241 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 767 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 KiB

View File

@ -0,0 +1,194 @@
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { DatePicker } from "@/components/ui/date-picker";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import Image from "next/image";
import Icon from "@/components/ui/icon";
const yacht = {
name: "Яхта",
length: "12 метров",
price: "от 18 000 ₽",
perTime: "/ час",
feet: "7 Футов",
mainImage: "/images/yacht.jpg",
thumbnails: [
"/images/yacht.jpg",
"/images/another-yacht.jpg",
"/images/yacht.jpg",
"/images/another-yacht.jpg",
"/images/yacht.jpg",
],
isPromoted: true,
totalPrice: "0 ₽",
};
export default function FeaturedYacht() {
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">
{/* 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={yacht.mainImage}
alt={yacht.name}
width={600}
height={400}
className="w-full h-80 object-cover rounded-lg"
/>
</div>
{/* Thumbnail images */}
<div className="flex gap-3 mb-6 overflow-x-auto">
{yacht.thumbnails.map(
(thumb, idx) => (
<div
key={idx}
className="relative flex-shrink-0"
>
<Image
src={thumb}
alt={`${
yacht.name
} view ${idx + 1}`}
width={80}
height={60}
className={`w-20 h-16 object-cover rounded cursor-pointer border-2 transition-all ${
idx === 0
? "border-blue-500"
: "border-gray-200 hover:border-gray-400"
}`}
/>
</div>
)
)}
</div>
{/* Promoted badge */}
{yacht.isPromoted && (
<div className="flex items-center gap-2 text-sm text-gray-600">
<div className="w-3 h-3 bg-blue-500 rounded-full flex-shrink-0"></div>
<span>
Это объявление продвигается.{" "}
<span className="underline cursor-pointer">
Хотите так же?
</span>
</span>
</div>
)}
</div>
{/* Right side - Booking form */}
<div className="min-w-[296px] flex flex-col justify-between">
<div>
{/* Promoted banner */}
<div
className="text-white flex items-center justify-center py-2 rounded-full text-center mb-6 relative"
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="space-y-5 mb-8">
<div>
<DatePicker />
</div>
<div>
<DatePicker />
</div>
<div>
<Select>
<SelectTrigger className="w-full h-[64px]">
<SelectValue placeholder="1 гость" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1">
1 гость
</SelectItem>
<SelectItem value="2">
2 гостя
</SelectItem>
<SelectItem value="3">
3 гостя
</SelectItem>
<SelectItem value="4">
4 гостя
</SelectItem>
<SelectItem value="5+">
5+ гостей
</SelectItem>
</SelectContent>
</Select>
</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>
);
}

View File

@ -40,7 +40,7 @@ export default function Services() {
<CarouselItem>
<div className="relative group">
<Image
src="/images/rod.png"
src="/images/services/service1.png"
alt="Морская рыбалка в Балаклаве"
width={600}
height={500}
@ -51,7 +51,7 @@ export default function Services() {
<CarouselItem>
<div className="relative group">
<Image
src="/images/rod.png"
src="/images/services/service1.png"
alt="Морская рыбалка в Балаклаве"
width={600}
height={500}
@ -85,7 +85,7 @@ export default function Services() {
<CarouselItem>
<div className="relative group">
<Image
src="/images/rod.png"
src="/images/services/service2.png"
alt="Прогулка на парусной яхте"
width={600}
height={500}
@ -119,11 +119,11 @@ export default function Services() {
<Card className="overflow-hidden">
<div className="relative group">
<Image
src="/images/rod.png"
src="/images/services/service3.png"
alt="Вечеринка на яхте"
width={400}
height={300}
className="w-full h-[300px] object-cover"
height={200}
className="w-full h-[200px] object-cover"
/>
<div className="absolute top-4 right-4">
<Icon
@ -138,6 +138,7 @@ export default function Services() {
<h3 className="text-l font-semibold text-black">
Вечеринка на яхте
</h3>
<p className="text-sm text-gray-500">Свадьба, девичник/мальчишник, день рождения</p>
</div>
</div>
@ -145,11 +146,11 @@ export default function Services() {
<Card className="overflow-hidden">
<div className="relative group">
<Image
src="/images/rod.png"
src="/images/services/service4.png"
alt="Корпоративная прогулка на яхте"
width={400}
height={300}
className="w-full h-[300px] object-cover"
height={200}
className="w-full h-[200px] object-cover"
/>
<div className="absolute top-4 right-4">
<Icon
@ -171,11 +172,11 @@ export default function Services() {
<Card className="overflow-hidden">
<div className="relative group">
<Image
src="/images/rod.png"
src="/images/services/service5.jpg"
alt="Морские прогулки на яхте"
width={400}
height={300}
className="w-full h-[300px] object-cover"
height={200}
className="w-full h-[200px] object-cover"
/>
<div className="absolute top-4 right-4">
<Icon
@ -188,7 +189,7 @@ export default function Services() {
</Card>
<div className="px-2">
<h3 className="text-l font-semibold text-black">
Морские прогулки на яхте в Бал...
Морская прогулка на яхте или катере
</h3>
</div>
</div>

View File

@ -1,15 +1,8 @@
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { DatePicker } from "@/components/ui/date-picker";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import Image from "next/image";
import Icon from "@/components/ui/icon";
import FeaturedYacht from "./FeaturedYacht";
const yachts = [
{
@ -18,7 +11,7 @@ const yachts = [
price: "от 12 500 ₽ / час",
feet: "7 Футов",
img: "/images/yachts/yacht1.jpg",
badge: "Быстрая бронь",
bestOfferText: "🔥 Лучшее предложение",
},
{
name: "Яхта",
@ -26,7 +19,7 @@ const yachts = [
price: "от 26 400 ₽ / час",
feet: "7 Футов",
img: "/images/yachts/yacht2.jpg",
badge: "По запросу",
bestOfferText: "🍷 Идеальна для заката с бокалом вина",
},
{
name: "Яхта",
@ -34,7 +27,7 @@ const yachts = [
price: "от 48 000 ₽ / час",
feet: "7 Футов",
img: "/images/yachts/yacht3.jpg",
badge: "По запросу",
bestOfferText: "⌛ Часто бронируется — успей",
},
{
name: "Яхта",
@ -62,24 +55,6 @@ const yachts = [
},
];
const featuredYacht = {
name: "Яхта",
length: "12 метров",
price: "от 18 000 ₽",
perTime: "/ час",
feet: "7 Футов",
mainImage: "/images/yacht.jpg",
thumbnails: [
"/images/yacht.jpg",
"/images/another-yacht.jpg",
"/images/yacht.jpg",
"/images/another-yacht.jpg",
"/images/yacht.jpg",
],
isPromoted: true,
totalPrice: "0 ₽",
};
export default function YachtGrid() {
return (
<section className="text-white">
@ -102,212 +77,79 @@ export default function YachtGrid() {
</div>
{/* Featured Yacht Block */}
<div className="mb-10">
<Card className="overflow-hidden bg-white text-gray-900 shadow-lg">
<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">
{/* Header with yacht name and length */}
<div className="flex items-center justify-between mb-6">
<h2 className="text-3xl font-bold">
{featuredYacht.name}
</h2>
<div className="flex items-center gap-2 text-gray-600">
<Icon size={16} name="width" />
<span className="text-lg">
{featuredYacht.length}
</span>
</div>
</div>
{/* Main yacht image */}
<div className="relative mb-6">
<Image
src={featuredYacht.mainImage}
alt={featuredYacht.name}
width={600}
height={400}
className="w-full h-80 object-cover rounded-lg"
/>
</div>
{/* Thumbnail images */}
<div className="flex gap-3 mb-6 overflow-x-auto">
{featuredYacht.thumbnails.map(
(thumb, idx) => (
<div
key={idx}
className="relative flex-shrink-0"
>
<Image
src={thumb}
alt={`${
featuredYacht.name
} view ${idx + 1}`}
width={80}
height={60}
className={`w-20 h-16 object-cover rounded cursor-pointer border-2 transition-all ${
idx === 0
? "border-blue-500"
: "border-gray-200 hover:border-gray-400"
}`}
/>
</div>
)
)}
</div>
{/* Promoted badge */}
{featuredYacht.isPromoted && (
<div className="flex items-center gap-2 text-sm text-gray-600">
<div className="w-3 h-3 bg-blue-500 rounded-full flex-shrink-0"></div>
<span>
Это объявление продвигается.{" "}
<span className="text-blue-500 underline cursor-pointer">
Хотите так же?
</span>
</span>
</div>
)}
</div>
{/* Right side - Booking form */}
<div className="min-w-[296px] flex flex-col justify-between">
<div>
{/* Promoted banner */}
<div
className="text-white flex items-center justify-center py-2 rounded-full text-center mb-6 relative"
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">
{featuredYacht.price}
<span className="text-sm font-normal text-gray-500">
{featuredYacht.perTime}
</span>
</p>
</div>
{/* Booking form */}
<div className="space-y-5 mb-8">
<div>
<DatePicker />
</div>
<div>
<DatePicker />
</div>
<div>
<Select>
<SelectTrigger className="w-full h-[64px]">
<SelectValue placeholder="1 гость" />
</SelectTrigger>
<SelectContent>
<SelectItem value="1">
1 гость
</SelectItem>
<SelectItem value="2">
2 гостя
</SelectItem>
<SelectItem value="3">
3 гостя
</SelectItem>
<SelectItem value="4">
4 гостя
</SelectItem>
<SelectItem value="5+">
5+ гостей
</SelectItem>
</SelectContent>
</Select>
</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>
{featuredYacht.totalPrice}
</span>
</div>
</div>
</div>
</div>
</div>
</CardContent>
</Card>
</div>
<FeaturedYacht />
{/* Yacht Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-6">
{yachts.map((yacht, idx) => (
<Card
key={idx}
className="overflow-hidden bg-white text-gray-900"
>
<CardHeader className="p-0 relative">
<div className="relative">
<Image
src={yacht.img}
alt={yacht.name}
width={400}
height={250}
className="w-full h-48 object-cover"
/>
{/* Badge Overlay */}
<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>{yacht.badge}</span>
<div key={idx} className="relative">
<Card className="overflow-hidden bg-white text-gray-900">
<CardHeader className="p-0 relative">
<div className="relative">
{/* Best Offer Badge - над карточкой */}
{yacht.bestOfferText && (
<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.bestOfferText}
</span>
</div>
</div>
)}
<Image
src={yacht.img}
alt={yacht.name}
width={400}
height={250}
className="w-full h-48 object-cover"
/>
{/* Badge Overlay */}
{yacht.badge && (
<>
<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>
{yacht.badge}
</span>
</div>
</div>
</>
)}
</div>
</CardHeader>
<CardContent className="p-4">
<div className="flex justify-between items-start mb-1">
<h3 className="font-bold text-l">
{yacht.name}
</h3>
<div className="text-right">
<p className="text-l">
{yacht.price}
</p>
</div>
</div>
</div>
</CardHeader>
<CardContent className="p-4">
<div className="flex justify-between items-start mb-1">
<h3 className="font-bold text-l">
{yacht.name}
</h3>
<div className="text-right">
<p className="text-l">{yacht.price}</p>
<div className="flex items-center justify-between text-gray-600">
<div className="flex items-center gap-1">
<Icon size={16} name="width" />
<span>{yacht.length}</span>
</div>
<div className="flex items-center gap-1">
<Icon size={16} name="anchor" />
<span>{yacht.feet}</span>
</div>
</div>
</div>
<div className="flex items-center justify-between text-gray-600">
<div className="flex items-center gap-1">
<Icon size={16} name="width" />
<span>{yacht.length}</span>
</div>
<div className="flex items-center gap-1">
<Icon size={16} name="anchor" />
<span>{yacht.feet}</span>
</div>
</div>
</CardContent>
</Card>
</CardContent>
</Card>
</div>
))}
</div>