"use client"; import React, { useState } from 'react'; import { UseCrashDataResult } from '../hooks/useCrashData'; interface UnifiedControlPanelProps { // Map controls props mapStyleChoice: 'dark' | 'streets'; onChangeStyle: (v: 'dark' | 'streets') => void; heatVisible: boolean; onToggleHeat: (v: boolean) => void; pointsVisible: boolean; onTogglePoints: (v: boolean) => void; heatRadius: number; onChangeRadius: (v: number) => void; heatIntensity: number; onChangeIntensity: (v: number) => void; gradientRoutes: boolean; onToggleGradientRoutes: (v: boolean) => void; // Crash data controls props crashDataHook: UseCrashDataResult; onDataLoaded?: (dataCount: number) => void; } export default function UnifiedControlPanel({ mapStyleChoice, onChangeStyle, heatVisible, onToggleHeat, pointsVisible, onTogglePoints, heatRadius, onChangeRadius, heatIntensity, onChangeIntensity, gradientRoutes, onToggleGradientRoutes, crashDataHook, onDataLoaded }: UnifiedControlPanelProps) { // Panel state management const [mainPanelOpen, setMainPanelOpen] = useState(() => { try { const v = typeof window !== 'undefined' ? window.localStorage.getItem('unified_panel_open') : null; return v === null ? true : v === '1'; } catch (e) { return true; } }); const [mapControlsOpen, setMapControlsOpen] = useState(() => { try { const v = typeof window !== 'undefined' ? window.localStorage.getItem('map_controls_section_open') : null; return v === null ? true : v === '1'; } catch (e) { return true; } }); const [crashDataOpen, setCrashDataOpen] = useState(() => { try { const v = typeof window !== 'undefined' ? window.localStorage.getItem('crash_data_section_open') : null; return v === null ? true : v === '1'; } catch (e) { return true; } }); // Crash data state const { data, loading, error, pagination, loadMore, refresh, yearFilter, setYearFilter } = crashDataHook; const currentYear = new Date().getFullYear().toString(); const [selectedYear, setSelectedYear] = useState(yearFilter || currentYear); React.useEffect(() => { if (onDataLoaded) { onDataLoaded(data.length); } }, [data.length, onDataLoaded]); const handleYearChange = (year: string) => { setSelectedYear(year); const filterYear = year === 'all' ? null : year; if (setYearFilter) { setYearFilter(filterYear); } }; const toggleMainPanel = (next: boolean) => { setMainPanelOpen(next); try { window.localStorage.setItem('unified_panel_open', next ? '1' : '0'); } catch (e) {} }; const toggleMapControls = (next: boolean) => { setMapControlsOpen(next); try { window.localStorage.setItem('map_controls_section_open', next ? '1' : '0'); } catch (e) {} }; const toggleCrashData = (next: boolean) => { setCrashDataOpen(next); try { window.localStorage.setItem('crash_data_section_open', next ? '1' : '0'); } catch (e) {} }; const panelStyle = { backgroundColor: 'var(--panel-darker)', color: '#f9fafb', border: '2px solid var(--panel-medium)', boxShadow: '0 20px 60px rgba(0,0,0,0.4), 0 4px 12px rgba(0,0,0,0.2)', backdropFilter: 'blur(20px)', zIndex: 20, fontWeight: '500' }; const selectStyle = { backgroundColor: 'var(--panel-dark)', color: '#f9fafb', border: '2px solid var(--panel-medium)', fontSize: '14px', fontWeight: '500', padding: '8px 12px', borderRadius: '8px', outline: 'none' }; const sectionHeaderStyle = { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '12px', paddingBottom: '8px', borderBottom: '1px solid var(--panel-medium)' }; const toggleButtonStyle = { borderRadius: 6, padding: '6px 10px', backgroundColor: 'var(--panel-dark)', color: '#e5e7eb', border: '1px solid var(--panel-medium)', fontWeight: '600', cursor: 'pointer', fontSize: '12px' }; return (
{/* Main panel header */}
Control Panel
{mainPanelOpen && ( <> {/* Map Controls Section */}
Map Controls
{mapControlsOpen && (
onToggleHeat(e.target.checked)} />
onTogglePoints(e.target.checked)} />
onToggleGradientRoutes(e.target.checked)} />
onChangeRadius(Number(e.target.value))} style={{ width: '100%' }} />
onChangeIntensity(Number(e.target.value))} style={{ width: '100%' }} />
Tip: switching style will reapply layers.
)}
{/* Crash Data Controls Section */}
Crash Data
{crashDataOpen && (
{/* Crash Density Legend */}
Density Legend
Low High
{/* Year Filter */}
{/* Data Status */}
Loaded: {data.length.toLocaleString()} crashes {yearFilter && ` (${yearFilter})`}
{pagination && !yearFilter && (
Page {pagination.page} of {pagination.totalPages}
Total: {pagination.total.toLocaleString()} crashes
)} {pagination && yearFilter && (
All crashes for {yearFilter} loaded
)} {loading && (
Loading...
)} {error && (
Error: {error}
)} {/* Action Buttons */}
{pagination?.hasNext && !yearFilter && ( )}
)}
)}
); }