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

@@ -1,14 +1,10 @@
<x-proxmox::layout :server="$server" view="subdomain" :status="$status" :status-polling="true" :status-polling-interval="'2s'">
<div class="flex items-center justify-between mb-6"
x-data="{ pageLoaded: false }"
x-init="setTimeout(() => pageLoaded = true, 50)"
:class="pageLoaded ? 'opacity-100 translate-y-0' : 'opacity-0 -translate-y-2'"
style="transition: all 0.4s ease-out;">
<div class="flex items-center justify-between mb-6">
<div>
<div class="flex items-center gap-2 min-w-0">
<h2 class="text-xl font-semibold break-words">Subdomain Management</h2>
<div class="relative" x-data="{ open: false }" x-cloak>
<button type="button" @click="open = true" class="text-base/50 hover:text-gray-600 dark:text-gray-400 transition-colors">
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
<x-ri-question-line class="size-4" />
</button>
<!-- Modal Backdrop -->
@@ -21,7 +17,7 @@
x-transition:leave-end="opacity-0"
@click="open = false"
@keydown.escape.window="open = false"
class="fixed inset-0 z-[60] bg-black/50 backdrop-blur-sm"
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
style="display: none;">
</div>
<!-- Modal -->
@@ -34,9 +30,9 @@
x-transition:leave-end="opacity-0 scale-95"
@click.away="open = false"
@keydown.escape.window="open = false"
class="fixed inset-0 z-[60] flex items-center justify-center p-4"
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-gray-200 dark:border-gray-800 shadow-2xl p-6">
<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" />
</button>
@@ -51,7 +47,7 @@
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
Create and manage DNS subdomains for your virtual machine. Each subdomain points to one of your assigned public IP addresses and is automatically configured with A and AAAA records.
</p>
<div class="pt-4 mt-4 border-t border-gray-200 dark:border-gray-800 space-y-2.5">
<div class="pt-4 mt-4 border-t border-neutral/30 space-y-2.5">
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
<span class="font-semibold text-base/90">Limitations:</span> Only A and AAAA records are created. One subdomain per public IP address. Wildcard subdomains (*) are automatically created for each subdomain.
</p>
@@ -63,7 +59,7 @@
</div>
</div>
</div>
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">Create and manage subdomains for dns.virtnet.host</p>
<p class="text-sm text-base/60 mt-1">Create and manage subdomains for dns.virtnet.host</p>
</div>
</div>
@@ -81,12 +77,12 @@
<div class="flex-1">
<div class="flex items-center justify-between mb-2">
<h3 class="text-sm font-semibold text-base">Subdomain Configuration Notice</h3>
<button @click="toggle()" type="button" class="text-gray-500 dark:text-gray-400 hover:text-base transition-colors">
<button @click="toggle()" type="button" class="text-base/60 hover:text-base transition-colors">
<x-ri-arrow-down-s-line x-bind:class="isCollapsed ? 'size-4 transition-transform rotate-180' : 'size-4 transition-transform'" />
</button>
</div>
<div x-show="!isCollapsed" x-transition>
<p class="text-xs text-gray-600 dark:text-gray-400 leading-relaxed">
<p class="text-xs text-base/70 leading-relaxed">
Only <strong>A and AAAA records</strong> are created. For any subdomain created, its child wildcard (*) subdomain is also automatically created. <strong>One subdomain per public IP address</strong> can be created. Under no circumstances will PTR, MX, NS, or other record types be added. These restrictions are in place to minimize abuse of the subdomain system.
</p>
</div>
@@ -101,7 +97,7 @@
<div class="flex items-center gap-2 min-w-0">
<h3 class="text-lg font-semibold break-words">Create Subdomain</h3>
<div class="relative" x-data="{ open: false }" x-cloak>
<button type="button" @click="open = true" class="text-base/50 hover:text-gray-600 dark:text-gray-400 transition-colors">
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
<x-ri-question-line class="size-4" />
</button>
<!-- Modal Backdrop -->
@@ -114,7 +110,7 @@
x-transition:leave-end="opacity-0"
@click="open = false"
@keydown.escape.window="open = false"
class="fixed inset-0 z-[60] bg-black/50 backdrop-blur-sm"
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
style="display: none;">
</div>
<!-- Modal -->
@@ -127,9 +123,9 @@
x-transition:leave-end="opacity-0 scale-95"
@click.away="open = false"
@keydown.escape.window="open = false"
class="fixed inset-0 z-[60] flex items-center justify-center p-4"
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-gray-200 dark:border-gray-800 shadow-2xl p-6">
<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" />
</button>
@@ -144,7 +140,7 @@
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
Create a new subdomain that points to one of your assigned public IP addresses. The subdomain will be created under the dns.virtnet.host domain.
</p>
<div class="pt-4 mt-4 border-t border-gray-200 dark:border-gray-800 space-y-2.5">
<div class="pt-4 mt-4 border-t border-neutral/30 space-y-2.5">
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
<span class="font-semibold text-base/90">Subdomain Name:</span> Choose a unique name for your subdomain. Only alphanumeric characters and hyphens are allowed.
</p>
@@ -159,14 +155,15 @@
</div>
</div>
</div>
<x-proxmox::ui.button wire:click="$set('showCreateModal', true)" :disabled="count($this->availableIpsForSubdomain) === 0" variant="primary" icon="ri-add-circle-fill">
<x-button.primary wire:click="$set('showCreateModal', true)" :disabled="count($this->availableIpsForSubdomain) === 0" class="!w-auto flex-shrink-0">
<x-ri-add-circle-fill class="size-4" />
Create Subdomain
</x-proxmox::ui.button>
</x-button.primary>
</div>
@if(count($this->availableIpsForSubdomain) === 0)
<p class="text-sm text-gray-500 dark:text-gray-400">All available public IP addresses already have subdomains assigned.</p>
<p class="text-sm text-base/60">All available public IP addresses already have subdomains assigned.</p>
@else
<p class="text-sm text-gray-500 dark:text-gray-400">You can create {{ count($this->availableIpsForSubdomain) }} more subdomain(s).</p>
<p class="text-sm text-base/60">You can create {{ count($this->availableIpsForSubdomain) }} more subdomain(s).</p>
@endif
</div>
@@ -175,7 +172,7 @@
<div class="flex items-center gap-2 min-w-0 mb-4">
<h3 class="text-lg font-semibold break-words">Your Subdomains</h3>
<div class="relative" x-data="{ open: false }" x-cloak>
<button type="button" @click="open = true" class="text-base/50 hover:text-gray-600 dark:text-gray-400 transition-colors">
<button type="button" @click="open = true" class="text-base/50 hover:text-base/70 transition-colors">
<x-ri-question-line class="size-4" />
</button>
<!-- Modal Backdrop -->
@@ -188,7 +185,7 @@
x-transition:leave-end="opacity-0"
@click="open = false"
@keydown.escape.window="open = false"
class="fixed inset-0 z-[60] bg-black/50 backdrop-blur-sm"
class="fixed inset-0 z-50 bg-black/50 backdrop-blur-sm"
style="display: none;">
</div>
<!-- Modal -->
@@ -201,9 +198,9 @@
x-transition:leave-end="opacity-0 scale-95"
@click.away="open = false"
@keydown.escape.window="open = false"
class="fixed inset-0 z-[60] flex items-center justify-center p-4"
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-gray-200 dark:border-gray-800 shadow-2xl p-6">
<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" />
</button>
@@ -218,7 +215,7 @@
<p class="block font-sans text-sm font-normal leading-relaxed text-base/90 mb-4">
Lists all subdomains you have created for this virtual machine. Each subdomain shows its full domain name, associated IP address, and automatically created wildcard record.
</p>
<div class="pt-4 mt-4 border-t border-gray-200 dark:border-gray-800 space-y-2.5">
<div class="pt-4 mt-4 border-t border-neutral/30 space-y-2.5">
<p class="block font-sans text-xs font-normal leading-relaxed text-base/75">
<span class="font-semibold text-base/90">Delete:</span> Removes the subdomain and all associated DNS records. This action cannot be undone.
</p>
@@ -231,7 +228,7 @@
</div>
</div>
@if(count($serverZones) === 0)
<p class="text-sm text-gray-500 dark:text-gray-400">No subdomains created yet.</p>
<p class="text-sm text-base/60">No subdomains created yet.</p>
@else
<div class="flex flex-col gap-4">
@foreach($serverZones as $zone)
@@ -239,7 +236,7 @@
<div class="flex items-center justify-between">
<div>
<h4 class="text-md font-semibold">{{ $zone['subdomain'] }}.dns.virtnet.host</h4>
<p class="text-sm text-gray-500 dark:text-gray-400">IP: {{ $zone['ipAddress'] }}</p>
<p class="text-sm text-base/60">IP: {{ $zone['ipAddress'] }}</p>
@php
$hasWildcard = false;
$wildcardType = null;
@@ -258,9 +255,10 @@
@endif
</div>
<div class="flex gap-2">
<x-proxmox::ui.button wire:click="openDeleteModal('{{ $zone['subdomain'] }}', {{ $zone['ipAddressId'] }})" variant="danger" icon="ri-delete-bin-line">
<x-button.danger wire:click="openDeleteModal('{{ $zone['subdomain'] }}', {{ $zone['ipAddressId'] }})">
<x-ri-delete-bin-line class="size-4" />
Delete
</x-proxmox::ui.button>
</x-button.danger>
</div>
</div>
</div>
@@ -276,7 +274,7 @@
<div class="bg-background border border-neutral rounded-lg p-6 max-w-md w-full mx-4" wire:click.stop>
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold">Create New Subdomain</h3>
<button wire:click="$set('showCreateModal', false)" class="text-gray-500 dark:text-gray-400 hover:text-base">
<button wire:click="$set('showCreateModal', false)" class="text-base/60 hover:text-base">
<x-ri-close-line class="size-5" />
</button>
</div>
@@ -287,7 +285,7 @@
<label class="text-sm font-semibold">Subdomain Name</label>
<button type="button"
wire:click="generateRandomSubdomain"
class="inline-flex items-center gap-1 text-xs font-semibold text-gray-600 dark:text-gray-400 hover:text-base transition-colors">
class="inline-flex items-center gap-1 text-xs font-semibold text-base/70 hover:text-base transition-colors">
<i class="ri-dice-line text-base"></i>
Random
</button>
@@ -295,7 +293,7 @@
<input type="text" wire:model.live="newSubdomain"
class="bg-background border border-neutral rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-secondary"
placeholder="myserver">
<p class="text-xs text-gray-500 dark:text-gray-400">Will create: <span class="font-semibold">{{ $newSubdomain ? $newSubdomain . '.dns.virtnet.host' : 'subdomain.dns.virtnet.host' }}</span></p>
<p class="text-xs text-base/60">Will create: <span class="font-semibold">{{ $newSubdomain ? $newSubdomain . '.dns.virtnet.host' : 'subdomain.dns.virtnet.host' }}</span></p>
@error('newSubdomain')
<p class="text-xs text-error">{{ $message }}</p>
@enderror
@@ -316,11 +314,12 @@
</div>
<div class="flex gap-2 justify-end">
<x-proxmox::ui.button wire:click="$set('showCreateModal', false)" variant="secondary">Cancel</x-proxmox::ui.button>
<x-proxmox::ui.button wire:click="createSubdomain" wire:loading.attr="disabled" variant="primary">
<x-button.secondary wire:click="$set('showCreateModal', false)">Cancel</x-button.secondary>
<x-button.primary wire:click="createSubdomain" wire:loading.attr="disabled">
<x-loading target="createSubdomain" />
<span wire:loading.remove wire:target="createSubdomain">Create</span>
<span wire:loading wire:target="createSubdomain">Creating...</span>
</x-proxmox::ui.button>
</x-button.primary>
</div>
</div>
</div>
@@ -333,13 +332,13 @@
<div class="bg-background border border-neutral rounded-lg p-6 max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto" wire:click.stop>
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold">DNS Records for {{ $selectedZone }}.dns.virtnet.host</h3>
<button wire:click="$set('showRecordModal', false)" class="text-gray-500 dark:text-gray-400 hover:text-base">
<button wire:click="$set('showRecordModal', false)" class="text-base/60 hover:text-base">
<x-ri-close-line class="size-5" />
</button>
</div>
<!-- Add Record Form -->
<div class="bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 rounded-2xl shadow-theme-sm p-4 mb-4">
<div class="bg-background-secondary border border-neutral rounded-lg p-4 mb-4">
<h4 class="text-md font-semibold mb-3">Add DNS Record</h4>
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
<div class="flex flex-col gap-2">
@@ -381,11 +380,11 @@
</div>
</div>
<div class="mt-3">
<x-proxmox::ui.button wire:click="addRecord" wire:loading.attr="disabled" size="sm" variant="primary">
<x-button.primary wire:click="addRecord" wire:loading.attr="disabled" size="sm">
<x-loading target="addRecord" />
<span wire:loading.remove wire:target="addRecord">Add Record</span>
<span wire:loading wire:target="addRecord">Adding...</span>
</x-proxmox::ui.button>
</x-button.primary>
</div>
</div>
@@ -393,7 +392,7 @@
<div wire:key="zone-records-{{ $selectedZone }}">
<h4 class="text-md font-semibold mb-3">Existing Records</h4>
@if(empty($zoneRecords) || count($zoneRecords) === 0)
<p class="text-sm text-gray-500 dark:text-gray-400">No DNS records found.</p>
<p class="text-sm text-base/60">No DNS records found.</p>
@else
<div class="overflow-x-auto">
<table class="w-full">
@@ -408,16 +407,16 @@
</thead>
<tbody>
@foreach($zoneRecords as $index => $record)
<tr class="border-b border-gray-200 dark:border-gray-800" wire:key="record-{{ $selectedZone }}-{{ $index }}">
<tr class="border-b border-neutral/40" wire:key="record-{{ $selectedZone }}-{{ $index }}">
<td class="py-2 px-3 text-sm">{{ $record['name'] ?? '@' }}</td>
<td class="py-2 px-3 text-sm">{{ $record['type'] ?? 'A' }}</td>
<td class="py-2 px-3 text-sm">{{ $record['rdata'] ?? $record['ipAddress'] ?? '' }}</td>
<td class="py-2 px-3 text-sm">{{ $record['ttl'] ?? 3600 }}</td>
<td class="py-2 px-3 text-sm text-right">
<x-proxmox::ui.button wire:click="deleteRecord('{{ $record['name'] ?? '@' }}', '{{ $record['type'] ?? 'A' }}')"
wire:confirm="Are you sure you want to delete this record?" size="sm" variant="danger">
<x-button.danger wire:click="deleteRecord('{{ $record['name'] ?? '@' }}', '{{ $record['type'] ?? 'A' }}')"
wire:confirm="Are you sure you want to delete this record?" size="sm">
<x-ri-delete-bin-line class="size-4" />
</x-proxmox::ui.button>
</x-button.danger>
</td>
</tr>
@endforeach
@@ -436,24 +435,24 @@
<div class="bg-background border border-neutral rounded-lg p-6 max-w-md w-full mx-4" wire:click.stop>
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold">Delete Subdomain</h3>
<button wire:click="closeDeleteModal" class="text-gray-500 dark:text-gray-400 hover:text-base">
<button wire:click="closeDeleteModal" class="text-base/60 hover:text-base">
<x-ri-close-line class="size-5" />
</button>
</div>
<div class="mb-6">
<p class="text-sm text-gray-500 dark:text-gray-400 mb-2">Are you sure you want to delete the following subdomain?</p>
<p class="text-sm text-base/60 mb-2">Are you sure you want to delete the following subdomain?</p>
<p class="text-md font-semibold">{{ $subdomainToDeleteFull }}</p>
<p class="text-xs text-gray-500 dark:text-gray-400 mt-2">This action cannot be undone. All DNS records associated with this subdomain will be deleted.</p>
<p class="text-xs text-base/60 mt-2">This action cannot be undone. All DNS records associated with this subdomain will be deleted.</p>
</div>
<div class="flex gap-2 justify-end">
<x-proxmox::ui.button wire:click="closeDeleteModal" variant="secondary">Cancel</x-proxmox::ui.button>
<x-proxmox::ui.button wire:click="deleteSubdomain" wire:loading.attr="disabled" variant="danger">
<x-button.secondary wire:click="closeDeleteModal">Cancel</x-button.secondary>
<x-button.danger wire:click="deleteSubdomain" wire:loading.attr="disabled">
<x-loading target="deleteSubdomain" />
<span wire:loading.remove wire:target="deleteSubdomain">Delete</span>
<span wire:loading wire:target="deleteSubdomain">Deleting...</span>
</x-proxmox::ui.button>
</x-button.danger>
</div>
</div>
</div>