Update homepage layout to a more modern grid-based design

Refactors the homepage layout from a carousel to a grid. Adjusts article slicing for new rows and removes carousel functionality. Introduces `MediumCard` component.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 517dfa7b-26ac-463d-a6e1-a58c6df97188
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: ceeb2a24-be77-456c-acfb-2e395f4b9d34
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/517dfa7b-26ac-463d-a6e1-a58c6df97188/0ZGabQy
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
sebastjanartic 2026-02-28 21:40:42 +00:00
parent 861f5bd2bc
commit 5c92bc69c8
3 changed files with 10 additions and 60 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 KiB

View File

@ -252,66 +252,16 @@ function TopStoriesList({ articles }: { articles: Article[] }) {
} }
function FeaturedCarousel({ articles, popular, galleryImages, focalPoints }: { articles: Article[]; popular?: Article[]; galleryImages?: GalleryImage[]; focalPoints?: Record<string, { x: number; y: number }> }) { function FeaturedCarousel({ articles, popular, galleryImages, focalPoints }: { articles: Article[]; popular?: Article[]; galleryImages?: GalleryImage[]; focalPoints?: Record<string, { x: number; y: number }> }) {
const hasGallery = galleryImages && galleryImages.length > 0; const featured = articles.slice(0, 3);
const articlePages = Math.min(5, Math.max(1, articles.length));
const total = articlePages + (hasGallery ? 1 : 0);
const [page, setPage] = useState(0);
const [paused, setPaused] = useState(false);
const next = useCallback(() => {
setPage((p) => (p + 1) % total);
}, [total]);
useEffect(() => {
if (paused || total <= 1) return;
const timer = setInterval(next, 8000);
return () => clearInterval(timer);
}, [paused, next, total]);
const isGalleryPage = hasGallery && page === total - 1;
const isWidePage = page === 1;
let hero: Article | null = null;
let side: Article[] = [];
if (!isGalleryPage && articles.length > 0) {
hero = articles[page % articles.length];
}
if (articles.length > 0) {
const offset = isGalleryPage ? 0 : 1;
side = [
articles[(page + offset) % articles.length],
articles[(page + offset + 1) % articles.length],
];
}
return ( return (
<section data-testid="featured-carousel" onMouseEnter={() => setPaused(true)} onMouseLeave={() => setPaused(false)}> <section data-testid="featured-carousel">
<div className="grid grid-cols-1 lg:grid-cols-8 gap-4 lg:max-h-[420px]"> <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div className="lg:col-span-3 lg:h-[420px]"> {featured.map((a) => (
{isGalleryPage && galleryImages ? ( <MediumCard key={a.id} article={a} focalPoints={focalPoints} />
<GalleryHeroCard images={galleryImages.slice(0, 30)} /> ))}
) : hero ? ( {popular && popular.length > 0 && <TopStoriesList articles={popular} />}
<HeroCard article={hero} focalPoints={focalPoints} />
) : null}
</div>
<div className="lg:col-span-3 grid grid-cols-1 gap-3 grid-rows-2 lg:h-[420px]">
{side.map((a) => (
<SideCard key={a.id} article={a} focalPoints={focalPoints} />
))}
</div>
<div className="lg:col-span-2 lg:h-[420px]">
{popular && popular.length > 0 && <TopStoriesList articles={popular} />}
</div>
</div> </div>
{total > 1 && (
<div className="flex justify-center gap-2 mt-3" data-testid="carousel-dots">
{Array.from({ length: total }).map((_, i) => (
<button key={i} onClick={() => setPage(i)} className={`w-2.5 h-2.5 rounded-full transition-all duration-300 ${i === page ? "bg-primary w-6" : "bg-muted-foreground/30 hover:bg-muted-foreground/50"}`} data-testid={`button-carousel-dot-${i}`} />
))}
</div>
)}
</section> </section>
); );
} }
@ -357,9 +307,9 @@ export default function Home() {
); );
} }
const row2 = articles.slice(0, 2); const row2 = articles.slice(3, 5);
const row3 = articles.slice(2, 4); const row3 = articles.slice(5, 7);
const remaining = articles.slice(4); const remaining = articles.slice(7);
const rows: Article[][] = []; const rows: Article[][] = [];
for (let i = 0; i < remaining.length; i += 4) { for (let i = 0; i < remaining.length; i += 4) {
rows.push(remaining.slice(i, i + 4)); rows.push(remaining.slice(i, i + 4));