import React, { useState, useEffect } from 'react'; import { TrendingUp, Vote, Users, Briefcase, Map as MapIcon, Target, ChevronRight } from 'lucide-react'; import { backendApi } from '../../services/apiClient'; import { readCache, saveCache } from '../../hooks/useCachedFetch'; import { REFRESH_EVENTS } from '../../constants/refreshEvents'; interface Props { onNavigate: (tab: any) => void; } const CACHE_KEY = 'mkd_dev_summary_cache'; const CACHE_DEFAULT = { summary: { growthM2: 0, ossSuccessRate: 0, cac: 15000, potentialRevenue: 0 }, locations: [] }; export const DevSummary: React.FC = ({ onNavigate }) => { const cached = readCache<{ summary: any; locations: any[] }>(CACHE_KEY, CACHE_DEFAULT); const [summary, setSummary] = useState(cached.summary || CACHE_DEFAULT.summary); const [locations, setLocations] = useState(cached.locations || []); const hasCache = (cached.locations?.length ?? 0) > 0; const [loading, setLoading] = useState(!hasCache); useEffect(() => { const fetchData = async () => { if (!hasCache) setLoading(true); try { const [summaryData, locationsData] = await Promise.all([ backendApi.getDevelopmentSummary(), backendApi.getDevelopmentLocations() ]); setSummary(summaryData); setLocations(locationsData); saveCache(CACHE_KEY, { summary: summaryData, locations: locationsData }); } catch (error) { console.error('Error fetching development summary:', error); } finally { setLoading(false); } }; fetchData(); }, []); useEffect(() => { const onRefresh = () => { (async () => { try { const [summaryData, locationsData] = await Promise.all([ backendApi.getDevelopmentSummary(), backendApi.getDevelopmentLocations() ]); setSummary(summaryData); setLocations(locationsData); saveCache(CACHE_KEY, { summary: summaryData, locations: locationsData }); } catch (e) { console.error('Error fetching development summary:', e); } })(); }; window.addEventListener(REFRESH_EVENTS.devSummary, onRefresh); return () => window.removeEventListener(REFRESH_EVENTS.devSummary, onRefresh); }, []); useEffect(() => { const interval = setInterval(async () => { try { const [summaryData, locationsData] = await Promise.all([ backendApi.getDevelopmentSummary(), backendApi.getDevelopmentLocations() ]); setSummary(summaryData); setLocations(locationsData); saveCache(CACHE_KEY, { summary: summaryData, locations: locationsData }); } catch (e) { console.error('Error fetching development summary:', e); } }, 10 * 1000); return () => clearInterval(interval); }, []); return (
{/* KPI Cards */}
{/* Capture Map Widget */}
Стратегия экспансии

Карта присутствия

Интерактивный мониторинг конкурентов и зон активного голосования в Центральном районе.

{/* Visual Map Simulation */}
{/* Map Pointers - динамические из БД */} {locations.length > 0 ? ( locations.slice(0, 10).map((loc, idx) => { // Распределяем точки по карте (упрощенная логика) const positions = [ { top: '20%', left: '30%' }, { top: '45%', left: '60%' }, { top: '70%', left: '25%' }, { top: '35%', left: '80%' }, { top: '15%', left: '70%' }, { top: '60%', left: '40%' }, { top: '30%', left: '50%' }, { top: '50%', left: '20%' }, { top: '80%', left: '60%' }, { top: '10%', left: '40%' }, ]; const pos = positions[idx % positions.length]; const label = loc.status === 'voting' ? 'ОСС ИДЕТ' : undefined; return ( ); }) ) : ( // Fallback статические точки, если нет данных <> )}
Наш фонд
Проходит ОСС
Другие УК
{/* Quick Actions */}
); }; const StatCard = ({ icon: Icon, label, value, color, bg }: any) => (

{value}

{label}

); const MapPointer = ({ top, left, status, label, address }: any) => (
{(label || address) && (
{label || address}
)}
);