[REFACTOR] 實作側邊欄與儀表板多語系化,修復 UI 位移與樣式優化
All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 52s

This commit is contained in:
2026-03-12 17:42:57 +08:00
parent 8ee14eaa29
commit 773396fc90
43 changed files with 1928 additions and 650 deletions

View File

@@ -139,6 +139,22 @@
@apply translate-y-0 scale-[0.98];
}
.btn-luxury-rose {
@apply inline-flex items-center justify-center gap-x-2 px-4 py-2.5 text-sm font-semibold rounded-xl text-white transition-all duration-300;
background: linear-gradient(135deg, #f43f5e, #e11d48);
box-shadow: 0 4px 12px -2px rgba(225, 29, 72, 0.3), 0 0 0 1px rgba(225, 29, 72, 0.1);
}
.btn-luxury-rose:hover {
@apply -translate-y-0.5;
box-shadow: 0 10px 25px -5px rgba(225, 29, 72, 0.5), 0 0 15px rgba(225, 29, 72, 0.2);
filter: brightness(1.1);
}
.btn-luxury-rose:active {
@apply translate-y-0 scale-[0.97];
}
.btn-luxury-secondary {
@apply inline-flex items-center justify-center gap-x-2 px-3 py-2 text-sm font-semibold rounded-xl transition-all duration-200;
@apply bg-white text-slate-700 border border-slate-200 shadow-sm;

View File

@@ -1,130 +1,226 @@
@extends('layouts.admin')
@section('content')
<div class="space-y-4 sm:space-y-6">
<!-- Grid -->
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-4 sm:gap-6">
<!-- Card -->
<div class="luxury-card rounded-2xl p-5 animate-luxury-in">
<div class="flex items-center gap-x-2">
<p class="text-xs font-semibold uppercase tracking-wider text-slate-400">
總營收 (餘額)
</p>
</div>
<div class="mt-2 flex items-baseline gap-x-2">
<h3 class="text-3xl font-bold text-slate-800 dark:text-white">${{ number_format($totalRevenue, 2) }}</h3>
<span class="text-xs font-medium text-cyan-500 bg-cyan-500/10 px-1.5 py-0.5 rounded">實時</span>
</div>
</div>
<!-- Card -->
<div class="luxury-card rounded-2xl p-5 animate-luxury-in" style="animation-delay: 100ms">
<div class="flex items-center gap-x-2">
<p class="text-xs font-semibold uppercase tracking-wider text-slate-400">
運作中機台
</p>
</div>
<div class="mt-2">
<h3 class="text-3xl font-bold text-slate-800 dark:text-white">{{ $activeMachines }} </h3>
</div>
</div>
<!-- Card -->
<div class="luxury-card rounded-2xl p-5 animate-luxury-in" style="animation-delay: 200ms">
<div class="flex items-center gap-x-2">
<p class="text-xs font-semibold uppercase tracking-wider text-slate-400">
待處理告警
</p>
</div>
<div class="mt-2">
<h3 class="text-3xl font-bold text-rose-500">{{ $alertsPending }} 則訊號</h3>
</div>
</div>
<!-- Card -->
<div class="luxury-card rounded-2xl p-5 animate-luxury-in" style="animation-delay: 300ms">
<div class="flex items-center gap-x-2">
<p class="text-xs font-semibold uppercase tracking-wider text-slate-400">
會員總數
</p>
</div>
<div class="mt-2 flex items-baseline gap-x-2">
<h3 class="text-3xl font-bold text-slate-800 dark:text-white">{{ number_format($memberCount) }}</h3>
<span class="text-xs font-medium text-emerald-500"></span>
</div>
</div>
</div>
<div class="space-y-6">
<!-- Top Section: Connectivity & Transactions -->
<div class="grid lg:grid-cols-2 gap-6 items-stretch">
<!-- Connectivity Card -->
<div class="luxury-card rounded-2xl p-8 animate-luxury-in flex flex-col">
<div class="flex justify-between items-start mb-6">
<div>
<h3 class="text-xl font-extrabold text-slate-800 dark:text-white font-display tracking-tight">{{ __('Connectivity Status') }}</h3>
<p class="text-xs font-bold text-slate-400 dark:text-slate-400 uppercase tracking-widest mt-1">{{ __('Real-time status monitoring') }}</p>
</div>
<div class="flex items-center gap-x-1.5 px-3 py-1 rounded-full bg-cyan-500/10 text-cyan-500 border border-cyan-500/20">
<span class="relative flex h-2 w-2">
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-cyan-400 opacity-75"></span>
<span class="relative inline-flex rounded-full h-2 w-2 bg-cyan-500"></span>
</span>
<span class="text-[10px] font-black uppercase tracking-wider">{{ __('LIVE') }}</span>
</div>
</div>
<div class="flex-1 flex items-center">
<!-- Left: Stats List -->
<div class="flex-1 space-y-6">
<div class="flex items-center justify-between pr-10">
<div class="flex items-center gap-x-4">
<div class="w-2 h-2 rounded-full bg-cyan-500 shadow-[0_0_10px_rgba(6,182,212,0.6)]"></div>
<span class="text-xs font-black text-slate-400 dark:text-slate-400 uppercase tracking-widest">{{ __('Online Machines') }}</span>
</div>
<span class="text-2xl font-black text-slate-900 dark:text-white">{{ $activeMachines }}</span>
</div>
<div class="flex items-center justify-between pr-10">
<div class="flex items-center gap-x-4">
<div class="w-2 h-2 rounded-full bg-rose-500 shadow-[0_0_10px_rgba(244,63,94,0.6)]"></div>
<span class="text-xs font-black text-slate-400 dark:text-slate-400 uppercase tracking-widest">{{ __('Offline Machines') }}</span>
</div>
<span class="text-2xl font-black text-rose-500">{{ $alertsPending }}</span>
</div>
<div class="flex items-center justify-between pr-10">
<div class="flex items-center gap-x-4">
<div class="w-2 h-2 rounded-full bg-amber-500 shadow-[0_0_10px_rgba(245,158,11,0.6)]"></div>
<span class="text-xs font-black text-slate-400 dark:text-slate-400 uppercase tracking-widest">{{ __('Alerts Pending') }}</span>
</div>
<span class="text-2xl font-black text-slate-900 dark:text-white">0</span>
</div>
</div>
<!-- Divider -->
<div class="w-px h-32 bg-slate-100 dark:bg-slate-800 mx-2"></div>
<!-- Right: Big Total -->
<div class="w-40 text-center">
<p class="text-7xl font-black text-cyan-500 drop-shadow-[0_0_20px_rgba(6,182,212,0.3)] leading-none">{{ $activeMachines }}</p>
<p class="text-[10px] font-black text-cyan-500/80 dark:text-cyan-400 uppercase tracking-[0.3em] mt-4">{{ __('Total Connected') }}</p>
</div>
</div>
</div>
<div class="grid lg:grid-cols-3 gap-6">
<!-- Chart Column -->
<div class="lg:col-span-2 luxury-card rounded-3xl p-6 animate-luxury-in" style="animation-delay: 400ms">
<div class="flex justify-between items-center mb-8">
<!-- Transaction Card -->
<div class="luxury-card rounded-2xl p-8 animate-luxury-in flex flex-col" style="animation-delay: 100ms">
<div class="flex justify-between items-start mb-6">
<div>
<h3 class="text-xl font-extrabold text-slate-800 dark:text-white font-display tracking-tight">{{ __('Monthly Transactions') }}</h3>
<p class="text-xs font-bold text-slate-400 dark:text-slate-400 uppercase tracking-widest mt-1">{{ __('Monthly cumulative revenue overview') }}</p>
</div>
<div class="p-2.5 rounded-xl bg-slate-50 dark:bg-slate-800/80 text-slate-400 dark:text-slate-500 border border-transparent dark:border-slate-700/50">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
</div>
</div>
<div class="flex-1 flex flex-col space-y-4 justify-center">
<!-- Today Stat Card -->
<div class="group flex items-center justify-between p-5 rounded-2xl bg-white dark:bg-slate-900 shadow-[0_2px_15px_-3px_rgba(0,0,0,0.07),0_10px_20px_-2px_rgba(0,0,0,0.04)] dark:shadow-none border border-slate-100 dark:border-slate-800 transition-all hover:border-cyan-500/30">
<div class="flex items-center gap-x-4">
<div class="w-12 h-12 rounded-xl bg-cyan-500/10 dark:bg-cyan-500/20 flex items-center justify-center text-cyan-600 dark:text-cyan-400 shadow-sm transition-transform group-hover:scale-110">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18L9 11.25l4.5 4.5L21.75 7.5M21.75 7.5V12m0-4.5H17.25"/></svg>
</div>
<div>
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">{{ __("Today's Transactions") }}</p>
<p class="text-2xl font-black text-slate-900 dark:text-white mt-0.5 tracking-tight">${{ number_format($totalRevenue / 30, 0) }}</p>
</div>
</div>
<div class="flex flex-col items-end gap-y-1">
<span class="text-[10px] font-black text-emerald-500 bg-emerald-500/10 px-2.5 py-0.5 rounded-full">+12.5%</span>
<p class="text-[9px] font-bold text-slate-300 dark:text-slate-500 uppercase tracking-tighter">{{ __('vs Yesterday') }}</p>
</div>
</div>
<!-- Previous Days Stats Row -->
<div class="grid grid-cols-2 gap-4">
<!-- Yesterday Card -->
<div class="group flex flex-col p-5 rounded-2xl bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800 transition-all hover:border-cyan-500/20">
<div class="flex justify-between items-start mb-2">
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">{{ __("Yesterday's Transactions") }}</p>
<div class="w-6 h-6 rounded-lg bg-slate-100 dark:bg-slate-800 flex items-center justify-center text-slate-400">
<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="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
</div>
</div>
<p class="text-xl font-black text-slate-800 dark:text-slate-200">${{ number_format($totalRevenue / 25, 0) }}</p>
</div>
<!-- Before Yesterday Card -->
<div class="group flex flex-col p-5 rounded-2xl bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800 transition-all hover:border-cyan-500/20">
<div class="flex justify-between items-start mb-2">
<p class="text-[10px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">{{ __("Before Yesterday's Transactions") }}</p>
<div class="w-6 h-6 rounded-lg bg-slate-100 dark:bg-slate-800 flex items-center justify-center text-slate-400">
<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="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"/></svg>
</div>
</div>
<p class="text-xl font-black text-slate-800 dark:text-slate-200">${{ number_format($totalRevenue / 40, 0) }}</p>
</div>
</div>
</div>
</div>
</div>
<!-- Bottom Section: Status List -->
<div class="luxury-card rounded-3xl p-8 animate-luxury-in" style="animation-delay: 200ms">
<div class="flex flex-col md:flex-row md:items-center justify-between mb-8 gap-6">
<div>
<h2 class="text-lg font-bold text-slate-800 dark:text-white">營收績效分析</h2>
<p class="text-sm text-slate-400">各地區每日營收洞察</p>
<div class="flex items-center gap-x-3">
<h2 class="text-2xl font-extrabold text-slate-800 dark:text-white font-display tracking-tight">{{ __('Machine Status List') }}</h2>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-lg text-xs font-black bg-slate-100 dark:bg-slate-800 text-slate-500 dark:text-slate-400 border border-slate-200 dark:border-slate-700 uppercase tracking-tighter">
{{ __('Total items', ['count' => count($latestActivities)]) }}
</span>
</div>
<p class="text-sm font-bold text-slate-400 dark:text-slate-400 mt-1 uppercase tracking-widest">{{ __('Real-time monitoring across all machines') }}</p>
</div>
<div x-data="{ open: false, selected: '最近 7 天' }" class="relative inline-block text-left">
<button @click="open = !open" type="button" class="btn-luxury-secondary">
<span x-text="selected"></span>
<svg class="shrink-0 w-4 h-4 transition-transform" :class="open ? 'rotate-180' : ''" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
<div class="flex items-center gap-x-4">
<div class="relative group">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none">
<svg class="h-4 w-4 text-slate-400 group-focus-within:text-cyan-500 transition-colors" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="8"></circle>
<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>
</span>
<input type="text" class="py-3 pl-12 pr-6 block w-64 border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-800 rounded-2xl text-sm font-bold text-slate-700 dark:text-slate-200 placeholder-slate-400 dark:placeholder-slate-500 focus:ring-4 focus:ring-cyan-500/10 focus:border-cyan-500 transition-all outline-none" placeholder="{{ __('Quick search...') }}">
</div>
</div>
</div>
<div class="overflow-x-auto">
<table class="w-full text-left border-separate border-spacing-y-0">
<thead>
<tr class="bg-slate-50/50 dark:bg-slate-900/30">
<th class="px-6 py-4 text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest border-b border-slate-100 dark:border-slate-800">{{ __('Machine Info') }}</th>
<th class="px-6 py-4 text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest border-b border-slate-100 dark:border-slate-800 text-center">{{ __('Running Status') }}</th>
<th class="px-6 py-4 text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest border-b border-slate-100 dark:border-slate-800 text-center">{{ __('Today Cumulative Sales') }}</th>
<th class="px-6 py-4 text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest border-b border-slate-100 dark:border-slate-800 text-center">{{ __('Current Stock') }}</th>
<th class="px-6 py-4 text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest border-b border-slate-100 dark:border-slate-800 text-center">{{ __('Last Communication') }}</th>
<th class="px-6 py-4 text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest border-b border-slate-100 dark:border-slate-800 text-right">{{ __('Alert Summary') }}</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-50 dark:divide-slate-800/50">
@forelse($latestActivities as $activity)
<tr class="group hover:bg-slate-50/80 dark:hover:bg-slate-800/40 transition-all duration-300">
<td class="px-6 py-6">
<div class="flex items-center gap-x-5">
<div class="w-11 h-11 rounded-2xl bg-slate-100 dark:bg-slate-800 flex items-center justify-center text-slate-400 dark:text-slate-300 group-hover:bg-cyan-500 group-hover:text-white transition-all shadow-sm">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z"/></svg>
</div>
<div class="flex flex-col">
<span class="text-base font-extrabold text-slate-800 dark:text-slate-100 group-hover:text-cyan-600 dark:group-hover:text-cyan-400 transition-colors">{{ $activity->machine->name ?? __('Machine Info') }}</span>
<span class="text-[11px] font-bold text-slate-400 dark:text-slate-500 mt-1 uppercase tracking-[0.15em]">(SN: {{ $activity->machine->serial_no ?? 'N/A' }})</span>
</div>
</div>
</td>
<td class="px-6 py-6 text-center">
<span class="inline-flex items-center px-4 py-1.5 rounded-full text-[10px] font-black bg-slate-100 dark:bg-slate-800 text-slate-500 dark:text-slate-300 border border-slate-200 dark:border-slate-700 tracking-widest uppercase">
{{ $activity->machine->status === 'online' ? __('Online') : __('Offline') }}
</span>
</td>
<td class="px-6 py-6 text-center">
<span class="text-xl font-black text-slate-900 dark:text-slate-100">$ 0</span>
</td>
<td class="px-6 py-6">
<div class="flex flex-col items-center gap-y-2.5">
<div class="w-32 h-2 bg-slate-100 dark:bg-slate-800 rounded-full overflow-hidden shadow-inner">
<div class="h-full bg-rose-500 rounded-full shadow-[0_0_8px_rgba(244,63,94,0.4)]" style="width: 15.5%"></div>
</div>
<span class="text-[11px] font-black text-rose-500 uppercase tracking-[0.2em]">15.5% {{ __('Low Stock') }}</span>
</div>
</td>
<td class="px-6 py-6 text-center">
<span class="text-sm text-slate-600 dark:text-slate-200 font-bold font-display tracking-tight bg-slate-50 dark:bg-slate-800 px-3 py-1 rounded-lg">{{ $activity->created_at->format('Y/m/d H:i') }}</span>
</td>
<td class="px-6 py-6 text-right">
<span class="text-[11px] font-bold text-slate-400/30 dark:text-slate-500 uppercase tracking-widest group-hover:text-slate-400 transition-colors">{{ __('No alert summary') }}</span>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="px-6 py-32 text-center text-slate-400">{{ __('No data available') }}</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<!-- Table Footer: Pagination -->
<div class="mt-8 flex items-center justify-between border-t border-slate-100 dark:border-slate-800 pt-6">
<p class="text-[11px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest">
{{ __('Showing :from to :to of :total items', ['from' => 1, 'to' => count($latestActivities), 'total' => count($latestActivities)]) }}
</p>
<div class="flex items-center gap-x-2">
<button class="inline-flex items-center gap-x-2 px-4 py-2 rounded-xl text-xs font-black bg-white dark:bg-slate-900 text-slate-600 dark:text-slate-300 border border-slate-200 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-800 transition-all disabled:opacity-50 disabled:cursor-not-allowed" disabled>
<svg class="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M15 19l-7-7 7-7"/></svg>
<span>{{ __('Previous') }}</span>
</button>
<div x-show="open"
@click.away="open = false"
x-transition:enter="transition ease-out duration-100"
x-transition:enter-start="opacity-0 scale-95"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-95"
class="absolute right-0 mt-2 w-40 z-10 origin-top-right bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl shadow-xl p-1 focus:outline-none"
x-cloak>
<button @click="selected = '最近 7 天'; open = false" class="w-full text-left px-3 py-2 text-sm rounded-lg hover:bg-slate-100 dark:hover:bg-slate-700/50 text-slate-700 dark:text-slate-300 transition-colors">最近 7 </button>
<button @click="selected = '最近 30 天'; open = false" class="w-full text-left px-3 py-2 text-sm rounded-lg hover:bg-slate-100 dark:hover:bg-slate-700/50 text-slate-700 dark:text-slate-300 transition-colors">最近 30 </button>
<button @click="selected = '最近 90 天'; open = false" class="w-full text-left px-3 py-2 text-sm rounded-lg hover:bg-slate-100 dark:hover:bg-slate-700/50 text-slate-700 dark:text-slate-300 transition-colors">最近 90 </button>
<div class="flex items-center gap-x-1">
<button class="w-8 h-8 rounded-lg text-xs font-black bg-cyan-500 text-white shadow-lg shadow-cyan-500/30">1</button>
<button class="w-8 h-8 rounded-lg text-xs font-black text-slate-500 hover:text-cyan-500 transition-colors">2</button>
<button class="w-8 h-8 rounded-lg text-xs font-black text-slate-500 hover:text-cyan-500 transition-colors">3</button>
</div>
</div>
</div>
<div class="h-[300px] relative group overflow-hidden rounded-2xl bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800 flex items-center justify-center transition-all">
<div class="absolute inset-0 bg-gradient-to-br from-cyan-500/5 to-transparent pointer-events-none"></div>
<div class="text-center">
<div class="inline-flex items-center justify-center w-12 h-12 rounded-full bg-white dark:bg-slate-800 shadow-sm border border-slate-200 dark:border-slate-700 mb-4">
<svg class="w-6 h-6 text-cyan-500" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3v18h18"/><path d="m19 9-5 5-4-4-3 3"/></svg>
</div>
<p class="text-sm font-semibold text-slate-600 dark:text-slate-400">營收圖表數據載入中</p>
<p class="text-xs text-slate-400 mt-1">即時數據串流將在此顯示</p>
<button class="inline-flex items-center gap-x-2 px-4 py-2 rounded-xl text-xs font-black bg-white dark:bg-slate-900 text-slate-600 dark:text-slate-300 border border-slate-200 dark:border-slate-700 hover:bg-slate-50 dark:hover:bg-slate-800 transition-all">
<span>{{ __('Next') }}</span>
<svg class="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M9 5l7 7-7 7"/></svg>
</button>
</div>
</div>
</div>
<!-- 即時動態 -->
<div class="luxury-card rounded-3xl p-6 animate-luxury-in" style="animation-delay: 500ms">
<h2 class="text-lg font-bold text-slate-800 dark:text-white mb-6">即時動態</h2>
<div class="space-y-6">
@forelse($latestActivities as $activity)
<div class="relative pl-6 before:absolute before:left-0 before:top-1 before:bottom-0 before:w-0.5 before:bg-slate-100 dark:before:bg-slate-800">
<div class="absolute left-[-4px] top-0 w-2.5 h-2.5 rounded-full {{ $activity->level === 'error' ? 'bg-rose-500' : 'bg-cyan-500' }} border-2 border-white dark:border-[#1e293b]"></div>
<p class="text-sm font-bold text-slate-700 dark:text-slate-200">#{{ $activity->machine->code ?? 'N/A' }} {{ $activity->content }}</p>
<p class="text-xs text-slate-400">{{ $activity->created_at->diffForHumans() }} {{ $activity->machine->location ?? '未知區域' }}</p>
</div>
@empty
<div class="text-center py-10">
<p class="text-sm text-slate-400">目前尚無動態資料</p>
</div>
@endforelse
</div>
<button class="btn-luxury-ghost w-full mt-8 py-3 font-bold uppercase tracking-wider">查看所有日誌 </button>
</div>
</div>
</div>
@endsection
@section('scripts')
<script>
window.addEventListener('load', () => {
// Here you would initialize charts using ApexCharts or similar,
// as Preline examples often use ApexCharts.
// For now, placeholders are sufficient.
});
</script>
@endsection

View File

@@ -39,7 +39,7 @@
x-cloak></div>
<!-- ========== HEADER ========== -->
<header class="sticky top-0 inset-x-0 flex flex-wrap sm:justify-start sm:flex-nowrap z-[48] w-full bg-white/80 backdrop-blur-md border-b border-slate-200/50 text-sm py-2.5 sm:py-4 lg:pl-64 dark:bg-[#0f172a]/80 dark:border-slate-800/50 shadow-sm">
<header class="sticky top-0 inset-x-0 flex flex-wrap sm:justify-start sm:flex-nowrap z-[48] w-full bg-white/80 backdrop-blur-md border-b border-slate-200/50 text-sm py-2.5 sm:py-4 lg:pl-72 dark:bg-[#0f172a]/80 dark:border-slate-800/50 shadow-sm">
<nav class="flex basis-full items-center w-full mx-auto px-4 sm:px-6 md:px-8" aria-label="Global">
<div class="mr-5 lg:mr-0 lg:hidden text-center">
<a class="flex-none text-xl font-bold dark:text-white font-display tracking-tight" href="{{ route('admin.dashboard') }}" aria-label="Brand">
@@ -47,7 +47,8 @@
</a>
</div>
<div class="w-full flex items-center justify-end ml-auto sm:justify-between sm:gap-x-3 sm:order-3">
<div class="w-full flex items-center justify-end ml-auto sm:gap-x-3 sm:order-3">
<!-- Mobile Search Toggle -->
<div class="sm:hidden">
<button type="button" class="inline-flex flex-shrink-0 justify-center items-center gap-2 h-[2.375rem] w-[2.375rem] rounded-full font-medium bg-white text-gray-700 align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition-all text-xs dark:bg-gray-800 dark:hover:bg-slate-800 dark:text-gray-400 dark:hover:text-white dark:focus:ring-gray-700 dark:focus:ring-offset-gray-800">
<svg class="w-3.5 h-3.5" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
@@ -56,20 +57,70 @@
</button>
</div>
<div class="hidden sm:block">
<!-- Desktop Search Placeholder -->
<div class="hidden sm:block flex-1 max-w-sm">
<!-- Search Input (Optional) -->
</div>
<div class="flex flex-row items-center justify-end gap-2">
<div class="flex flex-row items-center justify-end gap-x-1.5 sm:gap-x-3">
<!-- Language Switcher -->
<div class="relative inline-flex" x-data="{ langOpen: false }">
<button type="button" @click="langOpen = !langOpen" @click.away="langOpen = false" class="inline-flex flex-shrink-0 justify-center items-center gap-2 h-[2.375rem] px-3 rounded-full font-medium bg-white text-gray-700 align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition-all text-xs dark:bg-gray-800 dark:hover:bg-slate-800 dark:text-gray-400 dark:hover:text-white dark:focus:ring-gray-700 dark:focus:ring-offset-gray-800">
<span class="flex items-center gap-x-2">
@if(app()->getLocale() == 'zh_TW')
<span class="text-base">🇹🇼</span>
<span class="hidden md:inline font-bold">繁體中文</span>
@elseif(app()->getLocale() == 'ja')
<span class="text-base">🇯🇵</span>
<span class="hidden md:inline font-bold">日本語</span>
@else
<span class="text-base">🇬🇧</span>
<span class="hidden md:inline font-bold">English</span>
@endif
</span>
<svg class="size-3 text-gray-400" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="langOpen"
x-transition:enter="transition ease-out duration-100"
x-transition:enter-start="transform opacity-0 scale-95"
x-transition:enter-end="transform opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95"
class="absolute right-0 top-full mt-2 min-w-[10rem] bg-white shadow-xl rounded-2xl p-2 dark:bg-gray-800 dark:border dark:border-gray-700 z-50 border border-slate-100"
x-cloak>
<a href="{{ route('lang.switch', 'zh_TW') }}" class="flex items-center gap-x-3 py-2.5 px-3 rounded-xl text-sm text-gray-800 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 transition-colors {{ app()->getLocale() == 'zh_TW' ? 'bg-gray-50 dark:bg-gray-900/50' : '' }}">
<span class="text-lg">🇹🇼</span>
<span class="font-bold">繁體中文</span>
@if(app()->getLocale() == 'zh_TW')
<svg class="ml-auto size-4 text-cyan-500" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
@endif
</a>
<a href="{{ route('lang.switch', 'en') }}" class="flex items-center gap-x-3 py-2.5 px-3 rounded-xl text-sm text-gray-800 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 transition-colors {{ app()->getLocale() == 'en' ? 'bg-gray-50 dark:bg-gray-900/50' : '' }}">
<span class="text-lg">🇬🇧</span>
<span class="font-bold">English</span>
@if(app()->getLocale() == 'en')
<svg class="ml-auto size-4 text-cyan-500" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
@endif
</a>
<a href="{{ route('lang.switch', 'ja') }}" class="flex items-center gap-x-3 py-2.5 px-3 rounded-xl text-sm text-gray-800 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 transition-colors {{ app()->getLocale() == 'ja' ? 'bg-gray-50 dark:bg-gray-900/50' : '' }}">
<span class="text-lg">🇯🇵</span>
<span class="font-bold">日本語</span>
@if(app()->getLocale() == 'ja')
<svg class="ml-auto size-4 text-cyan-500" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
@endif
</a>
</div>
</div>
<!-- Dark Mode Toggle -->
<button type="button"
@click="darkMode = !darkMode; localStorage.setItem('darkMode', darkMode); document.documentElement.classList.toggle('dark', darkMode)"
class="inline-flex flex-shrink-0 justify-center items-center gap-2 h-[2.375rem] w-[2.375rem] rounded-full font-medium bg-white text-gray-700 align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition-all text-xs dark:bg-gray-800 dark:hover:bg-slate-800 dark:text-gray-400 dark:hover:text-white dark:focus:ring-gray-700 dark:focus:ring-offset-gray-800">
<!-- Moon Icon (shown in light mode) -->
<svg x-show="!darkMode" class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278zM4.858 1.311A7.269 7.269 0 0 0 1.025 7.71c0 4.02 3.279 7.276 7.319 7.276a7.316 7.316 0 0 0 5.205-2.162c-.337.042-.68.063-1.029.063-4.61 0-8.343-3.714-8.343-8.29 0-1.167.242-2.278.681-3.286z"/>
</svg>
<!-- Sun Icon (shown in dark mode) -->
<svg x-show="darkMode" class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"/>
</svg>
@@ -77,7 +128,7 @@
<!-- Profile Dropdown -->
<div class="relative inline-flex" x-data="{ open: false }">
<button id="hs-dropdown-with-header" type="button" @click="open = !open" @click.away="open = false" class="inline-flex flex-shrink-0 justify-center items-center gap-2 h-[2.375rem] w-[2.375rem] rounded-full font-medium bg-white text-gray-700 align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition-all text-xs dark:bg-gray-800 dark:hover:bg-slate-800 dark:text-gray-400 dark:hover:text-white dark:focus:ring-gray-700 dark:focus:ring-offset-gray-800">
<button type="button" @click="open = !open" @click.away="open = false" class="inline-flex flex-shrink-0 justify-center items-center gap-2 h-[2.375rem] w-[2.375rem] rounded-full font-medium bg-white text-gray-700 align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition-all text-xs dark:bg-gray-800 dark:hover:bg-slate-800 dark:text-gray-400 dark:hover:text-white dark:focus:ring-gray-700 dark:focus:ring-offset-gray-800">
<img class="inline-block h-[2.375rem] w-[2.375rem] rounded-full ring-2 ring-white dark:ring-gray-800" src="https://ui-avatars.com/api/?name={{ Auth::user()->name }}&background=0D8ABC&color=fff" alt="Image Description">
</button>
@@ -88,22 +139,23 @@
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95"
class="absolute right-0 top-full mt-2 min-w-[15rem] bg-white shadow-md rounded-lg p-2 dark:bg-gray-800 dark:border dark:border-gray-700 z-50"
class="absolute right-0 top-full mt-2 min-w-[15rem] bg-white shadow-xl rounded-2xl p-2 dark:bg-gray-800 dark:border dark:border-gray-700 z-50 border border-slate-100"
x-cloak>
<div class="py-3 px-5 -m-2 bg-gray-100 rounded-t-lg dark:bg-gray-700">
<p class="text-sm text-gray-500 dark:text-gray-400">Signed in as</p>
<p class="text-sm font-medium text-gray-800 dark:text-gray-300">{{ Auth::user()->email }}</p>
<div class="py-3 px-5 -m-2 bg-slate-50 rounded-t-2xl dark:bg-slate-900/50 border-b border-slate-100 dark:border-slate-700">
<p class="text-[10px] font-black uppercase tracking-widest text-slate-400 dark:text-slate-500">Signed in as</p>
<p class="text-sm font-bold text-slate-700 dark:text-slate-200 truncate">{{ Auth::user()->email }}</p>
</div>
<div class="mt-2 py-2 first:pt-0 last:pb-0">
<a class="flex items-center gap-x-3.5 py-2 px-3 rounded-md text-sm text-gray-800 hover:bg-gray-100 focus:ring-2 focus:ring-blue-500 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300 transition-colors" href="{{ route('profile.edit') }}">
<svg class="flex-shrink-0 w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
帳戶設定
<div class="mt-2 py-2">
<a class="flex items-center gap-x-3.5 py-2.5 px-3 rounded-xl text-sm font-bold text-slate-700 hover:bg-gray-100 focus:ring-2 focus:ring-blue-500 dark:text-slate-300 dark:hover:bg-gray-700 dark:hover:text-white transition-colors" href="{{ route('profile.edit') }}">
<svg class="flex-shrink-0 size-4 text-cyan-500" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
{{ __('Account Settings') }}
</a>
<div class="my-2 border-t border-slate-100 dark:border-slate-700"></div>
<form method="POST" action="{{ route('logout') }}">
@csrf
<button type="submit" class="w-full flex items-center gap-x-3.5 py-2 px-3 rounded-md text-sm text-gray-800 hover:bg-gray-100 focus:ring-2 focus:ring-blue-500 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300">
<svg class="flex-shrink-0 w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/></svg>
登出
<button type="submit" class="w-full flex items-center gap-x-3.5 py-2.5 px-3 rounded-xl text-sm font-bold text-rose-500 hover:bg-rose-50 dark:hover:bg-rose-500/10 transition-colors">
<svg class="flex-shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/></svg>
{{ __('Logout') }}
</button>
</form>
</div>

View File

@@ -2,7 +2,7 @@
<li>
<a class="luxury-nav-item {{ request()->routeIs('admin.dashboard') ? 'active' : '' }}" href="{{ route('admin.dashboard') }}">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.dashboard') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="7" height="9" x="3" y="3" rx="1"/><rect width="7" height="5" x="14" y="3" rx="1"/><rect width="7" height="9" x="14" y="12" rx="1"/><rect width="7" height="5" x="3" y="16" rx="1"/></svg>
儀表板
{{ __('Dashboard') }}
</a>
</li>
@@ -11,14 +11,14 @@
<button type="button" @click="open = !open; localStorage.setItem('menu_profile', open)"
class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('profile.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
個人設定
{{ __('Profile Settings') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li>
<a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('profile.edit') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('profile.edit') }}">
個人檔案
{{ __('Profile') }}
</a>
</li>
</ul>
@@ -29,16 +29,16 @@
<li x-data="{ open: localStorage.getItem('menu_members') === 'true' || {{ request()->routeIs('admin.members.*') || request()->routeIs('admin.membership-tiers.*') || request()->routeIs('admin.deposit-bonus-rules.*') || request()->routeIs('admin.point-rules.*') || request()->routeIs('admin.gift-definitions.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_members', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.members.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" /></svg>
會員管理
{{ __('Member Management') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.members.index') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.members.index') }}">會員列表</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.membership-tiers.*') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.membership-tiers.index') }}">會員等級</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.deposit-bonus-rules.*') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.deposit-bonus-rules.index') }}">儲值回饋</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.point-rules.*') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.point-rules.index') }}">點數規則</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.gift-definitions.*') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.gift-definitions.index') }}">禮品設定</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.members.index') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.members.index') }}">{{ __('Member List') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.membership-tiers.*') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.membership-tiers.index') }}">{{ __('Membership Tiers') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.deposit-bonus-rules.*') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.deposit-bonus-rules.index') }}">{{ __('Deposit Bonus') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.point-rules.*') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.point-rules.index') }}">{{ __('Point Rules') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.gift-definitions.*') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.gift-definitions.index') }}">{{ __('Gift Definitions') }}</a></li>
</ul>
</div>
</li>
@@ -47,17 +47,17 @@
<li x-data="{ open: localStorage.getItem('menu_machines') === 'true' || {{ request()->routeIs('admin.machines.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_machines', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.machines.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 01-2 2v4a2 2 0 012 2h14a2 2 0 012-2v-4a2 2 0 01-2-2m-2-4h.01M17 16h.01" /></svg>
機台管理
{{ __('Machine Management') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.logs') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.logs') }}">機台日誌</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.index') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.index') }}">機台列表</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.permissions') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.permissions') }}">機台權限</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.utilization') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.utilization') }}">機台稼動率</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.expiry') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.expiry') }}">效期管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.maintenance') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.maintenance') }}">維修管理單</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.logs') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.logs') }}">{{ __('Machine Logs') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.index') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.index') }}">{{ __('Machine List') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.permissions') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.permissions') }}">{{ __('Machine Permissions') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.utilization') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.utilization') }}">{{ __('Utilization Rate') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.expiry') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.expiry') }}">{{ __('Expiry Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.machines.maintenance') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.machines.maintenance') }}">{{ __('Maintenance Records') }}</a></li>
</ul>
</div>
</li>
@@ -66,16 +66,16 @@
<li x-data="{ open: localStorage.getItem('menu_app') === 'true' || {{ request()->routeIs('admin.app.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_app', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.app.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z" /></svg>
APP管理
{{ __('APP Management') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.app.ui-elements') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.app.ui-elements') }}">UI元素</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.app.helper') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.app.helper') }}">小幫手</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.app.questionnaire') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.app.questionnaire') }}">問卷</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.app.games') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.app.games') }}">互動遊戲</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.app.timer') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.app.timer') }}">計時器</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.app.ui-elements') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.app.ui-elements') }}">{{ __('UI Elements') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.app.helper') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.app.helper') }}">{{ __('Helper') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.app.questionnaire') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.app.questionnaire') }}">{{ __('Questionnaire') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.app.games') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.app.games') }}">{{ __('Games') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.app.timer') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.app.timer') }}">{{ __('Timer') }}</a></li>
</ul>
</div>
</li>
@@ -97,8 +97,8 @@
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.warehouses.replenishments') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.warehouses.replenishments') }}">機台補貨單</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.warehouses.replenishment-records') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.warehouses.replenishment-records') }}">機台補貨紀錄</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.warehouses.machine-stock') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.warehouses.machine-stock') }}">機台庫存</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.warehouses.staff-stock') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.warehouses.staff-stock') }}">人員庫存</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.warehouses.returns') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.warehouses.returns') }}">回庫單</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.warehouses.staff-stock') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.warehouses.staff-stock') }}">{{ __('Staff Stock') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.warehouses.returns') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.warehouses.returns') }}">{{ __('Returns') }}</a></li>
</ul>
</div>
</li>
@@ -107,17 +107,17 @@
<li x-data="{ open: localStorage.getItem('menu_sales') === 'true' || {{ request()->routeIs('admin.sales.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_sales', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.sales.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
銷售管理
{{ __('Sales Management') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.index') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.index') }}">銷售紀錄</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.pickup-codes') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.pickup-codes') }}">取貨碼</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.orders') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.orders') }}">購買單</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.promotions') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.promotions') }}">促銷時段</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.pass-codes') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.pass-codes') }}">通行碼</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.store-gifts') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.store-gifts') }}">來店禮</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.index') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.index') }}">{{ __('Sales Records') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.pickup-codes') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.pickup-codes') }}">{{ __('Pickup Codes') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.orders') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.orders') }}">{{ __('Orders') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.promotions') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.promotions') }}">{{ __('Promotions') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.pass-codes') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.pass-codes') }}">{{ __('Pass Codes') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.sales.store-gifts') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.sales.store-gifts') }}">{{ __('Store Gifts') }}</a></li>
</ul>
</div>
</li>
@@ -126,15 +126,15 @@
<li x-data="{ open: localStorage.getItem('menu_analysis') === 'true' || {{ request()->routeIs('admin.analysis.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_analysis', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.analysis.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z" /></svg>
分析管理
{{ __('Analysis Management') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.analysis.change-stock') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.analysis.change-stock') }}">零錢庫存</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.analysis.machine-reports') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.analysis.machine-reports') }}">機台報表</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.analysis.product-reports') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.analysis.product-reports') }}">商品報表</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.analysis.survey-analysis') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.analysis.survey-analysis') }}">問卷分析</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.analysis.change-stock') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.analysis.change-stock') }}">{{ __('Change Stock') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.analysis.machine-reports') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.analysis.machine-reports') }}">{{ __('Machine Reports') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.analysis.product-reports') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.analysis.product-reports') }}">{{ __('Product Reports') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.analysis.survey-analysis') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.analysis.survey-analysis') }}">{{ __('Survey Analysis') }}</a></li>
</ul>
</div>
</li>
@@ -143,14 +143,14 @@
<li x-data="{ open: localStorage.getItem('menu_audit') === 'true' || {{ request()->routeIs('admin.audit.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_audit', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.audit.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>
稽核管理
{{ __('Audit Management') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.audit.purchases') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.audit.purchases') }}">採購單</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.audit.transfers') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.audit.transfers') }}">調撥單</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.audit.replenishments') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.audit.replenishments') }}">補貨單</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.audit.purchases') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.audit.purchases') }}">{{ __('Purchase Audit') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.audit.transfers') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.audit.transfers') }}">{{ __('Transfer Audit') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.audit.replenishments') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.audit.replenishments') }}">{{ __('Replenishment Audit') }}</a></li>
</ul>
</div>
</li>
@@ -159,19 +159,19 @@
<li x-data="{ open: localStorage.getItem('menu_data_config') === 'true' || {{ request()->routeIs('admin.data-config.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_data_config', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.data-config.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" /><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /></svg>
資料設定
{{ __('Data Configuration') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.products') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.products') }}">商品管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.advertisements') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.advertisements') }}">廣告管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.admin-products') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.admin-products') }}">管理者可賣</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.accounts') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.accounts') }}">帳號管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.sub-accounts') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.sub-accounts') }}">子帳號</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.sub-account-roles') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.sub-account-roles') }}">子帳號角色</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.points') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.points') }}">點數設定</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.badges') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.badges') }}">識別證</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.products') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.products') }}">{{ __('Product Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.advertisements') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.advertisements') }}">{{ __('Advertisement Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.admin-products') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.admin-products') }}">{{ __('Admin Sellable Products') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.accounts') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.accounts') }}">{{ __('Account Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.sub-accounts') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.sub-accounts') }}">{{ __('Sub Accounts') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.sub-account-roles') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.sub-account-roles') }}">{{ __('Sub Account Roles') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.points') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.points') }}">{{ __('Point Settings') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.data-config.badges') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.data-config.badges') }}">{{ __('Badge Settings') }}</a></li>
</ul>
</div>
</li>
@@ -181,18 +181,18 @@
<li x-data="{ open: localStorage.getItem('menu_remote') === 'true' || {{ request()->routeIs('admin.remote.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_remote', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.remote.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5.636 18.364a9 9 0 010-12.728m12.728 0a9 9 0 010 12.728m-9.9-2.829a5 5 0 010-7.07m7.072 0a5 5 0 010 7.07M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
遠端管理
{{ __('Remote Management') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.stock') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.stock') }}">機台庫存</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.restart') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.restart') }}">機台重啟</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.restart-card-reader') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.restart-card-reader') }}">卡機重啟</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.checkout') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.checkout') }}">遠端結帳</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.lock') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.lock') }}">遠端鎖定</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.change') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.change') }}">遠端找零</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.dispense') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.dispense') }}">遠端出貨</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.stock') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.stock') }}">{{ __('Machine Stock') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.restart') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.restart') }}">{{ __('Machine Restart') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.restart-card-reader') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.restart-card-reader') }}">{{ __('Card Reader Restart') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.checkout') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.checkout') }}">{{ __('Remote Checkout') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.lock') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.lock') }}">{{ __('Remote Lock') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.change') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.change') }}">{{ __('Remote Change') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.remote.dispense') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.remote.dispense') }}">{{ __('Remote Dispense') }}</a></li>
</ul>
</div>
</li>
@@ -201,17 +201,17 @@
<li x-data="{ open: localStorage.getItem('menu_line') === 'true' || {{ request()->routeIs('admin.line.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_line', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.line.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" /></svg>
Line管理
{{ __('Line Management') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.members') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.members') }}">Line會員</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.machines') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.machines') }}">Line機台</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.products') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.products') }}">Line商品</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.official-account') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.official-account') }}">Line生活圈</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.orders') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.orders') }}">Line訂單</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.coupons') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.coupons') }}">Line優惠券</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.members') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.members') }}">{{ __('Line Members') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.machines') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.machines') }}">{{ __('Line Machines') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.products') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.products') }}">{{ __('Line Products') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.official-account') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.official-account') }}">{{ __('Line Official Account') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.orders') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.orders') }}">{{ __('Line Orders') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.line.coupons') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.coupons') }}">{{ __('Line Coupons') }}</a></li>
</ul>
</div>
</li>
@@ -220,18 +220,18 @@
<li x-data="{ open: localStorage.getItem('menu_reservation') === 'true' || {{ request()->routeIs('admin.reservation.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_reservation', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.reservation.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>
預約系統
{{ __('Reservation System') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.members') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.members') }}">預約會員</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.stores') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.stores') }}">店家管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.time-slots') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.time-slots') }}">時段組合</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.venues') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.venues') }}">場地管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.coupons') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.coupons') }}">優惠券</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.reservations') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.reservations') }}">預約管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.orders') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.orders') }}">訂單管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.members') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.members') }}">{{ __('Reservation Members') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.stores') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.stores') }}">{{ __('Store Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.time-slots') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.time-slots') }}">{{ __('Time Slots') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.venues') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.venues') }}">{{ __('Venue Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.coupons') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.coupons') }}">{{ __('Coupons') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.reservations') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.reservations') }}">{{ __('Reservations') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.reservation.orders') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.reservation.orders') }}">{{ __('Order Management') }}</a></li>
</ul>
</div>
</li>
@@ -240,14 +240,14 @@
<li x-data="{ open: localStorage.getItem('menu_special_permission') === 'true' || {{ request()->routeIs('admin.special-permission.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_special_permission', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.special-permission.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" /></svg>
特殊權限
{{ __('Special Permission') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.special-permission.clear-stock') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.special-permission.clear-stock') }}">庫存清空</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.special-permission.apk-versions') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.special-permission.apk-versions') }}">APK版本</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.special-permission.discord-notifications') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.special-permission.discord-notifications') }}">Discord通知</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.special-permission.clear-stock') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.special-permission.clear-stock') }}">{{ __('Clear Stock') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.special-permission.apk-versions') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.special-permission.apk-versions') }}">{{ __('APK Versions') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.special-permission.discord-notifications') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.special-permission.discord-notifications') }}">{{ __('Discord Notifications') }}</a></li>
</ul>
</div>
</li>
@@ -256,23 +256,23 @@
<li x-data="{ open: localStorage.getItem('menu_permissions') === 'true' || {{ request()->routeIs('admin.permission.*') ? 'true' : 'false' }} }">
<button type="button" @click="open = !open; localStorage.setItem('menu_permissions', open)" class="luxury-nav-item w-full text-start group">
<svg class="w-4 h-4 shrink-0 transition-colors {{ request()->routeIs('admin.permission.*') ? 'text-cyan-500' : 'text-slate-400 group-hover:text-cyan-500 dark:text-slate-400 dark:group-hover:text-cyan-400' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" /></svg>
權限設定
{{ __('Permission Settings') }}
<svg class="ms-auto w-4 h-4 transition-transform duration-300 text-slate-400 dark:text-slate-500" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
</button>
<div x-show="open" x-collapse>
<ul class="luxury-submenu">
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.app-features') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.app-features') }}">APP功能</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.data-config') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.data-config') }}">資料設定</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.sales') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.sales') }}">銷售管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.machines') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.machines') }}">機台管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.warehouses') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.warehouses') }}">倉庫管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.analysis') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.analysis') }}">分析管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.audit') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.audit') }}">稽核管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.remote') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.remote') }}">遠端管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.line') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.members') }}">Line管理</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.roles') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.roles') }}">角色設定</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.others') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.others') }}">其他功能</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.ai-prediction') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.ai-prediction') }}">AI智能預測</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.app-features') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.app-features') }}">{{ __('APP Features') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.data-config') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.data-config') }}">{{ __('Data Configuration') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.sales') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.sales') }}">{{ __('Sales') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.machines') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.machines') }}">{{ __('Machine Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.warehouses') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.warehouses') }}">{{ __('Warehouse Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.analysis') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.analysis') }}">{{ __('Analysis Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.audit') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.audit') }}">{{ __('Audit Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.remote') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.remote') }}">{{ __('Remote Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.line') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.line.members') }}">{{ __('Line Management') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.roles') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.roles') }}">{{ __('Roles') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.others') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.others') }}">{{ __('Others') }}</a></li>
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm transition-colors rounded-lg {{ request()->routeIs('admin.permission.ai-prediction') ? 'text-slate-900 dark:text-white bg-slate-100 dark:bg-white/5' : 'text-slate-500 hover:text-slate-900 dark:hover:text-white' }}" href="{{ route('admin.permission.ai-prediction') }}">{{ __('AI Prediction') }}</a></li>
</ul>
</div>
</li>

View File

@@ -1,23 +1,33 @@
@extends('layouts.admin')
@section('content')
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6">
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="max-w-xl">
<div class="max-w-5xl mx-auto space-y-8 animate-luxury-in">
<!-- Header -->
<div class="mb-8">
<h2 class="text-3xl font-extrabold text-slate-800 dark:text-white font-display tracking-tight">{{ __('Account Settings') }}</h2>
<p class="text-sm font-bold text-slate-400 dark:text-slate-400 mt-1 uppercase tracking-widest">{{ __('Manage your profile information, security settings, and login history') }}</p>
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Left Side: Basic Info & Security -->
<div class="lg:col-span-2 space-y-8">
<div class="luxury-card p-8">
@include('profile.partials.update-profile-information-form')
</div>
</div>
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="max-w-xl">
<div class="luxury-card p-8">
@include('profile.partials.update-password-form')
</div>
<div class="luxury-card p-8 border-rose-500/20 dark:border-rose-500/10">
@include('profile.partials.delete-user-form')
</div>
</div>
<div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="max-w-xl">
@include('profile.partials.delete-user-form')
<!-- Right Side: Login History -->
<div class="lg:col-span-1">
<div class="luxury-card p-6 sticky top-24">
@include('profile.partials.login-history')
</div>
</div>
</div>

View File

@@ -1,54 +1,57 @@
<section class="space-y-6">
<header>
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
{{ __('Delete Account') }}
<h2 class="text-xl font-black text-rose-600 dark:text-rose-500 tracking-tight">
{{ __('Danger Zone: Delete Account') }}
</h2>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
<p class="mt-1 text-sm font-bold text-slate-400 dark:text-slate-400 uppercase tracking-widest">
{{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.') }}
</p>
</header>
<x-danger-button
<button
x-data=""
x-on:click.prevent="$dispatch('open-modal', 'confirm-user-deletion')"
>{{ __('Delete Account') }}</x-danger-button>
class="btn-luxury-rose px-8"
>
<span>{{ __('Delete Account') }}</span>
</button>
<x-modal name="confirm-user-deletion" :show="$errors->userDeletion->isNotEmpty()" focusable>
<form method="post" action="{{ route('profile.destroy') }}" class="p-6">
<form method="post" action="{{ route('profile.destroy') }}" class="p-8">
@csrf
@method('delete')
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
<h2 class="text-2xl font-black text-slate-800 dark:text-white tracking-tight">
{{ __('Are you sure you want to delete your account?') }}
</h2>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
<p class="mt-3 text-sm font-bold text-slate-500 dark:text-slate-400 leading-relaxed">
{{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.') }}
</p>
<div class="mt-6">
<div class="mt-8">
<x-input-label for="password" value="{{ __('Password') }}" class="sr-only" />
<x-text-input
<input
id="password"
name="password"
type="password"
class="mt-1 block w-3/4"
placeholder="{{ __('Password') }}"
class="py-3 px-4 block w-full border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-900 rounded-2xl text-sm font-bold text-slate-700 dark:text-slate-200 focus:ring-4 focus:ring-rose-500/10 focus:border-rose-500 transition-all outline-none"
placeholder="{{ __('Enter your password to confirm') }}"
/>
<x-input-error :messages="$errors->userDeletion->get('password')" class="mt-2" />
</div>
<div class="mt-6 flex justify-end">
<x-secondary-button x-on:click="$dispatch('close')">
<div class="mt-8 flex justify-end gap-x-3">
<button type="button" x-on:click="$dispatch('close')" class="py-3 px-6 inline-flex items-center gap-x-2 text-sm font-black rounded-2xl border border-slate-200 bg-white text-slate-600 shadow-sm hover:bg-slate-50 focus:outline-none focus:bg-slate-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-slate-700 dark:text-slate-400 dark:hover:bg-slate-800 dark:focus:bg-slate-800 transition-all">
{{ __('Cancel') }}
</x-secondary-button>
</button>
<x-danger-button class="ms-3">
{{ __('Delete Account') }}
</x-danger-button>
<button type="submit" class="btn-luxury-rose px-8">
<span>{{ __('Permanently Delete Account') }}</span>
</button>
</div>
</form>
</x-modal>

View File

@@ -0,0 +1,46 @@
<div class="space-y-6">
<div class="flex items-center gap-x-3 mb-6">
<div class="size-10 rounded-xl bg-cyan-500/10 flex items-center justify-center text-cyan-600 dark:text-cyan-400">
<svg class="size-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Login History') }}</h3>
</div>
<div class="flow-root">
<ul role="list" class="-mb-8">
@forelse($user->loginLogs as $log)
<li>
<div class="relative pb-8">
@if(!$loop->last)
<span class="absolute left-4 top-4 -ml-px h-full w-0.5 bg-slate-100 dark:bg-slate-800" aria-hidden="true"></span>
@endif
<div class="relative flex space-x-3 mt-1">
<div>
<span class="h-8 w-8 rounded-full bg-slate-100 dark:bg-slate-800 flex items-center justify-center ring-8 ring-white dark:ring-slate-900">
<svg class="h-4 w-4 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"/>
</svg>
</span>
</div>
<div class="flex min-w-0 flex-1 justify-between space-x-4 pt-1.5">
<div>
<p class="text-[11px] font-black text-slate-700 dark:text-slate-300 uppercase tracking-widest">{{ $log->ip_address }}</p>
<p class="mt-1 text-xs text-slate-400 truncate max-w-[120px]" title="{{ $log->user_agent }}">
{{ Str::limit($log->user_agent, 20) }}
</p>
</div>
<div class="whitespace-nowrap text-right text-[10px] font-bold text-slate-400">
<time datetime="{{ $log->login_at }}">{{ $log->login_at->diffForHumans() }}</time>
</div>
</div>
</div>
</div>
</li>
@empty
<li class="py-4 text-center text-xs text-slate-400">尚無登入紀錄</li>
@endforelse
</ul>
</div>
</div>

View File

@@ -1,38 +1,42 @@
<section>
<header>
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
<h2 class="text-xl font-black text-slate-800 dark:text-white tracking-tight">
{{ __('Update Password') }}
</h2>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
<p class="mt-1 text-sm font-bold text-slate-400 dark:text-slate-400 uppercase tracking-widest">
{{ __('Ensure your account is using a long, random password to stay secure.') }}
</p>
</header>
<form method="post" action="{{ route('password.update') }}" class="mt-6 space-y-6">
<form method="post" action="{{ route('password.update') }}" class="mt-8 space-y-6">
@csrf
@method('put')
<div>
<x-input-label for="update_password_current_password" :value="__('Current Password')" />
<x-text-input id="update_password_current_password" name="current_password" type="password" class="mt-1 block w-full" autocomplete="current-password" />
<x-input-label for="update_password_current_password" :value="__('Current Password')" class="text-xs font-black text-slate-500 uppercase tracking-widest mb-2 ml-1" />
<input id="update_password_current_password" name="current_password" type="password" class="py-3 px-4 block w-full border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-900 rounded-2xl text-sm font-bold text-slate-700 dark:text-slate-200 focus:ring-4 focus:ring-cyan-500/10 focus:border-cyan-500 transition-all outline-none" autocomplete="current-password" />
<x-input-error :messages="$errors->updatePassword->get('current_password')" class="mt-2" />
</div>
<div>
<x-input-label for="update_password_password" :value="__('New Password')" />
<x-text-input id="update_password_password" name="password" type="password" class="mt-1 block w-full" autocomplete="new-password" />
<x-input-error :messages="$errors->updatePassword->get('password')" class="mt-2" />
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label for="update_password_password" :value="__('New Password')" class="text-xs font-black text-slate-500 uppercase tracking-widest mb-2 ml-1" />
<input id="update_password_password" name="password" type="password" class="py-3 px-4 block w-full border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-900 rounded-2xl text-sm font-bold text-slate-700 dark:text-slate-200 focus:ring-4 focus:ring-cyan-500/10 focus:border-cyan-500 transition-all outline-none" autocomplete="new-password" />
<x-input-error :messages="$errors->updatePassword->get('password')" class="mt-2" />
</div>
<div>
<x-input-label for="update_password_password_confirmation" :value="__('Confirm Password')" class="text-xs font-black text-slate-500 uppercase tracking-widest mb-2 ml-1" />
<input id="update_password_password_confirmation" name="password_confirmation" type="password" class="py-3 px-4 block w-full border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-900 rounded-2xl text-sm font-bold text-slate-700 dark:text-slate-200 focus:ring-4 focus:ring-cyan-500/10 focus:border-cyan-500 transition-all outline-none" autocomplete="new-password" />
<x-input-error :messages="$errors->updatePassword->get('password_confirmation')" class="mt-2" />
</div>
</div>
<div>
<x-input-label for="update_password_password_confirmation" :value="__('Confirm Password')" />
<x-text-input id="update_password_password_confirmation" name="password_confirmation" type="password" class="mt-1 block w-full" autocomplete="new-password" />
<x-input-error :messages="$errors->updatePassword->get('password_confirmation')" class="mt-2" />
</div>
<div class="flex items-center gap-4">
<x-primary-button>{{ __('Save') }}</x-primary-button>
<div class="flex items-center gap-4 pt-4">
<button type="submit" class="btn-luxury-primary px-8">
<span>{{ __('Update') }}</span>
</button>
@if (session('status') === 'password-updated')
<p
@@ -40,7 +44,7 @@
x-show="show"
x-transition
x-init="setTimeout(() => show = false, 2000)"
class="text-sm text-gray-600 dark:text-gray-400"
class="text-xs font-black text-emerald-500 dark:text-emerald-400 uppercase tracking-widest"
>{{ __('Saved.') }}</p>
@endif
</div>

View File

@@ -1,11 +1,11 @@
<section>
<header>
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
<h2 class="text-xl font-black text-slate-800 dark:text-white tracking-tight">
{{ __('Profile Information') }}
</h2>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
{{ __("Update your account's profile information and email address.") }}
<p class="mt-1 text-sm font-bold text-slate-400 dark:text-slate-400 uppercase tracking-widest">
{{ __('Update your account\'s profile information and email address.') }}
</p>
</header>
@@ -13,45 +13,42 @@
@csrf
</form>
<form method="post" action="{{ route('profile.update') }}" class="mt-6 space-y-6">
<form method="post" action="{{ route('profile.update') }}" class="mt-8 space-y-6">
@csrf
@method('patch')
<div>
<x-input-label for="name" :value="__('Name')" />
<x-text-input id="name" name="name" type="text" class="mt-1 block w-full" :value="old('name', $user->name)" required autofocus autocomplete="name" />
<x-input-error class="mt-2" :messages="$errors->get('name')" />
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<x-input-label for="name" :value="__('Name')" class="text-xs font-black text-slate-500 uppercase tracking-widest mb-2 ml-1" />
<input id="name" name="name" type="text" class="py-3 px-4 block w-full border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-900 rounded-2xl text-sm font-bold text-slate-700 dark:text-slate-200 focus:ring-4 focus:ring-cyan-500/10 focus:border-cyan-500 transition-all outline-none" value="{{ old('name', $user->name) }}" required autofocus autocomplete="name" />
<x-input-error class="mt-2" :messages="$errors->get('name')" />
</div>
<div>
<x-input-label for="phone" :value="__('Phone')" class="text-xs font-black text-slate-500 uppercase tracking-widest mb-2 ml-1" />
<input id="phone" name="phone" type="text" class="py-3 px-4 block w-full border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-900 rounded-2xl text-sm font-bold text-slate-700 dark:text-slate-200 focus:ring-4 focus:ring-cyan-500/10 focus:border-cyan-500 transition-all outline-none" value="{{ old('phone', $user->phone) }}" autocomplete="tel" />
<x-input-error class="mt-2" :messages="$errors->get('phone')" />
</div>
</div>
<div>
<x-input-label for="phone" :value="__('Phone')" />
<x-text-input id="phone" name="phone" type="text" class="mt-1 block w-full" :value="old('phone', $user->phone)" autocomplete="tel" />
<x-input-error class="mt-2" :messages="$errors->get('phone')" />
</div>
<div>
<x-input-label for="avatar" :value="__('Avatar URL')" />
<x-text-input id="avatar" name="avatar" type="text" class="mt-1 block w-full" :value="old('avatar', $user->avatar)" />
<x-input-error class="mt-2" :messages="$errors->get('avatar')" />
</div>
<div>
<x-input-label for="email" :value="__('Email')" />
<x-text-input id="email" name="email" type="email" class="mt-1 block w-full" :value="old('email', $user->email)" required autocomplete="username" />
<x-input-label for="email" :value="__('Email')" class="text-xs font-black text-slate-500 uppercase tracking-widest mb-2 ml-1" />
<input id="email" name="email" type="email" class="py-3 px-4 block w-full border-slate-200 dark:border-slate-700 bg-slate-50 dark:bg-slate-900 rounded-2xl text-sm font-bold text-slate-700 dark:text-slate-200 focus:ring-4 focus:ring-cyan-500/10 focus:border-cyan-500 transition-all outline-none" value="{{ old('email', $user->email) }}" required autocomplete="username" />
<x-input-error class="mt-2" :messages="$errors->get('email')" />
@if ($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! $user->hasVerifiedEmail())
<div>
<p class="text-sm mt-2 text-gray-800 dark:text-gray-200">
<div class="mt-4 p-4 bg-amber-50 dark:bg-amber-900/20 rounded-2xl border border-amber-200 dark:border-amber-900/30">
<p class="text-xs font-bold text-amber-700 dark:text-amber-400 flex items-center gap-x-2">
<svg class="size-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/></svg>
{{ __('Your email address is unverified.') }}
<button form="send-verification" class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800">
{{ __('Click here to re-send the verification email.') }}
</button>
</p>
<button form="send-verification" class="mt-2 text-xs font-black text-amber-600 dark:text-amber-500 hover:text-amber-700 underline underline-offset-4 decoration-amber-500/30 focus:outline-none transition-colors">
{{ __('Click here to re-send the verification email.') }}
</button>
@if (session('status') === 'verification-link-sent')
<p class="mt-2 font-medium text-sm text-green-600 dark:text-green-400">
<p class="mt-2 text-xs font-black text-green-600 dark:text-green-400">
{{ __('A new verification link has been sent to your email address.') }}
</p>
@endif
@@ -59,8 +56,10 @@
@endif
</div>
<div class="flex items-center gap-4">
<x-primary-button>{{ __('Save') }}</x-primary-button>
<div class="flex items-center gap-4 pt-4">
<button type="submit" class="btn-luxury-primary px-8">
<span>{{ __('Save') }}</span>
</button>
@if (session('status') === 'profile-updated')
<p
@@ -68,7 +67,7 @@
x-show="show"
x-transition
x-init="setTimeout(() => show = false, 2000)"
class="text-sm text-gray-600 dark:text-gray-400"
class="text-xs font-black text-emerald-500 dark:text-emerald-400 uppercase tracking-widest"
>{{ __('Saved.') }}</p>
@endif
</div>