# 📊 Intégration du Tracking - Résumé ## ✅ Pages Intégrées Le système de tracking des recherches a été intégré dans les pages suivantes : ### 1. Questions (`/questions`) **Catégorie** : `QUESTIONS` **Ce qui est tracké** : - Terme de recherche saisi - Filtre appliqué : `all`, `solved`, `unsolved` - Numéro de page - Nombre de résultats retournés **Implémentation** : ```tsx const { trackSearch } = useSearchTracking('QUESTIONS'); // Fetch questions with debounce (300ms for quick UX) useEffect(() => { const timer = setTimeout(() => { fetchQuestions(); }, 300); return () => clearTimeout(timer); }, [filter, searchTerm, currentPage]); // Track search separately with longer debounce (800ms - user has stopped typing) useEffect(() => { if (searchTerm.trim().length >= 2) { const trackTimer = setTimeout(() => { trackSearch( searchTerm, { filter: filter !== 'all' ? filter : undefined, page: currentPage }, totalCount ); }, 800); return () => clearTimeout(trackTimer); } }, [searchTerm, filter, currentPage, totalCount]); ``` **Stratégie de Debounce** : - **Fetch** : 300ms (UX rapide, résultats s'affichent vite) - **Tracking** : 800ms (l'utilisateur a vraiment fini de taper) - **Minimum** : 2 caractères pour éviter le bruit **Pourquoi 2 niveaux ?** - L'utilisateur voit les résultats rapidement (300ms) - Mais on ne track que la recherche finale (800ms) - Évite de polluer les analytics avec "p", "py", "pyt", etc. --- ### 2. Mentors (`/mentors`) **Catégorie** : `MENTORS` **Ce qui est tracké** : - Terme de recherche (nom ou bio) - Pays sélectionné - Spécialité sélectionnée - Tri appliqué (`rating`, `reviews`) - Nombre de résultats filtrés **Implémentation** : ```tsx const { trackSearch } = useSearchTracking('MENTORS'); // Track search with debounce (only when user stops typing) useEffect(() => { if (searchTerm.trim().length >= 2) { const timer = setTimeout(() => { trackSearch( searchTerm, { country: selectedCountry !== 'All' ? selectedCountry : undefined, specialty: selectedSpecialty !== 'All' ? selectedSpecialty : undefined, sortBy }, filteredMentors.length ); }, 800); return () => clearTimeout(timer); } }, [searchTerm, selectedCountry, selectedSpecialty, sortBy, filteredMentors.length]); ``` **Debounce** : 800ms (filtrage local, pas de fetch API) --- ### 3. Opportunities (`/opportunities`) **Catégorie** : `OPPORTUNITIES` **Ce qui est tracké** : - Type d'opportunité sélectionné (filtre) - Nombre de résultats correspondants **Implémentation** : ```tsx const { trackSearch } = useSearchTracking('OPPORTUNITIES'); // Track filter changes useEffect(() => { if (filter !== 'All') { trackSearch( filter, { type: filter }, filteredOpportunities.length ); } }, [filter, filteredOpportunities.length]); ``` **Note** : Pas de debounce car c'est un clic sur un bouton, pas une saisie --- ## 📈 Données Collectées Pour chaque recherche, le système enregistre : | Champ | Description | Exemple | |-------|-------------|---------| | `user` | Utilisateur connecté (ou null) | `user_id: 123` | | `category` | Type de recherche | `QUESTIONS` | | `search_query` | Terme recherché | `"python django"` | | `filters_applied` | Filtres JSON | `{"filter": "unsolved", "page": 2}` | | `results_count` | Nombre de résultats | `15` | | `session_id` | ID de session | Auto | | `ip_address` | IP de l'utilisateur | Auto | | `user_agent` | Navigateur | Auto | | `page_url` | URL de la page | Auto | | `created_at` | Timestamp | Auto | --- ## 🎯 Prochaines Étapes Suggérées ### Pages à Intégrer Ensuite 1. **Tools** (`/tools`) - Catégorie : `TOOLS` - Recherche d'outils pédagogiques 2. **Recherche Globale** (si existe) - Catégorie : `GENERAL` - Barre de recherche dans le header 3. **Users** (si page de recherche d'utilisateurs existe) - Catégorie : `USERS` ### Fonctionnalités Avancées 1. **Tracking des Clics** - Utiliser `trackClick()` quand un utilisateur clique sur un résultat - Exemple dans Questions : ```tsx const { trackClick } = useSearchTracking('QUESTIONS'); trackClick(null, question.id, index)} /> ``` 2. **Suggestions Autocomplete** - Utiliser `analyticsService.getPopularSearches()` pour suggérer des recherches populaires - Afficher en dessous de la barre de recherche 3. **Dashboard Analytics** - Créer une page admin pour visualiser : - Top 10 des recherches - Tendances de la semaine - Recherches sans résultats - Taux de clic par catégorie --- ## 🔍 Exemples de Requêtes Utiles ### Recherches les plus populaires cette semaine ```sql SELECT search_query, COUNT(*) as count FROM search_logs WHERE category = 'QUESTIONS' AND created_at >= NOW() - INTERVAL '7 days' GROUP BY search_query ORDER BY count DESC LIMIT 10; ``` ### Recherches sans résultats (lacunes de contenu) ```sql SELECT search_query, COUNT(*) as count FROM search_logs WHERE results_count = 0 AND created_at >= NOW() - INTERVAL '30 days' GROUP BY search_query ORDER BY count DESC LIMIT 20; ``` ### Filtres les plus utilisés ```sql SELECT category, jsonb_object_keys(filters_applied) as filter_key, COUNT(*) as usage_count FROM search_logs WHERE filters_applied != '{}'::jsonb GROUP BY category, filter_key ORDER BY usage_count DESC; ``` --- ## ✨ Bonnes Pratiques Appliquées 1. ✅ **Debounce** : Évite de tracker chaque frappe (300-500ms) 2. ✅ **Minimum 2 caractères** : Ne track que si `searchTerm.trim()` existe 3. ✅ **Non-bloquant** : Tracking async, n'affecte pas l'UX 4. ✅ **Gestion d'erreurs** : Le tracking échoue silencieusement si l'API est down 5. ✅ **Respect de la vie privée** : IP et User Agent pour analytics, pas de données sensibles 6. ✅ **Flexible** : Filtres en JSON permettent d'ajouter de nouveaux critères sans migration --- ## 📊 Métriques Disponibles Avec ce système, vous pouvez maintenant répondre à : - ❓ **Quels sujets intéressent le plus les étudiants ?** - 🔍 **Quelles recherches ne donnent aucun résultat ?** (opportunités de contenu) - 🌍 **Quels pays recherchent quels mentors ?** - 📈 **Quelles sont les tendances émergentes ?** - 🎯 **Les filtres sont-ils utilisés ?** Lesquels ? - ⏰ **À quelles heures les utilisateurs recherchent-ils le plus ?** --- **Système opérationnel et prêt à collecter des insights précieux ! 🚀** *Développé avec ❤️ par Marino ATOHOUN pour Hypee*