[STYLE] 優化機台列表頁面 UI 佈局與組件格式

1. 調整機台列表 (admin/machines/index) 的 Offcanvas 佈局與邊距設定。
2. 統一 x-status-badge 與 x-confirm-modal 組件的撰寫格式,提升程式碼可讀性。
3. 優化深色模式下的邊框與陰影視覺效果。
This commit is contained in:
sky121113 2026-05-14 15:02:47 +08:00
parent 11671f3a2b
commit 61b5e422ee

View File

@ -197,10 +197,7 @@
fetchPage(url.pathname + url.search);
}">
{{-- Page Header --}}
<x-page-header
:title="__('Machine List')"
:subtitle="__('Manage your machine fleet and operational data')"
/>
<x-page-header :title="__('Machine List')" :subtitle="__('Manage your machine fleet and operational data')" />
<!-- Main Card (Machine List) -->
<div class="luxury-card rounded-3xl p-8 animate-luxury-in relative overflow-hidden">
@ -211,11 +208,8 @@
:class="{ 'opacity-30 pointer-events-none transition-opacity duration-300': isLoadingTable }">
{{-- Filters --}}
<x-search-bar
:action="route('admin.machines.index')"
:value="request('search')"
:placeholder="__('Search machines...')"
>
<x-search-bar :action="route('admin.machines.index')" :value="request('search')"
:placeholder="__('Search machines...')">
<input type="hidden" name="tab" value="list">
</x-search-bar>
@ -252,7 +246,8 @@
</thead>
<tbody class="divide-y divide-slate-50 dark:divide-slate-800/80">
@foreach ($machines as $machine)
<tr class="group hover:bg-slate-50/50 dark:hover:bg-white/[0.02] transition-colors duration-200">
<tr
class="group hover:bg-slate-50/50 dark:hover:bg-white/[0.02] transition-colors duration-200">
<td class="px-6 py-6 cursor-pointer group"
@click="openLogPanel('{{ $machine->id }}', '{{ $machine->serial_no }}', '{{ addslashes($machine->name) }}')">
<div class="flex items-center gap-3">
@ -333,20 +328,17 @@
<div class="flex items-center justify-center gap-4">
<div class="flex items-center gap-1.5">
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500/50"></span>
<span
class="text-xs font-black text-slate-400 uppercase tracking-widest">{{
<span class="text-xs font-black text-slate-400 uppercase tracking-widest">{{
__('Normal') }}</span>
</div>
<div class="flex items-center gap-1.5">
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500/50"></span>
<span
class="text-xs font-black text-slate-400 uppercase tracking-widest">{{
<span class="text-xs font-black text-slate-400 uppercase tracking-widest">{{
__('Normal') }}</span>
</div>
<div class="flex items-center gap-1.5">
<span class="w-1.5 h-1.5 rounded-full bg-emerald-500/50"></span>
<span
class="text-xs font-black text-slate-400 uppercase tracking-widest">{{
<span class="text-xs font-black text-slate-400 uppercase tracking-widest">{{
__('Normal') }}</span>
</div>
</div>
@ -354,7 +346,8 @@
<td class="px-6 py-6 font-bold text-slate-600 dark:text-slate-400 text-center">
{{ $machine->current_page_label ?: '-' }}
</td>
<td class="px-6 py-6 font-mono text-xs font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest text-center">
<td
class="px-6 py-6 font-mono text-xs font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest text-center">
{{ $machine->firmware_version ?: '-' }}
</td>
<td
@ -469,13 +462,13 @@
$machine->current_page_label ?: '-' }}</p>
</div>
<div>
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-1">
<p
class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest mb-1">
{{ __('Status') }}
</p>
<x-status-badge
:status="$cStatus === 'online' ? 'online' : ($cStatus === 'error' ? 'error' : 'offline')"
size="sm"
/>
size="sm" />
</div>
<div class="col-span-2">
<p
@ -542,7 +535,8 @@
x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full"
class="w-screen max-w-4xl">
<div class="h-full flex flex-col bg-white dark:bg-slate-900 shadow-2xl border-l border-slate-200 dark:border-slate-800 rounded-l-[32px] overflow-hidden">
<div
class="h-full flex flex-col bg-white dark:bg-slate-900 shadow-2xl border-l border-slate-200 dark:border-slate-800 rounded-l-[32px] overflow-hidden">
<!-- Header -->
<div
class="px-5 py-6 sm:px-8 border-b border-slate-200 dark:border-slate-800 bg-slate-50/50 dark:bg-slate-900/50">
@ -636,8 +630,10 @@
<div class="flex flex-wrap items-center justify-start sm:justify-end gap-4 sm:gap-6">
<button @click="confirmResolve()"
class="text-[12px] font-bold text-rose-500 dark:text-rose-400 uppercase tracking-widest hover:text-rose-600 transition-colors flex items-center gap-1.5 px-3 py-1.5 rounded-xl hover:bg-rose-500/5 transition-all">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"
stroke-width="2.5">
<path stroke-linecap="round" stroke-linejoin="round"
d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
</svg>
{{ __('Clear Abnormal Status') }}
</button>
@ -826,37 +822,48 @@
<!-- Fixed Pagination Footer -->
<div x-show="logs.length > 0 && activeTab !== 'expiry'"
class="mt-auto border-t border-slate-100 dark:border-slate-800/80 px-6 py-4 flex items-center justify-between bg-slate-50/30 dark:bg-slate-900/30 backdrop-blur-sm rounded-bl-[32px]">
class="mt-auto border-t border-slate-100 dark:border-slate-800/80 px-6 py-4 flex items-center justify-between bg-slate-50/30 dark:bg-slate-900/30 backdrop-blur-sm rounded-bl-[32px]">
<div class="flex items-center gap-4">
<button @click="fetchLogs(currentPage - 1)"
:disabled="currentPage <= 1"
class="h-9 px-4 rounded-xl text-[11px] font-black uppercase tracking-widest transition-all shadow-sm border border-slate-200 dark:border-slate-700 disabled:opacity-30 disabled:cursor-not-allowed hover:bg-white dark:hover:bg-slate-800 flex items-center gap-2 text-slate-600 dark:text-slate-300">
<svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M15 19l-7-7 7-7"/></svg>
<button @click="fetchLogs(currentPage - 1)" :disabled="currentPage <= 1"
class="h-9 px-4 rounded-xl text-[11px] font-black uppercase tracking-widest transition-all shadow-sm border border-slate-200 dark:border-slate-700 disabled:opacity-30 disabled:cursor-not-allowed hover:bg-white dark:hover:bg-slate-800 flex items-center gap-2 text-slate-600 dark:text-slate-300">
<svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3"
d="M15 19l-7-7 7-7" />
</svg>
{{ __('Previous') }}
</button>
<div class="relative group">
<select @change="fetchLogs(parseInt($event.target.value))"
class="h-9 pl-4 pr-10 rounded-xl bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 text-[11px] font-black text-slate-600 dark:text-slate-300 appearance-none focus:ring-4 focus:ring-cyan-500/10 focus:border-cyan-500 outline-none transition-all cursor-pointer shadow-sm hover:border-slate-300 dark:hover:border-slate-600 !bg-none">
class="h-9 pl-4 pr-10 rounded-xl bg-white dark:bg-slate-900 border border-slate-200 dark:border-slate-700 text-[11px] font-black text-slate-600 dark:text-slate-300 appearance-none focus:ring-4 focus:ring-cyan-500/10 focus:border-cyan-500 outline-none transition-all cursor-pointer shadow-sm hover:border-slate-300 dark:hover:border-slate-600 !bg-none">
<template x-for="p in Array.from({length: lastPage}, (_, i) => i + 1)">
<option :value="p" :selected="p === currentPage" x-text="p + ' / ' + lastPage"></option>
<option :value="p" :selected="p === currentPage"
x-text="p + ' / ' + lastPage"></option>
</template>
</select>
<div class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none text-cyan-500/50 group-hover:text-cyan-500 transition-colors">
<svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M19 9l-7 7-7-7"/></svg>
<div
class="absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none text-cyan-500/50 group-hover:text-cyan-500 transition-colors">
<svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3"
d="M19 9l-7 7-7-7" />
</svg>
</div>
</div>
<button @click="fetchLogs(currentPage + 1)"
:disabled="currentPage >= lastPage"
class="h-9 px-4 rounded-xl text-[11px] font-black uppercase tracking-widest transition-all shadow-sm border border-slate-200 dark:border-slate-700 disabled:opacity-30 disabled:cursor-not-allowed hover:bg-white dark:hover:bg-slate-800 flex items-center gap-2 text-slate-600 dark:text-slate-300">
<button @click="fetchLogs(currentPage + 1)" :disabled="currentPage >= lastPage"
class="h-9 px-4 rounded-xl text-[11px] font-black uppercase tracking-widest transition-all shadow-sm border border-slate-200 dark:border-slate-700 disabled:opacity-30 disabled:cursor-not-allowed hover:bg-white dark:hover:bg-slate-800 flex items-center gap-2 text-slate-600 dark:text-slate-300">
{{ __('Next') }}
<svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M9 5l7 7-7 7"/></svg>
<svg class="size-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3"
d="M9 5l7 7-7 7" />
</svg>
</button>
</div>
<div class="text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-[0.1em]">
<span class="text-slate-600 dark:text-slate-300" x-text="totalLogs"></span> {{ __('items') }}
<div
class="text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-[0.1em]">
<span class="text-slate-600 dark:text-slate-300" x-text="totalLogs"></span> {{
__('items') }}
</div>
</div>
</div><!-- /Body -->
@ -947,7 +954,8 @@
x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full"
class="w-screen max-w-4xl">
<div class="h-full flex flex-col bg-white dark:bg-slate-900 shadow-2xl border-l border-slate-200 dark:border-slate-800 rounded-l-[32px] overflow-hidden">
<div
class="h-full flex flex-col bg-white dark:bg-slate-900 shadow-2xl border-l border-slate-200 dark:border-slate-800 rounded-l-[32px] overflow-hidden">
<!-- Header -->
<div
class="px-5 py-6 sm:px-8 border-b border-slate-200 dark:border-slate-800 bg-slate-50/50 dark:bg-slate-900/50">
@ -1167,15 +1175,9 @@
</div>
</div><!-- /Inventory Offcanvas -->
<x-confirm-modal
alpineVar="showResolveConfirm"
confirmAction="executeResolve()"
iconType="warning"
<x-confirm-modal alpineVar="showResolveConfirm" confirmAction="executeResolve()" iconType="warning"
title="{{ __('Clear Abnormal Status') }}"
message="{{ __('Are you sure you want to resolve all recent issues for this machine?') }}"
confirmText="{{ __('Confirm') }}"
cancelText="{{ __('Cancel') }}"
confirmColor="rose"
/>
confirmText="{{ __('Confirm') }}" cancelText="{{ __('Cancel') }}" confirmColor="rose" />
@endsection