import React, { useState, useEffect } from 'react';
import { useSocket } from '../contexts/SocketContext';
import MovementAlertsPanel from '../components/MovementAlertsPanel';
import api from '../services/api';
import { t } from '../utils/tempTranslations'; // Temporary translation system
import {
ServerIcon,
ExclamationTriangleIcon,
BellIcon,
SignalIcon,
EyeIcon
} from '@heroicons/react/24/outline';
import {
AreaChart,
Area,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
BarChart,
Bar,
PieChart,
Pie,
Cell
} from 'recharts';
import { format } from 'date-fns';
const Dashboard = () => {
const [overview, setOverview] = useState(null);
const [chartData, setChartData] = useState([]);
const [deviceActivity, setDeviceActivity] = useState([]);
const [recentActivity, setRecentActivity] = useState([]);
const [loading, setLoading] = useState(true);
const [showMovementAlerts, setShowMovementAlerts] = useState(true);
const { recentDetections, deviceStatus, connected, movementAlerts, notificationsEnabled, toggleNotifications } = useSocket();
useEffect(() => {
fetchDashboardData();
const interval = setInterval(fetchDashboardData, 30000); // Refresh every 30 seconds
return () => clearInterval(interval);
}, []);
const fetchDashboardData = async () => {
try {
const [overviewRes, chartRes, deviceRes, activityRes] = await Promise.all([
api.get('/dashboard/overview?hours=24'),
api.get('/dashboard/charts/detections?hours=24&interval=hour'),
api.get('/dashboard/charts/devices?hours=24'),
api.get('/dashboard/activity?hours=24&limit=10')
]);
setOverview(overviewRes.data.data);
setChartData(chartRes.data.data);
setDeviceActivity(deviceRes.data.data);
setRecentActivity(activityRes.data.data);
} catch (error) {
console.error('Error fetching dashboard data:', error);
} finally {
setLoading(false);
}
};
if (loading) {
return (
);
}
const stats = [
{
id: 1,
name: t('dashboard.totalDetections'),
stat: overview?.summary?.total_devices || 0,
icon: ServerIcon,
change: null,
changeType: 'neutral',
color: 'bg-blue-500'
},
{
id: 2,
name: t('dashboard.connectedDevices'),
stat: overview?.summary?.online_devices || 0,
icon: SignalIcon,
change: null,
changeType: 'positive',
color: 'bg-green-500'
},
{
id: 3,
name: t('dashboard.recentDetections'),
stat: overview?.summary?.recent_detections || 0,
icon: ExclamationTriangleIcon,
change: null,
changeType: 'negative',
color: 'bg-red-500'
},
{
id: 4,
name: t('dashboard.activeAlerts'),
stat: overview?.summary?.unique_drones_detected || 0,
icon: EyeIcon,
change: null,
changeType: 'neutral',
color: 'bg-purple-500'
}
];
const deviceStatusData = [
{ name: 'Online', value: overview?.device_status?.online || 0, color: '#22c55e' },
{ name: 'Offline', value: overview?.device_status?.offline || 0, color: '#ef4444' },
{ name: 'Inactive', value: overview?.device_status?.inactive || 0, color: '#6b7280' }
];
return (
{/* Stats */}
{t('dashboard.title')}
{stats.map((item) => (
))}
{/* Charts */}
{/* Detection Timeline */}
Detections Timeline (24h)
format(new Date(value), 'HH:mm')}
/>
format(new Date(value), 'MMM dd, HH:mm')}
/>
{/* Device Status */}
Device Status
{deviceStatusData.map((entry, index) => (
|
))}
{deviceStatusData.map((item, index) => (
{item.name}: {item.value}
))}
{/* Device Activity */}
{deviceActivity.length > 0 && (
)}
{/* Recent Activity & Real-time Detections */}
{/* Recent Activity */}
Recent Activity
{recentActivity.map((activity, index) => (
{activity.type === 'detection' ? (
<>Drone {activity.data.drone_id} detected by {activity.data.device_name}>
) : (
<>Heartbeat from {activity.data.device_name}>
)}
{format(new Date(activity.timestamp), 'MMM dd, HH:mm:ss')}
))}
{recentActivity.length === 0 && (
No recent activity
)}
{/* Real-time Detections */}
Live Detections
{connected ? 'Live' : 'Disconnected'}
{recentDetections.map((detection, index) => (
Drone {detection.drone_id} detected
{detection.device.name || `Device ${detection.device_id}`} •
RSSI: {detection.rssi}dBm •
Freq: {detection.freq}MHz
{format(new Date(detection.server_timestamp), 'HH:mm:ss')}
))}
{recentDetections.length === 0 && (
No recent detections
)}
{/* Movement Alerts Panel */}
{/* Movement Summary Stats */}
Movement Tracking
Critical Alerts
Very close approaches
{movementAlerts.filter(a => a.analysis.alertLevel >= 3).length}
High Priority
Approaching drones
{movementAlerts.filter(a => a.analysis.alertLevel === 2).length}
Medium Priority
Movement changes
{movementAlerts.filter(a => a.analysis.alertLevel === 1).length}
Total Tracked:
{movementAlerts.length} events
Last Alert:
{movementAlerts.length > 0
? format(new Date(movementAlerts[0].timestamp), 'HH:mm:ss')
: 'None'
}
);
};
export default Dashboard;