mirror of
https://github.com/Lapikud/tipilan.git
synced 2026-05-08 10:00:46 +00:00
Add very basic teasercarousel
This commit is contained in:
@@ -15,66 +15,87 @@ type Slide = {
|
|||||||
|
|
||||||
const slides: Slide[] = [
|
const slides: Slide[] = [
|
||||||
{ key: "compete", image: "/images/landing/compete_teaser.jpg", imageAlt: "Võistle", href: "/turniirid" },
|
{ key: "compete", image: "/images/landing/compete_teaser.jpg", imageAlt: "Võistle", href: "/turniirid" },
|
||||||
{ key: "play", image: "/images/landing/play_teaser.png", imageAlt: "Mängi", href: "/piletid" },
|
{ key: "play", image: "/images/landing/play_teaser.png", imageAlt: "Mängi", href: "/piletid" },
|
||||||
{ key: "explore", image: "/images/landing/explore_teaser.png", imageAlt: "Avasta", href: "/messiala" },
|
{ key: "explore", image: "/images/landing/explore_teaser.png", imageAlt: "Avasta", href: "/messiala" },
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function TeaserCarousel() {
|
export default function TeaserCarousel() {
|
||||||
const t = useTranslations("home.teaser");
|
const t = useTranslations("home.teaser");
|
||||||
const [current, setCurrent] = useState(0);
|
const [current, setCurrent] = useState(0);
|
||||||
|
|
||||||
const slide = slides[current];
|
const prev = () => setCurrent((c) => (c - 1 + slides.length) % slides.length);
|
||||||
const title = t(`${slide.key}.title`);
|
const next = () => setCurrent((c) => (c + 1) % slides.length);
|
||||||
const description = t(`${slide.key}.description`);
|
|
||||||
const prize = t.raw(`${slide.key}.prize`) as string | null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="border-b-3 border-[#1F5673]">
|
<div className="border-b-3 border-[#1F5673]">
|
||||||
{/* Card */}
|
{/* Sliding track */}
|
||||||
<div className="relative h-[729px] overflow-hidden">
|
<div className="relative h-[729px] overflow-hidden">
|
||||||
{/* Background image */}
|
<div
|
||||||
<Image
|
className="flex h-full transition-transform duration-500 ease-in-out"
|
||||||
src={slide.image}
|
style={{ transform: `translateX(-${current * 100}%)` }}
|
||||||
alt={slide.imageAlt}
|
>
|
||||||
fill
|
{slides.map((slide) => {
|
||||||
className="object-cover object-center"
|
const title = t(`${slide.key}.title`);
|
||||||
/>
|
const description = t(`${slide.key}.description`);
|
||||||
{/* Dark overlay */}
|
const prize = t.raw(`${slide.key}.prize`) as string | null;
|
||||||
<div className="absolute inset-0 bg-[#0E0F19]/70" />
|
|
||||||
|
|
||||||
{/* Content grid */}
|
return (
|
||||||
<div className="relative grid grid-cols-1 md:grid-cols-[1fr_1fr] h-full">
|
<div key={slide.key} className="relative flex-none w-full h-full">
|
||||||
{/* Left: text */}
|
{/* Background image */}
|
||||||
<div className="flex flex-col justify-between gap-4 px-8 py-8 md:px-12 md:py-10">
|
<Image
|
||||||
<div className="flex flex-col gap-3">
|
src={slide.image}
|
||||||
<h2
|
alt={slide.imageAlt}
|
||||||
className={`${vipnagorgialla.className} font-bold italic text-[clamp(1.1rem,0.9rem+1vw,1.75rem)] text-[#EEE5E5]`}
|
fill
|
||||||
>
|
className="object-cover object-center"
|
||||||
{t("heading")}
|
/>
|
||||||
</h2>
|
{/* Gradient: dark on left, fades out on right */}
|
||||||
<Link href={slide.href}>
|
<div className="absolute inset-0 bg-gradient-to-r from-[#0E0F19]/90 via-[#0E0F19]/60 to-[#0E0F19]/20" />
|
||||||
<h3
|
|
||||||
className={`${vipnagorgialla.className} font-bold italic text-[clamp(2.5rem,2rem+2.5vw,5rem)] leading-none text-[#EEE5E5] hover:text-[#00A3E0] transition`}
|
|
||||||
>
|
|
||||||
{title}
|
|
||||||
</h3>
|
|
||||||
</Link>
|
|
||||||
<p className="text-[clamp(0.875rem,0.75rem+0.5vw,1.1rem)] text-[#EEE5E5] max-w-prose">
|
|
||||||
{description}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{prize && (
|
|
||||||
<p
|
|
||||||
className={`${vipnagorgialla.className} font-bold italic text-[clamp(1.5rem,1.2rem+1.5vw,2.75rem)] text-[#00A3E0]`}
|
|
||||||
>
|
|
||||||
{prize}
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Right: spacer (image shows through the overlay) */}
|
{/* Content */}
|
||||||
<div className="hidden md:block" />
|
<div className="relative grid grid-cols-1 md:grid-cols-2 h-full">
|
||||||
|
<div className="flex flex-col justify-between gap-4 px-8 py-8 md:px-12 md:py-10">
|
||||||
|
<div className="flex flex-col gap-3">
|
||||||
|
<h2 className={`${vipnagorgialla.className} font-bold italic text-[clamp(1.1rem,0.9rem+1vw,1.75rem)] text-[#EEE5E5]`}>
|
||||||
|
{t("heading")}
|
||||||
|
</h2>
|
||||||
|
<Link href={slide.href}>
|
||||||
|
<h3 className={`${vipnagorgialla.className} font-bold italic text-[clamp(2.5rem,2rem+2.5vw,5rem)] leading-none text-[#EEE5E5] hover:text-[#00A3E0] transition`}>
|
||||||
|
{title}
|
||||||
|
</h3>
|
||||||
|
</Link>
|
||||||
|
<p className="text-[clamp(0.875rem,0.75rem+0.5vw,1.1rem)] text-[#EEE5E5] max-w-prose">
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{prize && (
|
||||||
|
<p className={`${vipnagorgialla.className} font-bold italic text-[clamp(1.5rem,1.2rem+1.5vw,2.75rem)] text-[#00A3E0]`}>
|
||||||
|
{prize}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{/* Right side: image shows through */}
|
||||||
|
<div className="hidden md:block" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Arrow buttons */}
|
||||||
|
<button
|
||||||
|
onClick={prev}
|
||||||
|
className="absolute left-4 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center bg-[#0E0F19]/50 hover:bg-[#007CAB] text-[#EEE5E5] transition"
|
||||||
|
aria-label="Previous slide"
|
||||||
|
>
|
||||||
|
<span className="material-symbols-outlined">chevron_left</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={next}
|
||||||
|
className="absolute right-4 top-1/2 -translate-y-1/2 w-10 h-10 flex items-center justify-center bg-[#0E0F19]/50 hover:bg-[#007CAB] text-[#EEE5E5] transition"
|
||||||
|
aria-label="Next slide"
|
||||||
|
>
|
||||||
|
<span className="material-symbols-outlined">chevron_right</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Navigation dots */}
|
{/* Navigation dots */}
|
||||||
@@ -84,9 +105,7 @@ export default function TeaserCarousel() {
|
|||||||
key={i}
|
key={i}
|
||||||
onClick={() => setCurrent(i)}
|
onClick={() => setCurrent(i)}
|
||||||
className={`w-3 h-3 rounded-full transition ${
|
className={`w-3 h-3 rounded-full transition ${
|
||||||
i === current
|
i === current ? "bg-[#007CAB]" : "bg-[#1F5673] hover:bg-[#007CAB]/60"
|
||||||
? "bg-[#007CAB]"
|
|
||||||
: "bg-[#1F5673] hover:bg-[#007CAB]/60"
|
|
||||||
}`}
|
}`}
|
||||||
aria-label={`Slide ${i + 1}`}
|
aria-label={`Slide ${i + 1}`}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user