From c4541f461ab816fa7d96d42cf6d134c94bd46ee1 Mon Sep 17 00:00:00 2001 From: headpatsyou Date: Wed, 7 Jan 2026 13:05:40 +0000 Subject: [PATCH] feat: add homepage image carousel with controls --- src/app/en/page.tsx | 3 ++ src/app/globals.css | 66 +++++++++++++++++++++++++ src/app/pt/page.tsx | 3 ++ src/components/layout/ImageCarousel.tsx | 64 ++++++++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 src/components/layout/ImageCarousel.tsx diff --git a/src/app/en/page.tsx b/src/app/en/page.tsx index f68cf0a..0737706 100644 --- a/src/app/en/page.tsx +++ b/src/app/en/page.tsx @@ -1,7 +1,10 @@ +import { ImageCarousel } from "@/components/layout/ImageCarousel"; + export default function EnHome() { return (
+

Portuguese Powerlifting Association

Accessible. Transparent. For all athletes.

diff --git a/src/app/globals.css b/src/app/globals.css index 9016759..13bb78f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -152,6 +152,72 @@ p { font-size: 1rem; line-height: 1.6; color: var(--foreground); } margin-top: 0.5rem; color: var(--color-muted); } + +/* Carousel */ +.carousel { + position: relative; + overflow: hidden; + border-radius: 12px; + border: 1px solid var(--color-border); + margin-bottom: 1.5rem; +} +.carousel-viewport { + position: relative; + width: 100%; + height: 320px; + background: #f8f8f8; +} +.carousel-slide { + position: absolute; + inset: 0; + opacity: 0; + transition: opacity 250ms ease; +} +.carousel-slide.active { + opacity: 1; +} +.carousel-controls { + position: absolute; + inset: auto 0 0 0; + display: flex; + align-items: center; + justify-content: center; + gap: 0.75rem; + padding: 0.5rem 0.75rem; + background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.35) 100%); +} +.carousel-btn { + background: rgba(255,255,255,0.9); + border: 1px solid var(--color-border); + border-radius: 999px; + width: 36px; + height: 36px; + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 1.25rem; + cursor: pointer; +} +.carousel-btn:hover, +.carousel-btn:focus-visible { + background: #fff; + border-color: var(--color-green); +} +.carousel-dots { + display: inline-flex; + gap: 0.4rem; +} +.carousel-dot { + width: 12px; + height: 12px; + border-radius: 50%; + border: 1px solid #fff; + background: rgba(255,255,255,0.6); + cursor: pointer; +} +.carousel-dot.active { + background: #fff; +} .btn { display: inline-flex; align-items: center; diff --git a/src/app/pt/page.tsx b/src/app/pt/page.tsx index dc2f8bd..1f6ada6 100644 --- a/src/app/pt/page.tsx +++ b/src/app/pt/page.tsx @@ -1,7 +1,10 @@ +import { ImageCarousel } from "@/components/layout/ImageCarousel"; + export default function PtHome() { return (
+

Associação Portuguesa de Powerlifting

Acessível. Transparente. Para todos os atletas.

diff --git a/src/components/layout/ImageCarousel.tsx b/src/components/layout/ImageCarousel.tsx new file mode 100644 index 0000000..c8c36c5 --- /dev/null +++ b/src/components/layout/ImageCarousel.tsx @@ -0,0 +1,64 @@ +"use client"; +import Image from "next/image"; +import { useEffect, useState } from "react"; + +const slides = [ + { src: "/content/images/1.png", alt: "Powerlifting highlight 1" }, + { src: "/content/images/2.png", alt: "Powerlifting highlight 2" }, + { src: "/content/images/3.png", alt: "Powerlifting highlight 3" }, +]; + +export function ImageCarousel() { + const [index, setIndex] = useState(0); + + useEffect(() => { + const id = setInterval(() => { + setIndex((prev) => (prev + 1) % slides.length); + }, 5000); + return () => clearInterval(id); + }, []); + + const goTo = (i: number) => setIndex(i % slides.length); + const prev = () => setIndex((prev) => (prev - 1 + slides.length) % slides.length); + const next = () => setIndex((prev) => (prev + 1) % slides.length); + + return ( +
+
+ {slides.map((slide, i) => ( +
+ {slide.alt} +
+ ))} +
+
+ +
+ {slides.map((_, i) => ( +
+ +
+
+ ); +}