Files
lambada-fiesta-live/src/components/HeroSection.tsx
Antoni Nuñez Romeu 445e1570b4
All checks were successful
Deploy NPM app / Deploy NPM (push) Successful in 53s
Font changes & adjustments in size, remove jenkins file & less tasks to runners.
2026-03-19 18:16:44 +01:00

113 lines
3.9 KiB
TypeScript

import { useState, useEffect } from "react";
import { motion } from "framer-motion";
import { Button } from "@/components/ui/button";
import { EVENT_INFO } from "@/data/event-data";
import heroBg from "@/assets/hero-bg.jpg";
/** Calcula diferencia entre ahora y la fecha del evento */
const getTimeLeft = (target: string) => {
const diff = new Date(target).getTime() - Date.now();
if (diff <= 0) return { days: 0, hours: 0, minutes: 0, seconds: 0 };
return {
days: Math.floor(diff / (1000 * 60 * 60 * 24)),
hours: Math.floor((diff / (1000 * 60 * 60)) % 24),
minutes: Math.floor((diff / (1000 * 60)) % 60),
seconds: Math.floor((diff / 1000) % 60),
};
};
const HeroSection = () => {
const [timeLeft, setTimeLeft] = useState(getTimeLeft(EVENT_INFO.date));
useEffect(() => {
const timer = setInterval(() => {
setTimeLeft(getTimeLeft(EVENT_INFO.date));
}, 1000);
return () => clearInterval(timer);
}, []);
const countdownItems = [
{ value: timeLeft.days, label: "Días" },
{ value: timeLeft.hours, label: "Horas" },
{ value: timeLeft.minutes, label: "Min" },
{ value: timeLeft.seconds, label: "Seg" },
];
return (
<section
className="relative min-h-[calc(100vh+50px)] flex items-center justify-center overflow-hidden z-20 pb-[50px]"
style={{ clipPath: "polygon(0 0, 100% 0, 100% calc(100% - 50px), 50% 100%, 0 calc(100% - 50px))" }}
>
{/* Background image */}
<div
className="absolute inset-0 bg-cover bg-center"
style={{ backgroundImage: `url(${heroBg})` }}
/>
{/* Overlay */}
<div className="absolute inset-0 bg-gradient-to-b from-foreground/70 via-foreground/50 to-foreground/80" />
<div className="relative z-10 text-center px-4 max-w-4xl mx-auto">
<motion.p
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.2 }}
className="text-primary font-body text-sm uppercase tracking-[0.3em] mb-4"
>
{EVENT_INFO.dateDisplay} · {EVENT_INFO.city}
</motion.p>
<motion.h1
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.4 }}
className="font-hero text-5xl md:text-7xl lg:text-8xl font-black text-primary-foreground mb-4 leading-tight"
>
{EVENT_INFO.name}
</motion.h1>
<motion.p
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.6 }}
className="text-primary-foreground/80 font-body text-lg md:text-xl mb-10"
>
{EVENT_INFO.subtitle}
</motion.p>
{/* Countdown */}
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.8 }}
className="flex justify-center gap-4 md:gap-8 mb-10"
>
{countdownItems.map((item) => (
<div key={item.label} className="text-center">
<div className="bg-primary-foreground/10 backdrop-blur-sm border border-primary-foreground/20 rounded-lg px-4 py-3 md:px-6 md:py-4 min-w-[60px] md:min-w-[80px]">
<span className="text-2xl md:text-4xl font-hero font-bold text-primary-foreground">
{String(item.value).padStart(2, "0")}
</span>
</div>
<p className="text-primary-foreground/60 text-xs mt-2 uppercase tracking-wider">
{item.label}
</p>
</div>
))}
</motion.div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 1 }}
>
<Button variant="hero" size="lg" className="text-lg px-10 py-6" asChild>
<a href="#booking">Reservar tu pase</a>
</Button>
</motion.div>
</div>
</section>
);
};
export default HeroSection;