From 9efb44269f2c9afe35822e98f4bc1f5f09ec4407 Mon Sep 17 00:00:00 2001 From: sebastjanartic <45803536-sebastjanartic@users.noreply.replit.com> Date: Sat, 28 Feb 2026 18:07:46 +0000 Subject: [PATCH] Add a carousel to rotate featured articles on the homepage Introduces a `FeaturedCarousel` component to `pages/home.tsx`, replacing the static hero and medium cards. This component displays the top 9 articles in a rotating 3-article set (hero + 2 medium cards) with manual navigation dots and auto-play functionality, refreshing every 8 seconds. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 413891e8-d784-4bea-b9f5-91a5a68316b4 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: d4e9014a-4e53-4f9d-8b89-76090db548d0 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/413891e8-d784-4bea-b9f5-91a5a68316b4/igVW4lQ Replit-Helium-Checkpoint-Created: true --- client/src/pages/home.tsx | 91 ++++++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 21 deletions(-) diff --git a/client/src/pages/home.tsx b/client/src/pages/home.tsx index 6d80a63..4419eba 100644 --- a/client/src/pages/home.tsx +++ b/client/src/pages/home.tsx @@ -199,6 +199,75 @@ function BentoSkeleton() { ); } +function FeaturedCarousel({ articles, popular }: { articles: Article[]; popular?: Article[] }) { + const totalPages = Math.ceil(Math.min(articles.length, 9) / 3); + const [page, setPage] = useState(0); + const [paused, setPaused] = useState(false); + + const next = useCallback(() => { + setPage((p) => (p + 1) % totalPages); + }, [totalPages]); + + useEffect(() => { + if (paused || totalPages <= 1) return; + const timer = setInterval(next, 8000); + return () => clearInterval(timer); + }, [paused, next, totalPages]); + + const pool = articles.slice(0, 9); + const start = page * 3; + const visible = pool.slice(start, start + 3); + while (visible.length < 3 && pool.length >= 3) { + visible.push(pool[visible.length % pool.length]); + } + + const hero = visible[0]; + const side = visible.slice(1, 3); + + if (!hero) return null; + + return ( +
setPaused(true)} + onMouseLeave={() => setPaused(false)} + > +
+
+ +
+ +
+ {side.map((a) => ( + + ))} +
+ +
+ {popular && popular.length > 0 && ( + + )} +
+
+ + {totalPages > 1 && ( +
+ {Array.from({ length: totalPages }).map((_, i) => ( +
+ )} +
+ ); +} + export default function Home() { const { data: articles, isLoading } = useQuery({ queryKey: ["/api/articles"], @@ -221,8 +290,6 @@ export default function Home() { } const all = articles; - const row1Hero = all[0]; - const row1Medium = all.slice(1, 3); const row2Items = all.slice(3, 6); const row3Items = all.slice(6); @@ -231,25 +298,7 @@ export default function Home() {
- {row1Hero && ( -
-
- -
- -
- {row1Medium.map((a) => ( - - ))} -
- -
- {popular && popular.length > 0 && ( - - )} -
-
- )} +