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: t('dashboard.online'), value: overview?.device_status?.online || 0, color: '#22c55e' },
{ name: t('dashboard.offline'), value: overview?.device_status?.offline || 0, color: '#ef4444' },
{ name: t('dashboard.inactive'), value: overview?.device_status?.inactive || 0, color: '#6b7280' }
];
return (
{/* Stats */}
{t('dashboard.title')}
{stats.map((item) => (
))}
{/* Charts */}
{/* Detection Timeline */}
{t('dashboard.detectionsTimeline24h')}
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 && (
{t('dashboard.deviceActivity24h')}
)}
{/* Recent Activity & Real-time Detections */}
{/* Recent Activity */}
{t('dashboard.recentActivity')}
{recentActivity.map((activity, index) => (
{activity.type === 'detection' ? (
<>{t('dashboard.droneDetected')} {activity.data.drone_id} {activity.data.device_name}>
) : (
<>{t('dashboard.heartbeatFrom')} {activity.data.device_name}>
)}
{format(new Date(activity.timestamp), 'MMM dd, HH:mm:ss')}
))}
{recentActivity.length === 0 && (
{t('dashboard.noRecentActivity')}
)}
{/* Real-time Detections */}
{t('dashboard.liveDetections')}
{connected ? t('dashboard.live') : t('dashboard.disconnected')}
{recentDetections.map((detection, index) => (
{t('dashboard.droneDetected')} {detection.drone_id}
{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 && (
{t('dashboard.noRecentDetections')}
)}
{/* Movement Alerts Panel */}
{/* Movement Summary Stats */}
{t('dashboard.movementTracking')}
{t('dashboard.criticalAlerts')}
{t('dashboard.veryCloseApproaches')}
{movementAlerts.filter(a => a.analysis.alertLevel >= 3).length}
{t('dashboard.highPriority')}
{t('dashboard.approachingDrones')}
{movementAlerts.filter(a => a.analysis.alertLevel === 2).length}
{t('dashboard.mediumPriority')}
{t('dashboard.movementChanges')}
{movementAlerts.filter(a => a.analysis.alertLevel === 1).length}
{t('dashboard.totalTracked')}:
{movementAlerts.length} {t('dashboard.events')}
{t('dashboard.lastAlert')}:
{movementAlerts.length > 0
? format(new Date(movementAlerts[0].timestamp), 'HH:mm:ss')
: t('dashboard.none')
}
);
};
export default Dashboard;