Fix jwt-token
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useSocket } from '../contexts/SocketContext';
|
||||
import MovementAlertsPanel from '../components/MovementAlertsPanel';
|
||||
import api from '../services/api';
|
||||
import {
|
||||
ServerIcon,
|
||||
@@ -30,7 +31,8 @@ const Dashboard = () => {
|
||||
const [deviceActivity, setDeviceActivity] = useState([]);
|
||||
const [recentActivity, setRecentActivity] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const { recentDetections, deviceStatus, connected } = useSocket();
|
||||
const [showMovementAlerts, setShowMovementAlerts] = useState(true);
|
||||
const { recentDetections, deviceStatus, connected, movementAlerts } = useSocket();
|
||||
|
||||
useEffect(() => {
|
||||
fetchDashboardData();
|
||||
@@ -318,6 +320,70 @@ const Dashboard = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Movement Alerts Panel */}
|
||||
<div className="grid grid-cols-1 xl:grid-cols-3 gap-6">
|
||||
<div className="xl:col-span-2">
|
||||
<MovementAlertsPanel />
|
||||
</div>
|
||||
|
||||
{/* Movement Summary Stats */}
|
||||
<div className="bg-white rounded-lg shadow p-6">
|
||||
<h3 className="text-lg font-medium text-gray-900 mb-4">
|
||||
Movement Tracking
|
||||
</h3>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between p-3 bg-red-50 rounded-lg">
|
||||
<div>
|
||||
<div className="font-medium text-red-900">Critical Alerts</div>
|
||||
<div className="text-sm text-red-700">Very close approaches</div>
|
||||
</div>
|
||||
<div className="text-2xl font-bold text-red-600">
|
||||
{movementAlerts.filter(a => a.analysis.alertLevel >= 3).length}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-3 bg-orange-50 rounded-lg">
|
||||
<div>
|
||||
<div className="font-medium text-orange-900">High Priority</div>
|
||||
<div className="text-sm text-orange-700">Approaching drones</div>
|
||||
</div>
|
||||
<div className="text-2xl font-bold text-orange-600">
|
||||
{movementAlerts.filter(a => a.analysis.alertLevel === 2).length}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between p-3 bg-blue-50 rounded-lg">
|
||||
<div>
|
||||
<div className="font-medium text-blue-900">Medium Priority</div>
|
||||
<div className="text-sm text-blue-700">Movement changes</div>
|
||||
</div>
|
||||
<div className="text-2xl font-bold text-blue-600">
|
||||
{movementAlerts.filter(a => a.analysis.alertLevel === 1).length}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pt-4 border-t border-gray-200">
|
||||
<div className="text-sm text-gray-600">
|
||||
<div className="flex justify-between">
|
||||
<span>Total Tracked:</span>
|
||||
<span className="font-medium">{movementAlerts.length} events</span>
|
||||
</div>
|
||||
<div className="flex justify-between mt-1">
|
||||
<span>Last Alert:</span>
|
||||
<span className="font-medium">
|
||||
{movementAlerts.length > 0
|
||||
? format(new Date(movementAlerts[0].timestamp), 'HH:mm:ss')
|
||||
: 'None'
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -468,6 +468,55 @@ const DroneDetectionPopup = ({ detection, age, droneTypes }) => (
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Movement Analysis */}
|
||||
{detection.movement_analysis && (
|
||||
<div className="pt-2 border-t border-gray-200">
|
||||
<span className="font-medium text-gray-700 block mb-1">Movement Analysis:</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' :
|
||||
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}
|
||||
</div>
|
||||
|
||||
{detection.movement_analysis.rssiTrend && (
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<span className="text-gray-600">Trend:</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.change !== 0 && (
|
||||
<span className="ml-1">
|
||||
({detection.movement_analysis.rssiTrend.change > 0 ? '+' : ''}{detection.movement_analysis.rssiTrend.change.toFixed(1)}dB)
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{detection.movement_analysis.proximityLevel && (
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="text-gray-600">Proximity:</span>
|
||||
<span className={`px-1 py-0.5 rounded text-xs font-medium ${
|
||||
detection.movement_analysis.proximityLevel === 'VERY_CLOSE' ? 'bg-red-100 text-red-700' :
|
||||
detection.movement_analysis.proximityLevel === 'CLOSE' ? 'bg-orange-100 text-orange-700' :
|
||||
detection.movement_analysis.proximityLevel === 'MEDIUM' ? 'bg-yellow-100 text-yellow-700' :
|
||||
'bg-green-100 text-green-700'
|
||||
}`}>
|
||||
{detection.movement_analysis.proximityLevel.replace('_', ' ')}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="pt-2 border-t border-gray-200">
|
||||
<div className="text-xs text-gray-500">
|
||||
<div>Detected by: Device {detection.device_id}</div>
|
||||
|
||||
Reference in New Issue
Block a user