turash/bugulma/frontend/contexts/MapActionsContext.tsx
Damir Mukimov 673e8d4361
Some checks failed
CI/CD Pipeline / backend-lint (push) Failing after 31s
CI/CD Pipeline / backend-build (push) Has been skipped
CI/CD Pipeline / frontend-lint (push) Failing after 1m37s
CI/CD Pipeline / frontend-build (push) Has been skipped
CI/CD Pipeline / e2e-test (push) Has been skipped
fix: resolve all frontend lint errors (85 issues fixed)
- Replace all 'any' types with proper TypeScript interfaces
- Fix React hooks setState in useEffect issues with lazy initialization
- Remove unused variables and imports across all files
- Fix React Compiler memoization dependency issues
- Add comprehensive i18n translation keys for admin interfaces
- Apply consistent prettier formatting throughout codebase
- Clean up unused bulk editing functionality
- Improve type safety and code quality across frontend

Files changed: 39
- ImpactMetrics.tsx: Fixed any types and interfaces
- AdminVerificationQueuePage.tsx: Added i18n keys, removed unused vars
- LocalizationUIPage.tsx: Fixed memoization, added translations
- LocalizationDataPage.tsx: Added type safety and translations
- And 35+ other files with various lint fixes
2025-12-25 14:14:58 +01:00

166 lines
4.9 KiB
TypeScript

/**
* Map Actions Context
* Coordinates actions across all map contexts
* Provides a unified interface for map operations
* Separated from MapContexts.tsx for better SRP
*/
import { createContext, ReactNode, useCallback, useContext } from 'react';
import { useNavigate } from 'react-router-dom';
import { useGetWebIntelligence } from '@/hooks/useGemini.ts';
import { useTranslation } from '@/hooks/useI18n.tsx';
import type { HistoricalLandmark } from '@/schemas/historical.ts';
import { analyzeSymbiosis } from '@/services/aiService.ts';
import type { Organization } from '@/types.ts';
import { useMapFilter } from '@/contexts/MapFilterContext.tsx';
import { useMapInteraction } from '@/contexts/MapInteractionContext.tsx';
import { useMapUI } from '@/contexts/MapUIContext.tsx';
import { useMapViewport } from '@/contexts/MapViewportContext.tsx';
interface MapActionsContextType {
// Organization actions
handleAddOrganization: () => void;
handleViewOrganization: (org: Organization) => void;
handleSelectOrg: (org: Organization | null) => void;
handleSelectLandmark: (landmark: HistoricalLandmark | null) => void;
// Navigation actions
handleMapNavigation: () => void;
// AI actions
handleAnalyzeSymbiosis: () => void;
handleFetchWebIntelligence: () => void;
// Composite actions
resetMapState: () => void;
}
const MapActionsContext = createContext<MapActionsContextType | undefined>(undefined);
export const useMapActions = () => {
const context = useContext(MapActionsContext);
if (context === undefined) {
throw new Error('useMapActions must be used within a MapActionsProvider');
}
return context;
};
interface MapActionsProviderProps {
children: ReactNode;
}
export const MapActionsProvider = ({ children }: MapActionsProviderProps) => {
const navigate = useNavigate();
const { t } = useTranslation();
// Use all the focused contexts
const viewport = useMapViewport();
const interaction = useMapInteraction();
const filter = useMapFilter();
const ui = useMapUI();
// Web intelligence hook
const { refetch: fetchWebIntelligence } = useGetWebIntelligence(interaction.selectedOrg?.Name, t);
const handleAddOrganization = useCallback(() => {
// Could navigate to add organization page or open modal
navigate('/add-organization');
}, [navigate]);
const handleViewOrganization = useCallback(
(org: Organization) => {
navigate(`/organization/${org.ID}`);
},
[navigate]
);
const handleSelectOrg = useCallback(
(org: Organization | null) => {
interaction.handleSelectOrg(org);
// Open sidebar to show organization details when an org is selected
if (org) {
ui.setIsSidebarOpen(true);
}
},
[interaction, ui]
);
const handleSelectLandmark = useCallback(
(landmark: HistoricalLandmark | null) => {
interaction.handleSelectLandmark(landmark);
// Open sidebar to show landmark details when a landmark is selected
if (landmark) {
ui.setIsSidebarOpen(true);
}
},
[interaction, ui]
);
const handleMapNavigation = useCallback(() => {
navigate('/map');
}, [navigate]);
const handleAnalyzeSymbiosis = useCallback(async () => {
if (!interaction.selectedOrg) return;
try {
interaction.setIsAnalyzing(true);
interaction.setAnalysisError(null);
const result = await analyzeSymbiosis(interaction.selectedOrg, []);
interaction.setSymbiosisResult(result);
} catch (error) {
interaction.setAnalysisError(error instanceof Error ? error.message : 'Analysis failed');
} finally {
interaction.setIsAnalyzing(false);
}
}, [interaction]);
const handleFetchWebIntelligence = useCallback(async () => {
if (!interaction.selectedOrg?.Name) return;
try {
interaction.setIsFetchingWebIntel(true);
interaction.setWebIntelError(null);
const result = await fetchWebIntelligence();
if (result.data) {
interaction.setWebIntelResult(result.data);
}
} catch (error) {
interaction.setWebIntelError(
error instanceof Error ? error.message : 'Web intelligence failed'
);
} finally {
interaction.setIsFetchingWebIntel(false);
}
}, [interaction, fetchWebIntelligence]);
const resetMapState = useCallback(() => {
// Reset viewport
viewport.resetView();
// Clear interactions
interaction.handleSelectOrg(null);
interaction.handleSelectLandmark(null);
interaction.clearAnalysisResults();
// Clear filters
filter.clearFilters();
// Close sidebar
ui.closeSidebar();
}, [viewport, interaction, filter, ui]);
const value: MapActionsContextType = {
handleAddOrganization,
handleViewOrganization,
handleSelectOrg,
handleSelectLandmark,
handleMapNavigation,
handleAnalyzeSymbiosis,
handleFetchWebIntelligence,
resetMapState,
};
return <MapActionsContext.Provider value={value}>{children}</MapActionsContext.Provider>;
};