[STYLE] 調整商品管理與遠端控制頁面之 UI 佈局與格式

1. 修正商品管理頁面 (Products Index) 中多處語系標籤的換行問題。
2. 調整遠端控制頁面 (Remote Index) 中 Slot No 標籤的顯示格式。
3. 優化 UI 組件的 HTML 縮排與可讀性。
4. 補齊同步商品機制相關之繁體中文翻譯 (Connection error, Failed to send command)。
This commit is contained in:
sky121113 2026-05-14 10:31:46 +08:00
parent 9ff9abef89
commit a9d44de98b
3 changed files with 24 additions and 47 deletions

View File

@ -1954,6 +1954,8 @@
"Uploading...": "上傳中...", "Uploading...": "上傳中...",
"Upload failed, please try again": "上傳失敗,請重試", "Upload failed, please try again": "上傳失敗,請重試",
"Sync to All Machines": "同步到所有機台", "Sync to All Machines": "同步到所有機台",
"Connection error": "連線錯誤",
"Failed to send command": "發送指令失敗",
"Sync Products": "同步商品資料", "Sync Products": "同步商品資料",
"Reason for this sync...": "此次同步的原因...", "Reason for this sync...": "此次同步的原因...",
"Select Target Company": "選擇目標公司", "Select Target Company": "選擇目標公司",

View File

@ -284,22 +284,19 @@ hover:bg-slate-100 dark:hover:bg-white/5 rounded-lg flex items-center justify-be
</template> </template>
<section class="space-y-4 animate-luxury-in" style="animation-delay: 100ms"> <section class="space-y-4 animate-luxury-in" style="animation-delay: 100ms">
<h3 class="text-xs font-black text-cyan-500 uppercase tracking-[0.3em]">{{ __('Identity <h3 class="text-xs font-black text-cyan-500 uppercase tracking-[0.3em]">{{ __('Identity & Codes') }}</h3>
& Codes') }}</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3"> <div class="grid grid-cols-1 sm:grid-cols-2 gap-3">
<div <div
class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80 group hover:border-cyan-500/30 transition-colors"> class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80 group hover:border-cyan-500/30 transition-colors">
<span <span
class="text-xs font-bold text-slate-400 uppercase tracking-widest block mb-1.5">{{ class="text-xs font-bold text-slate-400 uppercase tracking-widest block mb-1.5">{{ __('Barcode') }}</span>
__('Barcode') }}</span>
<div class="text-[15px] font-mono font-bold text-slate-700 dark:text-slate-200" <div class="text-[15px] font-mono font-bold text-slate-700 dark:text-slate-200"
x-text="selectedProduct?.barcode || '-'"></div> x-text="selectedProduct?.barcode || '-'"></div>
</div> </div>
<div <div
class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80 group hover:border-cyan-500/30 transition-colors"> class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80 group hover:border-cyan-500/30 transition-colors">
<span <span
class="text-xs font-bold text-slate-400 uppercase tracking-widest block mb-1.5">{{ class="text-xs font-bold text-slate-400 uppercase tracking-widest block mb-1.5">{{ __('Specification') }}</span>
__('Specification') }}</span>
<div class="text-[15px] font-bold text-slate-700 dark:text-slate-200" <div class="text-[15px] font-bold text-slate-700 dark:text-slate-200"
x-text="selectedProduct?.spec || '-'"></div> x-text="selectedProduct?.spec || '-'"></div>
</div> </div>
@ -307,8 +304,7 @@ hover:bg-slate-100 dark:hover:bg-white/5 rounded-lg flex items-center justify-be
<div <div
class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80 group hover:border-cyan-500/30 transition-colors"> class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80 group hover:border-cyan-500/30 transition-colors">
<span <span
class="text-xs font-bold text-slate-400 uppercase tracking-widest block mb-1.5">{{ class="text-xs font-bold text-slate-400 uppercase tracking-widest block mb-1.5">{{ __('Material Code') }}</span>
__('Material Code') }}</span>
<div class="text-[15px] font-mono font-bold text-slate-700 dark:text-slate-200" <div class="text-[15px] font-mono font-bold text-slate-700 dark:text-slate-200"
x-text="selectedProduct?.metadata?.material_code"></div> x-text="selectedProduct?.metadata?.material_code"></div>
</div> </div>
@ -316,8 +312,7 @@ hover:bg-slate-100 dark:hover:bg-white/5 rounded-lg flex items-center justify-be
<div <div
class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80 group hover:border-cyan-500/30 transition-colors"> class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80 group hover:border-cyan-500/30 transition-colors">
<span <span
class="text-xs font-bold text-slate-400 uppercase tracking-widest block mb-1.5">{{ class="text-xs font-bold text-slate-400 uppercase tracking-widest block mb-1.5">{{ __('Manufacturer') }}</span>
__('Manufacturer') }}</span>
<div class="text-[15px] font-bold text-slate-700 dark:text-slate-200" <div class="text-[15px] font-bold text-slate-700 dark:text-slate-200"
x-text="selectedProduct?.manufacturer || '-'"></div> x-text="selectedProduct?.manufacturer || '-'"></div>
</div> </div>
@ -325,8 +320,7 @@ hover:bg-slate-100 dark:hover:bg-white/5 rounded-lg flex items-center justify-be
<div <div
class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80 group hover:border-cyan-500/30 transition-colors"> class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80 group hover:border-cyan-500/30 transition-colors">
<span <span
class="text-xs font-bold text-slate-400 uppercase tracking-widest block mb-1.5">{{ class="text-xs font-bold text-slate-400 uppercase tracking-widest block mb-1.5">{{ __('Company') }}</span>
__('Company') }}</span>
<div class="text-[15px] font-bold text-slate-700 dark:text-slate-200" <div class="text-[15px] font-bold text-slate-700 dark:text-slate-200"
x-text="selectedProduct?.company?.name"></div> x-text="selectedProduct?.company?.name"></div>
</div> </div>
@ -336,8 +330,7 @@ hover:bg-slate-100 dark:hover:bg-white/5 rounded-lg flex items-center justify-be
<!-- Pricing Section --> <!-- Pricing Section -->
<section class="space-y-4 animate-luxury-in" style="animation-delay: 200ms"> <section class="space-y-4 animate-luxury-in" style="animation-delay: 200ms">
<h3 class="text-xs font-black text-emerald-500 uppercase tracking-[0.3em]">{{ <h3 class="text-xs font-black text-emerald-500 uppercase tracking-[0.3em]">{{ __('Pricing Information') }}</h3>
__('Pricing Information') }}</h3>
<div <div
class="luxury-card divide-y divide-slate-50 dark:divide-white/5 overflow-hidden border border-slate-100 dark:border-white/5 shadow-sm"> class="luxury-card divide-y divide-slate-50 dark:divide-white/5 overflow-hidden border border-slate-100 dark:border-white/5 shadow-sm">
<div <div
@ -348,8 +341,7 @@ hover:bg-slate-100 dark:hover:bg-white/5 rounded-lg flex items-center justify-be
</div> </div>
<div <div
class="p-5 flex items-center justify-between group hover:bg-slate-50/50 dark:hover:bg-white/5 transition-colors"> class="p-5 flex items-center justify-between group hover:bg-slate-50/50 dark:hover:bg-white/5 transition-colors">
<span class="text-[15px] font-bold text-slate-500">{{ __('Member Price') <span class="text-[15px] font-bold text-slate-500">{{ __('Member Price') }}</span>
}}</span>
<span class="text-lg font-black text-emerald-500">$<span <span class="text-lg font-black text-emerald-500">$<span
x-text="formatNumber(selectedProduct?.member_price)"></span></span> x-text="formatNumber(selectedProduct?.member_price)"></span></span>
</div> </div>
@ -364,21 +356,18 @@ hover:bg-slate-100 dark:hover:bg-white/5 rounded-lg flex items-center justify-be
<!-- Storage & Limits --> <!-- Storage & Limits -->
<section class="space-y-4 animate-luxury-in" style="animation-delay: 300ms"> <section class="space-y-4 animate-luxury-in" style="animation-delay: 300ms">
<h3 class="text-xs font-black text-indigo-500 uppercase tracking-[0.3em]">{{ __('Channel <h3 class="text-xs font-black text-indigo-500 uppercase tracking-[0.3em]">{{ __('Channel Limits Configuration') }}</h3>
Limits Configuration') }}</h3>
<div <div
class="luxury-card p-6 border border-slate-100 dark:border-white/5 space-y-6 shadow-sm"> class="luxury-card p-6 border border-slate-100 dark:border-white/5 space-y-6 shadow-sm">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="space-y-1"> <div class="space-y-1">
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest">{{ <p class="text-xs font-bold text-slate-400 uppercase tracking-widest">{{ __('Track Limit') }}</p>
__('Track Limit') }}</p>
<p class="text-3xl font-black text-indigo-500 tracking-tighter" <p class="text-3xl font-black text-indigo-500 tracking-tighter"
x-text="selectedProduct?.track_limit || '0'"></p> x-text="selectedProduct?.track_limit || '0'"></p>
</div> </div>
<div class="h-10 w-px bg-slate-100 dark:bg-white/10"></div> <div class="h-10 w-px bg-slate-100 dark:bg-white/10"></div>
<div class="space-y-1 text-right"> <div class="space-y-1 text-right">
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest">{{ <p class="text-xs font-bold text-slate-400 uppercase tracking-widest">{{ __('Spring Limit') }}</p>
__('Spring Limit') }}</p>
<p class="text-3xl font-black text-amber-500 tracking-tighter" <p class="text-3xl font-black text-amber-500 tracking-tighter"
x-text="selectedProduct?.spring_limit || '0'"></p> x-text="selectedProduct?.spring_limit || '0'"></p>
</div> </div>
@ -388,30 +377,26 @@ hover:bg-slate-100 dark:hover:bg-white/5 rounded-lg flex items-center justify-be
<!-- Loyalty Points --> <!-- Loyalty Points -->
<section class="space-y-4 animate-luxury-in" style="animation-delay: 400ms"> <section class="space-y-4 animate-luxury-in" style="animation-delay: 400ms">
<h3 class="text-xs font-black text-rose-500 uppercase tracking-[0.3em]">{{ __('Loyalty & <h3 class="text-xs font-black text-rose-500 uppercase tracking-[0.3em]">{{ __('Loyalty & Features') }}</h3>
Features') }}</h3>
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3"> <div class="grid grid-cols-1 sm:grid-cols-3 gap-3">
<div <div
class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80"> class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80">
<span <span
class="text-xs font-black text-slate-400 uppercase tracking-widest block mb-1">{{ class="text-xs font-black text-slate-400 uppercase tracking-widest block mb-1">{{ __('Full Points') }}</span>
__('Full Points') }}</span>
<div class="text-lg font-black text-rose-500 font-mono" <div class="text-lg font-black text-rose-500 font-mono"
x-text="selectedProduct?.metadata?.points_full || '0'"></div> x-text="selectedProduct?.metadata?.points_full || '0'"></div>
</div> </div>
<div <div
class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80"> class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80">
<span <span
class="text-xs font-black text-slate-400 uppercase tracking-widest block mb-1">{{ class="text-xs font-black text-slate-400 uppercase tracking-widest block mb-1">{{ __('Half Points') }}</span>
__('Half Points') }}</span>
<div class="text-lg font-black text-indigo-500 font-mono" <div class="text-lg font-black text-indigo-500 font-mono"
x-text="selectedProduct?.metadata?.points_half || '0'"></div> x-text="selectedProduct?.metadata?.points_half || '0'"></div>
</div> </div>
<div <div
class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80"> class="bg-slate-50 dark:bg-slate-800/40 p-5 rounded-2xl border border-slate-100 dark:border-slate-800/80">
<span <span
class="text-xs font-black text-slate-400 uppercase tracking-widest block mb-1">{{ class="text-xs font-black text-slate-400 uppercase tracking-widest block mb-1">{{ __('Half Points Amount') }}</span>
__('Half Points Amount') }}</span>
<div class="text-lg font-black text-emerald-500 font-mono" <div class="text-lg font-black text-emerald-500 font-mono"
x-text="selectedProduct?.metadata?.points_half_amount || '0'"></div> x-text="selectedProduct?.metadata?.points_half_amount || '0'"></div>
</div> </div>
@ -424,8 +409,7 @@ hover:bg-slate-100 dark:hover:bg-white/5 rounded-lg flex items-center justify-be
<div <div
class="p-6 border-t border-slate-100 dark:border-slate-800 bg-slate-50/50 dark:bg-slate-900/50"> class="p-6 border-t border-slate-100 dark:border-slate-800 bg-slate-50/50 dark:bg-slate-900/50">
<button @click="isDetailOpen = false" class="w-full btn-luxury-ghost">{{ __('Close Panel') <button @click="isDetailOpen = false" class="w-full btn-luxury-ghost">{{ __('Close Panel') }}</button>
}}</button>
</div> </div>
</div> </div>
</div> </div>
@ -499,8 +483,7 @@ hover:bg-slate-100 dark:hover:bg-white/5 rounded-lg flex items-center justify-be
</svg> </svg>
</div> </div>
<div> <div>
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight uppercase">{{ <h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight uppercase">{{ __('Command Confirmation') }}</h3>
__('Command Confirmation') }}</h3>
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest mt-0.5">{{ __('Please confirm the details below') }}</p> <p class="text-xs font-bold text-slate-400 uppercase tracking-widest mt-0.5">{{ __('Please confirm the details below') }}</p>
</div> </div>
</div> </div>
@ -531,8 +514,7 @@ hover:bg-slate-100 dark:hover:bg-white/5 rounded-lg flex items-center justify-be
<div class="space-y-2 px-1 pt-3 border-t border-slate-200/50 dark:border-slate-800/50"> <div class="space-y-2 px-1 pt-3 border-t border-slate-200/50 dark:border-slate-800/50">
<label <label
class="text-[10px] font-black text-slate-500 dark:text-slate-400 uppercase tracking-[0.2em] ml-1">{{ class="text-[10px] font-black text-slate-500 dark:text-slate-400 uppercase tracking-[0.2em] ml-1">{{ __('Operation Note') }}</label>
__('Operation Note') }}</label>
<textarea x-model="confirmModal.note" <textarea x-model="confirmModal.note"
class="luxury-input w-full min-h-[100px] text-sm py-3 px-4 bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-800 focus:border-cyan-500/50" class="luxury-input w-full min-h-[100px] text-sm py-3 px-4 bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-800 focus:border-cyan-500/50"
placeholder="{{ __('Reason for this sync...') }}"></textarea> placeholder="{{ __('Reason for this sync...') }}"></textarea>

View File

@ -810,9 +810,7 @@
</div> </div>
<div class="space-y-6"> <div class="space-y-6">
<div class="space-y-2"> <div class="space-y-2">
<label class="text-[10px] font-black text-slate-500 dark:text-slate-400 uppercase tracking-[0.2em] ml-1">{{ __('Select Target Slot') }}</label>
class="text-[10px] font-black text-slate-500 dark:text-slate-400 uppercase tracking-[0.2em] ml-1">{{
__('Select Target Slot') }}</label>
<div id="slot-select-wrapper" class="relative min-h-[60px]"> <div id="slot-select-wrapper" class="relative min-h-[60px]">
<!-- Content Injected Dynamically by Alpine.js --> <!-- Content Injected Dynamically by Alpine.js -->
</div> </div>
@ -942,8 +940,7 @@
</svg> </svg>
</div> </div>
<div> <div>
<h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight uppercase">{{ <h3 class="text-xl font-black text-slate-800 dark:text-white tracking-tight uppercase">{{ __('Command Confirmation') }}</h3>
__('Command Confirmation') }}</h3>
<p class="text-xs font-bold text-slate-400 uppercase tracking-widest mt-0.5">{{ __('Please confirm the details below') }}</p> <p class="text-xs font-bold text-slate-400 uppercase tracking-widest mt-0.5">{{ __('Please confirm the details below') }}</p>
</div> </div>
</div> </div>
@ -960,10 +957,7 @@
<span class="text-sm font-black text-slate-800 dark:text-slate-200" <span class="text-sm font-black text-slate-800 dark:text-slate-200"
x-text="selectedMachine ? selectedMachine.name : ''"></span> x-text="selectedMachine ? selectedMachine.name : ''"></span>
</div> </div>
<div class="space-y-2 px-1 pt-3 border-t border-slate-200/50 dark:border-slate-800/50"> class="text-[10px] font-black text-slate-500 dark:text-slate-400 uppercase tracking-[0.2em] ml-1">{{ __('Operation Note') }}</label>
<label
class="text-[10px] font-black text-slate-500 dark:text-slate-400 uppercase tracking-[0.2em] ml-1">{{
__('Operation Note') }}</label>
<textarea x-model="note" <textarea x-model="note"
class="luxury-input w-full min-h-[100px] text-sm py-3 px-4 bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-800 focus:border-cyan-500/50" class="luxury-input w-full min-h-[100px] text-sm py-3 px-4 bg-white dark:bg-slate-900 border-slate-200 dark:border-slate-800 focus:border-cyan-500/50"
placeholder="{{ __('Reason for this command...') }}"></textarea> placeholder="{{ __('Reason for this command...') }}"></textarea>
@ -980,8 +974,7 @@
<template x-if="confirmModal.params.slot_no"> <template x-if="confirmModal.params.slot_no">
<div <div
class="flex justify-between items-center pt-3 border-t border-slate-200/50 dark:border-slate-800/50"> class="flex justify-between items-center pt-3 border-t border-slate-200/50 dark:border-slate-800/50">
<span class="text-[10px] font-black text-violet-500 uppercase tracking-widest">{{ <span class="text-[10px] font-black text-violet-500 uppercase tracking-widest">{{ __('Slot No') }}</span>
__('Slot No') }}</span>
<span class="text-sm font-black text-slate-800 dark:text-slate-200" <span class="text-sm font-black text-slate-800 dark:text-slate-200"
x-text="confirmModal.params.slot_no"></span> x-text="confirmModal.params.slot_no"></span>
</div> </div>