'use client'; import { useState, useRef, useEffect } from 'react'; import { useTranslations } from 'next-intl'; import { Link } from '@/i18n/navigation'; import { motion, useInView } from 'framer-motion'; import { Ship, BookOpen, Calendar, Clock, User, ArrowRight, Search, TrendingUp, Globe, FileText, Anchor, type LucideIcon, } from 'lucide-react'; import { LandingHeader, LandingFooter } from '@/components/layout'; import { getBlogPosts, type BlogPost, type BlogPostCategory } from '@/lib/api/blog'; const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4000'; function resolveUrl(url: string | null | undefined): string | undefined { if (!url) return undefined; if (url.startsWith('http')) return url; return `${API_BASE_URL}${url}`; } type CategoryKey = 'all' | BlogPostCategory; const CATEGORIES: { key: CategoryKey; icon: LucideIcon }[] = [ { key: 'all', icon: BookOpen }, { key: 'industry', icon: Ship }, { key: 'technology', icon: TrendingUp }, { key: 'guides', icon: FileText }, { key: 'news', icon: Globe }, ]; const containerVariants = { hidden: { opacity: 0, y: 50 }, visible: { opacity: 1, y: 0, transition: { duration: 0.6, staggerChildren: 0.1 }, }, }; const itemVariants = { hidden: { opacity: 0, y: 20 }, visible: { opacity: 1, y: 0, transition: { duration: 0.5 } }, }; function formatDate(dateStr: string): string { return new Date(dateStr).toLocaleDateString('fr-FR', { year: 'numeric', month: 'long', day: 'numeric', }); } export default function BlogPage() { const t = useTranslations('marketing.blog'); const [selectedCategory, setSelectedCategory] = useState('all'); const [searchQuery, setSearchQuery] = useState(''); const [posts, setPosts] = useState([]); const [total, setTotal] = useState(0); const [loading, setLoading] = useState(true); const [featuredPost, setFeaturedPost] = useState(null); const heroRef = useRef(null); const articlesRef = useRef(null); const categoriesRef = useRef(null); const isHeroInView = useInView(heroRef, { once: true }); const isArticlesInView = useInView(articlesRef, { once: true }); const isCategoriesInView = useInView(categoriesRef, { once: true }); useEffect(() => { let cancelled = false; const load = async () => { setLoading(true); try { const res = await getBlogPosts({ category: selectedCategory !== 'all' ? selectedCategory : undefined, search: searchQuery || undefined, limit: 50, }); if (!cancelled) { const featured = res.posts.find(p => p.isFeatured) ?? res.posts[0] ?? null; const rest = res.posts.filter(p => p !== featured); setFeaturedPost(featured); setPosts(rest); setTotal(res.total); } } catch { if (!cancelled) { setPosts([]); setFeaturedPost(null); setTotal(0); } } finally { if (!cancelled) setLoading(false); } }; load(); return () => { cancelled = true; }; }, [selectedCategory, searchQuery]); return (
{/* Hero Section */}
{t('badge')}

{t('title1')}
{t('title2')}

{t('intro')}

setSearchQuery(e.target.value)} className="w-full pl-12 pr-4 py-4 rounded-xl bg-white text-gray-900 placeholder-gray-400 focus:ring-2 focus:ring-brand-turquoise focus:outline-none" />
{/* Categories */}
{CATEGORIES.map(category => { const IconComponent = category.icon; const isActive = selectedCategory === category.key; return ( ); })}
{/* Featured Article */} {!loading && featuredPost && (
{featuredPost.coverImageUrl ? (
) : (
)}
{t('featuredBadge')} {t(`categories.${featuredPost.category}`)}

{featuredPost.title}

{featuredPost.excerpt}

{featuredPost.authorName}
{featuredPost.publishedAt && (
{formatDate(featuredPost.publishedAt)}
)}
{t('readArticle')}
)} {/* Articles Grid */}

{t('allTitle')}

{t('articlesCount', { count: posts.length })}
{loading ? (
{[1, 2, 3].map(i => (
))}
) : posts.length === 0 ? (

{t('noResults.title')}

{t('noResults.body')}

) : ( {posts.map(post => (
{post.coverImageUrl ? ( {post.title} ) : ( )}
{t(`categories.${post.category}`)}

{post.title}

{post.excerpt}

{post.tags.map(tag => ( {tag} ))}
{post.authorName}
{post.publishedAt && (
{formatDate(post.publishedAt)}
)}
))}
)}
{/* Newsletter Section */}

{t('newsletter.title')}

{t('newsletter.body')}

{t('newsletter.disclaimer')}

); }