import React, { useState, useEffect } from 'react'; import Link from '@docusaurus/Link'; import { translate } from '@docusaurus/Translate'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import styles from './styles.module.css'; export interface Article { title: string; permalink: string; type: 'blog' | 'doc'; date?: string; } interface ArticleCarouselProps { articles: Article[]; maxVisible?: number; } /** * ArticleCarousel component displays recent blog posts and documentation * with auto-generated thumbnails featuring title and type badge. * * @param articles - Array of articles to display in the carousel * @param maxVisible - Maximum number of visible carousel items (default: 6) */ export default function ArticleCarousel({ articles, maxVisible = 6 }: ArticleCarouselProps): JSX.Element { const [currentIndex, setCurrentIndex] = useState(0); const [isAutoPlaying, setIsAutoPlaying] = useState(true); const { i18n } = useDocusaurusContext(); // Auto-play carousel every 5 seconds useEffect(() => { if (!isAutoPlaying || articles.length <= 1) return; const interval = setInterval(() => { setCurrentIndex((prev) => (prev + 1) % articles.length); }, 5000); return () => clearInterval(interval); }, [isAutoPlaying, articles.length]); // Limit articles to maxVisible const visibleArticles = articles.slice(0, maxVisible); const handlePrevious = () => { setIsAutoPlaying(false); setCurrentIndex((prev) => prev === 0 ? visibleArticles.length - 1 : prev - 1 ); }; const handleNext = () => { setIsAutoPlaying(false); setCurrentIndex((prev) => (prev + 1) % visibleArticles.length); }; const handleDotClick = (index: number) => { setIsAutoPlaying(false); setCurrentIndex(index); }; if (visibleArticles.length === 0) { return null; } // Get badge text based on article type and current locale const getBadgeText = (type: 'blog' | 'doc'): string => { return type === 'blog' ? translate({ id: 'carousel.badge.blog', message: 'BLOG', description: 'Badge text for blog articles in carousel', }) : translate({ id: 'carousel.badge.documentation', message: 'DOCUMENTATION', description: 'Badge text for documentation pages in carousel', }); }; // Generate consistent background colors for thumbnails const getBackgroundColor = (index: number): string => { const colors = [ '#4A90E2', // Blue '#50C878', // Emerald '#9B59B6', // Purple '#E67E22', // Orange '#1ABC9C', // Turquoise '#E74C3C', // Red ]; return colors[index % colors.length]; }; return (

{translate({ id: 'carousel.title', message: 'Articles récents', description: 'Title of the article carousel section', })}

{/* Navigation Arrow - Previous */} {/* Carousel Track */}
{visibleArticles.map((article, index) => (
{/* Type Badge */}
{getBadgeText(article.type)}
{/* Article Title */}

{article.title}

{/* Date (if available for blog posts) */} {article.date && (
{new Date(article.date).toLocaleDateString( i18n.currentLocale === 'fr' ? 'fr-FR' : 'en-US', { year: 'numeric', month: 'long', day: 'numeric', } )}
)}
))}
{/* Navigation Arrow - Next */}
{/* Carousel Indicators (Dots) */}
{visibleArticles.map((_, index) => (
); }