import React, { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import api from '../services/api'; import { format } from 'date-fns'; import { t } from '../utils/tempTranslations'; import { PlusIcon, PencilIcon, TrashIcon, ServerIcon, MapPinIcon, SignalIcon, BoltIcon } from '@heroicons/react/24/outline'; const Devices = () => { const navigate = useNavigate(); const [devices, setDevices] = useState([]); const [loading, setLoading] = useState(true); const [showAddModal, setShowAddModal] = useState(false); const [editingDevice, setEditingDevice] = useState(null); const [filter, setFilter] = useState('all'); // 'all', 'approved', 'pending' const [showDetailsModal, setShowDetailsModal] = useState(false); const [selectedDevice, setSelectedDevice] = useState(null); useEffect(() => { fetchDevices(); }, []); const fetchDevices = async () => { try { const response = await api.get('/devices?include_stats=true'); setDevices(response.data.data); } catch (error) { console.error('Error fetching devices:', error); } finally { setLoading(false); } }; const handleAddDevice = () => { setEditingDevice(null); setShowAddModal(true); }; const handleEditDevice = (device) => { setEditingDevice(device); setShowAddModal(true); }; const handleApproveDevice = async (deviceId) => { try { await api.post(`/devices/${deviceId}/approve`, { approved: true }); fetchDevices(); } catch (error) { console.error('Error approving device:', error); if (error.response?.status === 401 || error.response?.status === 403) { alert('Your session has expired. Please log in again.'); return; } alert('Error approving device: ' + (error.response?.data?.message || error.message)); } }; const handleRejectDevice = async (deviceId) => { if (window.confirm(t('devices.confirmReject'))) { try { await api.post(`/devices/${deviceId}/approve`, { approved: false }); fetchDevices(); } catch (error) { console.error('Error rejecting device:', error); if (error.response?.status === 401 || error.response?.status === 403) { alert('Your session has expired. Please log in again.'); return; } alert(t('devices.errorRejecting') + ' ' + (error.response?.data?.message || error.message)); } } }; const handleViewDetails = (device) => { setSelectedDevice(device); setShowDetailsModal(true); }; const handleViewOnMap = (device) => { if (device.geo_lat && device.geo_lon) { // Navigate to map with device information navigate('/map', { state: { focusDevice: { id: device.id, name: device.name || `Device ${device.id}`, lat: device.geo_lat, lon: device.geo_lon, status: device.stats?.status || 'unknown' } } }); } else { alert('Device location coordinates are not available'); } }; const handleDeleteDevice = async (deviceId) => { if (window.confirm(t('devices.confirmDelete'))) { try { await api.delete(`/devices/${deviceId}`); fetchDevices(); } catch (error) { console.error(t('devices.errorDeleting'), error); } } }; const getStatusColor = (status) => { switch (status) { case 'online': return 'bg-green-100 text-green-800'; case 'offline': return 'bg-red-100 text-red-800'; default: return 'bg-gray-100 text-gray-800'; } }; const getSignalStrength = (lastHeartbeat) => { if (!lastHeartbeat) return t('devices.unknown'); const timeSince = (new Date() - new Date(lastHeartbeat)) / 1000 / 60; // minutes if (timeSince < 5) return t('devices.signalStrong'); if (timeSince < 15) return t('devices.signalGood'); if (timeSince < 60) return t('devices.signalWeak'); return t('devices.signalLost'); }; const filteredDevices = devices.filter(device => { if (filter === 'approved') return device.is_approved; if (filter === 'pending') return !device.is_approved; return true; // 'all' }); const pendingCount = devices.filter(device => !device.is_approved).length; if (loading) { return (
{t('devices.description')} {pendingCount > 0 && ( {pendingCount} {t('devices.pendingApproval')} )}
{filter === 'pending' ? t('devices.noDevicesPending') : filter === 'approved' ? t('devices.noDevicesApproved') : t('devices.noDevicesFiltered') }
{t('devices.noDevicesDescription')}