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

151 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

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 { useState } from "react";
import { Calendar } from "@/components/ui/calendar";
import { format } from "date-fns";
import { ru } from "date-fns/locale";
import { ChevronLeft, ChevronRight } from "lucide-react";
import Icon from "@/components/ui/icon";
interface YachtAvailabilityProps {
price: string;
}
export function YachtAvailability({ price }: YachtAvailabilityProps) {
const [currentMonth, setCurrentMonth] = useState(new Date(2025, 3, 1)); // Апрель 2025
// Генерируем доступные даты (27, 28, 29 апреля доступны)
const availableDates = [
new Date(2025, 3, 27),
new Date(2025, 3, 28),
new Date(2025, 3, 29),
];
const unavailableDates = Array.from({ length: 26 }, (_, i) => {
return new Date(2025, 3, i + 1);
});
const isDateAvailable = (date: Date) => {
return availableDates.some(
(d) =>
d.getDate() === date.getDate() &&
d.getMonth() === date.getMonth() &&
d.getFullYear() === date.getFullYear()
);
};
const isDateUnavailable = (date: Date) => {
return unavailableDates.some(
(d) =>
d.getDate() === date.getDate() &&
d.getMonth() === date.getMonth() &&
d.getFullYear() === date.getFullYear()
);
};
const handlePreviousMonth = () => {
setCurrentMonth(
new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1)
);
};
const handleNextMonth = () => {
setCurrentMonth(
new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 1)
);
};
return (
<div className="space-y-4">
<div className="flex items-center justify-between">
<h2 className="text-xl font-bold text-[#333333]">
Доступность яхты
</h2>
<div className="flex items-center gap-2 text-sm text-[#999999]">
<Icon name="calendar" size={16} />
<span>По местному времени яхты</span>
</div>
</div>
<div className="bg-white border border-gray-200 rounded-lg p-4">
<div className="flex items-center justify-between mb-4">
<button
onClick={handlePreviousMonth}
className="p-2 hover:bg-gray-100 rounded-md transition-colors"
>
<ChevronLeft className="w-5 h-5 text-gray-600" />
</button>
<h3 className="text-lg font-semibold text-[#333333] capitalize">
{format(currentMonth, "LLLL yyyy", { locale: ru })}
</h3>
<button
onClick={handleNextMonth}
className="p-2 hover:bg-gray-100 rounded-md transition-colors"
>
<ChevronRight className="w-5 h-5 text-gray-600" />
</button>
</div>
<Calendar
mode="single"
month={currentMonth}
onMonthChange={setCurrentMonth}
className="w-full"
locale={ru}
classNames={{
root: "w-full",
month: "flex w-full flex-col gap-4",
month_caption:
"flex h-8 w-full items-center justify-center px-8 text-gray-700 font-semibold",
table: "w-full border-collapse",
weekdays: "flex",
weekday:
"flex-1 text-gray-500 text-xs font-normal p-2 text-center",
week: "mt-2 flex w-full",
day: "relative",
}}
components={{
DayButton: ({ day, ...props }) => {
const isAvailable = isDateAvailable(day.date);
const isUnavailable = isDateUnavailable(day.date);
const isDay30 = day.date.getDate() === 30;
return (
<button
{...props}
className={`relative w-full h-16 flex flex-col items-center justify-center rounded-md transition-colors ${
isAvailable
? "bg-[#008299] text-white hover:bg-[#008299]"
: isUnavailable || isDay30
? "text-gray-400 cursor-not-allowed bg-gray-100"
: "hover:bg-gray-100"
}`}
disabled={isUnavailable || isDay30}
>
<span className="text-sm font-medium">
{day.date.getDate()}
</span>
{isAvailable && (
<>
<span className="text-[10px] mt-1 text-center leading-tight">
Доступно: 08:00-20:00
</span>
<span className="text-[10px] mt-0.5 text-center leading-tight">
{price} р/час
</span>
</>
)}
{(isUnavailable || isDay30) && (
<span className="text-lg mt-1"></span>
)}
</button>
);
},
}}
/>
</div>
</div>
);
}