From f002130c1e8406bcf2f2fd549fb5f0c7d8427ba8 Mon Sep 17 00:00:00 2001 From: Alexander Borg Date: Mon, 18 Aug 2025 06:44:16 +0200 Subject: [PATCH] Fix jwt-token --- client/src/App.jsx | 20 ++- client/src/components/AlertModals.jsx | 44 ++++++ client/src/contexts/SocketContext.jsx | 140 +++++++++++++++++--- client/src/index.css | 44 ++++++ client/src/pages/Alerts.jsx | 76 ++++++++++- client/src/pages/Dashboard.jsx | 30 ++++- test_orlan_scenario.py | 184 ++++++++++++++++++++++++++ 7 files changed, 505 insertions(+), 33 deletions(-) create mode 100644 test_orlan_scenario.py diff --git a/client/src/App.jsx b/client/src/App.jsx index 8ba9f40..8fc7a4e 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -19,28 +19,40 @@ function App() {
diff --git a/client/src/components/AlertModals.jsx b/client/src/components/AlertModals.jsx index 8968dfe..e15b519 100644 --- a/client/src/components/AlertModals.jsx +++ b/client/src/components/AlertModals.jsx @@ -14,6 +14,8 @@ export const EditAlertModal = ({ rule, onClose, onSuccess }) => { cooldown_period: 600, alert_channels: ['sms'], min_threat_level: '', + drone_types: [], + device_ids: [], sms_phone_number: '', webhook_url: '' }); @@ -30,6 +32,8 @@ export const EditAlertModal = ({ rule, onClose, onSuccess }) => { cooldown_period: rule.cooldown_period || 600, alert_channels: rule.alert_channels || ['sms'], min_threat_level: rule.min_threat_level || '', + drone_types: rule.drone_types || [], + device_ids: rule.device_ids || [], sms_phone_number: rule.sms_phone_number || '', webhook_url: rule.webhook_url || '' }); @@ -53,6 +57,15 @@ export const EditAlertModal = ({ rule, onClose, onSuccess }) => { })); }; + const handleDroneTypeChange = (droneType, checked) => { + setFormData(prev => ({ + ...prev, + drone_types: checked + ? [...prev.drone_types, droneType] + : prev.drone_types.filter(type => type !== droneType) + })); + }; + const handleSubmit = async (e) => { e.preventDefault(); setSaving(true); @@ -148,6 +161,37 @@ export const EditAlertModal = ({ rule, onClose, onSuccess }) => {
+
+ +
+
+ Leave empty to monitor all drone types +
+ {[ + { id: 0, name: 'Consumer/Hobby' }, + { id: 1, name: 'Orlan/Military' }, + { id: 2, name: 'Professional/Commercial' }, + { id: 3, name: 'Racing/High-speed' }, + { id: 4, name: 'Unknown/Custom' } + ].map(droneType => ( + + ))} +
+
+
@@ -427,8 +459,8 @@ const CreateAlertRuleModal = ({ onClose, onSave }) => { min_detections: 1, time_window: 300, cooldown_period: 600, - device_ids: null, - drone_types: null, + device_ids: [], + drone_types: [], min_rssi: '', max_rssi: '', frequency_ranges: [] @@ -475,6 +507,15 @@ const CreateAlertRuleModal = ({ onClose, onSave }) => { })); }; + const handleDroneTypeChange = (droneType, checked) => { + setFormData(prev => ({ + ...prev, + drone_types: checked + ? [...prev.drone_types, droneType] + : prev.drone_types.filter(type => type !== droneType) + })); + }; + return (
@@ -600,6 +641,37 @@ const CreateAlertRuleModal = ({ onClose, onSave }) => { ))}
+ +
+ +
+
+ Leave empty to monitor all drone types +
+ {[ + { id: 0, name: 'Consumer/Hobby' }, + { id: 1, name: 'Orlan/Military' }, + { id: 2, name: 'Professional/Commercial' }, + { id: 3, name: 'Racing/High-speed' }, + { id: 4, name: 'Unknown/Custom' } + ].map(droneType => ( + + ))} +
+
diff --git a/client/src/pages/Dashboard.jsx b/client/src/pages/Dashboard.jsx index 6c158d1..f92a934 100644 --- a/client/src/pages/Dashboard.jsx +++ b/client/src/pages/Dashboard.jsx @@ -32,7 +32,7 @@ const Dashboard = () => { const [recentActivity, setRecentActivity] = useState([]); const [loading, setLoading] = useState(true); const [showMovementAlerts, setShowMovementAlerts] = useState(true); - const { recentDetections, deviceStatus, connected, movementAlerts } = useSocket(); + const { recentDetections, deviceStatus, connected, movementAlerts, notificationsEnabled, toggleNotifications } = useSocket(); useEffect(() => { fetchDashboardData(); @@ -116,12 +116,28 @@ const Dashboard = () => { return (
{/* Stats */} -
-

- System Overview -

-
- {stats.map((item) => ( +
+
+

+ System Overview +

+
+
+ +
+
+
+ {stats.map((item) => (
10: + delay = 3.0 # 3 seconds for long-range + elif distance_km > 5: + delay = 2.0 # 2 seconds for medium-range + elif distance_km > 1: + delay = 1.5 # 1.5 seconds for close-range + else: + delay = 1.0 # 1 second for critical proximity + + time.sleep(delay) + + print() + print("=" * 60) + print("🚨 ORLAN APPROACH SIMULATION COMPLETED") + print("=" * 60) + print("Summary:") + print(f"- Total detections sent: {total_steps}") + print(f"- Distance covered: {start_distance - final_distance:.1f}km") + print(f"- Target facility: {target_device['name']}") + print("- All alerts should have triggered critical notifications") + print("- Check the dashboard for real-time tracking") + print("=" * 60) + +if __name__ == "__main__": + try: + run_orlan_approach_scenario() + except KeyboardInterrupt: + print("\n\nāš ļø Simulation interrupted by user") + except Exception as e: + print(f"\nāŒ Error during simulation: {e}")