Fix jwt-token

This commit is contained in:
2025-09-19 14:26:27 +02:00
parent 52cc013016
commit 395a5b8842
2 changed files with 108 additions and 44 deletions

View File

@@ -63,7 +63,7 @@ const Devices = () => {
};
const handleRejectDevice = async (deviceId) => {
if (window.confirm('Are you sure you want to reject this device?')) {
if (window.confirm(t('devices.confirmReject'))) {
try {
await api.post(`/devices/${deviceId}/approve`, { approved: false });
fetchDevices();
@@ -73,7 +73,7 @@ const Devices = () => {
alert('Your session has expired. Please log in again.');
return;
}
alert('Error rejecting device: ' + (error.response?.data?.message || error.message));
alert(t('devices.errorRejecting') + ' ' + (error.response?.data?.message || error.message));
}
}
};
@@ -103,12 +103,12 @@ const Devices = () => {
};
const handleDeleteDevice = async (deviceId) => {
if (window.confirm('Are you sure you want to deactivate this device?')) {
if (window.confirm(t('devices.confirmDelete'))) {
try {
await api.delete(`/devices/${deviceId}`);
fetchDevices();
} catch (error) {
console.error('Error deleting device:', error);
console.error(t('devices.errorDeleting'), error);
}
}
};
@@ -125,13 +125,13 @@ const Devices = () => {
};
const getSignalStrength = (lastHeartbeat) => {
if (!lastHeartbeat) return 'Unknown';
if (!lastHeartbeat) return t('devices.unknown');
const timeSince = (new Date() - new Date(lastHeartbeat)) / 1000 / 60; // minutes
if (timeSince < 5) return 'Strong';
if (timeSince < 15) return 'Good';
if (timeSince < 60) return 'Weak';
return 'Lost';
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 => {
@@ -162,7 +162,7 @@ const Devices = () => {
{t('devices.description')}
{pendingCount > 0 && (
<span className="ml-2 px-2 py-1 text-xs font-medium bg-yellow-200 text-yellow-800 rounded-full">
{pendingCount} pending approval
{pendingCount} {t('devices.pendingApproval')}
</span>
)}
</p>
@@ -187,7 +187,7 @@ const Devices = () => {
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
}`}
>
All Devices ({devices.length})
{t('devices.allDevices')} ({devices.length})
</button>
<button
onClick={() => setFilter('approved')}
@@ -197,7 +197,7 @@ const Devices = () => {
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
}`}
>
Approved ({devices.filter(d => d.is_approved).length})
{t('devices.approved')} ({devices.filter(d => d.is_approved).length})
</button>
<button
onClick={() => setFilter('pending')}
@@ -207,7 +207,7 @@ const Devices = () => {
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
}`}
>
Pending Approval ({pendingCount})
{t('devices.pendingApprovalTab')} ({pendingCount})
{pendingCount > 0 && (
<span className="absolute -top-1 -right-1 h-2 w-2 bg-yellow-400 rounded-full"></span>
)}
@@ -228,11 +228,11 @@ const Devices = () => {
device.stats?.status === 'online' ? 'bg-green-400' : 'bg-red-400'
}`} />
<h4 className="text-lg font-medium text-gray-900">
{device.name || `Device ${device.id}`}
{device.name || `${t('devices.device')} ${device.id}`}
</h4>
{!device.is_approved && (
<span className="px-2 py-1 text-xs font-medium bg-yellow-200 text-yellow-800 rounded-full">
Needs Approval
{t('devices.needsApproval')}
</span>
)}
</div>
@@ -254,25 +254,25 @@ const Devices = () => {
<div className="space-y-3">
<div className="flex items-center justify-between">
<span className="text-sm text-gray-500">Status</span>
<span className="text-sm text-gray-500">{t('devices.status')}</span>
<span className={`px-2 py-1 rounded-full text-xs font-medium ${
getStatusColor(device.stats?.status)
}`}>
{device.stats?.status || 'Unknown'}
{device.stats?.status ? t(`devices.${device.stats.status}`) : t('devices.unknown')}
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-sm text-gray-500">Approval</span>
<span className="text-sm text-gray-500">{t('devices.approval')}</span>
<span className={`px-2 py-1 rounded-full text-xs font-medium ${
device.is_approved ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800'
}`}>
{device.is_approved ? 'Approved' : 'Pending'}
{device.is_approved ? t('devices.approved') : t('devices.pending')}
</span>
</div>
<div className="flex items-center justify-between">
<span className="text-sm text-gray-500">Device ID</span>
<span className="text-sm text-gray-500">{t('devices.deviceId')}</span>
<span className="text-sm font-medium text-gray-900">
{device.id}
</span>
@@ -280,7 +280,7 @@ const Devices = () => {
{device.location_description && (
<div className="flex items-start justify-between">
<span className="text-sm text-gray-500">Location</span>
<span className="text-sm text-gray-500">{t('devices.location')}</span>
<span className="text-sm text-gray-900 text-right">
{device.location_description}
</span>
@@ -289,7 +289,7 @@ const Devices = () => {
{(device.geo_lat && device.geo_lon) && (
<div className="flex items-center justify-between">
<span className="text-sm text-gray-500">Coordinates</span>
<span className="text-sm text-gray-500">{t('devices.coordinates')}</span>
<span className="text-sm text-gray-900">
{device.geo_lat}, {device.geo_lon}
</span>
@@ -297,7 +297,7 @@ const Devices = () => {
)}
<div className="flex items-center justify-between">
<span className="text-sm text-gray-500">Signal</span>
<span className="text-sm text-gray-500">{t('devices.signal')}</span>
<span className="text-sm text-gray-900">
{getSignalStrength(device.last_heartbeat)}
</span>
@@ -305,7 +305,7 @@ const Devices = () => {
{device.stats && (
<div className="flex items-center justify-between">
<span className="text-sm text-gray-500">Detections (24h)</span>
<span className="text-sm text-gray-500">{t('devices.detections24h')}</span>
<span className={`text-sm font-medium ${
device.stats.detections_24h > 0 ? 'text-red-600' : 'text-green-600'
}`}>
@@ -316,7 +316,7 @@ const Devices = () => {
{device.last_heartbeat && (
<div className="flex items-center justify-between">
<span className="text-sm text-gray-500">Last Seen</span>
<span className="text-sm text-gray-500">{t('devices.lastSeen')}</span>
<span className="text-sm text-gray-900">
{format(new Date(device.last_heartbeat), 'MMM dd, HH:mm')}
</span>
@@ -325,7 +325,7 @@ const Devices = () => {
{device.firmware_version && (
<div className="flex items-center justify-between">
<span className="text-sm text-gray-500">Firmware</span>
<span className="text-sm text-gray-500">{t('devices.firmware')}</span>
<span className="text-sm text-gray-900">
{device.firmware_version}
</span>
@@ -341,13 +341,13 @@ const Devices = () => {
onClick={() => handleApproveDevice(device.id)}
className="flex-1 text-xs bg-green-100 text-green-700 py-2 px-3 rounded hover:bg-green-200 transition-colors font-medium"
>
Approve Device
{t('devices.approveDevice')}
</button>
<button
onClick={() => handleRejectDevice(device.id)}
className="flex-1 text-xs bg-red-100 text-red-700 py-2 px-3 rounded hover:bg-red-200 transition-colors font-medium"
>
Reject
{t('devices.reject')}
</button>
</div>
) : null}
@@ -356,13 +356,13 @@ const Devices = () => {
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
{t('devices.viewDetails')}
</button>
<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
{t('devices.viewOnMap')}
</button>
</div>
</div>
@@ -375,14 +375,14 @@ const Devices = () => {
<div className="text-center py-12">
<ServerIcon className="mx-auto h-12 w-12 text-gray-400" />
<h3 className="mt-2 text-sm font-medium text-gray-900">
No {filter === 'all' ? '' : filter} devices
{filter === 'all' ? t('devices.noDevices') : `${t('devices.noDevicesFiltered').replace('the current filter', filter)}`}
</h3>
<p className="mt-1 text-sm text-gray-500">
{filter === 'pending'
? 'No devices are currently pending approval.'
? t('devices.noDevicesPending')
: filter === 'approved'
? 'No devices have been approved yet.'
: 'No devices match the current filter.'
? t('devices.noDevicesApproved')
: t('devices.noDevicesFiltered')
}
</p>
</div>
@@ -391,9 +391,9 @@ const Devices = () => {
{devices.length === 0 && (
<div className="text-center py-12">
<ServerIcon className="mx-auto h-12 w-12 text-gray-400" />
<h3 className="mt-2 text-sm font-medium text-gray-900">No devices</h3>
<h3 className="mt-2 text-sm font-medium text-gray-900">{t('devices.noDevices')}</h3>
<p className="mt-1 text-sm text-gray-500">
Get started by adding your first drone detection device.
{t('devices.noDevicesDescription')}
</p>
<div className="mt-6">
<button