import { notFound } from "next/navigation"; import { getTranslations } from "next-intl/server"; import { getApartmentBySlug, getHouseById, bookingConfig } from "@/src/config/apartments"; import { getEffectiveMinStay } from "@/src/lib/beds24"; import { tomorrowDateString } from "@/src/lib/date"; import { Bed, Bath, Users, Calendar, Check, Wind, Sofa, Wifi, WashingMachine, Tv } from "lucide-react"; import { BookingForm } from "@/components/ui/BookingForm"; import { ImageGallery } from "@/components/ui/ImageGallery"; import Link from "next/link"; export async function generateMetadata({ params: { locale, apartmentSlug }, }: { params: { locale: string; apartmentSlug: string }; }) { const apartment = getApartmentBySlug(apartmentSlug); if (!apartment) return { title: "Not Found" }; const t = await getTranslations({ locale, namespace: "metadata" }); return { title: `${apartment.nameEn} - ${t("title")}`, description: apartment.descriptionEn || t("description"), }; } export default async function ApartmentPage({ params: { locale, apartmentSlug }, }: { params: { locale: string; apartmentSlug: string }; }) { const t = await getTranslations({ locale, namespace: "apartment" }); const apartment = getApartmentBySlug(apartmentSlug); const house = apartment ? getHouseById(apartment.houseId) : undefined; if (!apartment || !house) notFound(); // Real, effective minimum stay for this apartment as of "tomorrow" — this // combines Beds24's room-level minimum with whatever the currently active // rate/price plan requires (the higher of the two wins), so it reflects // what a guest could actually book, not just the room's base setting. // The BookingForm re-fetches this whenever the guest picks a different // check-in date, since it can vary by season. const minStayNights = await getEffectiveMinStay( apartment.houseId, apartment.beds24PropertyId, apartment.beds24RoomId, tomorrowDateString(), bookingConfig.minStayNights ); const displayName = locale === "de" ? apartment.name : apartment.nameEn; const displayDescription = locale === "de" ? apartment.description : apartment.descriptionEn; const displayFloor = locale === "de" ? apartment.floor : apartment.floorEn; const amenities = locale === "de" ? apartment.amenities : apartment.amenitiesEn; const houseName = locale === "de" ? house.name : house.nameEn; const hasAmenity = (keys: string[]) => amenities.some((a) => keys.some((k) => a.toLowerCase().includes(k.toLowerCase()))); // Apartment-specific highlights (excludes "Fully furnished", already shown elsewhere) const specificHighlights = [ hasAmenity(["Klimaanlage", "Air conditioning"]) && { icon: Wind, title: locale === "de" ? "Klimaanlage" : "Air conditioning", }, hasAmenity(["Waschmaschine", "Washing machine"]) && { icon: WashingMachine, title: locale === "de" ? "Eigene Waschmaschine" : "In-unit Washer", }, hasAmenity(["WLAN", "WiFi"]) && { icon: Wifi, title: locale === "de" ? "High-Speed WLAN" : "High-Speed WiFi", }, hasAmenity(["TV"]) && { icon: Tv, title: "Smart TV", }, ].filter(Boolean) as { icon: typeof Wind; title: string }[]; return (
{houseName} • {displayFloor}
{displayDescription && ({displayDescription}
)}{t("guests")}
{apartment.maxGuests}
{t("minStay")}
{minStayNights} {t("nights")}
{locale === "de" ? "Klimaanlage" : "Air conditioning"}
{locale === "de" ? "Vorhanden" : "Available"}
{locale === "de" ? "Vollmöbliert" : "Fully furnished"}
{locale === "de" ? "Ja" : "Yes"}
{locale === "de" ? "Schlafzimmer" : "Bedrooms"}
{apartment.bedrooms}
{locale === "de" ? "Bäder" : "Bathrooms"}
{apartment.bathrooms}
{highlight.title}