'use client'; interface BackupStats { date: string; manual: number; automatic: number; total: number; } interface BackupTimelineChartProps { stats?: BackupStats[]; className?: string; } export function BackupTimelineChart({ stats = [], className = '' }: BackupTimelineChartProps) { // Protection contre les stats non-array const safeStats = Array.isArray(stats) ? stats : []; const error = safeStats.length === 0 ? 'Aucune donnée disponible' : null; // Convertir les stats en map pour accès rapide const statsMap = new Map(safeStats.map(s => [s.date, s])); // Générer les 30 derniers jours const days = Array.from({ length: 30 }, (_, i) => { const date = new Date(); date.setDate(date.getDate() - (29 - i)); // Utiliser la date locale pour éviter les décalages UTC const localDate = new Date(date.getTime() - date.getTimezoneOffset() * 60000); return localDate.toISOString().split('T')[0]; }); // Organiser en semaines (5 semaines de 6 jours + quelques jours) const weeks = []; for (let i = 0; i < days.length; i += 7) { weeks.push(days.slice(i, i + 7)); } const formatDateFull = (dateStr: string) => { const date = new Date(dateStr); return date.toLocaleDateString('fr-FR', { weekday: 'long', day: 'numeric', month: 'long' }); }; if (error) { return (
{error}
); } return (

💾 Activité de sauvegarde (30 derniers jours)

{/* Vue en ligne avec indicateurs clairs */}
{/* En-têtes des jours */}
{['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'].map(day => (
{day}
))}
{/* Grille des jours avec indicateurs visuels */}
{weeks.map((week, weekIndex) => (
{week.map((day) => { const stat = statsMap.get(day) || { date: day, manual: 0, automatic: 0, total: 0 }; const hasManual = stat.manual > 0; const hasAuto = stat.automatic > 0; const dayNumber = new Date(day).getDate(); return (
{/* Jour du mois */} 0 ? 'text-white font-bold' : ''}`}> {dayNumber} {/* Fond selon le type */} {stat.total > 0 && (
)} {/* Indicateurs visuels pour l'intensité */} {stat.total > 0 && stat.total > 1 && (
{stat.total > 9 ? '9+' : stat.total}
)}
{/* Tooltip détaillé */}
{formatDateFull(day)}
{stat.total > 0 ? (
{stat.manual > 0 && (
Manuel: {stat.manual}
)} {stat.automatic > 0 && (
Auto: {stat.automatic}
)}
Total: {stat.total}
) : (
Aucune sauvegarde
)}
); })}
))}
{/* Légende claire */}

Légende

15
Manuel seul
15
Auto seul
15
Manuel + Auto
15
Aucune
💡 Le badge orange indique le nombre total quand > 1
{/* Statistiques résumées */}
{safeStats.reduce((sum, s) => sum + s.manual, 0)}
Manuelles
{safeStats.reduce((sum, s) => sum + s.automatic, 0)}
Automatiques
{safeStats.reduce((sum, s) => sum + s.total, 0)}
Total
); }