Fix jwt-token

This commit is contained in:
2025-08-28 07:39:20 +02:00
parent 4d41ccbd96
commit 2328c6d1a0

View File

@@ -17,6 +17,8 @@ const Devices = () => {
const [showAddModal, setShowAddModal] = useState(false); const [showAddModal, setShowAddModal] = useState(false);
const [editingDevice, setEditingDevice] = useState(null); const [editingDevice, setEditingDevice] = useState(null);
const [filter, setFilter] = useState('all'); // 'all', 'approved', 'pending' const [filter, setFilter] = useState('all'); // 'all', 'approved', 'pending'
const [showDetailsModal, setShowDetailsModal] = useState(false);
const [selectedDevice, setSelectedDevice] = useState(null);
useEffect(() => { useEffect(() => {
fetchDevices(); fetchDevices();
@@ -63,6 +65,21 @@ const Devices = () => {
} }
}; };
const handleViewDetails = (device) => {
setSelectedDevice(device);
setShowDetailsModal(true);
};
const handleViewOnMap = (device) => {
if (device.geo_lat && device.geo_lon) {
// Open Google Maps with the device location
const url = `https://www.google.com/maps?q=${device.geo_lat},${device.geo_lon}&z=15`;
window.open(url, '_blank');
} else {
alert('Device location coordinates are not available');
}
};
const handleDeleteDevice = async (deviceId) => { const handleDeleteDevice = async (deviceId) => {
if (window.confirm('Are you sure you want to deactivate this device?')) { if (window.confirm('Are you sure you want to deactivate this device?')) {
try { try {
@@ -312,10 +329,16 @@ const Devices = () => {
</div> </div>
) : null} ) : null}
<div className="flex space-x-2"> <div className="flex space-x-2">
<button className="flex-1 text-xs bg-gray-100 text-gray-700 py-2 px-3 rounded hover:bg-gray-200 transition-colors"> <button
onClick={() => handleViewDetails(device)}
className="flex-1 text-xs bg-gray-100 text-gray-700 py-2 px-3 rounded hover:bg-gray-200 transition-colors"
>
View Details View Details
</button> </button>
<button className="flex-1 text-xs bg-primary-100 text-primary-700 py-2 px-3 rounded hover:bg-primary-200 transition-colors"> <button
onClick={() => handleViewOnMap(device)}
className="flex-1 text-xs bg-primary-100 text-primary-700 py-2 px-3 rounded hover:bg-primary-200 transition-colors"
>
View on Map View on Map
</button> </button>
</div> </div>
@@ -372,6 +395,133 @@ const Devices = () => {
}} }}
/> />
)} )}
{/* Device Details Modal */}
{showDetailsModal && selectedDevice && (
<div className="fixed inset-0 bg-gray-600 bg-opacity-50 overflow-y-auto h-full w-full z-50">
<div className="relative top-20 mx-auto p-5 border w-96 shadow-lg rounded-md bg-white">
<div className="mt-3">
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-medium text-gray-900">
Device Details
</h3>
<button
onClick={() => setShowDetailsModal(false)}
className="text-gray-400 hover:text-gray-600"
>
</button>
</div>
<div className="space-y-3 text-sm">
<div className="flex justify-between">
<span className="font-medium text-gray-700">Device ID:</span>
<span className="text-gray-900">{selectedDevice.id}</span>
</div>
<div className="flex justify-between">
<span className="font-medium text-gray-700">Name:</span>
<span className="text-gray-900">{selectedDevice.name || 'Unnamed'}</span>
</div>
<div className="flex justify-between">
<span className="font-medium text-gray-700">Status:</span>
<span className={`px-2 py-1 rounded-full text-xs font-medium ${
getStatusColor(selectedDevice.stats?.status)
}`}>
{selectedDevice.stats?.status || 'Unknown'}
</span>
</div>
<div className="flex justify-between">
<span className="font-medium text-gray-700">Approved:</span>
<span className={`px-2 py-1 rounded-full text-xs font-medium ${
selectedDevice.is_approved ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800'
}`}>
{selectedDevice.is_approved ? 'Yes' : 'Pending'}
</span>
</div>
{selectedDevice.location_description && (
<div className="flex justify-between">
<span className="font-medium text-gray-700">Location:</span>
<span className="text-gray-900 text-right">{selectedDevice.location_description}</span>
</div>
)}
{(selectedDevice.geo_lat && selectedDevice.geo_lon) && (
<div className="flex justify-between">
<span className="font-medium text-gray-700">Coordinates:</span>
<span className="text-gray-900">{selectedDevice.geo_lat}, {selectedDevice.geo_lon}</span>
</div>
)}
{selectedDevice.last_heartbeat && (
<div className="flex justify-between">
<span className="font-medium text-gray-700">Last Heartbeat:</span>
<span className="text-gray-900">{format(new Date(selectedDevice.last_heartbeat), 'MMM dd, yyyy HH:mm')}</span>
</div>
)}
{selectedDevice.firmware_version && (
<div className="flex justify-between">
<span className="font-medium text-gray-700">Firmware:</span>
<span className="text-gray-900">{selectedDevice.firmware_version}</span>
</div>
)}
{selectedDevice.stats && (
<div className="flex justify-between">
<span className="font-medium text-gray-700">Detections (24h):</span>
<span className={`font-medium ${
selectedDevice.stats.detections_24h > 0 ? 'text-red-600' : 'text-green-600'
}`}>
{selectedDevice.stats.detections_24h}
</span>
</div>
)}
{selectedDevice.created_at && (
<div className="flex justify-between">
<span className="font-medium text-gray-700">Created:</span>
<span className="text-gray-900">{format(new Date(selectedDevice.created_at), 'MMM dd, yyyy HH:mm')}</span>
</div>
)}
</div>
<div className="flex space-x-2 mt-6">
{!selectedDevice.is_approved && (
<button
onClick={() => {
handleApproveDevice(selectedDevice.id);
setShowDetailsModal(false);
}}
className="flex-1 bg-green-100 text-green-700 py-2 px-3 rounded hover:bg-green-200 transition-colors text-sm font-medium"
>
Approve
</button>
)}
{(selectedDevice.geo_lat && selectedDevice.geo_lon) && (
<button
onClick={() => handleViewOnMap(selectedDevice)}
className="flex-1 bg-primary-100 text-primary-700 py-2 px-3 rounded hover:bg-primary-200 transition-colors text-sm font-medium"
>
View on Map
</button>
)}
<button
onClick={() => setShowDetailsModal(false)}
className="flex-1 bg-gray-100 text-gray-700 py-2 px-3 rounded hover:bg-gray-200 transition-colors text-sm font-medium"
>
Close
</button>
</div>
</div>
</div>
</div>
)}
</div> </div>
); );
}; };