Initial upload of BB-Apartment 2026 website.
Adds the complete Next.js website including i18n routing, house and apartment pages, Beds24 v2 integration for live availability/pricing, Stripe checkout, contact forms, Docker setup and deployment docs. Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent
232770afe7
commit
2b24334bfa
@@ -0,0 +1,102 @@
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { Apartment, House } from "@/src/config/apartments";
|
||||
import { formatPrice } from "@/src/lib/pricing";
|
||||
import { CheckCircle2, XCircle, Users, MapPin, ArrowRight } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
interface AvailableApartmentCardProps {
|
||||
apartment: Apartment;
|
||||
house: House;
|
||||
locale: string;
|
||||
available: boolean;
|
||||
minStayValid: boolean;
|
||||
pricePerNight?: number;
|
||||
currency?: string;
|
||||
arrival: string;
|
||||
departure: string;
|
||||
}
|
||||
|
||||
export function AvailableApartmentCard({
|
||||
apartment,
|
||||
house,
|
||||
locale,
|
||||
available,
|
||||
minStayValid,
|
||||
pricePerNight,
|
||||
currency,
|
||||
arrival,
|
||||
departure,
|
||||
}: AvailableApartmentCardProps) {
|
||||
const t = useTranslations("houses.search");
|
||||
const displayName = locale === "de" ? apartment.name : apartment.nameEn;
|
||||
const houseName = locale === "de" ? house.name : house.nameEn;
|
||||
const canBook = available && minStayValid;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`bg-white rounded-2xl overflow-hidden shadow-sm border transition-shadow ${
|
||||
canBook
|
||||
? "border-brand-grey-soft hover:shadow-lg"
|
||||
: "border-brand-grey-soft opacity-70"
|
||||
}`}
|
||||
>
|
||||
<div className="relative h-48">
|
||||
<Image
|
||||
src={apartment.images[0] || "/images/placeholder.jpg"}
|
||||
alt={displayName}
|
||||
fill
|
||||
className={`object-cover ${canBook ? "" : "grayscale"}`}
|
||||
/>
|
||||
<div
|
||||
className={`absolute top-3 right-3 flex items-center gap-1.5 text-xs font-semibold px-2.5 py-1.5 rounded-full backdrop-blur-sm ${
|
||||
canBook ? "bg-brand-green/90 text-white" : "bg-white/90 text-brand-grey"
|
||||
}`}
|
||||
>
|
||||
{canBook ? (
|
||||
<CheckCircle2 className="w-3.5 h-3.5" />
|
||||
) : (
|
||||
<XCircle className="w-3.5 h-3.5" />
|
||||
)}
|
||||
{canBook ? t("available") : !minStayValid ? t("minStayNotMet") : t("notAvailable")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-5">
|
||||
<h3 className="text-lg font-bold mb-1 text-brand-grey-dark">{displayName}</h3>
|
||||
<div className="flex items-center gap-1.5 text-sm text-brand-grey mb-3">
|
||||
<MapPin className="w-4 h-4 text-brand-green" />
|
||||
<span>{houseName}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sm text-brand-grey mb-1">
|
||||
<Users className="w-4 h-4 text-brand-green" />
|
||||
<span>
|
||||
{apartment.maxGuests} {locale === "de" ? "Gäste" : "guests"}
|
||||
</span>
|
||||
</div>
|
||||
{canBook && pricePerNight !== undefined && (
|
||||
<p className="text-lg font-bold text-brand-green-dark mb-4">
|
||||
{formatPrice(pricePerNight, currency)}{" "}
|
||||
<span className="text-sm font-normal text-brand-grey">/ {t("perNight")}</span>
|
||||
</p>
|
||||
)}
|
||||
|
||||
{canBook ? (
|
||||
<Link
|
||||
href={`/${locale}/apartments/${apartment.slug}?checkin=${arrival}&checkout=${departure}`}
|
||||
className="inline-flex items-center justify-center gap-2 w-full bg-brand-green text-white font-semibold px-4 py-3 rounded-xl hover:bg-brand-green-dark transition-colors"
|
||||
>
|
||||
{t("bookThis")}
|
||||
<ArrowRight className="w-4 h-4" />
|
||||
</Link>
|
||||
) : (
|
||||
<Link
|
||||
href={`/${locale}/apartments/${apartment.slug}`}
|
||||
className="inline-flex items-center justify-center gap-2 w-full bg-brand-grey-soft text-brand-grey-dark font-semibold px-4 py-3 rounded-xl hover:bg-brand-grey-soft/70 transition-colors"
|
||||
>
|
||||
{locale === "de" ? "Details ansehen" : "View details"}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user