From 24be56ad0c47fbda5a8288b62c2acfc472f380c8 Mon Sep 17 00:00:00 2001 From: Alexander Borg Date: Mon, 18 Aug 2025 10:28:08 +0200 Subject: [PATCH] Fix jwt-token --- client/src/pages/MapView.jsx | 337 ++++++++++++++++++++++++----------- 1 file changed, 231 insertions(+), 106 deletions(-) diff --git a/client/src/pages/MapView.jsx b/client/src/pages/MapView.jsx index a6cd8dc..0506826 100644 --- a/client/src/pages/MapView.jsx +++ b/client/src/pages/MapView.jsx @@ -421,7 +421,21 @@ const MapView = () => { opacity: opacity * 0.8, dashArray: dashPattern }} - /> + eventHandlers={{ + click: () => { + console.log('MapView: Ring clicked for drone:', detection); + } + }} + > + + + + {/* Drone ID label for multiple drones */} {totalDrones > 1 && age < 5 && ( // Show labels for recent detections with multiple drones @@ -451,7 +465,12 @@ const MapView = () => { opacity={opacity * 0.9} > - + )} @@ -464,7 +483,12 @@ const MapView = () => { opacity={opacity * 0.7} > - + )} @@ -607,121 +631,222 @@ const DevicePopup = ({ device, status, detections }) => ( ); -const DroneDetectionPopup = ({ detection, age, droneTypes }) => ( -
-
-

- 🚨 - Drone Detection -

- - {age < 1 ? 'LIVE' : `${Math.round(age)}m ago`} - -
+const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory }) => { + // Get all detections for this specific drone from history + const droneHistory = droneDetectionHistory.filter(d => + d.drone_id === detection.drone_id && d.device_id === detection.device_id + ).slice(0, 10); // Last 10 detections for this drone + + // Calculate movement trend from history + const calculateMovementTrend = () => { + if (droneHistory.length < 2) return null; -
-
-
- Drone ID: -
{detection.drone_id}
-
-
- Type: -
{droneTypes[detection.drone_type] || 'Unknown'}
-
+ const sortedHistory = [...droneHistory].sort((a, b) => + new Date(a.device_timestamp) - new Date(b.device_timestamp) + ); + + const first = sortedHistory[0]; + const latest = sortedHistory[sortedHistory.length - 1]; + const rssiChange = latest.rssi - first.rssi; + + return { + change: rssiChange, + trend: rssiChange > 2 ? 'APPROACHING' : + rssiChange < -2 ? 'RETREATING' : 'STABLE', + duration: (new Date(latest.device_timestamp) - new Date(first.device_timestamp)) / 1000 / 60, // minutes + detectionCount: droneHistory.length + }; + }; + + const movementTrend = calculateMovementTrend(); + const firstDetection = droneHistory.length > 0 ? + droneHistory.reduce((earliest, current) => + new Date(current.device_timestamp) < new Date(earliest.device_timestamp) ? current : earliest + ) : detection; + + return ( +
+
+

+ 🚨 + Drone Detection Details +

+ + {age < 1 ? 'LIVE' : `${Math.round(age)}m ago`} +
-
-
- RSSI: -
-50 ? 'text-red-600' : - detection.rssi > -70 ? 'text-orange-600' : - 'text-green-600' - }`}> - {detection.rssi}dBm -
-
-
- Frequency: -
{detection.freq}MHz
-
-
- -
-
- Confidence: -
{(detection.confidence_level * 100).toFixed(0)}%
-
-
- Duration: -
{(detection.signal_duration / 1000).toFixed(1)}s
-
-
- - {/* Movement Analysis */} - {detection.movement_analysis && ( -
- Movement Analysis: -
-
= 3 ? 'bg-red-100 text-red-800' : - detection.movement_analysis.alertLevel >= 2 ? 'bg-orange-100 text-orange-800' : - detection.movement_analysis.alertLevel >= 1 ? 'bg-blue-100 text-blue-800' : - 'bg-gray-100 text-gray-800' - }`}> - {detection.movement_analysis.description} +
+ {/* Basic Information */} +
+
+
+ Drone ID: +
{detection.drone_id}
- - {detection.movement_analysis.rssiTrend && ( -
- Trend: - - {detection.movement_analysis.rssiTrend.trend} - {detection.movement_analysis.rssiTrend.change !== 0 && ( - - ({detection.movement_analysis.rssiTrend.change > 0 ? '+' : ''}{detection.movement_analysis.rssiTrend.change.toFixed(1)}dB) - - )} - +
+ Type: +
{droneTypes[detection.drone_type] || 'Unknown'}
+
+
+ +
+
+ RSSI: +
-50 ? 'text-red-600' : + detection.rssi > -70 ? 'text-orange-600' : + 'text-green-600' + }`}> + {detection.rssi}dBm
- )} - - {detection.movement_analysis.proximityLevel && ( -
- Proximity: - - {detection.movement_analysis.proximityLevel.replace('_', ' ')} - +
+
+ Frequency: +
{detection.freq}MHz
+
+
+
+ + {/* Detection Timeline */} +
+ Detection Timeline: +
+
+ First detected: + + {format(new Date(firstDetection.device_timestamp), 'MMM dd, HH:mm:ss')} + +
+
+ Latest detection: + + {format(new Date(detection.device_timestamp), 'MMM dd, HH:mm:ss')} + +
+ {droneHistory.length > 1 && ( +
+ Total detections: + {droneHistory.length}
)}
- )} - -
-
-
Detected by: Device {detection.device_id}
-
Location: {detection.geo_lat?.toFixed(4)}, {detection.geo_lon?.toFixed(4)}
-
Time: {format(new Date(detection.device_timestamp), 'MMM dd, HH:mm:ss')}
+ + {/* Movement Analysis */} + {movementTrend && ( +
+ Movement Analysis: +
+
+
+ {movementTrend.trend === 'APPROACHING' ? '⚠️ APPROACHING' : + movementTrend.trend === 'RETREATING' ? '✅ RETREATING' : + '➡️ STABLE POSITION'} +
+
+ RSSI change: {movementTrend.change > 0 ? '+' : ''}{movementTrend.change.toFixed(1)}dB + over {movementTrend.duration.toFixed(1)} minutes +
+
+ + {/* Signal Strength History Graph (simplified) */} +
+
Signal Strength Trend:
+
+ {droneHistory.slice(0, 8).reverse().map((hist, idx) => { + const height = Math.max(10, Math.min(32, (hist.rssi + 100) / 2)); // Scale -100 to 0 dBm to 10-32px + return ( +
-50 ? 'bg-red-400' : + hist.rssi > -70 ? 'bg-orange-400' : + 'bg-green-400' + }`} + style={{ height: `${height}px` }} + title={`${hist.rssi}dBm at ${format(new Date(hist.device_timestamp), 'HH:mm:ss')}`} + /> + ); + })} +
+
Last 8 detections (oldest to newest)
+
+
+
+ )} + + {/* Current Detection Details */} +
+ Current Detection: +
+
+ Confidence: +
{(detection.confidence_level * 100).toFixed(0)}%
+
+
+ Duration: +
{(detection.signal_duration / 1000).toFixed(1)}s
+
+
+ Detector: +
Device {detection.device_id}
+
+
+ Location: +
+ {detection.geo_lat?.toFixed(4)}, {detection.geo_lon?.toFixed(4)} +
+
+
+ + {/* Legacy movement analysis from detection */} + {detection.movement_analysis && ( +
+ Real-time Analysis: +
+
= 3 ? 'bg-red-100 text-red-800' : + detection.movement_analysis.alertLevel >= 2 ? 'bg-orange-100 text-orange-800' : + detection.movement_analysis.alertLevel >= 1 ? 'bg-blue-100 text-blue-800' : + 'bg-gray-100 text-gray-800' + }`}> + {detection.movement_analysis.description} +
+ + {detection.movement_analysis.rssiTrend && ( +
+ Instant trend: + + {detection.movement_analysis.rssiTrend.trend} + {detection.movement_analysis.rssiTrend.change !== 0 && ( + + ({detection.movement_analysis.rssiTrend.change > 0 ? '+' : ''}{detection.movement_analysis.rssiTrend.change.toFixed(1)}dB) + + )} + +
+ )} +
+
+ )}
-
-); + ); +}; const DeviceListItem = ({ device, status, detections, onClick }) => (