|
1 | | -import { useOptimizedAuth } from '@/hooks/useOptimizedAuth'; |
| 1 | + |
| 2 | +import { useAuth } from '@/hooks/useAuth'; |
2 | 3 | import { useCampaigns } from '@/hooks/useCampaigns'; |
3 | 4 | import { useAffiliates } from '@/hooks/useAffiliates'; |
4 | | -import { useGlobalStats } from '@/hooks/useGlobalStats'; |
5 | 5 | import { DashboardBackground } from '@/components/DashboardBackground'; |
6 | 6 | import { DashboardHeader } from '@/components/DashboardHeader'; |
7 | | -import { DashboardStats } from '@/components/DashboardStats'; |
8 | 7 | import { DashboardContent } from '@/components/DashboardContent'; |
9 | 8 | import { NetworkStatus } from '@/components/NetworkStatus'; |
10 | 9 | import { ErrorBoundary } from '@/components/ErrorBoundary'; |
11 | 10 | import { Helmet } from 'react-helmet-async'; |
12 | | -import { memo, useCallback, useMemo } from 'react'; |
| 11 | +import { memo, useCallback, useMemo, useState } from 'react'; |
| 12 | +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; |
| 13 | +import { BarChart3, Users, DollarSign, Percent } from 'lucide-react'; |
| 14 | + |
| 15 | +// Composant de stats simplifié SANS requêtes Firebase lourdes |
| 16 | +const SimpleDashboardStats = ({ activeCampaigns, totalCampaigns, totalAffiliates }) => { |
| 17 | + return ( |
| 18 | + <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 sm:gap-6 mb-6 sm:mb-8"> |
| 19 | + <Card className="bg-gradient-to-br from-white to-blue-50/50 border-slate-200/50 shadow-xl"> |
| 20 | + <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> |
| 21 | + <CardTitle className="text-sm font-medium text-slate-700">Campagnes Actives</CardTitle> |
| 22 | + <div className="p-2 bg-blue-100 rounded-full"> |
| 23 | + <BarChart3 className="h-4 w-4 text-blue-600" /> |
| 24 | + </div> |
| 25 | + </CardHeader> |
| 26 | + <CardContent> |
| 27 | + <div className="text-2xl font-bold text-slate-900">{activeCampaigns}</div> |
| 28 | + <p className="text-xs text-slate-500">sur {totalCampaigns} campagne{totalCampaigns > 1 ? 's' : ''}</p> |
| 29 | + </CardContent> |
| 30 | + </Card> |
| 31 | + |
| 32 | + <Card className="bg-gradient-to-br from-white to-green-50/50 border-slate-200/50 shadow-xl"> |
| 33 | + <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> |
| 34 | + <CardTitle className="text-sm font-medium text-slate-700">Total Affiliés</CardTitle> |
| 35 | + <div className="p-2 bg-green-100 rounded-full"> |
| 36 | + <Users className="h-4 w-4 text-green-600" /> |
| 37 | + </div> |
| 38 | + </CardHeader> |
| 39 | + <CardContent> |
| 40 | + <div className="text-2xl font-bold text-slate-900">{totalAffiliates}</div> |
| 41 | + <p className="text-xs text-slate-500">affiliés actifs</p> |
| 42 | + </CardContent> |
| 43 | + </Card> |
| 44 | + |
| 45 | + <Card className="bg-gradient-to-br from-white to-purple-50/50 border-slate-200/50 shadow-xl"> |
| 46 | + <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> |
| 47 | + <CardTitle className="text-sm font-medium text-slate-700">Chiffre d'affaires</CardTitle> |
| 48 | + <div className="p-2 bg-purple-100 rounded-full"> |
| 49 | + <DollarSign className="h-4 w-4 text-purple-600" /> |
| 50 | + </div> |
| 51 | + </CardHeader> |
| 52 | + <CardContent> |
| 53 | + <div className="text-2xl font-bold text-slate-900">0.00€</div> |
| 54 | + <p className="text-xs text-slate-500">En attente de conversions</p> |
| 55 | + </CardContent> |
| 56 | + </Card> |
| 57 | + |
| 58 | + <Card className="bg-gradient-to-br from-white to-orange-50/50 border-slate-200/50 shadow-xl"> |
| 59 | + <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-2"> |
| 60 | + <CardTitle className="text-sm font-medium text-slate-700">Taux Conversion</CardTitle> |
| 61 | + <div className="p-2 bg-orange-100 rounded-full"> |
| 62 | + <Percent className="h-4 w-4 text-orange-600" /> |
| 63 | + </div> |
| 64 | + </CardHeader> |
| 65 | + <CardContent> |
| 66 | + <div className="text-2xl font-bold text-slate-900">0.0%</div> |
| 67 | + <p className="text-xs text-slate-500">Aucun clic pour le moment</p> |
| 68 | + </CardContent> |
| 69 | + </Card> |
| 70 | + </div> |
| 71 | + ); |
| 72 | +}; |
13 | 73 |
|
14 | 74 | export const Dashboard = memo(() => { |
15 | | - const { user, logout } = useOptimizedAuth(); |
16 | | - const { campaigns } = useCampaigns(); |
17 | | - const { affiliates } = useAffiliates(); |
18 | | - const { stats: globalStats, loading: globalStatsLoading } = useGlobalStats(); |
| 75 | + const { user } = useAuth(); |
| 76 | + const { campaigns, loading: campaignsLoading } = useCampaigns(); |
| 77 | + const { affiliates, loading: affiliatesLoading } = useAffiliates(); |
19 | 78 |
|
20 | 79 | const handleLogout = useCallback(async () => { |
21 | 80 | try { |
22 | | - await logout(); |
| 81 | + // Simple logout Firebase |
| 82 | + await auth.signOut(); |
| 83 | + localStorage.removeItem('auth_user'); |
23 | 84 | } catch (error) { |
24 | | - console.error('Erreur lors de la déconnexion:', error); |
| 85 | + console.error('Erreur logout:', error); |
25 | 86 | } |
26 | | - }, [logout]); |
| 87 | + }, []); |
27 | 88 |
|
28 | 89 | const dashboardMetrics = useMemo(() => { |
29 | 90 | const activeCampaigns = campaigns.filter(c => c.isActive).length; |
30 | | - const totalAffiliates = affiliates.length; |
31 | | - |
32 | 91 | return { |
33 | 92 | activeCampaigns, |
34 | 93 | totalCampaigns: campaigns.length, |
35 | | - totalAffiliates, |
| 94 | + totalAffiliates: affiliates.length, |
36 | 95 | }; |
37 | 96 | }, [campaigns, affiliates]); |
38 | 97 |
|
| 98 | + // Chargement ultra-rapide |
| 99 | + if (campaignsLoading || affiliatesLoading) { |
| 100 | + return ( |
| 101 | + <div className="min-h-screen bg-white flex items-center justify-center"> |
| 102 | + <div className="w-8 h-8 border-2 border-blue-600 border-t-transparent rounded-full animate-spin"></div> |
| 103 | + </div> |
| 104 | + ); |
| 105 | + } |
| 106 | + |
39 | 107 | return ( |
40 | 108 | <> |
41 | 109 | <Helmet> |
42 | 110 | <title>RefSpring - Dashboard</title> |
43 | | - <meta name="description" content="Gérez vos campagnes d'affiliation, suivez vos performances et optimisez vos revenus avec RefSpring." /> |
44 | | - <meta name="robots" content="noindex, nofollow" /> |
45 | 111 | </Helmet> |
46 | 112 |
|
47 | 113 | <NetworkStatus /> |
48 | 114 | <div className="min-h-screen bg-gradient-to-br from-blue-50/50 via-white to-purple-50/50 relative overflow-hidden"> |
49 | 115 | <DashboardBackground /> |
50 | | - |
51 | 116 | <DashboardHeader user={user} onLogout={handleLogout} /> |
52 | 117 |
|
53 | | - {/* Main Content */} |
54 | 118 | <main className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4 sm:py-6 lg:py-8"> |
55 | | - <ErrorBoundary fallback={ |
56 | | - <div className="text-center py-8"> |
57 | | - <p className="text-gray-600">Erreur lors du chargement des statistiques</p> |
58 | | - </div> |
59 | | - }> |
60 | | - <DashboardStats |
| 119 | + <ErrorBoundary fallback={<div>Erreur stats</div>}> |
| 120 | + <SimpleDashboardStats |
61 | 121 | activeCampaigns={dashboardMetrics.activeCampaigns} |
62 | 122 | totalCampaigns={dashboardMetrics.totalCampaigns} |
63 | 123 | totalAffiliates={dashboardMetrics.totalAffiliates} |
64 | | - globalStats={globalStats} |
65 | | - globalStatsLoading={globalStatsLoading} |
66 | 124 | /> |
67 | 125 | </ErrorBoundary> |
68 | 126 |
|
69 | | - <ErrorBoundary fallback={ |
70 | | - <div className="text-center py-8"> |
71 | | - <p className="text-gray-600">Erreur lors du chargement du contenu</p> |
72 | | - </div> |
73 | | - }> |
| 127 | + <ErrorBoundary fallback={<div>Erreur contenu</div>}> |
74 | 128 | <DashboardContent /> |
75 | 129 | </ErrorBoundary> |
76 | 130 | </main> |
|
0 commit comments