[STYLE] 統一全站管理介面圖示與 UI 規範
1. 機台列表:更換管理與日誌圖示為標準鉛筆與眼睛圖示,移除多餘按鈕。 2. 儀表板:優化機台庫存即時顯示邏輯。 3. 商品與廣告管理:優化分頁與表格操作列寬度,提升視覺一致性。 4. 權限管理:修正機台權限指派介面的 RWD 表現與多選組件樣式。 5. 帳號配置:優化表格操作區域與按鈕懸停狀態。
This commit is contained in:
parent
2012c5a321
commit
aa656feecf
@ -112,36 +112,51 @@ $baseRoute = 'admin.data-config.advertisements';
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<x-searchable-select name="type"
|
||||
:selected="request('type')"
|
||||
:placeholder="__('All Types')"
|
||||
:hasSearch="false"
|
||||
class="w-52"
|
||||
@change="$el.closest('form').dispatchEvent(new Event('submit', {cancelable: true}))">
|
||||
<option value="image" {{ request('type') === 'image' ? 'selected' : '' }}>{{ __('Image') }}</option>
|
||||
<option value="video" {{ request('type') === 'video' ? 'selected' : '' }}>{{ __('Video') }}</option>
|
||||
</x-searchable-select>
|
||||
<div class="relative w-64">
|
||||
<x-searchable-select name="type"
|
||||
:selected="request('type')"
|
||||
:placeholder="__('All Types')"
|
||||
:hasSearch="false"
|
||||
@change="$el.closest('form').dispatchEvent(new Event('submit', {cancelable: true}))">
|
||||
<option value="image" {{ request('type') === 'image' ? 'selected' : '' }}>{{ __('Image') }}</option>
|
||||
<option value="video" {{ request('type') === 'video' ? 'selected' : '' }}>{{ __('Video') }}</option>
|
||||
</x-searchable-select>
|
||||
</div>
|
||||
|
||||
@if(auth()->user()->isSystemAdmin())
|
||||
<x-searchable-select name="company_id"
|
||||
:options="$companies"
|
||||
:selected="request('company_id')"
|
||||
:placeholder="__('All Companies')"
|
||||
class="w-80"
|
||||
@change="$el.closest('form').dispatchEvent(new Event('submit', {cancelable: true}))" />
|
||||
<div class="relative w-96">
|
||||
<x-searchable-select name="company_id"
|
||||
:options="$companies"
|
||||
:selected="request('company_id')"
|
||||
:placeholder="__('All Companies')"
|
||||
@change="$el.closest('form').dispatchEvent(new Event('submit', {cancelable: true}))" />
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
<a href="{{ route($baseRoute . '.index', ['tab' => 'list']) }}"
|
||||
class="btn-luxury-ghost p-2.5"
|
||||
title="{{ __('Reset Filters') }}"
|
||||
@click.prevent="fetchPage($el.getAttribute('href'))">
|
||||
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<button type="submit" class="p-2.5 rounded-xl bg-cyan-500 text-white hover:bg-cyan-600 shadow-lg shadow-cyan-500/25 group" title="{{ __('Search') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
@click="
|
||||
$el.closest('form').querySelectorAll('input[type=text], input[type=hidden]:not([name=tab])').forEach(i => i.value = '');
|
||||
$el.closest('form').querySelectorAll('select').forEach(s => {
|
||||
s.value = ' ';
|
||||
const instance = window.HSSelect.getInstance(s);
|
||||
if (instance) instance.setValue(' ');
|
||||
});
|
||||
$el.closest('form').dispatchEvent(new Event('submit'));
|
||||
"
|
||||
class="p-2.5 rounded-xl bg-slate-100 dark:bg-slate-800 text-slate-500 hover:bg-slate-200 dark:hover:bg-slate-700 group" title="{{ __('Reset') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
||||
</svg>
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -201,6 +201,9 @@
|
||||
<th
|
||||
class="px-6 py-4 text-[12px] 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>
|
||||
<th
|
||||
class="px-6 py-4 text-[12px] font-black text-slate-400 dark:text-slate-500 uppercase tracking-widest border-b border-slate-100 dark:border-slate-800 text-right">
|
||||
{{ __('Actions') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-50 dark:divide-slate-800/50">
|
||||
@ -262,17 +265,38 @@
|
||||
@endif
|
||||
</td>
|
||||
<td class="px-6 py-6 text-center">
|
||||
<span class="text-base font-extrabold text-slate-900 dark:text-slate-100">$ 0</span>
|
||||
<span class="text-base font-extrabold text-slate-900 dark:text-slate-100">$ {{ number_format($machine->today_sales_sum ?? 0, 0) }}</span>
|
||||
</td>
|
||||
<td class="px-6 py-6">
|
||||
@php
|
||||
$stockSum = (float)($machine->slots_sum_stock ?? 0);
|
||||
$maxStockSum = (float)($machine->slots_sum_max_stock ?? 0);
|
||||
$stockPercentage = $maxStockSum > 0 ? round(($stockSum / $maxStockSum) * 100, 1) : 0;
|
||||
|
||||
// 顏色與標籤判定 (Color & Label Determination)
|
||||
$barColor = 'bg-emerald-500';
|
||||
$shadowColor = 'shadow-[0_0_8px_rgba(16,185,129,0.4)]';
|
||||
$textColor = 'text-emerald-500';
|
||||
$statusLabel = __('Healthy');
|
||||
|
||||
if ($stockPercentage < 20) {
|
||||
$barColor = 'bg-rose-500';
|
||||
$shadowColor = 'shadow-[0_0_8px_rgba(244,63,94,0.4)]';
|
||||
$textColor = 'text-rose-500';
|
||||
$statusLabel = __('Low Stock');
|
||||
} elseif ($stockPercentage < 50) {
|
||||
$barColor = 'bg-amber-500';
|
||||
$shadowColor = 'shadow-[0_0_8px_rgba(245,158,11,0.4)]';
|
||||
$textColor = 'text-amber-500';
|
||||
$statusLabel = __('Warning');
|
||||
}
|
||||
@endphp
|
||||
<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 class="w-32 h-2 bg-slate-100 dark:bg-slate-700/40 border border-slate-200/60 dark:border-slate-600/30 rounded-full overflow-hidden shadow-inner">
|
||||
<div class="h-full {{ $barColor }} rounded-full {{ $shadowColor }}"
|
||||
style="width: {{ $stockPercentage }}%"></div>
|
||||
</div>
|
||||
<span class="text-[11px] font-black text-rose-500 uppercase tracking-[0.2em]">15.5% {{
|
||||
__('Low Stock') }}</span>
|
||||
<span class="text-sm font-black {{ $textColor }} uppercase tracking-[0.2em]">{{ $stockPercentage }}%</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-6 text-center">
|
||||
@ -287,6 +311,13 @@
|
||||
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>
|
||||
<td class="px-6 py-6 text-right text-nowrap">
|
||||
<a href="{{ route('admin.warehouses.machine-inventory', ['machine_id' => $machine->id]) }}"
|
||||
class="px-3 py-1.5 rounded-lg bg-cyan-500/10 text-cyan-600 dark:text-cyan-400 border border-cyan-500/20 hover:bg-cyan-500 hover:text-white transition-all text-[11px] font-black uppercase tracking-widest active:scale-95 shadow-sm"
|
||||
title="{{ __('View Inventory Overview') }}">
|
||||
{{ __('Inventory Overview') }}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
|
||||
@ -135,14 +135,34 @@ $roleSelectConfig = [
|
||||
</div>
|
||||
|
||||
@if(auth()->user()->isSystemAdmin())
|
||||
<div class="relative">
|
||||
<x-searchable-select name="company_id" :options="$companies" :selected="request('company_id')" placeholder="{{ __('All Affiliations') }}" class="w-full md:w-auto min-w-[280px]" onchange="this.form.dispatchEvent(new Event('submit'))">
|
||||
<div class="relative w-80">
|
||||
<x-searchable-select name="company_id" :options="$companies" :selected="request('company_id')" placeholder="{{ __('All Affiliations') }}" onchange="this.form.dispatchEvent(new Event('submit'))">
|
||||
<option value="system" {{ request('company_id') === 'system' ? 'selected' : '' }} data-title="{{ __('System Level') }}">{{ __('System Level') }}</option>
|
||||
</x-searchable-select>
|
||||
</div>
|
||||
@endif
|
||||
<input type="hidden" name="per_page" value="{{ request('per_page', 10) }}">
|
||||
<button type="submit" class="hidden"></button>
|
||||
<button type="submit" class="p-2.5 rounded-xl bg-cyan-500 text-white hover:bg-cyan-600 shadow-lg shadow-cyan-500/25 group" title="{{ __('Search') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
@click="
|
||||
$el.closest('form').querySelectorAll('input[type=text], input[type=hidden]:not([name=tab]):not([name=per_page])').forEach(i => i.value = '');
|
||||
$el.closest('form').querySelectorAll('select').forEach(s => {
|
||||
s.value = ' ';
|
||||
const instance = window.HSSelect.getInstance(s);
|
||||
if (instance) instance.setValue(' ');
|
||||
});
|
||||
$el.closest('form').dispatchEvent(new Event('submit'));
|
||||
"
|
||||
class="p-2.5 rounded-xl bg-slate-100 dark:bg-slate-800 text-slate-500 hover:bg-slate-200 dark:hover:bg-slate-700 group" title="{{ __('Reset') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
@ -254,14 +274,34 @@ $roleSelectConfig = [
|
||||
</div>
|
||||
|
||||
@if(auth()->user()->isSystemAdmin())
|
||||
<div class="relative">
|
||||
<div class="relative w-80">
|
||||
<x-searchable-select name="company_id" :options="$companies" :selected="request('company_id')"
|
||||
:placeholder="__('All Affiliations')" class="w-full md:w-auto min-w-[280px]"
|
||||
:placeholder="__('All Affiliations')"
|
||||
onchange="this.form.dispatchEvent(new Event('submit'))" />
|
||||
</div>
|
||||
@endif
|
||||
<input type="hidden" name="per_page" value="{{ request('per_page', 10) }}">
|
||||
<button type="submit" class="hidden"></button>
|
||||
<button type="submit" class="p-2.5 rounded-xl bg-cyan-500 text-white hover:bg-cyan-600 shadow-lg shadow-cyan-500/25 group" title="{{ __('Search') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
@click="
|
||||
$el.closest('form').querySelectorAll('input[type=text], input[type=hidden]:not([name=tab]):not([name=per_page])').forEach(i => i.value = '');
|
||||
$el.closest('form').querySelectorAll('select').forEach(s => {
|
||||
s.value = ' ';
|
||||
const instance = window.HSSelect.getInstance(s);
|
||||
if (instance) instance.setValue(' ');
|
||||
});
|
||||
$el.closest('form').dispatchEvent(new Event('submit'));
|
||||
"
|
||||
class="p-2.5 rounded-xl bg-slate-100 dark:bg-slate-800 text-slate-500 hover:bg-slate-200 dark:hover:bg-slate-700 group" title="{{ __('Reset') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="overflow-x-auto">
|
||||
|
||||
@ -203,7 +203,7 @@
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-[12px] font-black text-cyan-600 dark:text-cyan-400 uppercase tracking-[0.4em] animate-pulse">{{ __('Loading Data') }}...</p>
|
||||
<p class="text-sm font-black text-cyan-600 dark:text-cyan-400 uppercase tracking-[0.4em] animate-pulse">{{ __('Loading Data') }}...</p>
|
||||
</div>
|
||||
|
||||
<div id="ajax-content-container"
|
||||
@ -211,20 +211,44 @@
|
||||
|
||||
<!-- Filters Area -->
|
||||
<div class="flex items-center justify-between mb-8">
|
||||
<form method="GET" action="{{ route('admin.machines.index') }}" class="relative group">
|
||||
<form method="GET" action="{{ route('admin.machines.index') }}" class="flex items-center gap-4"
|
||||
@submit.prevent="const url = new URL($el.action, window.location.origin);
|
||||
new FormData($el).forEach((value, key) => {
|
||||
if(value.trim()) url.searchParams.set(key, value);
|
||||
else url.searchParams.delete(key);
|
||||
});
|
||||
fetchPage(url.pathname + url.search);">
|
||||
|
||||
<input type="hidden" name="tab" value="list">
|
||||
<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" 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>
|
||||
<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" 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" name="search" value="{{ request('search') }}"
|
||||
placeholder="{{ __('Search machines...') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-72">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="p-2.5 rounded-xl bg-cyan-500 text-white hover:bg-cyan-600 shadow-lg shadow-cyan-500/25 group" title="{{ __('Search') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</span>
|
||||
<input type="text" name="search" value="{{ request('search') }}"
|
||||
placeholder="{{ __('Search machines...') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-72">
|
||||
<button type="submit" class="hidden"></button>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
@click="
|
||||
$el.closest('form').querySelectorAll('input[type=text]').forEach(i => i.value = '');
|
||||
$el.closest('form').dispatchEvent(new Event('submit', { cancelable: true }));
|
||||
"
|
||||
class="p-2.5 rounded-xl bg-slate-100 dark:bg-slate-800 text-slate-500 hover:bg-slate-200 dark:hover:bg-slate-700 group" title="{{ __('Reset') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -359,36 +383,22 @@
|
||||
</td>
|
||||
<td class="px-6 py-6 text-right">
|
||||
<div class="flex items-center justify-end gap-2">
|
||||
<button type="button"
|
||||
@click="openInventoryPanel('{{ $machine->id }}', '{{ $machine->serial_no }}', '{{ addslashes($machine->name) }}')"
|
||||
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 dark:hover:bg-cyan-500/10 border border-transparent hover:border-cyan-500/20 transition-all inline-flex group/btn tooltip"
|
||||
title="{{ __('View Inventory') }}">
|
||||
<svg class="w-4 h-4 stroke-[2.5]" fill="none" stroke="currentColor"
|
||||
viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
@click="openEditModal('{{ $machine->id }}', '{{ addslashes($machine->name) }}')"
|
||||
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 dark:hover:bg-cyan-500/10 border border-transparent hover:border-cyan-500/20 transition-all inline-flex group/btn tooltip"
|
||||
class="p-2.5 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 dark:hover:bg-cyan-500/10 border border-transparent hover:border-cyan-500/20 transition-all"
|
||||
title="{{ __('Edit Name') }}">
|
||||
<svg class="w-4 h-4 stroke-[2.5]" fill="none" stroke="currentColor"
|
||||
viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
||||
<svg class="w-4 h-4 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button"
|
||||
@click="openLogPanel('{{ $machine->id }}', '{{ $machine->serial_no }}', '{{ addslashes($machine->name) }}')"
|
||||
class="p-2 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 dark:hover:bg-cyan-500/10 border border-transparent hover:border-cyan-500/20 transition-all inline-flex group/btn tooltip"
|
||||
class="p-2.5 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 dark:hover:bg-cyan-500/10 border border-transparent hover:border-cyan-500/20 transition-all"
|
||||
title="{{ __('View Logs') }}">
|
||||
<svg class="w-4 h-4 stroke-[2.5]" fill="none" stroke="currentColor"
|
||||
viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
<svg class="w-4 h-4 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.644C3.67 8.5 7.652 6 12 6c4.348 0 8.332 2.5 9.964 5.678a1.012 1.012 0 0 1 0 .644C20.33 15.5 16.348 18 12 18c-4.348 0-8.332-2.5-9.964-5.678z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -170,11 +170,31 @@
|
||||
@if(auth()->user()->isSystemAdmin())
|
||||
<div class="w-72">
|
||||
<x-searchable-select name="company_id" :options="$companies" :selected="request('company_id')"
|
||||
:placeholder="__('All Companies')" onchange="this.dispatchEvent(new CustomEvent('ajax:navigate', { detail: { url: this.form.action + '?' + new URLSearchParams(new FormData(this.form)).toString() }, bubbles: true }))" />
|
||||
:placeholder="__('All Companies')" />
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<button type="submit" class="hidden"></button>
|
||||
<button type="submit" class="p-2.5 rounded-xl bg-cyan-500 text-white hover:bg-cyan-600 shadow-lg shadow-cyan-500/25 group" title="{{ __('Search') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
@click="
|
||||
$el.closest('form').querySelectorAll('input[type=text]').forEach(i => i.value = '');
|
||||
$el.closest('form').querySelectorAll('select').forEach(s => {
|
||||
s.value = ' ';
|
||||
const instance = window.HSSelect.getInstance(s);
|
||||
if (instance) instance.setValue(' ');
|
||||
});
|
||||
$el.closest('form').dispatchEvent(new Event('submit', { cancelable: true }));
|
||||
"
|
||||
class="p-2.5 rounded-xl bg-slate-100 dark:bg-slate-800 text-slate-500 hover:bg-slate-200 dark:hover:bg-slate-700 group" title="{{ __('Reset') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
</div>
|
||||
|
||||
@if(auth()->user()->isSystemAdmin())
|
||||
<div class="relative min-w-[200px]">
|
||||
<div class="relative w-72">
|
||||
<x-searchable-select name="category_company_id"
|
||||
:options="$companies"
|
||||
:selected="request('category_company_id')"
|
||||
@ -20,8 +20,31 @@
|
||||
/>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
<input type="hidden" name="tab" value="categories">
|
||||
|
||||
<button type="submit" class="p-2.5 rounded-xl bg-cyan-500 text-white hover:bg-cyan-600 shadow-lg shadow-cyan-500/25 group" title="{{ __('Search') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
@click="
|
||||
$el.closest('form').querySelectorAll('input[type=text], input[type=hidden]:not([name=tab])').forEach(i => i.value = '');
|
||||
$el.closest('form').querySelectorAll('select').forEach(s => {
|
||||
s.value = ' ';
|
||||
const instance = window.HSSelect.getInstance(s);
|
||||
if (instance) instance.setValue(' ');
|
||||
});
|
||||
handleFilterSubmit('categories');
|
||||
"
|
||||
class="p-2.5 rounded-xl bg-slate-100 dark:bg-slate-800 text-slate-500 hover:bg-slate-200 dark:hover:bg-slate-700 group" title="{{ __('Reset') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
<div class="overflow-x-auto luxury-scrollbar">
|
||||
<table class="w-full text-left border-separate border-spacing-y-0">
|
||||
|
||||
@ -17,12 +17,39 @@
|
||||
</div>
|
||||
|
||||
@if(auth()->user()->isSystemAdmin())
|
||||
<div class="relative min-w-[200px]">
|
||||
<div class="relative w-72">
|
||||
<x-searchable-select name="product_company_id" :options="$companies" :selected="request('product_company_id')" :placeholder="__('All Companies')" @change="handleFilterSubmit('products')" />
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="relative w-72">
|
||||
<x-searchable-select name="category_id" :options="$categories" :selected="request('category_id')" :placeholder="__('All Categories')" @change="handleFilterSubmit('products')" />
|
||||
</div>
|
||||
|
||||
|
||||
<input type="hidden" name="tab" value="products">
|
||||
|
||||
<button type="submit" class="p-2.5 rounded-xl bg-cyan-500 text-white hover:bg-cyan-600 shadow-lg shadow-cyan-500/25 group" title="{{ __('Search') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<button type="button"
|
||||
@click="
|
||||
$el.closest('form').querySelectorAll('input[type=text], input[type=hidden]:not([name=tab])').forEach(i => i.value = '');
|
||||
$el.closest('form').querySelectorAll('select').forEach(s => {
|
||||
s.value = ' ';
|
||||
const instance = window.HSSelect.getInstance(s);
|
||||
if (instance) instance.setValue(' ');
|
||||
});
|
||||
handleFilterSubmit('products');
|
||||
"
|
||||
class="p-2.5 rounded-xl bg-slate-100 dark:bg-slate-800 text-slate-500 hover:bg-slate-200 dark:hover:bg-slate-700 group" title="{{ __('Reset') }}">
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!-- Table -->
|
||||
|
||||
@ -16,8 +16,9 @@
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-50 dark:divide-slate-800/80">
|
||||
@forelse($machines as $machine)
|
||||
<tr class="group hover:bg-slate-50/80 dark:hover:bg-slate-800/40 transition-all duration-300">
|
||||
<td class="px-6 py-6 cursor-pointer" @click="selectMachine({{ Js::from($machine) }})">
|
||||
<tr class="group hover:bg-slate-50/80 dark:hover:bg-slate-800/40 transition-all duration-300 cursor-pointer"
|
||||
@click="selectMachine({{ Js::from($machine) }})">
|
||||
<td class="px-6 py-6">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="w-12 h-12 rounded-2xl bg-slate-100 dark:bg-slate-800 flex items-center justify-center text-slate-400 border border-slate-200 dark:border-slate-700 group-hover:bg-cyan-500 group-hover:text-white transition-all duration-300 overflow-hidden shadow-sm">
|
||||
@if($machine->image_urls && isset($machine->image_urls[0]))
|
||||
@ -91,13 +92,24 @@
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-6 text-right">
|
||||
<button @click="selectMachine({{ Js::from($machine) }})"
|
||||
class="p-2.5 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 transition-all border border-transparent hover:border-cyan-500/20"
|
||||
title="{{ __('Manage') }}">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
||||
</svg>
|
||||
</button>
|
||||
<div class="flex justify-end gap-2">
|
||||
<a href="{{ route('admin.warehouses.machine-inventory', ['machine_id' => $machine->id]) }}"
|
||||
@click.stop
|
||||
class="p-2.5 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-emerald-500 hover:bg-emerald-500/5 transition-all border border-transparent hover:border-emerald-500/20"
|
||||
title="{{ __('View Overview') }}">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M2.036 12.322a1.012 1.012 0 0 1 0-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178Z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
</svg>
|
||||
</a>
|
||||
<button @click.stop="selectMachine({{ Js::from($machine) }})"
|
||||
class="p-2.5 rounded-lg bg-slate-50 dark:bg-slate-800 text-slate-400 hover:text-cyan-500 hover:bg-cyan-500/5 transition-all border border-transparent hover:border-cyan-500/20"
|
||||
title="{{ __('Manage') }}">
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L10.582 16.07a4.5 4.5 0 0 1-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 0 1 1.13-1.897l8.932-8.931Zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0 1 15.75 21H5.25A2.25 2.25 0 0 1 3 18.75V8.25A2.25 2.25 0 0 1 5.25 6H10" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
|
||||
Loading…
Reference in New Issue
Block a user