Update blog homepage carousel to display articles in a new layout

Refactor the `FeaturedCarousel` component in `client/src/pages/home.tsx` to dynamically adjust the display of hero and side articles based on the current page and available gallery images. This includes modifying column spans and article slicing logic to accommodate the new layout.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 413891e8-d784-4bea-b9f5-91a5a68316b4
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 3eaf2b0e-320a-43fa-a05e-a3d651f534ae
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/413891e8-d784-4bea-b9f5-91a5a68316b4/RVXhOPb
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
sebastjanartic 2026-02-28 19:31:52 +00:00
parent f951e18b20
commit 5e03283560
2 changed files with 26 additions and 6 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 KiB

View File

@ -203,9 +203,10 @@ function TopStoriesList({ articles }: { articles: Article[] }) {
}
function FeaturedCarousel({ articles, popular, galleryImages }: { articles: Article[]; popular?: Article[]; galleryImages?: GalleryImage[] }) {
const pool = articles.slice(0, 5);
const PAGES = 5;
const hasGallery = galleryImages && galleryImages.length > 0;
const total = pool.length + (hasGallery ? 1 : 0);
const articlePages = Math.min(PAGES, Math.ceil(articles.length / 3));
const total = articlePages + (hasGallery ? 1 : 0);
const [page, setPage] = useState(0);
const [paused, setPaused] = useState(false);
@ -220,18 +221,37 @@ function FeaturedCarousel({ articles, popular, galleryImages }: { articles: Arti
}, [paused, next, total]);
const isGalleryPage = hasGallery && page === total - 1;
const hero: Article | null = isGalleryPage ? null : (pool[page] || null);
let hero: Article | null = null;
let side: Article[] = [];
if (!isGalleryPage) {
const start = page * 3;
const visible = articles.slice(start, start + 3);
while (visible.length < 3 && articles.length >= 3) {
visible.push(articles[visible.length % articles.length]);
}
hero = visible[0] || null;
side = visible.slice(1, 3);
}
return (
<section data-testid="featured-carousel" onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)}>
<div className="grid grid-cols-1 lg:grid-cols-6 gap-4">
<div className="lg:col-span-5">
<div className={isGalleryPage ? "lg:col-span-5" : "lg:col-span-3"}>
{isGalleryPage && galleryImages ? (
<GalleryHeroCard images={galleryImages.slice(0, 30)} />
) : hero ? (
<HeroCard article={hero} />
) : null}
</div>
{!isGalleryPage && (
<div className="lg:col-span-2 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-1 gap-4">
{side.map((a) => (
<MediumCard key={a.id} article={a} />
))}
</div>
)}
<div className="lg:col-span-1">
{popular && popular.length > 0 && <TopStoriesList articles={popular} />}
</div>
@ -296,8 +316,8 @@ export default function Home() {
);
}
const carouselCount = Math.min(articles.length, 5);
const remaining = articles.slice(carouselCount);
const carouselUsed = Math.min(articles.length, 5 * 3);
const remaining = articles.slice(carouselUsed);
const row2Articles = remaining.slice(0, 4);
const row3Articles = remaining.slice(4, 7);
const row4Articles = remaining.slice(7, 10);