/** * Map Interaction Context * Manages user interactions: selections, hovers, analysis results * Separated from MapContexts.tsx for better SRP */ import React, { createContext, ReactNode, useCallback, useContext, useState } from 'react'; import type { HistoricalLandmark, Organization, SymbiosisMatch, WebIntelligenceResult, } from '@/types.ts'; interface MapInteractionState { // Organization interactions selectedOrg: Organization | null; hoveredOrgId: string | null; // Landmark interactions selectedLandmark: HistoricalLandmark | null; hoveredLandmarkId: string | null; // Analysis results symbiosisResult: SymbiosisMatch[] | null; isAnalyzing: boolean; analysisError: string | null; webIntelResult: WebIntelligenceResult | null; isFetchingWebIntel: boolean; webIntelError: string | null; } interface MapInteractionActions { handleSelectOrg: (org: Organization | null) => void; setHoveredOrgId: (id: string | null) => void; handleSelectLandmark: (landmark: HistoricalLandmark | null) => void; setHoveredLandmarkId: (id: string | null) => void; setSymbiosisResult: (result: SymbiosisMatch[] | null) => void; setIsAnalyzing: (analyzing: boolean) => void; setAnalysisError: (error: string | null) => void; setWebIntelResult: (result: WebIntelligenceResult | null) => void; setIsFetchingWebIntel: (fetching: boolean) => void; setWebIntelError: (error: string | null) => void; clearAnalysisResults: () => void; } interface MapInteractionContextType extends MapInteractionState, MapInteractionActions {} const MapInteractionContext = createContext(undefined); export const useMapInteraction = () => { const context = useContext(MapInteractionContext); if (context === undefined) { throw new Error('useMapInteraction must be used within a MapInteractionProvider'); } return context; }; interface MapInteractionProviderProps { children: ReactNode; } export const MapInteractionProvider = ({ children }: MapInteractionProviderProps) => { // Organization interactions const [selectedOrg, setSelectedOrg] = useState(null); const [hoveredOrgId, setHoveredOrgId] = useState(null); // Landmark interactions const [selectedLandmark, setSelectedLandmark] = useState(null); const [hoveredLandmarkId, setHoveredLandmarkId] = useState(null); // Analysis state const [symbiosisResult, setSymbiosisResult] = useState(null); const [isAnalyzing, setIsAnalyzing] = useState(false); const [analysisError, setAnalysisError] = useState(null); const [webIntelResult, setWebIntelResult] = useState(null); const [isFetchingWebIntel, setIsFetchingWebIntel] = useState(false); const [webIntelError, setWebIntelError] = useState(null); const handleSelectOrg = useCallback((org: Organization | null) => { setSelectedOrg(org); }, []); const handleSelectLandmark = useCallback((landmark: HistoricalLandmark | null) => { setSelectedLandmark(landmark); }, []); const clearAnalysisResults = useCallback(() => { setSymbiosisResult(null); setWebIntelResult(null); setAnalysisError(null); setWebIntelError(null); }, []); const value: MapInteractionContextType = { // State selectedOrg, hoveredOrgId, selectedLandmark, hoveredLandmarkId, symbiosisResult, isAnalyzing, analysisError, webIntelResult, isFetchingWebIntel, webIntelError, // Actions handleSelectOrg, setHoveredOrgId, handleSelectLandmark, setHoveredLandmarkId, setSymbiosisResult, setIsAnalyzing, setAnalysisError, setWebIntelResult, setIsFetchingWebIntel, setWebIntelError, clearAnalysisResults, }; return {children}; };