import React, { useState, useEffect, useCallback } from 'react'; import '../FontMap.css'; // Import des hooks import { useFontData } from './hooks/useFontData'; import { useD3Visualization } from './hooks/useD3Visualization'; import { useArrowNavigation } from './hooks/useArrowNavigation'; // Import des composants de contrôles import FilterControls from './components/controls/FilterControls'; import SearchBar from './components/controls/SearchBar'; import ZoomControls from './components/controls/ZoomControls'; import ActiveFont from './components/ActiveFont'; import TooltipManager from './components/TooltipManager'; import IntroModal from './components/IntroModal'; import AboutModal from './components/AboutModal'; import FPSMonitor from './components/FPSMonitor'; // Import du hook Tweakpane import { useTweakpane } from './hooks/useTweakpane'; import { useFontMapStore } from '../../store/fontMapStore'; import './styles/intro-modal.css'; import './styles/about-modal.css'; /** * Composant principal FontMap unifié */ const FontMap = ({ darkMode = false }) => { // États locaux (seulement ceux vraiment nécessaires) const [filter, setFilter] = useState('all'); const [searchTerm, setSearchTerm] = useState(''); const [appState, setAppState] = useState('loading'); // 'loading', 'intro', 'ready' const [showAboutModal, setShowAboutModal] = useState(false); // Récupérer seulement l'état nécessaire (les autres sont gérés dans les hooks) const { selectedFont, hoveredFont, setSelectedFont, setHoveredFont } = useFontMapStore(); // Dataset fixe à 'new' (nouveau pipeline) const dataset = 'new'; console.log('🔧 FontMap using dataset:', dataset); const handleFilterChange = (newFilter) => { setFilter(newFilter); }; const handleSearchChange = (newSearchTerm) => { setSearchTerm(newSearchTerm); }; const handleFontSelect = (font) => { console.log('FontMap: handleFontSelect called with', font); setSelectedFont(font); }; const handleCloseDetails = () => { setSelectedFont(null); }; const handleShowAbout = () => { setShowAboutModal(true); }; const handleCloseAbout = () => { setShowAboutModal(false); }; const handleFontHover = useCallback((font) => { setHoveredFont(font); }, [setHoveredFont]); const handleFontUnhover = useCallback(() => { setHoveredFont(null); }, [setHoveredFont]); const handleStartExploring = () => { setAppState('ready'); }; // Hooks personnalisés const { fonts, loading, error } = useFontData(dataset); // Hook pour la navigation aux flèches (doit être avant useD3Visualization) useArrowNavigation( selectedFont, fonts, filter, searchTerm, handleFontSelect ); const svgRef = useD3Visualization(fonts, filter, searchTerm, darkMode, loading); // Initialiser Tweakpane const { isDebugMode } = useTweakpane(darkMode); // Calculer les compteurs pour la recherche const totalFonts = fonts.length; // Compter les polices correspondant au filtre actif (sans recherche) const filterOnlyCount = filter === 'all' ? totalFonts : fonts.filter(font => font.family === filter).length; // Compter les polices correspondant au filtre ET à la recherche const filteredFonts = fonts.filter(font => { const familyMatch = filter === 'all' || font.family === filter; const searchMatch = !searchTerm || font.name.toLowerCase().includes(searchTerm.toLowerCase()) || font.family.toLowerCase().includes(searchTerm.toLowerCase()); return familyMatch && searchMatch; }); const filteredCount = filteredFonts.length; // Configurer les callbacks globaux pour le TooltipManager useEffect(() => { window.onFontHover = handleFontHover; window.onFontUnhover = handleFontUnhover; return () => { delete window.onFontHover; delete window.onFontUnhover; }; }, [handleFontHover, handleFontUnhover]); // Surveiller les changements de selectedFont useEffect(() => { console.log('FontMap: selectedFont state changed to', selectedFont); }, [selectedFont]); // Gérer les transitions d'état de l'application useEffect(() => { if (loading) { setAppState('loading'); } else if (fonts.length > 0 && appState === 'loading') { setAppState('intro'); } }, [loading, fonts.length, appState]); // Affichage de l'erreur if (error) { return (
{error}