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,88 @@
|
||||
"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 AvailabilitySearchBarProps {
|
||||
locale: string;
|
||||
defaultArrival?: string;
|
||||
defaultMonths?: number;
|
||||
}
|
||||
|
||||
export function AvailabilitySearchBar({
|
||||
locale,
|
||||
defaultArrival,
|
||||
defaultMonths,
|
||||
}: AvailabilitySearchBarProps) {
|
||||
const t = useTranslations("houses.search");
|
||||
const router = useRouter();
|
||||
const [arrival, setArrival] = useState(defaultArrival || tomorrowDateString());
|
||||
const [months, setMonths] = useState(defaultMonths || 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 (
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
className="bg-white rounded-2xl shadow-lg border border-brand-grey-soft/80 p-6 md:p-8 mb-12"
|
||||
>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 items-end">
|
||||
<div className="space-y-2">
|
||||
<label
|
||||
htmlFor="search-arrival"
|
||||
className="flex items-center gap-2 text-sm font-bold text-brand-grey-dark"
|
||||
>
|
||||
<Calendar className="w-4 h-4 text-brand-green" />
|
||||
{t("arrival")}
|
||||
</label>
|
||||
<input
|
||||
id="search-arrival"
|
||||
type="date"
|
||||
required
|
||||
lang={locale === "de" ? "de-DE" : "en-US"}
|
||||
value={arrival}
|
||||
min={tomorrowDateString()}
|
||||
onChange={(e) => setArrival(e.target.value)}
|
||||
className="w-full px-4 py-3 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 className="space-y-2">
|
||||
<label htmlFor="search-months" className="block text-sm font-bold text-brand-grey-dark">
|
||||
{t("stayMonths")}
|
||||
</label>
|
||||
<input
|
||||
id="search-months"
|
||||
type="number"
|
||||
min={1}
|
||||
max={24}
|
||||
required
|
||||
value={months}
|
||||
onChange={(e) => setMonths(Number(e.target.value))}
|
||||
className="w-full px-4 py-3 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>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="inline-flex items-center justify-center gap-2 bg-brand-green text-white font-bold px-6 py-3 rounded-xl hover:bg-brand-green-dark hover:shadow-lg transition-all"
|
||||
>
|
||||
{t("checkAvailability")}
|
||||
<ArrowRight className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user