'use client'; import { useRef, useEffect, useState } from 'react'; import Link from 'next/link'; import Image from 'next/image'; import { useTranslations } from 'next-intl'; import { Article } from '@/lib/blog/types'; type props = { locale: string; articles: Article[]; }; function FeaturedCover({ cover, title, category }: { cover?: string; title: string; category: string }) { const [hidden, setHidden] = useState(false); if (!cover || hidden) return null; return (
{title} setHidden(true)} />
{category}
); } function MediumCover({ cover, title, category }: { cover?: string; title: string; category: string }) { const [hidden, setHidden] = useState(false); if (!cover || hidden) return null; return (
{title} setHidden(true)} />
{category}
); } function ThumbnailCover({ cover, title }: { cover?: string; title: string }) { const [hidden, setHidden] = useState(false); if (!cover || hidden) return null; return (
{title} setHidden(true)} />
); } export function ArticleList({ locale, articles }: props) { const ref = useRef(null); const t = useTranslations('blogPage'); useEffect(() => { const el = ref.current; if (!el) return; const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { el.querySelectorAll('.reveal').forEach((node, i) => { setTimeout(() => node.classList.add('visible'), i * 100); }); observer.unobserve(el); } }, { threshold: 0.05 } ); observer.observe(el); return () => observer.disconnect(); }, []); if (!articles.length) { return (

{t('noArticles')}

); } const formatDate = (dateStr: string) => new Date(dateStr).toLocaleDateString(locale === 'fr' ? 'fr-FR' : 'en-US', { year: 'numeric', month: 'long', day: 'numeric', }); const [featured, ...rest] = articles; const secondRow = rest.slice(0, 2); const remaining = rest.slice(2); return (
{/* Featured — most recent article, full width */}
{formatDate(featured.date)} {featured.readTime && ( <> {featured.readTime} )}

{featured.title}

{featured.description}

{t('readArticle')}
{/* Second row — 2 medium cards */} {secondRow.length > 0 && (
{secondRow.map((article, i) => (
{formatDate(article.date)} {article.readTime && ( <> {article.readTime} )}

{article.title}

{article.description}

{t('readArticle')}
))}
)} {/* Remaining — compact horizontal list */} {remaining.length > 0 && (
{remaining.map((article, i) => (
{article.category} {formatDate(article.date)} {article.readTime && ( <> {article.readTime} )}

{article.title}

{article.description}

{t('readArticle')}
))}
)}
); }