Fix jwt-token
This commit is contained in:
@@ -148,7 +148,7 @@ const MapView = () => {
|
||||
10: "DJI Mavic",
|
||||
11: "DJI Phantom",
|
||||
20: "DJI Mini",
|
||||
99: "Unknown"
|
||||
99: t('map.unknown')
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -788,14 +788,14 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<h4 className="font-semibold text-red-700 flex items-center space-x-1">
|
||||
<span>🚨</span>
|
||||
<span>Drone Detection Details</span>
|
||||
<span>{t('map.droneDetectionDetails')}</span>
|
||||
</h4>
|
||||
<span className={`px-2 py-1 rounded-full text-xs font-medium ${
|
||||
age < 1 ? 'bg-red-100 text-red-800' :
|
||||
age < 3 ? 'bg-orange-100 text-orange-800' :
|
||||
'bg-gray-100 text-gray-800'
|
||||
}`}>
|
||||
{age < 1 ? 'LIVE' : `${Math.round(age)}m ago`}
|
||||
{ age < 1 ? t('map.live') : `${Math.round(age)}m ago`}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -804,11 +804,11 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
<div className="bg-gray-50 rounded-lg p-2">
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<div>
|
||||
<span className="font-medium text-gray-700">Drone ID:</span>
|
||||
<span className="font-medium text-gray-700">{t('map.droneId')}:</span>
|
||||
<div className="text-gray-900 font-mono">{detection.drone_id}</div>
|
||||
</div>
|
||||
<div>
|
||||
<span className="font-medium text-gray-700">Type:</span>
|
||||
<span className="font-medium text-gray-700">{t('map.type')}:</span>
|
||||
<div className="text-gray-900">
|
||||
{droneTypes[detection.drone_type] || `Type ${detection.drone_type}`}
|
||||
</div>
|
||||
@@ -822,7 +822,7 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
|
||||
<div className="grid grid-cols-2 gap-2 mt-2">
|
||||
<div>
|
||||
<span className="font-medium text-gray-700">RSSI:</span>
|
||||
<span className="font-medium text-gray-700">{t('map.rssi')}:</span>
|
||||
<div className={`font-mono ${
|
||||
detection.rssi > -50 ? 'text-red-600' :
|
||||
detection.rssi > -70 ? 'text-orange-600' :
|
||||
@@ -832,7 +832,7 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span className="font-medium text-gray-700">Frequency:</span>
|
||||
<span className="font-medium text-gray-700">{t('map.frequency')}:</span>
|
||||
<div className="text-gray-900">{detection.freq}MHz</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -840,10 +840,10 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
|
||||
{/* Detection Timeline */}
|
||||
<div className="border-t border-gray-200 pt-2">
|
||||
<span className="font-medium text-gray-700 block mb-2">Detection Timeline:</span>
|
||||
<span className="font-medium text-gray-700 block mb-2">{t('map.detectionTimeline')}:</span>
|
||||
<div className="text-xs space-y-1">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">First detected:</span>
|
||||
<span className="text-gray-600">{t('map.firstDetected')}:</span>
|
||||
<span className="font-mono text-gray-900">
|
||||
{(() => {
|
||||
const timestamp = firstDetection.device_timestamp || firstDetection.timestamp || firstDetection.server_timestamp;
|
||||
@@ -854,12 +854,12 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
} catch (e) {
|
||||
console.warn('Invalid firstDetection timestamp:', timestamp, e);
|
||||
}
|
||||
return 'Unknown';
|
||||
return t('map.unknown');
|
||||
})()}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">Latest detection:</span>
|
||||
<span className="text-gray-600">{t('map.latestDetection')}:</span>
|
||||
<span className="font-mono text-gray-900">
|
||||
{(() => {
|
||||
const timestamp = detection.device_timestamp || detection.timestamp || detection.server_timestamp;
|
||||
@@ -870,13 +870,13 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
} catch (e) {
|
||||
console.warn('Invalid detection timestamp:', timestamp, e);
|
||||
}
|
||||
return 'Unknown';
|
||||
return t('map.unknown');
|
||||
})()}
|
||||
</span>
|
||||
</div>
|
||||
{droneHistory.length > 1 && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-gray-600">Total detections:</span>
|
||||
<span className="text-gray-600">{t('map.totalDetections')}:</span>
|
||||
<span className="font-medium text-gray-900">{droneHistory.length}</span>
|
||||
</div>
|
||||
)}
|
||||
@@ -886,7 +886,7 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
{/* Movement Analysis */}
|
||||
{movementTrend && (
|
||||
<div className="border-t border-gray-200 pt-2">
|
||||
<span className="font-medium text-gray-700 block mb-2">Movement Analysis:</span>
|
||||
<span className="font-medium text-gray-700 block mb-2">{t('map.movementAnalysis')}:</span>
|
||||
<div className="text-xs space-y-2">
|
||||
<div className={`px-2 py-1 rounded ${
|
||||
movementTrend.trend === 'APPROACHING' ? 'bg-red-100 text-red-800' :
|
||||
@@ -894,19 +894,19 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
'bg-yellow-100 text-yellow-800'
|
||||
}`}>
|
||||
<div className="font-medium">
|
||||
{movementTrend.trend === 'APPROACHING' ? '⚠️ APPROACHING' :
|
||||
movementTrend.trend === 'RETREATING' ? '✅ RETREATING' :
|
||||
'➡️ STABLE POSITION'}
|
||||
{movementTrend.trend === 'APPROACHING' ? `⚠️ ${t('map.approaching')}` :
|
||||
movementTrend.trend === 'RETREATING' ? `✅ ${t('map.retreating')}` :
|
||||
`➡️ ${t('map.stablePosition')}`}
|
||||
</div>
|
||||
<div className="mt-1">
|
||||
RSSI change: {movementTrend.change > 0 ? '+' : ''}{typeof movementTrend.change === 'number' ? movementTrend.change.toFixed(1) : 'N/A'}dB
|
||||
over {typeof movementTrend.duration === 'number' ? movementTrend.duration.toFixed(1) : 'N/A'} minutes
|
||||
{t('map.rssiChange')}: {movementTrend.change > 0 ? '+' : ''}{typeof movementTrend.change === 'number' ? movementTrend.change.toFixed(1) : 'N/A'}dB
|
||||
{t('map.over')} {typeof movementTrend.duration === 'number' ? movementTrend.duration.toFixed(1) : 'N/A'} {t('map.minutes')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Signal Strength History Graph (simplified) */}
|
||||
<div className="bg-gray-50 rounded p-2">
|
||||
<div className="text-gray-600 mb-1">Signal Strength Trend:</div>
|
||||
<div className="text-gray-600 mb-1">{t('map.signalStrengthTrend')}:</div>
|
||||
<div className="flex items-end space-x-1 h-8">
|
||||
{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
|
||||
@@ -934,7 +934,7 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div className="text-xs text-gray-500 mt-1">Last 8 detections (oldest to newest)</div>
|
||||
<div className="text-xs text-gray-500 mt-1">{t('map.lastDetections')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -942,26 +942,26 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
|
||||
{/* Current Detection Details */}
|
||||
<div className="border-t border-gray-200 pt-2">
|
||||
<span className="font-medium text-gray-700 block mb-2">Current Detection:</span>
|
||||
<span className="font-medium text-gray-700 block mb-2">{t('map.currentDetection')}:</span>
|
||||
<div className="grid grid-cols-2 gap-2 text-xs">
|
||||
<div>
|
||||
<span className="text-gray-600">Confidence:</span>
|
||||
<span className="text-gray-600">{t('map.confidence')}:</span>
|
||||
<div className="text-gray-900">
|
||||
{typeof detection.confidence_level === 'number' ? (detection.confidence_level * 100).toFixed(0) : 'N/A'}%
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-gray-600">Duration:</span>
|
||||
<span className="text-gray-600">{t('map.duration')}:</span>
|
||||
<div className="text-gray-900">
|
||||
{typeof detection.signal_duration === 'number' ? (detection.signal_duration / 1000).toFixed(1) : 'N/A'}s
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-gray-600">Detector:</span>
|
||||
<div className="text-gray-900">Device {detection.device_id}</div>
|
||||
<span className="text-gray-600">{t('map.detector')}:</span>
|
||||
<div className="text-gray-900">{t('map.deviceName')} {detection.device_id}</div>
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-gray-600">Location:</span>
|
||||
<span className="text-gray-600">{t('map.location')}:</span>
|
||||
<div className="text-gray-900 font-mono">
|
||||
{typeof detection.geo_lat === 'number' ? detection.geo_lat.toFixed(4) : 'N/A'}, {typeof detection.geo_lon === 'number' ? detection.geo_lon.toFixed(4) : 'N/A'}
|
||||
</div>
|
||||
@@ -972,7 +972,7 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
{/* Legacy movement analysis from detection */}
|
||||
{detection.movement_analysis && (
|
||||
<div className="border-t border-gray-200 pt-2">
|
||||
<span className="font-medium text-gray-700 block mb-1">Real-time Analysis:</span>
|
||||
<span className="font-medium text-gray-700 block mb-1">{t('map.realTimeAnalysis')}:</span>
|
||||
<div className="text-xs space-y-1">
|
||||
<div className={`px-2 py-1 rounded ${
|
||||
detection.movement_analysis.alertLevel >= 3 ? 'bg-red-100 text-red-800' :
|
||||
@@ -985,13 +985,15 @@ const DroneDetectionPopup = ({ detection, age, droneTypes, droneDetectionHistory
|
||||
|
||||
{detection.movement_analysis.rssiTrend && (
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<span className="text-gray-600">Instant trend:</span>
|
||||
<span className="text-gray-600">{t('map.instantTrend')}:</span>
|
||||
<span className={`font-medium ${
|
||||
detection.movement_analysis.rssiTrend.trend === 'STRENGTHENING' ? 'text-red-600' :
|
||||
detection.movement_analysis.rssiTrend.trend === 'WEAKENING' ? 'text-green-600' :
|
||||
'text-gray-600'
|
||||
}`}>
|
||||
{detection.movement_analysis.rssiTrend.trend}
|
||||
{detection.movement_analysis.rssiTrend.trend === 'STRENGTHENING' ? t('map.strengthening') :
|
||||
detection.movement_analysis.rssiTrend.trend === 'WEAKENING' ? t('map.weakening') :
|
||||
detection.movement_analysis.rssiTrend.trend}
|
||||
{detection.movement_analysis.rssiTrend.change !== 0 && (
|
||||
<span className="ml-1">
|
||||
({detection.movement_analysis.rssiTrend.change > 0 ? '+' : ''}{typeof detection.movement_analysis.rssiTrend.change === 'number' ? detection.movement_analysis.rssiTrend.change.toFixed(1) : 'N/A'}dB)
|
||||
|
||||
Reference in New Issue
Block a user