Fix jwt-token

This commit is contained in:
2025-09-23 16:05:34 +02:00
parent 25d910ed3f
commit e41ae5d65b
5 changed files with 262 additions and 10 deletions

View File

@@ -1,12 +1,15 @@
import React, { useState, useEffect } from 'react'
import api from '../services/api'
import toast from 'react-hot-toast'
import {
TrashIcon,
ServerIcon,
ChartBarIcon,
ClockIcon,
ExclamationTriangleIcon,
CheckCircleIcon
CheckCircleIcon,
PlayIcon,
EyeIcon
} from '@heroicons/react/24/outline'
const DataRetentionMetrics = () => {
@@ -14,6 +17,9 @@ const DataRetentionMetrics = () => {
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
const [lastUpdate, setLastUpdate] = useState(null)
const [cleanupLoading, setCleanupLoading] = useState(false)
const [previewData, setPreviewData] = useState(null)
const [showPreview, setShowPreview] = useState(false)
useEffect(() => {
loadDataRetentionMetrics()
@@ -36,6 +42,42 @@ const DataRetentionMetrics = () => {
}
}
const loadCleanupPreview = async () => {
try {
setError(null)
const response = await api.get('/data-retention/stats')
setPreviewData(response.data.data)
setShowPreview(true)
} catch (error) {
console.error('Error loading cleanup preview:', error)
toast.error('Failed to load cleanup preview')
}
}
const executeCleanup = async () => {
if (!window.confirm('Are you sure you want to execute data retention cleanup? This will permanently delete old data according to each tenant\'s retention policy.')) {
return
}
setCleanupLoading(true)
try {
// Note: This endpoint would need to be implemented in the backend
const response = await api.post('/data-retention/cleanup')
toast.success('Data retention cleanup initiated successfully')
// Refresh metrics after cleanup
setTimeout(() => {
loadDataRetentionMetrics()
}, 2000)
} catch (error) {
console.error('Error executing cleanup:', error)
toast.error(error.response?.data?.message || 'Failed to execute cleanup')
} finally {
setCleanupLoading(false)
}
}
const formatUptime = (seconds) => {
if (!seconds) return 'Unknown'
const days = Math.floor(seconds / 86400)
@@ -111,8 +153,36 @@ const DataRetentionMetrics = () => {
<ExclamationTriangleIcon className="h-5 w-5 text-red-500 ml-2" />
)}
</div>
<div className="text-sm text-gray-500">
{lastUpdate && `Updated ${lastUpdate.toLocaleTimeString()}`}
<div className="flex items-center gap-4">
<div className="text-sm text-gray-500">
{lastUpdate && `Updated ${lastUpdate.toLocaleTimeString()}`}
</div>
{/* Action Buttons */}
{isConnected && (
<div className="flex gap-2">
<button
onClick={loadCleanupPreview}
className="px-3 py-1.5 bg-blue-100 text-blue-700 rounded-md hover:bg-blue-200 transition-colors text-sm flex items-center gap-1"
>
<EyeIcon className="h-4 w-4" />
Preview Cleanup
</button>
<button
onClick={executeCleanup}
disabled={cleanupLoading}
className="px-3 py-1.5 bg-red-100 text-red-700 rounded-md hover:bg-red-200 transition-colors text-sm flex items-center gap-1 disabled:opacity-50"
>
{cleanupLoading ? (
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-red-700"></div>
) : (
<PlayIcon className="h-4 w-4" />
)}
{cleanupLoading ? 'Running...' : 'Run Cleanup'}
</button>
</div>
)}
</div>
</div>
@@ -211,6 +281,78 @@ const DataRetentionMetrics = () => {
</p>
</div>
)}
{/* Cleanup Preview Modal */}
{showPreview && previewData && (
<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-11/12 md:w-3/4 lg:w-1/2 shadow-lg rounded-md bg-white">
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-medium">Data Retention Cleanup Preview</h3>
<button
onClick={() => setShowPreview(false)}
className="text-gray-400 hover:text-gray-600"
>
<span className="sr-only">Close</span>
</button>
</div>
<div className="space-y-4">
<p className="text-sm text-gray-600">
This preview shows what data would be deleted based on each tenant's retention policy.
</p>
{previewData.tenants && previewData.tenants.map((tenant, index) => (
<div key={index} className="border rounded-lg p-4">
<div className="flex items-center justify-between mb-2">
<h4 className="font-medium">{tenant.name}</h4>
<span className="text-sm text-gray-500">
{tenant.retentionDays === -1 ? 'Unlimited' : `${tenant.retentionDays} days`}
</span>
</div>
{tenant.retentionDays === -1 ? (
<p className="text-sm text-gray-600">No data will be deleted (unlimited retention)</p>
) : (
<div className="grid grid-cols-3 gap-4 text-sm">
<div>
<span className="font-medium">Detections:</span>
<span className="ml-2">{tenant.toDelete?.detections || 0}</span>
</div>
<div>
<span className="font-medium">Heartbeats:</span>
<span className="ml-2">{tenant.toDelete?.heartbeats || 0}</span>
</div>
<div>
<span className="font-medium">Logs:</span>
<span className="ml-2">{tenant.toDelete?.logs || 0}</span>
</div>
</div>
)}
</div>
))}
<div className="flex justify-end gap-3 pt-4 border-t">
<button
onClick={() => setShowPreview(false)}
className="px-4 py-2 bg-gray-100 text-gray-700 rounded-md hover:bg-gray-200"
>
Cancel
</button>
<button
onClick={() => {
setShowPreview(false)
executeCleanup()
}}
className="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700"
>
Execute Cleanup
</button>
</div>
</div>
</div>
</div>
)}
</div>
)
}

View File

@@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react'
import api from '../services/api'
import { t } from '../utils/tempTranslations' // Temporary translation system
import { BuildingOfficeIcon, UsersIcon, ServerIcon, ChartBarIcon } from '@heroicons/react/24/outline'
import DataRetentionMetrics from '../components/DataRetentionMetrics'
const Dashboard = () => {
const [stats, setStats] = useState({
@@ -97,8 +96,8 @@ const Dashboard = () => {
))}
</div>
{/* Quick Actions and Data Retention */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
{/* Quick Actions and Recent Activity */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="bg-white rounded-lg shadow p-6">
<h3 className="text-lg font-semibold text-gray-900 mb-4">Quick Actions</h3>
<div className="space-y-3">
@@ -143,9 +142,6 @@ const Dashboard = () => {
</div>
</div>
</div>
{/* Data Retention Service Metrics */}
<DataRetentionMetrics />
</div>
)
}

View File

@@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react'
import api from '../services/api'
import toast from 'react-hot-toast'
import { t } from '../utils/tempTranslations' // Temporary translation system
import DataRetentionMetrics from '../components/DataRetentionMetrics'
import {
CogIcon,
ServerIcon,
@@ -516,6 +517,11 @@ const System = () => {
</div>
</StatusCard>
</div>
{/* Data Retention Service */}
<div className="mb-8">
<DataRetentionMetrics />
</div>
</div>
)
}