feat: add loading overlays and animations across various pages

- Implemented new CSS animations for UI elements including bobbing, pulsing, rotating, and spinning effects.
- Integrated loading overlays in CrowdSecConfig, Login, ProxyHosts, Security, and WafConfig pages to enhance user experience during asynchronous operations.
- Added contextual messages for loading states to inform users about ongoing processes.
- Created tests for Login and Security pages to ensure overlays function correctly during login attempts and security operations.
This commit is contained in:
GitHub Actions
2025-12-04 15:10:02 +00:00
parent 33c31a32c6
commit 3e4323155f
29 changed files with 5575 additions and 1344 deletions

View File

@@ -7,6 +7,7 @@ import { createBackup } from '../api/backups'
import { updateSetting } from '../api/settings'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { toast } from '../utils/toast'
import { ConfigReloadOverlay } from '../components/LoadingStates'
export default function CrowdSecConfig() {
const { data: status } = useQuery({ queryKey: ['security-status'], queryFn: getSecurityStatus })
@@ -82,10 +83,41 @@ export default function CrowdSecConfig() {
toast.success('CrowdSec mode saved (restart may be required)')
}
// Determine if any operation is in progress
const isApplyingConfig =
importMutation.isPending ||
writeMutation.isPending ||
updateModeMutation.isPending ||
backupMutation.isPending
// Determine contextual message
const getMessage = () => {
if (importMutation.isPending) {
return { message: 'Summoning the guardian...', submessage: 'Importing CrowdSec configuration' }
}
if (writeMutation.isPending) {
return { message: 'Guardian inscribes...', submessage: 'Saving configuration file' }
}
if (updateModeMutation.isPending) {
return { message: 'Three heads turn...', submessage: 'CrowdSec mode updating' }
}
return { message: 'Strengthening the guard...', submessage: 'Configuration in progress' }
}
const { message, submessage } = getMessage()
if (!status) return <div className="p-8 text-center">Loading...</div>
return (
<div className="space-y-6">
<>
{isApplyingConfig && (
<ConfigReloadOverlay
message={message}
submessage={submessage}
type="cerberus"
/>
)}
<div className="space-y-6">
<h1 className="text-2xl font-bold">CrowdSec Configuration</h1>
<Card>
<div className="flex items-center justify-between">
@@ -141,6 +173,7 @@ export default function CrowdSecConfig() {
</div>
</div>
</Card>
</div>
</div>
</>
)
}