1. 重構廣告管理模組 (Ads Management) UI,完全對齊「極簡奢華風 (Minimal Luxury)」設計規範。 2. 新增 x-luxury-datetime-input 標準化組件,統一全站日期時間選擇器介面,並解決手機版顯示問題。 3. 修復 ad-modal.blade.php 內多語系標籤斷行與空格導致的翻譯失效問題,確保中文正確顯示。 4. 優化廣告列表與卡片視圖,移除冗餘時間資訊,強化資訊層級與行動裝置適應性。 5. 更新相關頁面導覽按鈕邏輯,確保在分頁切換時按鈕渲染與佈局穩定。
120 lines
5.1 KiB
PHP
120 lines
5.1 KiB
PHP
{{--
|
||
搜尋欄 + 重置按鈕 (x-search-bar)
|
||
鎖定全站搜尋輸入框、搜尋按鈕、重置按鈕的樣式與重置邏輯。
|
||
|
||
Props:
|
||
- $action (string) 必填 — 表單 action URL,通常使用 route()
|
||
- $name (string) 選填 — 搜尋欄 input name,預設 "search"
|
||
- $value (string) 選填 — 搜尋欄預填值,通常 request('search')
|
||
- $placeholder (string) 選填 — placeholder 文字
|
||
- $onSubmit (string) 選填 — Alpine submit handler,預設標準 AJAX fetchPage 方式
|
||
- $width (string) 選填 — 搜尋框寬度 class,預設 "sm:w-72"
|
||
|
||
Slot:
|
||
- $slot — 選填,額外的篩選器(如下拉選單、日期選擇器)
|
||
|
||
用法:
|
||
════════════════════════════════════
|
||
1. 基本用法(AJAX 搜尋):
|
||
<x-search-bar
|
||
:action="route('admin.machines.index')"
|
||
:value="request('search')"
|
||
:placeholder="__('Search machines...')"
|
||
/>
|
||
|
||
2. 帶額外篩選器:
|
||
<x-search-bar
|
||
:action="route('admin.warehouses.index')"
|
||
:value="request('search')"
|
||
:placeholder="__('Search...')"
|
||
>
|
||
<x-searchable-select name="type" ... />
|
||
</x-search-bar>
|
||
|
||
3. 帶隱藏欄位(如 tab):
|
||
直接在 x-search-bar 區塊外面的 form 補 hidden input 即可。
|
||
由於此組件自帶 <form>,若需 hidden input 可透過 slot 傳入。
|
||
════════════════════════════════════
|
||
|
||
注意:
|
||
- 重置按鈕邏輯已統一:清除所有 text input → 觸發 submit。
|
||
- 組件自帶 <form>,不需要外層再包 <form>。
|
||
--}}
|
||
|
||
@props([
|
||
'action' => '',
|
||
'name' => 'search',
|
||
'value' => '',
|
||
'placeholder' => '',
|
||
'width' => 'sm:w-72',
|
||
])
|
||
|
||
<form
|
||
method="GET"
|
||
action="{{ $action }}"
|
||
class="flex flex-wrap items-center gap-3 sm:gap-4 mb-8"
|
||
@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);
|
||
"
|
||
>
|
||
{{-- 額外隱藏欄位 / 額外篩選器(透過 slot 傳入) --}}
|
||
{{ $slot }}
|
||
|
||
{{-- 搜尋輸入框 + 按鈕群組 --}}
|
||
<div class="flex items-center gap-3 flex-1 sm:flex-none">
|
||
{{-- 搜尋輸入框 --}}
|
||
<div class="relative group flex-1 sm:flex-none">
|
||
<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="{{ $name }}"
|
||
value="{{ $value }}"
|
||
placeholder="{{ $placeholder ?: __('Search...') }}"
|
||
class="luxury-input py-2.5 pl-11 pr-4 block w-full {{ $width }} text-sm"
|
||
>
|
||
</div>
|
||
|
||
{{-- 搜尋按鈕 + 重置按鈕 --}}
|
||
<div class="flex items-center gap-2 flex-none">
|
||
{{-- 搜尋按鈕 --}}
|
||
<button
|
||
type="submit"
|
||
class="p-2.5 rounded-xl bg-cyan-500 text-white hover:bg-cyan-600 shadow-lg shadow-cyan-500/25 transition-all active:scale-95"
|
||
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>
|
||
|
||
{{-- 重置按鈕(統一邏輯:清除所有 text input → 觸發 submit) --}}
|
||
<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 transition-all active:scale-95"
|
||
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>
|
||
</div>
|
||
</div>
|
||
</form>
|