Private
Public Access
1
0

Refactor Proxmox views for improved styling and consistency

- Updated subdomain.blade.php to enhance button styles and modal transitions.
- Changed text colors for better readability and consistency across the UI.
- Refactored system.blade.php to unify button components and improve layout structure.
- Adjusted modal z-index values for consistent layering.
- Enhanced accessibility by ensuring proper text contrast and hover states.
This commit is contained in:
2025-12-18 09:40:58 -05:00
parent 5c5184aec8
commit 0ed29d782e
22 changed files with 6734 additions and 3813 deletions

View File

@@ -36,22 +36,40 @@
$vmRunning = $status && $status->status !== 'stopped';
@endphp
<div class="space-y-6" x-data="{ pageLoaded: false }" x-init="setTimeout(() => pageLoaded = true, 50)">
{{-- Page Header --}}
<div :class="pageLoaded ? 'opacity-100 translate-y-0' : 'opacity-0 -translate-y-2'"
style="transition: all 0.4s ease-out;">
<div class="flex items-center gap-2 mb-6">
<h2 class="text-xl font-semibold flex items-center gap-3">
<div class="flex items-center justify-center w-11 h-11 rounded-lg bg-primary/10">
<x-ri-hard-drive-2-line class="size-5 text-primary" />
</div>
Storage Management
<div class="space-y-6">
<!-- Page Header -->
<div class="flex flex-col gap-2">
<div class="flex items-center gap-2 min-w-0">
<h2 class="text-xl font-semibold break-words">Storage Management</h2>
<div class="relative" x-data="{ open: false }" x-cloak>
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
<x-ri-question-line class="size-4" />
</button>
<div x-show="open" @click="open = false" @keydown.escape.window="open = false" class="fixed inset-0 z-[60] bg-black/50 backdrop-blur-sm" style="display: none;"></div>
<div x-show="open" @click.away="open = false" @keydown.escape.window="open = false" class="fixed inset-0 z-[60] flex items-center justify-center p-4" style="display: none;">
<!-- Modal Backdrop -->
<div x-show="open"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
@click="open = false"
@keydown.escape.window="open = false"
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
style="display: none;">
</div>
<!-- Modal -->
<div x-show="open"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 scale-95"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-95"
@click.away="open = false"
@keydown.escape.window="open = false"
class="fixed inset-0 z-50 flex items-center justify-center p-4"
style="display: none;">
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6">
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
<x-ri-close-line class="size-5" />
@@ -60,7 +78,9 @@
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10">
<x-ri-hard-drive-2-line class="size-5 text-primary" />
</div>
<h6 class="font-sans text-lg font-semibold leading-tight">Storage Management</h6>
<h6 class="font-sans text-lg font-semibold leading-tight text-base">
Storage Management
</h6>
</div>
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
Manage the storage drives attached to your VPS. You can add, remove, and configure drives with different bus types, cache modes, and performance options.
@@ -76,55 +96,67 @@
</div>
</div>
</div>
</h2>
</div>
<p class="text-sm text-base/60">Manage virtual hard disks attached to your VPS. Add, configure, or remove storage drives.</p>
</div>
<p class="text-sm text-base/60 mb-6">Manage virtual hard disks attached to your VPS. Add, configure, or remove storage drives.</p>
{{-- VM Running Warning --}}
<!-- VM Running Warning -->
@if($status && $status->status !== 'stopped')
<x-proxmox::ui.alert variant="danger" title="Server Must Be Powered Off">
Storage changes can only be made when the server is in a powered off state. Please shut down your server before making any storage modifications.
</x-proxmox::ui.alert>
<div class="bg-error/10 border border-error/30 rounded-lg p-4">
<div class="flex items-start gap-3">
<x-ri-error-warning-fill class="size-5 text-error flex-shrink-0 mt-0.5" />
<div class="flex-1">
<h3 class="text-sm font-semibold">Server Must Be Powered Off</h3>
<p class="text-xs text-base/70 leading-relaxed mt-1">Storage changes can only be made when the server is in a powered off state. Please shut down your server before making any storage modifications.</p>
</div>
</div>
</div>
@endif
{{-- Storage Over-Provisioned Warning --}}
<!-- Storage Over-Provisioned Warning -->
@if($totalAllocatedStorage > $maxAllowedStorage && $maxAllowedStorage > 0)
<x-proxmox::ui.alert variant="danger" title="Storage Quota Exceeded" icon="ri-alarm-warning-fill">
<strong>Your server has {{ number_format($totalAllocatedStorage, 1) }} GB of storage configured, but your plan only allows {{ number_format($maxAllowedStorage, 1) }} GB.</strong>
The server cannot be started until storage is reduced to within your plan limits. Please delete drives or upgrade your service to allow this configuration.
</x-proxmox::ui.alert>
<div class="bg-error/10 border border-error/30 rounded-lg p-4">
<div class="flex items-start gap-3">
<x-ri-alarm-warning-fill class="size-5 text-error flex-shrink-0 mt-0.5" />
<div class="flex-1">
<h3 class="text-sm font-semibold">Storage Quota Exceeded</h3>
<p class="text-xs text-base/70 leading-relaxed mt-1">
<strong>Your server has {{ number_format($totalAllocatedStorage, 1) }} GB of storage configured, but your plan only allows {{ number_format($maxAllowedStorage, 1) }} GB.</strong>
The server cannot be started until storage is reduced to within your plan limits. Please delete drives or upgrade your service to allow this configuration.
</p>
</div>
</div>
</div>
@endif
<!-- Storage Usage Overview -->
<div class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl p-5 shadow-theme-sm transition-all duration-300 hover:shadow-md"
:class="pageLoaded ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4'"
style="transition: all 0.4s ease-out 0.1s;">
<div class="bg-background-secondary border border-neutral rounded-lg p-5">
<div class="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-4">
<div>
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">Storage Quota</h3>
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">
<h3 class="text-lg font-semibold">Storage Quota</h3>
<p class="text-sm text-base/60 mt-1">
{{ number_format($totalAllocatedStorage, 1) }} GB used of {{ number_format($maxAllowedStorage, 1) }} GB allocated
@if(count($unusedDrives) > 0)
<span class="text-warning-500">(includes detached drives)</span>
<span class="text-warning">(includes detached drives)</span>
@endif
</p>
</div>
<div class="flex items-center gap-2">
<button wire:click="loadStorageConfiguration"
class="inline-flex items-center gap-2 px-3 py-2 text-theme-sm font-medium rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 transition-all duration-200">
class="inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-lg border border-neutral bg-background hover:bg-background-secondary transition-colors">
<x-ri-refresh-line class="size-4" wire:loading.class="animate-spin" wire:target="loadStorageConfiguration" />
Refresh
</button>
@if($this->remainingStorage > 0 && !$vmRunning)
<button wire:click="openAddDriveModal"
class="inline-flex items-center gap-2 px-3 py-2 text-theme-sm font-medium rounded-lg bg-brand-500 text-white hover:bg-brand-600 transition-all duration-200 shadow-theme-xs">
class="inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-lg bg-primary text-white hover:bg-primary/90 transition-colors">
<x-ri-add-line class="size-4" />
Add Drive
</button>
@elseif($this->remainingStorage > 0 && $vmRunning)
<button disabled
title="Server must be powered off to add drives"
class="inline-flex items-center gap-2 px-3 py-2 text-theme-sm font-medium rounded-lg bg-gray-100 dark:bg-gray-800/50 text-gray-400 dark:text-gray-500 cursor-not-allowed">
class="inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-lg bg-neutral/50 text-base/50 cursor-not-allowed">
<x-ri-add-line class="size-4" />
Add Drive
</button>
@@ -138,10 +170,7 @@
$usagePercent = $maxAllowedStorage > 0 ? min(100, ($totalAllocatedStorage / $maxAllowedStorage) * 100) : 0;
$colorClass = $usagePercent < 70 ? 'bg-success' : ($usagePercent < 90 ? 'bg-warning' : 'bg-danger');
@endphp
<div class="{{ $colorClass }} h-3 rounded-full transition-all duration-700 ease-out"
x-data="{ width: 0 }"
x-init="setTimeout(() => width = {{ $usagePercent }}, 300)"
:style="'width: ' + width + '%'"></div>
<div class="{{ $colorClass }} h-3 rounded-full transition-all duration-500" style="width: {{ $usagePercent }}%"></div>
</div>
<div class="flex justify-between mt-2 text-xs text-base/50">
<span>{{ number_format($this->remainingStorage, 1) }} GB remaining</span>
@@ -149,18 +178,41 @@
</div>
</div>
{{-- SCSI Controller Configuration --}}
<x-proxmox::ui.card>
<div class="flex items-center justify-between mb-4">
<!-- SCSI Controller Configuration -->
<div class="bg-background-secondary border border-neutral rounded-lg p-5 space-y-4">
<div class="flex items-center justify-between">
<div>
<div class="flex items-center gap-2">
<h3 class="text-lg font-semibold text-base">SCSI Controller</h3>
<h3 class="text-lg font-semibold">SCSI Controller</h3>
<div class="relative" x-data="{ open: false }" x-cloak>
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
<x-ri-question-line class="size-4" />
</button>
<div x-show="open" @click="open = false" @keydown.escape.window="open = false" class="fixed inset-0 z-[60] bg-black/50 backdrop-blur-sm" style="display: none;"></div>
<div x-show="open" @click.away="open = false" @keydown.escape.window="open = false" class="fixed inset-0 z-[60] flex items-center justify-center p-4" style="display: none;">
<!-- Modal Backdrop -->
<div x-show="open"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
@click="open = false"
@keydown.escape.window="open = false"
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
style="display: none;">
</div>
<!-- Modal -->
<div x-show="open"
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 scale-95"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-95"
@click.away="open = false"
@keydown.escape.window="open = false"
class="fixed inset-0 z-50 flex items-center justify-center p-4"
style="display: none;">
<div class="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl p-6">
<button @click="open = false" class="absolute top-4 right-4 text-base/50 hover:text-base transition-colors">
<x-ri-close-line class="size-5" />
@@ -169,7 +221,9 @@
<div class="flex items-center justify-center w-10 h-10 rounded-lg bg-primary/10">
<x-ri-cpu-line class="size-5 text-primary" />
</div>
<h6 class="font-sans text-lg font-semibold leading-tight">SCSI Controller Types</h6>
<h6 class="font-sans text-lg font-semibold leading-tight text-base">
SCSI Controller Types
</h6>
</div>
<div class="space-y-3 text-sm text-base/90">
<p><strong>VirtIO SCSI / VirtIO SCSI Single:</strong> Best performance with paravirtualized drivers. Recommended for Linux and modern Windows.</p>
@@ -205,26 +259,24 @@
</div>
@if($vmRunning && !$this->scsiControllerSynced)
<x-proxmox::ui.alert variant="warning" class="mt-4">
VM must be stopped to change the SCSI controller type.
</x-proxmox::ui.alert>
<div class="flex items-center gap-2 p-3 rounded-lg bg-warning/10 border border-warning/30 text-warning text-sm">
<x-ri-alert-line class="size-4 flex-shrink-0" />
<span>VM must be stopped to change the SCSI controller type.</span>
</div>
@endif
</x-proxmox::ui.card>
</div>
{{-- Drives List --}}
<x-proxmox::ui.card :noPadding="true">
<div class="p-5 border-b border-neutral/20">
<h3 class="text-lg font-semibold text-base">Attached Drives</h3>
<!-- Drives List -->
<div class="bg-background-secondary border border-neutral rounded-lg overflow-hidden">
<div class="p-5 border-b border-neutral">
<h3 class="text-lg font-semibold">Attached Drives</h3>
<p class="text-sm text-base/60 mt-1">Manage the virtual hard disks connected to your VPS.</p>
</div>
@if(count($drives) === 0)
<x-proxmox::ui.empty-state
title="No Drives Attached"
description="No drives are currently attached to this VM."
icon="ri-hard-drive-2-line"
class="py-8"
>
<div class="p-8 text-center">
<x-ri-hard-drive-2-line class="size-12 mx-auto text-base/30 mb-3" />
<p class="text-base/60">No drives attached to this VM.</p>
@if($this->remainingStorage > 0 && !$vmRunning)
<button wire:click="openAddDriveModal" class="mt-4 text-primary hover:text-primary/80 text-sm font-medium">
Add your first drive →
@@ -232,7 +284,7 @@
@elseif($this->remainingStorage > 0 && $vmRunning)
<p class="mt-4 text-base/50 text-sm">Power off server to add drives</p>
@endif
</x-proxmox::ui.empty-state>
</div>
@else
<div class="divide-y divide-neutral">
@foreach($drives as $driveKey => $drive)
@@ -329,37 +381,41 @@
@endforeach
</div>
@endif
</x-proxmox::ui.card>
</div>
{{-- Detached/Unused Drives --}}
<!-- Detached/Unused Drives -->
@if(count($unusedDrives) > 0)
<x-proxmox::ui.card :noPadding="true">
<div class="p-5 border-b border-neutral/20">
<div class="bg-background-secondary border border-neutral rounded-lg overflow-hidden">
<div class="p-5 border-b border-neutral">
<div class="flex items-center justify-between">
<div>
<div class="flex items-center gap-2">
<x-ri-eject-line class="size-5 text-warning" />
<h3 class="text-lg font-semibold text-base">Detached Drives</h3>
<x-proxmox::ui.badge :variant="count($unusedDrives) >= 2 ? 'danger' : 'warning'">
{{ count($unusedDrives) }}/2
</x-proxmox::ui.badge>
<h3 class="text-lg font-semibold">Detached Drives</h3>
<span class="px-2 py-0.5 text-xs font-medium rounded {{ count($unusedDrives) >= 2 ? 'bg-danger/20 text-danger' : 'bg-warning/20 text-warning' }}">{{ count($unusedDrives) }}/2</span>
</div>
<p class="text-sm text-base/60 mt-1">These drives have been detached but their data is preserved. You can reattach them or delete them permanently.</p>
</div>
</div>
@if(count($unusedDrives) >= 2)
<x-proxmox::ui.alert variant="danger" class="mt-3">
Maximum detached drives reached. Please reattach or delete drives before detaching more.
</x-proxmox::ui.alert>
<div class="mt-3 p-3 rounded-lg bg-danger/10 border border-danger/30">
<p class="text-xs text-danger flex items-center gap-2">
<x-ri-error-warning-line class="size-4 flex-shrink-0" />
Maximum detached drives reached. Please reattach or delete drives before detaching more.
</p>
</div>
@endif
@if($totalAllocatedStorage >= $maxAllowedStorage && $maxAllowedStorage > 0)
<x-proxmox::ui.alert variant="danger" class="mt-3">
Storage quota reached ({{ number_format($totalAllocatedStorage, 1) }} GB / {{ number_format($maxAllowedStorage, 1) }} GB). Reattaching drives is disabled. Please upgrade your service or delete drives to allow this configuration.
</x-proxmox::ui.alert>
<div class="mt-3 p-3 rounded-lg bg-danger/10 border border-danger/30">
<p class="text-xs text-danger flex items-center gap-2">
<x-ri-error-warning-line class="size-4 flex-shrink-0" />
Storage quota reached ({{ number_format($totalAllocatedStorage, 1) }} GB / {{ number_format($maxAllowedStorage, 1) }} GB). Reattaching drives is disabled. Please upgrade your service or delete drives to allow this configuration.
</p>
</div>
@endif
</div>
<div class="divide-y divide-neutral/20">
<div class="divide-y divide-neutral">
@foreach($unusedDrives as $unusedKey => $unusedDrive)
<div class="p-4 hover:bg-background/50 transition-colors">
<div class="flex flex-col lg:flex-row lg:items-center justify-between gap-4">
@@ -433,13 +489,13 @@
</div>
@endforeach
</div>
</x-proxmox::ui.card>
</div>
@endif
</div>
<!-- Add Drive Modal -->
@if($showAddDriveModal)
<div class="fixed inset-0 z-[60] overflow-y-auto" x-data x-init="$el.querySelector('input')?.focus()">
<div class="fixed inset-0 z-50 overflow-y-auto" x-data x-init="$el.querySelector('input')?.focus()">
<div class="fixed inset-0 bg-black/50 backdrop-blur-sm" wire:click="closeAddDriveModal"></div>
<div class="relative min-h-screen flex items-center justify-center p-4">
<div class="relative w-full max-w-lg bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl">
@@ -565,7 +621,7 @@
<!-- Edit Drive Modal -->
@if($showEditDriveModal && $editingDriveKey && isset($drives[$editingDriveKey]))
@php $editDrive = $drives[$editingDriveKey]; @endphp
<div class="fixed inset-0 z-[60] overflow-y-auto">
<div class="fixed inset-0 z-50 overflow-y-auto">
<div class="fixed inset-0 bg-black/50 backdrop-blur-sm" wire:click="closeEditDriveModal"></div>
<div class="relative min-h-screen flex items-center justify-center p-4">
<div class="relative w-full max-w-lg bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl">
@@ -666,7 +722,7 @@
<!-- Change Device Bus Modal -->
@if($showMoveDriveModal && $movingDriveKey && isset($drives[$movingDriveKey]))
@php $moveDrive = $drives[$movingDriveKey]; @endphp
<div class="fixed inset-0 z-[60] overflow-y-auto">
<div class="fixed inset-0 z-50 overflow-y-auto">
<div class="fixed inset-0 bg-black/50 backdrop-blur-sm" wire:click="closeMoveDriveModal"></div>
<div class="relative min-h-screen flex items-center justify-center p-4">
<div class="relative w-full max-w-lg bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl">
@@ -731,7 +787,7 @@
<!-- Detach Drive Confirmation Modal -->
@if($showDetachModal && $detachingDriveKey && isset($drives[$detachingDriveKey]))
@php $detachDrive = $drives[$detachingDriveKey]; @endphp
<div class="fixed inset-0 z-[60] overflow-y-auto">
<div class="fixed inset-0 z-50 overflow-y-auto">
<div class="fixed inset-0 bg-black/50 backdrop-blur-sm" wire:click="closeDetachModal"></div>
<div class="relative min-h-screen flex items-center justify-center p-4">
<div class="relative w-full max-w-md bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl">
@@ -793,7 +849,7 @@
<!-- Delete Drive Confirmation Modal -->
@if($showDeleteModal && $deletingDriveKey && isset($drives[$deletingDriveKey]))
@php $deleteDrive = $drives[$deletingDriveKey]; @endphp
<div class="fixed inset-0 z-[60] overflow-y-auto">
<div class="fixed inset-0 z-50 overflow-y-auto">
<div class="fixed inset-0 bg-black/50 backdrop-blur-sm" wire:click="closeDeleteModal"></div>
<div class="relative min-h-screen flex items-center justify-center p-4">
<div class="relative w-full max-w-md bg-background-secondary rounded-xl border border-neutral/20 shadow-2xl">
@@ -854,7 +910,7 @@
<!-- Reattach Drive Modal -->
@if($showReattachModal)
<div class="fixed inset-0 z-[60] overflow-y-auto">
<div class="fixed inset-0 z-50 overflow-y-auto">
<div class="fixed inset-0 bg-black/50 transition-opacity"></div>
<div class="flex min-h-full items-center justify-center p-4">
<div class="relative w-full max-w-lg transform overflow-hidden rounded-xl bg-background border border-neutral shadow-xl transition-all">