|
1 | | -import { useEffect, useState } from 'react'; |
2 | | -import { |
3 | | - collection, |
4 | | - addDoc, |
5 | | - query, |
6 | | - where, |
7 | | - onSnapshot, |
8 | | - updateDoc, |
9 | | - deleteDoc, |
10 | | - doc, |
11 | | - getDocs |
12 | | -} from 'firebase/firestore'; |
13 | | -import { db } from '@/lib/firebase'; |
| 1 | + |
14 | 2 | import { useAuth } from '@/hooks/useAuth'; |
15 | | -import { Campaign } from '@/types'; |
| 3 | +import { useCampaignData } from '@/hooks/useCampaignData'; |
| 4 | +import { useCampaignOperations } from '@/hooks/useCampaignOperations'; |
16 | 5 |
|
17 | 6 | export const useCampaigns = () => { |
18 | | - const [campaigns, setCampaigns] = useState<Campaign[]>([]); |
19 | | - const [loading, setLoading] = useState(true); |
20 | 7 | const { user, loading: authLoading } = useAuth(); |
21 | | - |
22 | | - useEffect(() => { |
23 | | - console.log('🎯 useCampaigns - Effect triggered'); |
24 | | - console.log('🎯 authLoading:', authLoading, 'user:', !!user); |
25 | | - |
26 | | - // PROTECTION STRICTE : Aucune requête avant auth complète |
27 | | - if (authLoading) { |
28 | | - console.log('🎯 Auth encore en cours, pas de requête Firebase'); |
29 | | - return; |
30 | | - } |
31 | | - |
32 | | - if (!user) { |
33 | | - console.log('🎯 Pas d\'utilisateur, nettoyage des campagnes'); |
34 | | - setCampaigns([]); |
35 | | - setLoading(false); |
36 | | - return; |
37 | | - } |
38 | | - |
39 | | - console.log('🎯 Auth OK, démarrage requête Firestore pour user:', user.uid); |
40 | | - |
41 | | - const campaignsRef = collection(db, 'campaigns'); |
42 | | - const q = query( |
43 | | - campaignsRef, |
44 | | - where('userId', '==', user.uid) |
45 | | - ); |
46 | | - |
47 | | - const unsubscribe = onSnapshot(q, (snapshot) => { |
48 | | - console.log('🎯 Firestore snapshot reçu, docs:', snapshot.docs.length); |
49 | | - |
50 | | - const campaignsData = snapshot.docs.map(doc => { |
51 | | - const data = doc.data(); |
52 | | - return { |
53 | | - id: doc.id, |
54 | | - ...data, |
55 | | - createdAt: data.createdAt?.toDate(), |
56 | | - updatedAt: data.updatedAt?.toDate(), |
57 | | - // Valeurs par défaut pour les nouveaux champs Stripe |
58 | | - paymentConfigured: data.paymentConfigured || false, |
59 | | - isDraft: data.isDraft || false, |
60 | | - }; |
61 | | - }) as Campaign[]; |
62 | | - |
63 | | - // Tri côté client - Ne montrer que les campagnes finalisées (non-draft) |
64 | | - const finalizedCampaigns = campaignsData |
65 | | - .filter(campaign => !campaign.isDraft) |
66 | | - .sort((a, b) => { |
67 | | - if (!a.createdAt || !b.createdAt) return 0; |
68 | | - return b.createdAt.getTime() - a.createdAt.getTime(); |
69 | | - }); |
70 | | - |
71 | | - console.log('🎯 Campagnes chargées:', finalizedCampaigns.length); |
72 | | - setCampaigns(finalizedCampaigns); |
73 | | - setLoading(false); |
74 | | - }, (error) => { |
75 | | - console.error('🎯 Erreur Firestore:', error); |
76 | | - setLoading(false); |
77 | | - }); |
78 | | - |
79 | | - return unsubscribe; |
80 | | - }, [user, authLoading]); |
81 | | - |
82 | | - const createCampaign = async (campaignData: Omit<Campaign, 'id' | 'createdAt' | 'updatedAt' | 'userId'>) => { |
83 | | - if (!user) throw new Error('User not authenticated'); |
84 | | - |
85 | | - const newCampaign = { |
86 | | - ...campaignData, |
87 | | - userId: user.uid, |
88 | | - createdAt: new Date(), |
89 | | - updatedAt: new Date(), |
90 | | - // Valeurs par défaut pour Stripe |
91 | | - paymentConfigured: campaignData.paymentConfigured || false, |
92 | | - isDraft: campaignData.isDraft || false, |
93 | | - }; |
94 | | - |
95 | | - console.log('Creating campaign:', newCampaign); |
96 | | - const docRef = await addDoc(collection(db, 'campaigns'), newCampaign); |
97 | | - console.log('Campaign created with ID:', docRef.id); |
98 | | - return docRef.id; |
99 | | - }; |
100 | | - |
101 | | - const updateCampaign = async (id: string, updates: Partial<Campaign>) => { |
102 | | - const campaignRef = doc(db, 'campaigns', id); |
103 | | - await updateDoc(campaignRef, { |
104 | | - ...updates, |
105 | | - updatedAt: new Date(), |
106 | | - }); |
107 | | - }; |
108 | | - |
109 | | - const finalizeCampaign = async (id: string, stripeData: { customerId: string; setupIntentId: string }) => { |
110 | | - const campaignRef = doc(db, 'campaigns', id); |
111 | | - await updateDoc(campaignRef, { |
112 | | - isDraft: false, |
113 | | - paymentConfigured: true, |
114 | | - stripeCustomerId: stripeData.customerId, |
115 | | - stripeSetupIntentId: stripeData.setupIntentId, |
116 | | - updatedAt: new Date(), |
117 | | - }); |
118 | | - console.log('✅ Campagne finalisée avec succès:', id); |
119 | | - }; |
120 | | - |
121 | | - const deleteCampaign = async (id: string) => { |
122 | | - if (!user) { |
123 | | - throw new Error('User not authenticated'); |
124 | | - } |
125 | | - |
126 | | - console.log('🗑️ Début suppression campagne:', id); |
127 | | - console.log('🗑️ User connecté:', user.uid); |
128 | | - |
129 | | - try { |
130 | | - // 1. Supprimer tous les affiliés de cette campagne |
131 | | - console.log('🗑️ Suppression des affiliés...'); |
132 | | - const affiliatesQuery = query( |
133 | | - collection(db, 'affiliates'), |
134 | | - where('campaignId', '==', id), |
135 | | - where('userId', '==', user.uid) // Ajout de l'userId pour respecter les règles |
136 | | - ); |
137 | | - const affiliatesSnapshot = await getDocs(affiliatesQuery); |
138 | | - console.log('🗑️ Affiliés trouvés:', affiliatesSnapshot.size); |
139 | | - |
140 | | - const deleteAffiliatesPromises = affiliatesSnapshot.docs.map(doc => { |
141 | | - console.log('🗑️ Suppression affilié:', doc.id); |
142 | | - return deleteDoc(doc.ref); |
143 | | - }); |
144 | | - await Promise.all(deleteAffiliatesPromises); |
145 | | - console.log('✅ Affiliés supprimés avec succès'); |
146 | | - |
147 | | - // 2. Supprimer tous les clics de cette campagne |
148 | | - console.log('🗑️ Suppression des clics...'); |
149 | | - const clicksQuery = query( |
150 | | - collection(db, 'clicks'), |
151 | | - where('campaignId', '==', id) |
152 | | - ); |
153 | | - const clicksSnapshot = await getDocs(clicksQuery); |
154 | | - console.log('🗑️ Clics trouvés:', clicksSnapshot.size); |
155 | | - |
156 | | - const deleteClicksPromises = clicksSnapshot.docs.map(doc => { |
157 | | - console.log('🗑️ Suppression clic:', doc.id); |
158 | | - return deleteDoc(doc.ref); |
159 | | - }); |
160 | | - await Promise.all(deleteClicksPromises); |
161 | | - console.log('✅ Clics supprimés avec succès'); |
162 | | - |
163 | | - // 3. Supprimer tous les liens courts de cette campagne |
164 | | - console.log('🗑️ Suppression des liens courts...'); |
165 | | - const shortLinksQuery = query( |
166 | | - collection(db, 'shortLinks'), |
167 | | - where('campaignId', '==', id) |
168 | | - ); |
169 | | - const shortLinksSnapshot = await getDocs(shortLinksQuery); |
170 | | - console.log('🗑️ Liens courts trouvés:', shortLinksSnapshot.size); |
171 | | - |
172 | | - const deleteShortLinksPromises = shortLinksSnapshot.docs.map(doc => { |
173 | | - console.log('🗑️ Suppression lien court:', doc.id); |
174 | | - return deleteDoc(doc.ref); |
175 | | - }); |
176 | | - await Promise.all(deleteShortLinksPromises); |
177 | | - console.log('✅ Liens courts supprimés avec succès'); |
178 | | - |
179 | | - // 4. Supprimer toutes les conversions de cette campagne |
180 | | - console.log('🗑️ Suppression des conversions...'); |
181 | | - const conversionsQuery = query( |
182 | | - collection(db, 'conversions'), |
183 | | - where('campaignId', '==', id) |
184 | | - ); |
185 | | - const conversionsSnapshot = await getDocs(conversionsQuery); |
186 | | - console.log('🗑️ Conversions trouvées:', conversionsSnapshot.size); |
187 | | - |
188 | | - const deleteConversionsPromises = conversionsSnapshot.docs.map(doc => { |
189 | | - console.log('🗑️ Suppression conversion:', doc.id); |
190 | | - return deleteDoc(doc.ref); |
191 | | - }); |
192 | | - await Promise.all(deleteConversionsPromises); |
193 | | - console.log('✅ Conversions supprimées avec succès'); |
194 | | - |
195 | | - // 5. Finalement, supprimer la campagne elle-même |
196 | | - console.log('🗑️ Suppression de la campagne...'); |
197 | | - const campaignRef = doc(db, 'campaigns', id); |
198 | | - await deleteDoc(campaignRef); |
199 | | - |
200 | | - console.log('✅ Suppression complète terminée pour la campagne:', id); |
201 | | - |
202 | | - } catch (error) { |
203 | | - console.error('❌ Erreur lors de la suppression en cascade:', error); |
204 | | - console.error('❌ Détails de l\'erreur:', { |
205 | | - message: error.message, |
206 | | - code: error.code, |
207 | | - stack: error.stack |
208 | | - }); |
209 | | - throw error; |
210 | | - } |
211 | | - }; |
| 8 | + const { campaigns, loading } = useCampaignData(user?.uid || null, authLoading); |
| 9 | + const operations = useCampaignOperations(user?.uid || null); |
212 | 10 |
|
213 | 11 | return { |
214 | 12 | campaigns, |
215 | 13 | loading, |
216 | | - createCampaign, |
217 | | - updateCampaign, |
218 | | - finalizeCampaign, |
219 | | - deleteCampaign, |
| 14 | + ...operations, |
220 | 15 | }; |
221 | 16 | }; |
0 commit comments