1. 修正客戶管理頁面 H1 標題與麵包屑導覽路徑。 2. 在機台編輯頁面實作分頁功能(基本、營運、機台系統設定)。 3. 實作極簡奢華風的機台系統設定 UI,按功能模組(電子發票、刷卡、支付、購物車等)進行卡片式分組。 4. 將系統設定資料從 Company JSON 遷移至 Machine 資料表獨立欄位,並更新關聯控制器與模型邏輯。 5. 清理 CompanyController 與視圖中的冗餘設定邏輯。 6. 完成現有資料遷移,確保機台正確繼承客戶層級之設定。 7. 優化倉儲管理「現有庫存」矩陣視圖與導覽功能。
100 lines
7.3 KiB
PHP
100 lines
7.3 KiB
PHP
<div class="luxury-card rounded-3xl p-8 animate-luxury-in">
|
|
<form action="{{ route('admin.warehouses.inventory') }}" method="GET" class="flex flex-col md:flex-row md:items-center gap-4 mb-8"
|
|
@submit.prevent="handleFilterSubmit('stock')">
|
|
<input type="hidden" name="tab" value="stock">
|
|
<div class="relative group">
|
|
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10"><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="2.5"><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" name="search" value="{{ request('search') }}" class="py-2.5 pl-12 pr-6 block w-64 luxury-input" placeholder="{{ __('Search products...') }}">
|
|
</div>
|
|
<div class="min-w-[240px]">
|
|
<x-searchable-select
|
|
name="warehouse_id"
|
|
:options="$warehouses"
|
|
:selected="request('warehouse_id')"
|
|
:placeholder="__('Filter by Warehouse Presence')"
|
|
@change="handleFilterSubmit('stock')"
|
|
/>
|
|
</div>
|
|
</form>
|
|
|
|
<div class="overflow-x-auto -mx-8 px-8 custom-scrollbar">
|
|
<table class="w-full text-left border-separate border-spacing-y-0 min-w-max">
|
|
<thead>
|
|
<tr class="bg-slate-50/50 dark:bg-white/[0.02]">
|
|
<th class="px-6 py-5 text-sm font-black text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 sticky left-0 bg-white dark:bg-[#1e293b] z-20">{{ __('Product') }}</th>
|
|
@foreach($inventory_warehouses as $w)
|
|
<th class="px-6 py-5 text-sm font-black text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 text-center">
|
|
<div class="flex flex-col items-center">
|
|
<span class="text-base font-black text-slate-800 dark:text-slate-200 tracking-tight">{{ $w->name }}</span>
|
|
<span class="text-[10px] font-bold opacity-60 tracking-widest mt-0.5 uppercase">{{ $w->type === 'main' ? __('Main') : __('Branch') }}</span>
|
|
</div>
|
|
</th>
|
|
@endforeach
|
|
<th class="px-6 py-5 text-sm font-black text-cyan-600 dark:text-cyan-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 text-center bg-cyan-50/30 dark:bg-cyan-500/5">{{ __('Total') }}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-slate-50 dark:divide-white/[0.05]">
|
|
@forelse($products as $product)
|
|
@php $totalQuantity = $product->stocks->sum('quantity'); @endphp
|
|
<tr class="group hover:bg-slate-50 dark:hover:bg-white/[0.03] transition-all duration-300">
|
|
<td class="px-6 py-4 sticky left-0 bg-white dark:bg-[#1e293b] group-hover:bg-slate-50 dark:group-hover:bg-white/[0.03] z-10 transition-colors shadow-[4px_0_12px_-4px_rgba(0,0,0,0.05)] dark:shadow-[4px_0_12px_-4px_rgba(0,0,0,0.2)]">
|
|
<div class="flex items-center gap-4">
|
|
<div class="w-11 h-11 rounded-2xl bg-slate-100 dark:bg-slate-800/50 flex items-center justify-center overflow-hidden border border-slate-200/50 dark:border-white/5 group-hover:border-cyan-500/30 transition-colors">
|
|
@if($product->image_url)
|
|
<img src="{{ $product->image_url }}" class="w-full h-full object-cover">
|
|
@else
|
|
<svg class="w-5 h-5 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m21 7.5-9-5.25L3 7.5m18 0-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9" /></svg>
|
|
@endif
|
|
</div>
|
|
<div class="flex flex-col">
|
|
<span class="font-extrabold text-slate-800 dark:text-slate-100 group-hover:text-cyan-600 dark:group-hover:text-cyan-400 transition-colors">{{ $product->localized_name }}</span>
|
|
@if($product->barcode)
|
|
<span class="text-[10px] font-bold text-slate-400 mt-0.5 tracking-tight">{{ $product->barcode }}</span>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</td>
|
|
@foreach($inventory_warehouses as $w)
|
|
@php
|
|
$stock = $product->stocks->firstWhere('warehouse_id', $w->id);
|
|
$isLow = $stock && $stock->safety_stock > 0 && $stock->quantity <= $stock->safety_stock;
|
|
@endphp
|
|
<td class="px-6 py-4 text-center">
|
|
@if($stock && $stock->quantity > 0)
|
|
<div class="flex flex-col items-center">
|
|
<span class="text-base font-black {{ $isLow ? 'text-rose-500 drop-shadow-[0_0_8px_rgba(244,63,94,0.2)]' : 'text-slate-700 dark:text-slate-200' }}">
|
|
{{ $stock->quantity }}
|
|
</span>
|
|
@if($isLow)
|
|
<span class="text-[9px] font-black text-rose-500 uppercase tracking-tighter opacity-80">{{ __('Low') }}</span>
|
|
@endif
|
|
</div>
|
|
@else
|
|
<span class="text-sm font-bold text-slate-300 dark:text-slate-700/50">-</span>
|
|
@endif
|
|
</td>
|
|
@endforeach
|
|
<td class="px-6 py-4 text-center bg-cyan-50/30 dark:bg-cyan-500/5 group-hover:bg-cyan-100/30 dark:group-hover:bg-cyan-500/10 transition-colors">
|
|
<span class="text-xl font-mono font-black text-cyan-600 dark:text-cyan-400 drop-shadow-[0_0_10px_rgba(6,182,212,0.1)]">
|
|
{{ $totalQuantity }}
|
|
</span>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="{{ count($inventory_warehouses) + 2 }}" class="px-6 py-20 text-center">
|
|
<div class="flex flex-col items-center">
|
|
<div class="w-16 h-16 rounded-full bg-slate-100 dark:bg-slate-800 flex items-center justify-center mb-4">
|
|
<svg class="w-8 h-8 text-slate-300" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
</div>
|
|
<p class="text-slate-400 font-bold tracking-widest uppercase">{{ __('No products found') }}</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="mt-6 py-6 border-t border-slate-50 dark:border-slate-800/50">{{ $products->links('vendor.pagination.luxury') }}</div>
|
|
</div>
|