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,89 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
|
||||
interface HeroProps {
|
||||
title: string;
|
||||
subtitle: string;
|
||||
description: string;
|
||||
cta: string;
|
||||
ctaHref: string;
|
||||
}
|
||||
|
||||
const heroImages = [
|
||||
{ src: "/images/heroshots/MKE_1996.JPG", alt: "BB-Apartment Hero 1" },
|
||||
{ src: "/images/heroshots/MKE_1959.JPG", alt: "BB-Apartment Hero 2" },
|
||||
{ src: "/images/heroshots/MKE_1974.jpg", alt: "BB-Apartment Hero 3" },
|
||||
];
|
||||
|
||||
export function Hero({ title, subtitle, description, cta, ctaHref }: HeroProps) {
|
||||
const [activeIndex, setActiveIndex] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setActiveIndex((prev) => (prev + 1) % heroImages.length);
|
||||
}, 5000);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<section className="relative -mt-20 pt-20 h-screen flex items-center justify-center overflow-hidden">
|
||||
<div className="absolute inset-0 z-0">
|
||||
{heroImages.map((image, index) => (
|
||||
<div
|
||||
key={image.src}
|
||||
className={`absolute inset-0 transition-opacity duration-1000 ease-in-out ${
|
||||
index === activeIndex ? "opacity-100" : "opacity-0"
|
||||
}`}
|
||||
>
|
||||
<Image
|
||||
src={image.src}
|
||||
alt={image.alt}
|
||||
fill
|
||||
className="object-cover"
|
||||
priority={index === 0}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
<div className="absolute inset-0 bg-black/20" />
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 max-w-5xl mx-auto px-4 sm:px-6 text-center text-white">
|
||||
<p className="text-lg md:text-xl text-brand-green-light mb-4 font-medium tracking-wide uppercase">
|
||||
{subtitle}
|
||||
</p>
|
||||
<h1 className="text-5xl md:text-7xl font-bold mb-10 text-white tracking-tight">
|
||||
{title}
|
||||
</h1>
|
||||
{description && (
|
||||
<p className="text-lg md:text-2xl text-white/90 mb-10 max-w-3xl mx-auto leading-relaxed">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
<Link
|
||||
href={ctaHref}
|
||||
className="inline-flex items-center gap-2 bg-brand-green text-white font-semibold px-8 py-4 rounded-2xl text-lg hover:bg-brand-green-dark hover:shadow-lg hover:-translate-y-0.5 transition-all"
|
||||
>
|
||||
{cta}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="absolute bottom-8 left-1/2 -translate-x-1/2 z-20 flex gap-2">
|
||||
{heroImages.map((_, index) => (
|
||||
<button
|
||||
key={index}
|
||||
onClick={() => setActiveIndex(index)}
|
||||
className={`w-2.5 h-2.5 rounded-full transition-all ${
|
||||
index === activeIndex
|
||||
? "bg-white scale-110"
|
||||
: "bg-white/50 hover:bg-white/80"
|
||||
}`}
|
||||
aria-label={`Zum Hero-Bild ${index + 1} wechseln`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user