import { useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuthStore } from '@/stores/auth'; import { useLibraryItems, useLibraryActions, useLibraryStatus } from '@/utils/storeSelectors'; import { useDashboard } from '@/features/dashboard/hooks/useDashboard'; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Music, MessageSquare, Users, Heart, Library, Upload } from 'lucide-react'; import { formatDistanceToNow } from 'date-fns'; import { fr } from 'date-fns/locale'; /** * Page principale du dashboard avec statistiques et aperçu de l'activité. * FE-PAGE-001: Complete Dashboard page implementation */ export function DashboardPage() { const { user } = useAuthStore(); // FE-STATE-009: Use selector that returns denormalized array const items = useLibraryItems(); const { fetchItems } = useLibraryActions(); const { isLoading: isLoadingLibrary } = useLibraryStatus(); const { stats, recentActivity, isLoading: isLoadingDashboard } = useDashboard(); const navigate = useNavigate(); useEffect(() => { fetchItems({ limit: 5 }); }, [fetchItems]); // FE-PAGE-001: Format stats with real data const formatNumber = (num: number): string => { if (num >= 1000000) { return (num / 1000000).toFixed(1) + 'M'; } if (num >= 1000) { return (num / 1000).toFixed(1) + 'K'; } return num.toString(); }; const dashboardStats = [ { title: 'Pistes écoutées', value: stats ? formatNumber(stats.tracks_played) : '0', change: stats?.tracks_played_change || '+0%', icon: Music, color: 'text-blue-600', }, { title: 'Messages envoyés', value: stats ? formatNumber(stats.messages_sent) : '0', change: stats?.messages_sent_change || '+0%', icon: MessageSquare, color: 'text-green-600', }, { title: 'Favoris', value: stats ? formatNumber(stats.favorites) : '0', change: stats?.favorites_change || '+0%', icon: Heart, color: 'text-red-600', }, { title: 'Amis actifs', value: stats ? formatNumber(stats.active_friends) : '0', change: stats?.active_friends_change || '+0%', icon: Users, color: 'text-purple-600', }, ]; // FE-PAGE-001: Get activity icon color based on type const getActivityColor = (type: string) => { switch (type) { case 'track_upload': return 'bg-blue-600'; case 'message_received': return 'bg-green-600'; case 'favorite_added': return 'bg-red-600'; case 'playlist_created': return 'bg-purple-600'; case 'comment_added': return 'bg-yellow-600'; default: return 'bg-gray-600'; } }; // FE-PAGE-001: Format timestamp to relative time const formatTimestamp = (timestamp: string) => { try { return formatDistanceToNow(new Date(timestamp), { addSuffix: true, locale: fr, }); } catch { return 'Récemment'; } }; return (

Dashboard

{/* En-tête avec salutation */}

{user?.first_name || user?.username ? `Bonjour, ${user.first_name || user.username} !` : 'Bienvenue sur Veza'}

{/* FE-PAGE-001: Statistiques avec données réelles */}
{isLoadingDashboard ? ( // Loading skeleton [...Array(4)].map((_, i) => (
)) ) : ( dashboardStats.map((stat) => ( {stat.title}
{stat.value}

{stat.change && ( {stat.change} )} {stat.change && ' par rapport au mois dernier'}

)) )}
{/* Aperçu récent */}
{/* Activité récente */} Activité récente Vos dernières interactions sur la plateforme {isLoadingDashboard ? ( // Loading skeleton
{[...Array(3)].map((_, i) => (
))}
) : recentActivity.length > 0 ? ( // FE-PAGE-001: Real activity data
{recentActivity.slice(0, 5).map((activity) => (

{activity.title}

{activity.description && (

{activity.description}

)}

{formatTimestamp(activity.timestamp)}

))}
) : (

Aucune activité récente

)}
{/* Pistes récentes */} Pistes récentes Dernières pistes de votre bibliothèque {isLoadingLibrary ? (
{[...Array(3)].map((_, i) => (
))}
) : (
{items.slice(0, 3).map((item) => (

{item.title}

{item.description || 'Aucune description'}

))} {items.length === 0 && (

Aucune piste dans votre bibliothèque

)}
)}
{/* FE-PAGE-001: Actions rapides avec navigation fonctionnelle */} Actions rapides Accédez rapidement aux fonctionnalités principales
); }