Files
cd7b7d58-a585-42e5-acb1-390…/src/components/sections/hero/HeroBillboard.tsx
2026-05-07 15:00:10 +00:00

107 lines
3.6 KiB
TypeScript

import Button from "@/components/ui/Button";
import HeroBackgroundSlot from "@/components/ui/HeroBackgroundSlot";
import TextAnimation from "@/components/ui/TextAnimation";
import ImageOrVideo from "@/components/ui/ImageOrVideo";
import ScrollReveal from "@/components/ui/ScrollReveal";
import AvatarGroup from "@/components/ui/AvatarGroup";
import { Clock, ShieldCheck, DollarSign } from "lucide-react";
type HeroBillboardProps = {
tag?: string;
title: string;
description: string;
primaryButton: { text: string; href: string };
secondaryButton: { text: string; href: string };
avatars?: { src: string }[];
avatarsLabel?: string;
} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never });
const HeroBillboard = ({
tag,
title,
description,
primaryButton,
secondaryButton,
avatars,
avatarsLabel,
imageSrc,
videoSrc,
}: HeroBillboardProps) => {
const usps = [
{
icon: Clock,
title: "24/7 Service",
description: "Always available for emergency repairs.",
},
{
icon: ShieldCheck,
title: "Certified Technicians",
description: "Expertise you can trust for every job.",
},
{
icon: DollarSign,
title: "Transparent Pricing",
description: "No hidden fees, just honest quotes.",
},
];
return (
<section aria-label="Hero section" className="relative pt-25 pb-20 md:py-30 mb-20">
<HeroBackgroundSlot />
<div className="flex flex-col gap-10 w-content-width mx-auto">
<div className="flex flex-col items-center gap-2 text-center">
{avatars && avatars.length > 0 ? (
<AvatarGroup avatars={avatars} label={avatarsLabel} />
) : tag ? (
<span className="px-3 py-1 mb-1 text-sm card rounded">{tag}</span>
) : null}
<TextAnimation
text={title}
variant="slide-up"
gradientText={true}
tag="h1"
className="text-6xl font-medium text-balance"
/>
<TextAnimation
text={description}
variant="slide-up"
gradientText={false}
tag="p"
className="text-base md:text-lg leading-tight text-balance"
/>
<div className="flex flex-wrap justify-center gap-3 mt-3">
<Button text={primaryButton.text} href={primaryButton.href} variant="primary"/>
<Button text={secondaryButton.text} href={secondaryButton.href} variant="secondary" animationDelay={0.1} />
</div>
</div>
<ScrollReveal variant="fade-blur" delay={0.2} className="relative w-full p-3 xl:p-4 2xl:p-5 card rounded overflow-hidden">
<ImageOrVideo imageSrc={imageSrc} videoSrc={videoSrc} className="aspect-4/5 md:aspect-video" />
<div className="absolute inset-0 flex justify-center items-center">
{usps.map((usp, index) => (
<div
key={index}
className={`absolute bg-white/10 backdrop-blur-lg rounded-lg p-4 flex flex-col items-center justify-center text-center text-white border border-white/20
${index === 0 ? 'bottom-4 left-4' : ''}
${index === 1 ? 'top-4' : ''}
${index === 2 ? 'bottom-4 right-4' : ''}
`}
style={{ width: '200px', height: '150px' }}
>
<usp.icon className="w-8 h-8 mb-2" />
<h3 className="font-semibold text-lg">{usp.title}</h3>
<p className="text-sm">{usp.description}</p>
</div>
))}
</div>
</ScrollReveal>
</div>
</section>
);
};
export default HeroBillboard;