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:
Markus
2026-08-19 22:54:49 +02:00
co-authored by Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
parent 232770afe7
commit 2b24334bfa
153 changed files with 5621 additions and 176 deletions
+95
View File
@@ -0,0 +1,95 @@
"use client";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { Calendar, ArrowRight } from "lucide-react";
import { tomorrowDateString, addMonths } from "@/src/lib/date";
interface BookingBannerProps {
locale: string;
}
export function BookingBanner({ locale }: BookingBannerProps) {
const t = useTranslations("home.bookingBanner");
const router = useRouter();
const [arrival, setArrival] = useState(tomorrowDateString());
const [months, setMonths] = useState(3);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
const departure = addMonths(arrival, months);
const searchParams = new URLSearchParams({
arrival,
departure,
months: String(months),
});
router.push(`/${locale}/houses?${searchParams.toString()}`);
};
return (
<section className="relative z-20 -mt-16 mb-24">
<div className="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
<form
onSubmit={handleSubmit}
className="bg-white rounded-3xl shadow-2xl shadow-brand-grey-dark/15 border border-brand-grey-soft/80 overflow-hidden"
>
<div className="h-1.5 w-full bg-gradient-to-r from-brand-green via-brand-green-light to-brand-green" />
<div className="p-8 md:p-10">
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 items-end">
<div className="space-y-3">
<label
htmlFor="booking-arrival"
className="flex items-center gap-2 text-base font-bold text-brand-grey-dark"
>
<Calendar className="w-5 h-5 text-brand-green" />
{t("arrival")}
</label>
<div className="relative">
<input
id="booking-arrival"
type="date"
required
value={arrival}
min={tomorrowDateString()}
onChange={(e) => setArrival(e.target.value)}
className="w-full pl-4 pr-4 py-4 text-lg rounded-xl border-2 border-brand-grey-soft/60 bg-brand-grey-soft/20 text-brand-grey-dark focus:outline-none focus:ring-2 focus:ring-brand-green focus:border-transparent transition-all"
/>
</div>
</div>
<div className="space-y-3">
<label
htmlFor="booking-months"
className="block text-base font-bold text-brand-grey-dark"
>
{t("stayMonths")}
</label>
<div className="relative">
<input
id="booking-months"
type="number"
min={1}
max={24}
required
value={months}
onChange={(e) => setMonths(Number(e.target.value))}
className="w-full px-4 py-4 text-lg text-center rounded-xl border-2 border-brand-grey-soft/60 bg-brand-grey-soft/20 text-brand-grey-dark focus:outline-none focus:ring-2 focus:ring-brand-green focus:border-transparent transition-all"
/>
</div>
</div>
<button
type="submit"
className="inline-flex items-center justify-center gap-3 bg-brand-green text-white text-lg font-bold px-8 py-4 rounded-xl hover:bg-brand-green-dark hover:shadow-xl hover:-translate-y-1 transition-all"
>
{t("checkAvailability")}
<ArrowRight className="w-6 h-6" />
</button>
</div>
</div>
</form>
</div>
</section>
);
}