feat: implement custom toggle switch for firewall control with improved styling

This commit is contained in:
2025-12-18 06:33:36 -05:00
parent 405401c2d0
commit db48adaeb4

View File

@@ -52,6 +52,72 @@
@keyframes fw-loader-spin {
100% { transform: rotate(1turn); }
}
/* Firewall Toggle Switch */
.fw-toggle {
position: relative;
width: 64px;
height: 32px;
cursor: pointer;
flex-shrink: 0;
}
.fw-toggle input {
opacity: 0;
width: 0;
height: 0;
}
.fw-toggle-slider {
position: absolute;
inset: 0;
background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);
border-radius: 32px;
transition: all 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
box-shadow: inset 0 2px 4px rgba(0,0,0,0.2), 0 2px 8px rgba(220, 38, 38, 0.3);
}
.fw-toggle-slider::before {
content: '';
position: absolute;
width: 24px;
height: 24px;
left: 4px;
bottom: 4px;
background: linear-gradient(135deg, #ffffff 0%, #f3f4f6 100%);
border-radius: 50%;
transition: all 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}
.fw-toggle input:checked + .fw-toggle-slider {
background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
box-shadow: inset 0 2px 4px rgba(0,0,0,0.2), 0 2px 8px rgba(34, 197, 94, 0.3);
}
.fw-toggle input:checked + .fw-toggle-slider::before {
transform: translateX(32px);
}
.fw-toggle:hover .fw-toggle-slider {
filter: brightness(1.1);
}
.fw-toggle input:disabled + .fw-toggle-slider {
opacity: 0.6;
cursor: not-allowed;
}
.fw-toggle-label {
font-weight: 600;
font-size: 0.875rem;
transition: color 0.3s ease;
}
.fw-toggle-label-enabled {
color: #22c55e;
}
.fw-toggle-label-disabled {
color: #dc2626;
}
@keyframes fw-toggle-pulse {
0%, 100% { box-shadow: inset 0 2px 4px rgba(0,0,0,0.2), 0 2px 8px rgba(34, 197, 94, 0.3); }
50% { box-shadow: inset 0 2px 4px rgba(0,0,0,0.2), 0 2px 16px rgba(34, 197, 94, 0.5); }
}
.fw-toggle input:checked + .fw-toggle-slider {
animation: fw-toggle-pulse 2s infinite ease-in-out;
}
</style>
<div class="flex flex-col gap-6" x-data="{ pageLoaded: false }" x-init="setTimeout(() => pageLoaded = true, 50)">
@@ -115,27 +181,25 @@
</p>
</div>
</div>
<div class="flex items-center gap-2">
@if($firewallEnabled)
<x-proxmox::ui.button
wire:click="toggleFirewall"
wire:loading.attr="disabled"
variant="danger"
icon="ri-shield-cross-line">
<span wire:loading.remove wire:target="toggleFirewall">Disable</span>
<span wire:loading wire:target="toggleFirewall">Disabling...</span>
</x-proxmox::ui.button>
@else
<x-proxmox::ui.button
wire:click="toggleFirewall"
wire:loading.attr="disabled"
variant="success"
icon="ri-shield-check-line"
class="whitespace-nowrap">
<span wire:loading.remove wire:target="toggleFirewall">Enable Firewall</span>
<span wire:loading wire:target="toggleFirewall">Enabling...</span>
</x-proxmox::ui.button>
@endif
<div class="flex items-center gap-4">
<div class="flex items-center gap-3">
<span class="fw-toggle-label {{ $firewallEnabled ? 'fw-toggle-label-enabled' : 'fw-toggle-label-disabled' }}">
{{ $firewallEnabled ? 'Enabled' : 'Disabled' }}
</span>
<label class="fw-toggle" wire:loading.class="pointer-events-none">
<input
type="checkbox"
wire:click="toggleFirewall"
wire:loading.attr="disabled"
{{ $firewallEnabled ? 'checked' : '' }}
>
<span class="fw-toggle-slider"></span>
</label>
</div>
<span wire:loading wire:target="toggleFirewall" class="text-xs text-base/50 flex items-center gap-1.5">
<span class="fw-loader-sm text-primary"></span>
{{ $firewallEnabled ? 'Disabling...' : 'Enabling...' }}
</span>
</div>
</div>
</div>