import React, { useState } from 'react'; import type { ScreenData, ViewMode, MetricsSource, DeviceStatus } from '../types/simulator'; import { Smartphone, Layers, Flame, Download, Upload, Camera, Search, Database, ChevronRight, PlusCircle, HardDriveDownload, AlertTriangle } from 'lucide-react'; interface SidebarProps { screens: ScreenData[]; currentScreenId: string; onSelectScreen: (id: string) => void; mode: ViewMode; onSetMode: (mode: ViewMode) => void; onSyncClickhouse: () => void; isSyncing: boolean; onExportJson: () => void; onImportJson: (e: React.ChangeEvent) => void; onTriggerAdbCapture: (screenId?: string) => void; onAddNewScreenWithAdb: () => void; isCapturing: boolean; onSaveAppMap: () => void; isSavingMap: boolean; isDirty: boolean; metricsSource: MetricsSource; deviceStatus: DeviceStatus | null; } export const Sidebar: React.FC = ({ screens, currentScreenId, onSelectScreen, mode, onSetMode, onSyncClickhouse, isSyncing, onExportJson, onImportJson, onTriggerAdbCapture, onAddNewScreenWithAdb, isCapturing, onSaveAppMap, isSavingMap, isDirty, metricsSource, deviceStatus }) => { const [searchQuery, setSearchQuery] = useState(''); // Filter screens or hotspots by search const filteredScreens = screens.filter(s => s.name.toLowerCase().includes(searchQuery.toLowerCase()) || s.hotspots.some(h => h.label.toLowerCase().includes(searchQuery.toLowerCase()) || h.eventKey.toLowerCase().includes(searchQuery.toLowerCase()) || h.eventNameRu.toLowerCase().includes(searchQuery.toLowerCase()) ) ); const currentScreen = screens.find(s => s.id === currentScreenId); return (
{/* Mode Switcher Buttons */}
{/* Search Input */}
setSearchQuery(e.target.value)} style={{ width: '100%', padding: '8px 12px 8px 34px', background: 'rgba(0,0,0,0.3)', border: '1px solid rgba(255,255,255,0.08)', borderRadius: '8px', color: '#fff', fontSize: '0.8rem' }} />
{/* Screen Selector List */}
{filteredScreens.map(s => { const isActive = s.id === currentScreenId; const measuredCount = s.hotspots.filter(h => !!h.metrics).length; const totalScreenEvents = s.hotspots.reduce((sum, h) => sum + (h.metrics?.totalEvents || 0), 0); return (
onSelectScreen(s.id)} style={{ padding: '10px 12px', borderRadius: '10px', background: isActive ? 'rgba(0, 163, 255, 0.15)' : 'rgba(255,255,255,0.02)', border: isActive ? '1px solid #00d2ff' : '1px solid rgba(255,255,255,0.05)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'space-between', transition: 'all 0.2s ease' }} >
{s.name}
{s.hotspots.length} зон • {measuredCount > 0 ? ( {totalScreenEvents.toLocaleString('ru-RU')} событий ) : ( без метрик )} {s.screenshotStale && }
); })}
{/* Capture Options & Actions */}
{/* Persist edits. Export downloads a copy; this writes the file the app reads. */} {/* ADB Capture Button for Selected Screen */} {/* ClickHouse Sync Button */} {metricsSource !== 'clickhouse' && (
Показаны демонстрационные числа, а не данные ClickHouse. Укажите CLICKHOUSE_HOST в .env и запустите py tools/fetch_clickhouse.py.
)} {/* Import & Export JSON buttons */}
); };