'use client'; import { useState } from 'react'; import { WeeklySummary, WeeklyActivity, PERIOD_OPTIONS, PeriodOption } from '@/services/weekly-summary'; import { Card, CardHeader, CardContent } from '@/components/ui/Card'; import { Button } from '@/components/ui/Button'; import { Badge } from '@/components/ui/Badge'; import { VelocityMetrics } from './VelocityMetrics'; import { CategoryBreakdown } from './CategoryBreakdown'; import { PeriodSelector } from './PeriodSelector'; import { PDFExportService } from '@/services/pdf-export'; interface WeeklySummaryClientProps { initialSummary: WeeklySummary; } export default function WeeklySummaryClient({ initialSummary }: WeeklySummaryClientProps) { const [summary, setSummary] = useState(initialSummary); const [selectedDay, setSelectedDay] = useState(null); const [isRefreshing, setIsRefreshing] = useState(false); const [isExportingPDF, setIsExportingPDF] = useState(false); const [currentPeriod, setCurrentPeriod] = useState(PERIOD_OPTIONS[0]); const [activeTab, setActiveTab] = useState('all'); const handlePeriodChange = async (newPeriod: PeriodOption) => { setCurrentPeriod(newPeriod); setIsRefreshing(true); try { // Appel API pour récupérer les données de la nouvelle période const response = await fetch(`/api/weekly-summary?period=${newPeriod.days}`); if (response.ok) { const newSummary = await response.json(); setSummary(newSummary); } else { console.error('Erreur lors du changement de période'); } } catch (error) { console.error('Erreur lors du changement de période:', error); } finally { setIsRefreshing(false); } }; const handleRefresh = async () => { setIsRefreshing(true); // Recharger la page pour refaire le fetch côté serveur window.location.reload(); }; const handleExportPDF = async () => { setIsExportingPDF(true); try { await PDFExportService.exportWeeklySummary(summary); } catch (error) { console.error('Erreur lors de l\'export PDF:', error); alert('Erreur lors de la génération du PDF'); } finally { setIsExportingPDF(false); } }; const formatDate = (date: Date) => { return new Date(date).toLocaleDateString('fr-FR', { weekday: 'long', day: 'numeric', month: 'long' }); }; const getActivityIcon = (activity: WeeklyActivity) => { if (activity.type === 'checkbox') { return activity.completed ? '✅' : '☐'; } return activity.completed ? '🎯' : '📝'; }; const getActivityTypeLabel = (type: 'checkbox' | 'task') => { return type === 'checkbox' ? 'Daily' : 'Tâche'; }; // Obtenir les catégories disponibles const availableCategories = Object.keys(summary.categoryBreakdown).filter( categoryName => summary.categoryBreakdown[categoryName].count > 0 ); // Fonction pour catégoriser une activité const getActivityCategory = (activity: WeeklyActivity): string => { // Logique simple pour associer une activité à une catégorie // En production, cette logique devrait être dans un service const title = activity.title.toLowerCase(); if (title.includes('meeting') || title.includes('réunion') || title.includes('call') || title.includes('standup')) { return 'Meeting'; } if (title.includes('dev') || title.includes('code') || title.includes('bug') || title.includes('fix') || title.includes('feature')) { return 'Dev'; } if (title.includes('admin') || title.includes('email') || title.includes('report') || title.includes('planning')) { return 'Admin'; } if (title.includes('learn') || title.includes('study') || title.includes('formation') || title.includes('tutorial')) { return 'Learning'; } return 'Other'; }; // Filtrer les activités let filteredActivities = selectedDay ? summary.activities.filter(a => a.dayName === selectedDay) : summary.activities; // Filtrer par catégorie si ce n'est pas "all" if (activeTab !== 'all') { filteredActivities = filteredActivities.filter(activity => getActivityCategory(activity) === activeTab ); } return (
{/* Sélecteur de période */} {/* Métriques de vélocité */} {/* Onglets par catégorie */}
{/* Contenu de l'onglet sélectionné */} {activeTab === 'all' && ( <> {/* Répartition par catégorie */} )} {/* Vue spécifique par catégorie */} {activeTab !== 'all' && (
{summary.categoryBreakdown[activeTab]?.icon}

{activeTab}

{summary.categoryBreakdown[activeTab]?.count} activités ({summary.categoryBreakdown[activeTab]?.percentage.toFixed(1)}% de votre temps)

{/* Métriques spécifiques à la catégorie */}
{filteredActivities.length}
Total activités
{filteredActivities.filter(a => a.completed).length}
Complétées
{filteredActivities.length > 0 ? Math.round((filteredActivities.filter(a => a.completed).length / filteredActivities.length) * 100) : 0}%
Taux completion
{summary.categoryBreakdown[activeTab]?.percentage.toFixed(1)}%
Du temps total
)} {/* Contenu commun à tous les onglets */}

{activeTab === 'all' ? '📅 Résumé de la semaine' : `${summary.categoryBreakdown[activeTab]?.icon} Activités ${activeTab}`}

Du {formatDate(summary.period.start)} au {formatDate(summary.period.end)} {activeTab !== 'all' && ` • ${filteredActivities.length} activités`}

{/* Statistiques globales ou spécifiques à la catégorie */} {activeTab === 'all' ? (
{summary.stats.completedCheckboxes}
Daily items
sur {summary.stats.totalCheckboxes} ({summary.stats.checkboxCompletionRate.toFixed(0)}%)
{summary.stats.completedTasks}
Tâches
sur {summary.stats.totalTasks} ({summary.stats.taskCompletionRate.toFixed(0)}%)
{summary.stats.completedCheckboxes + summary.stats.completedTasks}
Total complété
sur {summary.stats.totalCheckboxes + summary.stats.totalTasks}
{summary.stats.mostProductiveDay}
Jour le plus productif
) : (
{filteredActivities.length}
Activités {activeTab}
{filteredActivities.filter(a => a.completed).length}
Complétées
{filteredActivities.length > 0 ? Math.round((filteredActivities.filter(a => a.completed).length / filteredActivities.length) * 100) : 0}%
Taux de réussite
{summary.categoryBreakdown[activeTab]?.percentage.toFixed(1)}%
Du temps total
)} {/* Breakdown par jour */}

📊 Répartition par jour {activeTab !== 'all' && - {activeTab}}

{summary.stats.dailyBreakdown.map((day) => { // Pour chaque jour, calculer les activités de la catégorie sélectionnée const dayActivitiesAll = summary.activities.filter(a => a.dayName === day.dayName); const dayActivitiesFiltered = activeTab === 'all' ? dayActivitiesAll : dayActivitiesAll.filter(activity => getActivityCategory(activity) === activeTab); const completedCount = dayActivitiesFiltered.filter(a => a.completed).length; const totalCount = dayActivitiesFiltered.length; return ( ); })}
{selectedDay && (
📍 Filtré sur: {selectedDay} {activeTab !== 'all' && • Catégorie: {activeTab}}
)}
{/* Timeline des activités */}

🕒 Timeline des activités {activeTab !== 'all' && `- ${activeTab}`} ({filteredActivities.length} items{activeTab !== 'all' && ` de la catégorie ${activeTab}`})

{filteredActivities.length === 0 ? (
{selectedDay ? 'Aucune activité ce jour-là' : 'Aucune activité cette semaine'}
) : (
{filteredActivities.map((activity) => (
{getActivityIcon(activity)}
{activity.title} {getActivityTypeLabel(activity.type)}
{activity.dayName} • {new Date(activity.createdAt).toLocaleDateString('fr-FR')} {activity.completedAt && ( • Complété le {new Date(activity.completedAt).toLocaleDateString('fr-FR')} )}
))}
)}
); }