[PROMOTE] Dev to Demo

1. 修正通行碼載入失敗問題
2. 標準化所有單據模組日期篩選器 UI
3. 優化操作紀錄查詢效能 (新增複合索引)
This commit is contained in:
sky121113 2026-05-16 23:42:37 +08:00
commit b33f91896f
19 changed files with 668 additions and 301 deletions

View File

@ -120,8 +120,22 @@ class ProductController extends Controller
});
}
if ($request->filled('start_date') && $request->filled('end_date')) {
$logQuery->whereBetween('created_at', [$request->start_date, $request->end_date]);
$logDefaultStart = now()->startOfDay()->format('Y-m-d H:i');
$logDefaultEnd = now()->endOfDay()->format('Y-m-d H:i');
if ($request->filled('start_date') || $request->filled('end_date')) {
if ($request->filled('start_date')) {
$logQuery->where('created_at', '>=', \Illuminate\Support\Carbon::parse($request->start_date));
}
if ($request->filled('end_date')) {
$logQuery->where('created_at', '<=', \Illuminate\Support\Carbon::parse($request->end_date)->endOfMinute());
}
} else {
$logQuery->whereBetween('created_at', [now()->startOfDay(), now()->endOfDay()]);
$request->merge([
'start_date' => $logDefaultStart,
'end_date' => $logDefaultEnd
]);
}
$logs = $logQuery->latest()->paginate($per_page, ['*'], 'log_page')->withQueryString();
@ -130,18 +144,25 @@ class ProductController extends Controller
'success' => true,
'html' => view('admin.products.partials.tab-logs', [
'logs' => $logs,
'companies' => $companies
'companies' => $companies,
'logDefaultStart' => $logDefaultStart,
'logDefaultEnd' => $logDefaultEnd
])->render()
]);
}
}
$logDefaultStart = now()->startOfDay()->format('Y-m-d H:i');
$logDefaultEnd = now()->endOfDay()->format('Y-m-d H:i');
return view('admin.products.index', [
'products' => $products,
'categories' => $categories,
'companies' => $companies,
'companySettings' => $companySettings,
'routeName' => $routeName
'routeName' => $routeName,
'logDefaultStart' => $logDefaultStart,
'logDefaultEnd' => $logDefaultEnd
]);
}

View File

@ -36,6 +36,14 @@ class SalesController extends Controller
$startDate = $request->input('start_date');
$endDate = $request->input('end_date');
// 判斷是否為隱含篩選 (未選日期時預設抓6個月)
$isImplicitFilter = false;
if (!$startDate || !$endDate) {
$isImplicitFilter = true;
$startDate = now()->subMonths(6)->format('Y-m-d H:i');
$endDate = now()->format('Y-m-d H:i');
}
$data = [
'title' => '銷售&金流紀錄',
'description' => '銷售交易與金流明細查詢',
@ -45,9 +53,10 @@ class SalesController extends Controller
'machine_id' => $machineId,
'payment_type' => $paymentType,
'status' => $status,
'start_date' => $startDate,
'end_date' => $endDate,
'start_date' => $request->input('start_date'), // 保留原始輸入以顯示於 UI (如果是隱含的則 UI 顯示空)
'end_date' => $request->input('end_date'),
],
'isImplicitFilter' => $isImplicitFilter,
'machines' => Machine::select('id', 'name', 'serial_no')->get(),
'paymentTypes' => Order::getPaymentTypeLabels(),
];
@ -58,13 +67,12 @@ class SalesController extends Controller
$dispenseQuery = DispenseRecord::with(['order:id,order_no,flow_id', 'machine:id,name,serial_no', 'product:id,name']);
// 共用過濾器:日期
if ($startDate && $endDate) {
$start = Carbon::parse($startDate);
$end = Carbon::parse($endDate)->endOfMinute();
$ordersQuery->whereBetween('created_at', [$start, $end]);
$invoicesQuery->whereBetween('invoice_date', [$start, $end]);
$dispenseQuery->whereBetween('machine_time', [$start, $end]);
}
$start = Carbon::parse($startDate);
$end = Carbon::parse($endDate)->endOfMinute();
$ordersQuery->whereBetween('created_at', [$start, $end]);
$invoicesQuery->whereBetween('invoice_date', [$start, $end]);
$dispenseQuery->whereBetween('machine_time', [$start, $end]);
// 共用過濾器:機台
if ($machineId) {
@ -195,12 +203,20 @@ class SalesController extends Controller
$logQuery->where('action', $request->action);
}
// 新增:日期區間篩選
if ($request->filled('start_date') && $request->filled('end_date')) {
// 新增:日期區間篩選 (隱含 6 個月限制)
$startDate = $request->input('start_date');
$endDate = $request->input('end_date');
if (!$startDate && !$endDate) {
$logQuery->where('created_at', '>=', now()->subMonths(6));
} else {
try {
$start = \Carbon\Carbon::parse($request->start_date)->startOfMinute();
$end = \Carbon\Carbon::parse($request->end_date)->endOfMinute();
$logQuery->whereBetween('created_at', [$start, $end]);
if ($startDate) {
$logQuery->where('created_at', '>=', \Carbon\Carbon::parse($startDate)->startOfMinute());
}
if ($endDate) {
$logQuery->where('created_at', '<=', \Carbon\Carbon::parse($endDate)->endOfMinute());
}
} catch (\Exception $e) { }
}
@ -416,12 +432,20 @@ class SalesController extends Controller
$logQuery->where('action', $request->action);
}
// 新增:日期區間篩選
if ($request->filled('start_date') && $request->filled('end_date')) {
// 新增:日期區間篩選 (隱含 6 個月限制)
$startDate = $request->input('start_date');
$endDate = $request->input('end_date');
if (!$startDate && !$endDate) {
$logQuery->where('created_at', '>=', now()->subMonths(6));
} else {
try {
$start = \Carbon\Carbon::parse($request->start_date)->startOfMinute();
$end = \Carbon\Carbon::parse($request->end_date)->endOfMinute();
$logQuery->whereBetween('created_at', [$start, $end]);
if ($startDate) {
$logQuery->where('created_at', '>=', \Carbon\Carbon::parse($startDate)->startOfMinute());
}
if ($endDate) {
$logQuery->where('created_at', '<=', \Carbon\Carbon::parse($endDate)->endOfMinute());
}
} catch (\Exception $e) { }
}

View File

@ -191,8 +191,19 @@ class WarehouseController extends Controller
if ($search = $request->input('search_order')) {
$query->where('order_no', 'like', "%{$search}%");
}
if ($request->filled('start_date') && $request->filled('end_date')) {
$query->whereBetween('created_at', [$request->start_date, $request->end_date]);
if ($request->filled('start_date') || $request->filled('end_date')) {
if ($request->filled('start_date')) {
$query->where('created_at', '>=', \Illuminate\Support\Carbon::parse($request->start_date));
}
if ($request->filled('end_date')) {
$query->where('created_at', '<=', \Illuminate\Support\Carbon::parse($request->end_date)->endOfMinute());
}
} else {
// 隱性限制:預設只抓 6 個月內的單據以保護效能,但 UI 保持空白
$query->where('created_at', '>=', now()->subMonths(6)->startOfDay());
$data['stockInDefaultStart'] = '';
$data['stockInDefaultEnd'] = '';
}
$data['orders'] = $query->paginate($request->input('per_page', 10), ['*'], 'order_page')->withQueryString();
$data['stock_in_products'] = Product::with('translations')->orderBy('name')->get(['id', 'name', 'image_url', 'name_dictionary_key']);
@ -210,8 +221,29 @@ class WarehouseController extends Controller
if ($request->filled('type')) {
$query->where('type', $request->input('type'));
}
if ($request->filled('start_date') && $request->filled('end_date')) {
$query->whereBetween('created_at', [$request->start_date, $request->end_date]);
if ($request->filled('start_date') || $request->filled('end_date')) {
if ($request->filled('start_date')) {
$query->where('created_at', '>=', \Illuminate\Support\Carbon::parse($request->start_date));
}
if ($request->filled('end_date')) {
$query->where('created_at', '<=', \Illuminate\Support\Carbon::parse($request->end_date)->endOfMinute());
}
} else {
// 預設當天
$start = now()->startOfDay();
$end = now()->endOfDay();
$query->whereBetween('created_at', [$start, $end]);
$data['movementDefaultStart'] = $start->format('Y-m-d H:i');
$data['movementDefaultEnd'] = $end->format('Y-m-d H:i');
// 只有在當前分頁是 movements 時才合併到 request
if ($tab === 'movements') {
$request->merge([
'start_date' => $data['movementDefaultStart'],
'end_date' => $data['movementDefaultEnd']
]);
}
}
$data['movements'] = $query->paginate($request->input('per_page', 15), ['*'], 'movement_page')->withQueryString();
}
@ -378,8 +410,16 @@ class WarehouseController extends Controller
if ($search = $request->input('search_order')) {
$query->where('order_no', 'like', "%{$search}%");
}
if ($request->filled('start_date') && $request->filled('end_date')) {
$query->whereBetween('created_at', [$request->start_date, $request->end_date]);
if ($request->filled('start_date') || $request->filled('end_date')) {
if ($request->filled('start_date')) {
$query->where('created_at', '>=', \Illuminate\Support\Carbon::parse($request->start_date));
}
if ($request->filled('end_date')) {
$query->where('created_at', '<=', \Illuminate\Support\Carbon::parse($request->end_date)->endOfMinute());
}
} else {
// 隱性限制:預設只抓 6 個月內的單據以保護效能,但 UI 保持空白
$query->where('created_at', '>=', now()->subMonths(6)->startOfDay());
}
$orders = $query->paginate($request->input('per_page', 15))->withQueryString();
@ -394,8 +434,11 @@ class WarehouseController extends Controller
$warehouses = Warehouse::active()->orderBy('name')->get(['id', 'name']);
$machines = Machine::orderBy('name')->get(['id', 'name', 'serial_no']);
$products = Product::with('translations')->orderBy('name')->get(['id', 'name', 'image_url', 'name_dictionary_key']);
$defaultStart = '';
$defaultEnd = '';
return view('admin.warehouses.transfers', compact('orders', 'warehouses', 'machines', 'products'));
return view('admin.warehouses.transfers', compact('orders', 'warehouses', 'machines', 'products', 'defaultStart', 'defaultEnd'));
}
/**
@ -674,8 +717,16 @@ class WarehouseController extends Controller
if ($search = $request->input('search_order')) {
$query->where('order_no', 'like', "%{$search}%");
}
if ($request->filled('start_date') && $request->filled('end_date')) {
$query->whereBetween('created_at', [$request->start_date, $request->end_date]);
if ($request->filled('start_date') || $request->filled('end_date')) {
if ($request->filled('start_date')) {
$query->where('created_at', '>=', \Illuminate\Support\Carbon::parse($request->start_date));
}
if ($request->filled('end_date')) {
$query->where('created_at', '<=', \Illuminate\Support\Carbon::parse($request->end_date)->endOfMinute());
}
} else {
// 隱性限制:預設只抓 6 個月內的單據以保護效能,但 UI 保持空白
$query->where('created_at', '>=', now()->subMonths(6)->startOfDay());
}
$orders = $query->paginate($request->input('per_page', 10))->withQueryString();
@ -691,14 +742,16 @@ class WarehouseController extends Controller
$machines = Machine::orderBy('name')->get(['id', 'name', 'serial_no']);
$products = Product::with('translations')->orderBy('name')->get(['id', 'name', 'image_url', 'name_dictionary_key']);
// 同租戶帳號(用於指派人員)
$userQuery = \App\Models\System\User::where('status', 1)->orderBy('name');
if (!Auth::user()->isSystemAdmin()) {
$userQuery->where('company_id', Auth::user()->company_id);
}
$users = $userQuery->get(['id', 'name']);
return view('admin.warehouses.replenishments', compact('orders', 'warehouses', 'machines', 'products', 'users'));
$defaultStart = '';
$defaultEnd = '';
return view('admin.warehouses.replenishments', compact('orders', 'warehouses', 'machines', 'products', 'users', 'defaultStart', 'defaultEnd'));
}
/**

View File

@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('system_operation_logs', function (Blueprint $table) {
$table->index(['company_id', 'created_at']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('system_operation_logs', function (Blueprint $table) {
$table->dropIndex(['company_id', 'created_at']);
});
}
};

View File

@ -1464,6 +1464,7 @@
"Show points rules in products": "Show points rules in products",
"Showing": "Showing",
"Showing :from to :to of :total items": "Showing :from to :to of :total items",
"Showing last 6 months by default when no date range is selected": "Showing last 6 months by default when no date range is selected",
"Sign in to your account": "Sign in to your account",
"Signed in as": "Signed in as",
"Slot": "Slot",

View File

@ -1464,6 +1464,7 @@
"Show points rules in products": "商品にポイントルールフィールドを表示する",
"Showing": "表示中",
"Showing :from to :to of :total items": "全 :total 件中 :from から :to 件を表示",
"Showing last 6 months by default when no date range is selected": "日付範囲が未選択の場合、デフォルトで過去6ヶ月分を表示します",
"Sign in to your account": "アカウントにサインイン",
"Signed in as": "ログイン中のユーザー",
"Slot": "スロット",

View File

@ -1484,6 +1484,7 @@
"Show points rules in products": "在商品資料中顯示點數規則相關欄位",
"Showing": "目前顯示",
"Showing :from to :to of :total items": "顯示第 :from 到 :to 項,共 :total 項",
"Showing last 6 months by default when no date range is selected": "未選擇日期區間時,預設顯示最近 6 個月的資料",
"Sign in to your account": "隨時隨地掌控您的業務。",
"Signed in as": "登入身份",
"Slot": "貨道",

View File

@ -30,49 +30,73 @@
placeholder="{{ __('Search notes or values...') }}">
</div>
{{-- Date Range --}}
<div class="relative group w-full sm:w-72 sm:flex-none"
{{-- 開始時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.dateRange, {
mode: 'range',
x-init="fp = flatpickr($refs.startDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
locale: '{{ app()->getLocale() == 'zh_TW' ? 'zh_tw' : 'en' }}',
defaultDate: '{{ request('start_date') }}' && '{{ request('end_date') }}' ? ['{{ request('start_date') }}', '{{ request('end_date') }}'] : [],
onChange: function(selectedDates, dateStr, instance) {
if (selectedDates.length === 2) {
$refs.startDate.value = instance.formatDate(selectedDates[0], 'Y-m-d H:i');
$refs.endDate.value = instance.formatDate(selectedDates[1], 'Y-m-d H:i');
} else if (selectedDates.length === 0) {
$refs.startDate.value = '';
$refs.endDate.value = '';
}
}
defaultHour: 0,
defaultMinute: 0,
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('start_date', $logDefaultStart ?? '') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="hidden" name="start_date" x-ref="startDate" value="{{ request('start_date') }}">
<input type="hidden" name="end_date" x-ref="endDate" value="{{ request('end_date') }}">
<input type="text" x-ref="dateRange"
value="{{ request('start_date') && request('end_date') ? request('start_date') . ' 至 ' . request('end_date') : (request('start_date') ?: '') }}"
placeholder="{{ __('Select Date Range') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<input type="text" name="start_date" x-ref="startDate"
value="{{ request('start_date', $logDefaultStart ?? '') }}"
placeholder="{{ __('Start Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('Start Time') }}</div>
</div>
{{-- 結束時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.endDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 23,
defaultMinute: 59,
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('end_date', $logDefaultEnd ?? '') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="end_date" x-ref="endDate"
value="{{ request('end_date', $logDefaultEnd ?? '') }}"
placeholder="{{ __('End Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('End Time') }}</div>
</div>
{{-- Buttons --}}
<div class="flex items-center gap-2 ml-auto sm:ml-0">
<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">
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>
<button type="button" @click="
$el.closest('form').querySelectorAll('input[type=text], input[type=hidden]:not([name=tab]), select').forEach(i => i.value = '');
$el.closest('form').querySelectorAll('input').forEach(i => {
if (i.name === 'start_date' && i._flatpickr) i._flatpickr.setDate('{{ $logDefaultStart }}');
else if (i.name === 'end_date' && i._flatpickr) i._flatpickr.setDate('{{ $logDefaultEnd }}');
else if (i._flatpickr) i._flatpickr.clear();
else if (i.name !== 'tab') i.value = '';
});
$el.closest('form').querySelectorAll('select').forEach(s => {
s.value = ' ';
const instance = window.HSSelect.getInstance(s);
if (instance) instance.setValue(' ');
});
fetchTabData('logs', '{{ route('admin.data-config.products.index') }}?tab=logs');
"
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">
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>

View File

@ -30,6 +30,8 @@
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: 'zh_tw',
defaultDate: historyStartDate || '{{ now()->startOfDay()->format('Y-m-d H:i') }}',
onChange: (selectedDates, dateStr) => { historyStartDate = dateStr }
@ -52,6 +54,8 @@
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 23,
defaultMinute: 59,
locale: 'zh_tw',
defaultDate: historyEndDate || '{{ now()->endOfDay()->format('Y-m-d H:i') }}',
position: 'auto right',

View File

@ -28,41 +28,48 @@
</x-searchable-select>
</div>
{{-- 日期範圍 --}}
<div class="relative group w-full lg:w-72 lg:flex-none" x-data="{ fp: null }" x-init="fp = flatpickr($refs.dateRange, {
mode: 'range',
{{-- 開始時間 --}}
<div class="relative group w-full lg:w-56 lg:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.startDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: '{{ app()->getLocale() == 'zh_TW' ? 'zh_tw' : 'en' }}',
defaultDate: '{{ $filters['start_date'] }}' && '{{ $filters['end_date'] }}' ? ['{{ $filters['start_date'] }}', '{{ $filters['end_date'] }}'] : [],
onChange: function(selectedDates, dateStr, instance) {
if (selectedDates.length === 2) {
$refs.startDate.value = instance.formatDate(selectedDates[0], 'Y-m-d H:i');
$refs.endDate.value = instance.formatDate(selectedDates[1], 'Y-m-d H:i');
$el.closest('form').dispatchEvent(new Event('submit'));
} else if (selectedDates.length === 0) {
$refs.startDate.value = '';
$refs.endDate.value = '';
$el.closest('form').dispatchEvent(new Event('submit'));
}
}
position: 'auto right',
defaultDate: '{{ $filters['start_date'] }}'
})">
<span
class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
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>
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="hidden" name="start_date" x-ref="startDate" value="{{ $filters['start_date'] }}">
<input type="hidden" name="end_date" x-ref="endDate" value="{{ $filters['end_date'] }}">
<input type="text" x-ref="dateRange"
value="{{ $filters['start_date'] && $filters['end_date'] ? $filters['start_date'] . ' 至 ' . $filters['end_date'] : ($filters['start_date'] ?: '') }}"
placeholder="{{ __('Select Date Range') }}"
class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<input type="text" name="start_date" x-ref="startDate"
value="{{ $filters['start_date'] }}"
placeholder="{{ __('Start Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('Start Time') }}</div>
</div>
{{-- 結束時間 --}}
<div class="relative group w-full lg:w-56 lg:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.endDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 23,
defaultMinute: 59,
locale: '{{ app()->getLocale() == 'zh_TW' ? 'zh_tw' : 'en' }}',
position: 'auto right',
defaultDate: '{{ $filters['end_date'] }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="end_date" x-ref="endDate"
value="{{ $filters['end_date'] }}"
placeholder="{{ __('End Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('End Time') }}</div>
</div>
<div class="flex items-center gap-2 ml-auto lg:ml-0 shrink-0">
@ -73,7 +80,19 @@
<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="switchTab('dispense', '{{ route('admin.sales.index', ['tab' => 'dispense']) }}')"
<button type="button"
@click="
$el.closest('form').querySelectorAll('input').forEach(i => {
if (i._flatpickr) i._flatpickr.clear();
else if (i.name !== 'tab') i.value = '';
});
$el.closest('form').querySelectorAll('select').forEach(s => {
s.value = ' ';
const instance = window.HSSelect.getInstance(s);
if (instance) instance.setValue(' ');
});
switchTab('dispense', '{{ route('admin.sales.index', ['tab' => 'dispense']) }}');
"
class="p-2.5 rounded-xl bg-slate-100 dark:bg-slate-800 text-slate-500 dark:text-slate-400 hover:bg-slate-200 dark:hover:bg-slate-700 transition-all active:scale-95 border border-slate-200 dark:border-slate-700"
title="{{ __('Reset') }}">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
@ -84,6 +103,15 @@
</div>
</form>
@if($isImplicitFilter)
<div class="flex items-center gap-2 px-1 mb-6 -mt-4">
<div class="w-1.5 h-1.5 rounded-full bg-cyan-500/50"></div>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">
{{ __('Showing last 6 months by default when no date range is selected') }}
</span>
</div>
@endif
{{-- Table (Desktop) --}}
<div class="hidden xl:block overflow-x-auto">
<table class="w-full text-left border-separate border-spacing-0">

View File

@ -29,41 +29,48 @@
</x-searchable-select>
</div>
{{-- 日期範圍 --}}
<div class="relative group w-full lg:w-72 lg:flex-none" x-data="{ fp: null }" x-init="fp = flatpickr($refs.dateRange, {
mode: 'range',
{{-- 開始時間 --}}
<div class="relative group w-full lg:w-56 lg:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.startDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: '{{ app()->getLocale() == 'zh_TW' ? 'zh_tw' : 'en' }}',
defaultDate: '{{ $filters['start_date'] }}' && '{{ $filters['end_date'] }}' ? ['{{ $filters['start_date'] }}', '{{ $filters['end_date'] }}'] : [],
onChange: function(selectedDates, dateStr, instance) {
if (selectedDates.length === 2) {
$refs.startDate.value = instance.formatDate(selectedDates[0], 'Y-m-d H:i');
$refs.endDate.value = instance.formatDate(selectedDates[1], 'Y-m-d H:i');
$el.closest('form').dispatchEvent(new Event('submit'));
} else if (selectedDates.length === 0) {
$refs.startDate.value = '';
$refs.endDate.value = '';
$el.closest('form').dispatchEvent(new Event('submit'));
}
}
position: 'auto right',
defaultDate: '{{ $filters['start_date'] }}'
})">
<span
class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
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>
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="hidden" name="start_date" x-ref="startDate" value="{{ $filters['start_date'] }}">
<input type="hidden" name="end_date" x-ref="endDate" value="{{ $filters['end_date'] }}">
<input type="text" x-ref="dateRange"
value="{{ $filters['start_date'] && $filters['end_date'] ? $filters['start_date'] . ' 至 ' . $filters['end_date'] : ($filters['start_date'] ?: '') }}"
placeholder="{{ __('Select Date Range') }}"
class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<input type="text" name="start_date" x-ref="startDate"
value="{{ $filters['start_date'] }}"
placeholder="{{ __('Start Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('Start Time') }}</div>
</div>
{{-- 結束時間 --}}
<div class="relative group w-full lg:w-56 lg:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.endDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 23,
defaultMinute: 59,
locale: '{{ app()->getLocale() == 'zh_TW' ? 'zh_tw' : 'en' }}',
position: 'auto right',
defaultDate: '{{ $filters['end_date'] }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="end_date" x-ref="endDate"
value="{{ $filters['end_date'] }}"
placeholder="{{ __('End Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('End Time') }}</div>
</div>
<div class="flex items-center gap-2 ml-auto lg:ml-0 shrink-0">
@ -74,7 +81,19 @@
<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="switchTab('invoices', '{{ route('admin.sales.index', ['tab' => 'invoices']) }}')"
<button type="button"
@click="
$el.closest('form').querySelectorAll('input').forEach(i => {
if (i._flatpickr) i._flatpickr.clear();
else if (i.name !== 'tab') i.value = '';
});
$el.closest('form').querySelectorAll('select').forEach(s => {
s.value = ' ';
const instance = window.HSSelect.getInstance(s);
if (instance) instance.setValue(' ');
});
switchTab('invoices', '{{ route('admin.sales.index', ['tab' => 'invoices']) }}');
"
class="p-2.5 rounded-xl bg-slate-100 dark:bg-slate-800 text-slate-500 dark:text-slate-400 hover:bg-slate-200 dark:hover:bg-slate-700 transition-all active:scale-95 border border-slate-200 dark:border-slate-700"
title="{{ __('Reset') }}">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
@ -85,6 +104,15 @@
</div>
</form>
@if($isImplicitFilter)
<div class="flex items-center gap-2 px-1 mb-6 -mt-4">
<div class="w-1.5 h-1.5 rounded-full bg-cyan-500/50"></div>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">
{{ __('Showing last 6 months by default when no date range is selected') }}
</span>
</div>
@endif
{{-- Table (Desktop) --}}
<div class="hidden xl:block overflow-x-auto">
<table class="w-full text-left border-separate border-spacing-0">

View File

@ -29,41 +29,48 @@
</x-searchable-select>
</div>
{{-- 日期範圍 --}}
<div class="relative group w-full lg:w-72 lg:flex-none" x-data="{ fp: null }" x-init="fp = flatpickr($refs.dateRange, {
mode: 'range',
{{-- 開始時間 --}}
<div class="relative group w-full lg:w-56 lg:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.startDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: '{{ app()->getLocale() == 'zh_TW' ? 'zh_tw' : 'en' }}',
defaultDate: '{{ $filters['start_date'] }}' && '{{ $filters['end_date'] }}' ? ['{{ $filters['start_date'] }}', '{{ $filters['end_date'] }}'] : [],
onChange: function(selectedDates, dateStr, instance) {
if (selectedDates.length === 2) {
$refs.startDate.value = instance.formatDate(selectedDates[0], 'Y-m-d H:i');
$refs.endDate.value = instance.formatDate(selectedDates[1], 'Y-m-d H:i');
$el.closest('form').dispatchEvent(new Event('submit'));
} else if (selectedDates.length === 0) {
$refs.startDate.value = '';
$refs.endDate.value = '';
$el.closest('form').dispatchEvent(new Event('submit'));
}
}
position: 'auto right',
defaultDate: '{{ $filters['start_date'] }}'
})">
<span
class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
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>
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="hidden" name="start_date" x-ref="startDate" value="{{ $filters['start_date'] }}">
<input type="hidden" name="end_date" x-ref="endDate" value="{{ $filters['end_date'] }}">
<input type="text" x-ref="dateRange"
value="{{ $filters['start_date'] && $filters['end_date'] ? $filters['start_date'] . ' 至 ' . $filters['end_date'] : ($filters['start_date'] ?: '') }}"
placeholder="{{ __('Select Date Range') }}"
class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<input type="text" name="start_date" x-ref="startDate"
value="{{ $filters['start_date'] }}"
placeholder="{{ __('Start Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('Start Time') }}</div>
</div>
{{-- 結束時間 --}}
<div class="relative group w-full lg:w-56 lg:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.endDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 23,
defaultMinute: 59,
locale: '{{ app()->getLocale() == 'zh_TW' ? 'zh_tw' : 'en' }}',
position: 'auto right',
defaultDate: '{{ $filters['end_date'] }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="end_date" x-ref="endDate"
value="{{ $filters['end_date'] }}"
placeholder="{{ __('End Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('End Time') }}</div>
</div>
<div class="flex items-center gap-2 ml-auto lg:ml-0 shrink-0">
@ -74,7 +81,19 @@
<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="switchTab('orders', '{{ route('admin.sales.index', ['tab' => 'orders']) }}')"
<button type="button"
@click="
$el.closest('form').querySelectorAll('input').forEach(i => {
if (i._flatpickr) i._flatpickr.clear();
else if (i.name !== 'tab') i.value = '';
});
$el.closest('form').querySelectorAll('select').forEach(s => {
s.value = ' ';
const instance = window.HSSelect.getInstance(s);
if (instance) instance.setValue(' ');
});
switchTab('orders', '{{ route('admin.sales.index', ['tab' => 'orders']) }}');
"
class="p-2.5 rounded-xl bg-slate-100 dark:bg-slate-800 text-slate-500 dark:text-slate-400 hover:bg-slate-200 dark:hover:bg-slate-700 transition-all active:scale-95 border border-slate-200 dark:border-slate-700"
title="{{ __('Reset') }}">
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">
@ -85,6 +104,15 @@
</div>
</form>
@if($isImplicitFilter)
<div class="flex items-center gap-2 px-1 mb-6 -mt-4">
<div class="w-1.5 h-1.5 rounded-full bg-cyan-500/50"></div>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">
{{ __('Showing last 6 months by default when no date range is selected') }}
</span>
</div>
@endif
{{-- Table (Desktop) --}}
<div class="hidden xl:block overflow-x-auto">
<table class="w-full text-left border-separate border-spacing-0">

View File

@ -97,7 +97,7 @@
});
}
const historyUrl = new URL(url);
const historyUrl = new URL(url, window.location.origin);
historyUrl.searchParams.delete('_ajax');
window.history.pushState({}, '', historyUrl.toString());
}

View File

@ -33,38 +33,62 @@
</x-searchable-select>
</div>
{{-- 日期範圍 --}}
<div class="relative group w-full sm:w-72 sm:flex-none"
{{-- 開始時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.dateRange, {
mode: 'range',
x-init="fp = flatpickr($refs.startDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: '{{ app()->getLocale() == 'zh_TW' ? 'zh_tw' : 'en' }}',
defaultDate: '{{ request('start_date') }}' && '{{ request('end_date') }}' ? ['{{ request('start_date') }}', '{{ request('end_date') }}'] : [],
onChange: function(selectedDates, dateStr, instance) {
if (selectedDates.length === 2) {
$refs.startDate.value = instance.formatDate(selectedDates[0], 'Y-m-d H:i');
$refs.endDate.value = instance.formatDate(selectedDates[1], 'Y-m-d H:i');
} else if (selectedDates.length === 0) {
$refs.startDate.value = '';
$refs.endDate.value = '';
}
}
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('start_date') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="hidden" name="start_date" x-ref="startDate" value="{{ request('start_date') }}">
<input type="hidden" name="end_date" x-ref="endDate" value="{{ request('end_date') }}">
<input type="text" x-ref="dateRange"
value="{{ request('start_date') && request('end_date') ? request('start_date') . ' 至 ' . request('end_date') : (request('start_date') ?: '') }}"
placeholder="{{ __('Select Date Range') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<input type="text" name="start_date" x-ref="startDate"
value="{{ request('start_date') }}"
placeholder="{{ __('Start Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('Start Time') }}</div>
</div>
{{-- 結束時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.endDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 23,
defaultMinute: 59,
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('end_date') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="end_date" x-ref="endDate"
value="{{ request('end_date') }}"
placeholder="{{ __('End Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('End Time') }}</div>
</div>
{{-- 6 個月限制提示 (僅在未搜尋時間時顯示) --}}
@if(!request('start_date') && !request('end_date'))
<div class="hidden md:flex items-center gap-2 px-4 py-2 bg-amber-50/50 dark:bg-amber-900/10 border border-amber-100/50 dark:border-amber-800/30 rounded-xl">
<svg class="w-4 h-4 text-amber-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span class="text-[10px] font-bold text-amber-600/80 dark:text-amber-500/80 uppercase tracking-wider">
{{ __('Showing last 6 months by default when no date range is selected') }}
</span>
</div>
@endif
{{-- 按鈕組 --}}
<div class="flex items-center gap-2 ml-auto sm:ml-0">
<button type="submit"

View File

@ -17,38 +17,62 @@
placeholder="{{ __('Search logs...') }}">
</div>
{{-- 日期範圍 --}}
<div class="relative group w-full sm:w-72 sm:flex-none"
{{-- 開始時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.dateRange, {
mode: 'range',
x-init="fp = flatpickr($refs.startDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: '{{ app()->getLocale() == 'zh_TW' ? 'zh_tw' : 'en' }}',
defaultDate: '{{ request('start_date') }}' && '{{ request('end_date') }}' ? ['{{ request('start_date') }}', '{{ request('end_date') }}'] : [],
onChange: function(selectedDates, dateStr, instance) {
if (selectedDates.length === 2) {
$refs.startDate.value = instance.formatDate(selectedDates[0], 'Y-m-d H:i');
$refs.endDate.value = instance.formatDate(selectedDates[1], 'Y-m-d H:i');
} else if (selectedDates.length === 0) {
$refs.startDate.value = '';
$refs.endDate.value = '';
}
}
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('start_date') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="hidden" name="start_date" x-ref="startDate" value="{{ request('start_date') }}">
<input type="hidden" name="end_date" x-ref="endDate" value="{{ request('end_date') }}">
<input type="text" x-ref="dateRange"
value="{{ request('start_date') && request('end_date') ? request('start_date') . ' 至 ' . request('end_date') : (request('start_date') ?: '') }}"
placeholder="{{ __('Select Date Range') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<input type="text" name="start_date" x-ref="startDate"
value="{{ request('start_date') }}"
placeholder="{{ __('Start Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('Start Time') }}</div>
</div>
{{-- 結束時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.endDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 23,
defaultMinute: 59,
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('end_date') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="end_date" x-ref="endDate"
value="{{ request('end_date') }}"
placeholder="{{ __('End Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('End Time') }}</div>
</div>
{{-- 6 個月限制提示 (僅在未搜尋時間時顯示) --}}
@if(!request('start_date') && !request('end_date'))
<div class="hidden md:flex items-center gap-2 px-4 py-2 bg-amber-50/50 dark:bg-amber-900/10 border border-amber-100/50 dark:border-amber-800/30 rounded-xl">
<svg class="w-4 h-4 text-amber-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<span class="text-[10px] font-bold text-amber-600/80 dark:text-amber-500/80 uppercase tracking-wider">
{{ __('Showing last 6 months by default when no date range is selected') }}
</span>
</div>
@endif
{{-- 按鈕組 --}}
<div class="flex items-center gap-2 ml-auto sm:ml-0">
<button type="submit"

View File

@ -28,36 +28,44 @@
</x-searchable-select>
</div>
{{-- 日期範圍 --}}
<div class="relative group w-full sm:w-72 sm:flex-none"
{{-- 開始時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.dateRange, {
mode: 'range',
x-init="fp = flatpickr($refs.startDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: 'zh_tw',
defaultDate: '{{ request('start_date') }}' && '{{ request('end_date') }}' ? ['{{ request('start_date') }}', '{{ request('end_date') }}'] : [],
onChange: function(selectedDates, dateStr, instance) {
if (selectedDates.length === 2) {
$refs.startDate.value = instance.formatDate(selectedDates[0], 'Y-m-d H:i');
$refs.endDate.value = instance.formatDate(selectedDates[1], 'Y-m-d H:i');
} else if (selectedDates.length === 0) {
$refs.startDate.value = '';
$refs.endDate.value = '';
}
}
position: 'auto right',
defaultDate: '{{ request('start_date', $movementDefaultStart ?? '') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="hidden" name="start_date" x-ref="startDate" value="{{ request('start_date') }}">
<input type="hidden" name="end_date" x-ref="endDate" value="{{ request('end_date') }}">
<input type="text" x-ref="dateRange"
value="{{ request('start_date') && request('end_date') ? request('start_date') . ' 至 ' . request('end_date') : (request('start_date') ?: '') }}"
placeholder="{{ __('Select Date Range') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<input type="text" name="start_date" x-ref="startDate"
value="{{ request('start_date', $movementDefaultStart ?? '') }}"
placeholder="{{ __('Start Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('Start Time') }}</div>
</div>
{{-- 結束時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.endDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('end_date', $movementDefaultEnd ?? '') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="end_date" x-ref="endDate"
value="{{ request('end_date', $movementDefaultEnd ?? '') }}"
placeholder="{{ __('End Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('End Time') }}</div>
</div>
{{-- 搜尋 + 重置按鈕 --}}
@ -70,7 +78,12 @@
<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('input').forEach(i => {
if (i.name === 'start_date' && i._flatpickr) i._flatpickr.setDate('{{ $movementDefaultStart }}');
else if (i.name === 'end_date' && i._flatpickr) i._flatpickr.setDate('{{ $movementDefaultEnd }}');
else if (i._flatpickr) i._flatpickr.clear();
else if (i.name !== 'tab' && i.name !== 'per_page') i.value = '';
});
$el.closest('form').querySelectorAll('select').forEach(s => {
s.value = ' ';
const instance = window.HSSelect.getInstance(s);

View File

@ -18,36 +18,48 @@
class="luxury-input py-2.5 pl-12 pr-6 block w-full sm:w-72 text-sm font-bold" placeholder="{{ __('Search order number...') }}">
</div>
{{-- 日期範圍 --}}
<div class="relative group w-full sm:w-72 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.dateRange, {
mode: 'range',
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: 'zh_tw',
defaultDate: '{{ request('start_date') }}' && '{{ request('end_date') }}' ? ['{{ request('start_date') }}', '{{ request('end_date') }}'] : [],
onChange: function(selectedDates, dateStr, instance) {
if (selectedDates.length === 2) {
$refs.startDate.value = instance.formatDate(selectedDates[0], 'Y-m-d H:i');
$refs.endDate.value = instance.formatDate(selectedDates[1], 'Y-m-d H:i');
} else if (selectedDates.length === 0) {
$refs.startDate.value = '';
$refs.endDate.value = '';
}
}
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="hidden" name="start_date" x-ref="startDate" value="{{ request('start_date') }}">
<input type="hidden" name="end_date" x-ref="endDate" value="{{ request('end_date') }}">
<input type="text" x-ref="dateRange"
value="{{ request('start_date') && request('end_date') ? request('start_date') . ' 至 ' . request('end_date') : (request('start_date') ?: '') }}"
placeholder="{{ __('Select Date Range') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
{{-- 開始時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.startDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('start_date', $stockInDefaultStart ?? '') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="start_date" x-ref="startDate"
value="{{ request('start_date', $stockInDefaultStart ?? '') }}"
placeholder="{{ __('Start Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('Start Time') }}</div>
</div>
{{-- 結束時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.endDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 23,
defaultMinute: 59,
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('end_date', $stockInDefaultEnd ?? '') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="end_date" x-ref="endDate"
value="{{ request('end_date', $stockInDefaultEnd ?? '') }}"
placeholder="{{ __('End Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('End Time') }}</div>
</div>
{{-- 狀態篩選 --}}
@ -76,7 +88,12 @@
<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('input').forEach(i => {
if (i.name === 'start_date' && i._flatpickr) i._flatpickr.setDate('{{ $stockInDefaultStart }}');
else if (i.name === 'end_date' && i._flatpickr) i._flatpickr.setDate('{{ $stockInDefaultEnd }}');
else if (i._flatpickr) i._flatpickr.clear();
else if (i.name !== 'tab' && i.name !== 'per_page') i.value = '';
});
$el.closest('form').querySelectorAll('select').forEach(s => {
s.value = ' ';
const instance = window.HSSelect.getInstance(s);
@ -91,6 +108,12 @@
</button>
</div>
</form>
<div class="flex items-center gap-2 px-1 mb-6 -mt-4">
<div class="w-1.5 h-1.5 rounded-full bg-cyan-500/50"></div>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">
{{ __('Showing last 6 months by default when no date range is selected') }}
</span>
</div>
{{-- Table Mode (Desktop) --}}
<div class="hidden xl:block overflow-x-auto">

View File

@ -625,38 +625,48 @@
</x-searchable-select>
</div>
{{-- Date Range --}}
<div class="w-full sm:w-72">
<div class="relative group"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.dateRange, {
mode: 'range',
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: 'zh_tw',
defaultDate: '{{ request('start_date') }}' && '{{ request('end_date') }}' ? ['{{ request('start_date') }}', '{{ request('end_date') }}'] : [],
onChange: function(selectedDates, dateStr, instance) {
if (selectedDates.length === 2) {
$refs.startDate.value = instance.formatDate(selectedDates[0], 'Y-m-d H:i');
$refs.endDate.value = instance.formatDate(selectedDates[1], 'Y-m-d H:i');
} else if (selectedDates.length === 0) {
$refs.startDate.value = '';
$refs.endDate.value = '';
}
}
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="hidden" name="start_date" x-ref="startDate" value="{{ request('start_date') }}">
<input type="hidden" name="end_date" x-ref="endDate" value="{{ request('end_date') }}">
<input type="text" x-ref="dateRange"
value="{{ request('start_date') && request('end_date') ? request('start_date') . ' 至 ' . request('end_date') : (request('start_date') ?: '') }}"
placeholder="{{ __('Select Date Range') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full cursor-pointer font-bold">
</div>
{{-- 開始時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.startDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('start_date', $defaultStart ?? '') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="start_date" x-ref="startDate"
value="{{ request('start_date', $defaultStart ?? '') }}"
placeholder="{{ __('Start Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('Start Time') }}</div>
</div>
{{-- 結束時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.endDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 23,
defaultMinute: 59,
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('end_date', $defaultEnd ?? '') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="end_date" x-ref="endDate"
value="{{ request('end_date', $defaultEnd ?? '') }}"
placeholder="{{ __('End Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('End Time') }}</div>
</div>
<div class="flex items-center gap-2 ml-auto sm:ml-0">
@ -668,7 +678,12 @@
<button type="button"
@click="
$el.closest('form').querySelectorAll('input[type=text], input[type=hidden]:not([name=per_page])').forEach(i => i.value = '');
$el.closest('form').querySelectorAll('input').forEach(i => {
if (i.name === 'start_date' && i._flatpickr) i._flatpickr.setDate('{{ $defaultStart }}');
else if (i.name === 'end_date' && i._flatpickr) i._flatpickr.setDate('{{ $defaultEnd }}');
else if (i._flatpickr) i._flatpickr.clear();
else if (i.name !== 'per_page') i.value = '';
});
$el.closest('form').querySelectorAll('select').forEach(s => {
s.value = ' ';
const instance = window.HSSelect.getInstance(s);
@ -683,6 +698,12 @@
</button>
</div>
</form>
<div class="flex items-center gap-2 px-1 mb-6 -mt-4">
<div class="w-1.5 h-1.5 rounded-full bg-cyan-500/50"></div>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">
{{ __('Showing last 6 months by default when no date range is selected') }}
</span>
</div>
@include('admin.warehouses.partials.table-replenishments')
</div>

View File

@ -392,38 +392,48 @@
</x-searchable-select>
</div>
{{-- Date Range --}}
<div class="w-full sm:w-72">
<div class="relative group"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.dateRange, {
mode: 'range',
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: 'zh_tw',
defaultDate: '{{ request('start_date') }}' && '{{ request('end_date') }}' ? ['{{ request('start_date') }}', '{{ request('end_date') }}'] : [],
onChange: function(selectedDates, dateStr, instance) {
if (selectedDates.length === 2) {
$refs.startDate.value = instance.formatDate(selectedDates[0], 'Y-m-d H:i');
$refs.endDate.value = instance.formatDate(selectedDates[1], 'Y-m-d H:i');
} else if (selectedDates.length === 0) {
$refs.startDate.value = '';
$refs.endDate.value = '';
}
}
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="hidden" name="start_date" x-ref="startDate" value="{{ request('start_date') }}">
<input type="hidden" name="end_date" x-ref="endDate" value="{{ request('end_date') }}">
<input type="text" x-ref="dateRange"
value="{{ request('start_date') && request('end_date') ? request('start_date') . ' 至 ' . request('end_date') : (request('start_date') ?: '') }}"
placeholder="{{ __('Select Date Range') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full cursor-pointer font-bold">
</div>
{{-- 開始時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.startDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 0,
defaultMinute: 0,
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('start_date', $defaultStart ?? '') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="start_date" x-ref="startDate"
value="{{ request('start_date', $defaultStart ?? '') }}"
placeholder="{{ __('Start Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('Start Time') }}</div>
</div>
{{-- 結束時間 --}}
<div class="relative group w-full sm:w-56 sm:flex-none"
x-data="{ fp: null }"
x-init="fp = flatpickr($refs.endDate, {
dateFormat: 'Y-m-d H:i',
enableTime: true,
time_24hr: true,
defaultHour: 23,
defaultMinute: 59,
locale: 'zh_tw',
position: 'auto right',
defaultDate: '{{ request('end_date', $defaultEnd ?? '') }}'
})">
<span class="absolute inset-y-0 left-0 flex items-center pl-4 pointer-events-none z-10 text-slate-400 group-focus-within:text-cyan-500 transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 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>
</span>
<input type="text" name="end_date" x-ref="endDate"
value="{{ request('end_date', $defaultEnd ?? '') }}"
placeholder="{{ __('End Time') }}" class="luxury-input py-2.5 pl-12 pr-6 block w-full text-sm font-bold cursor-pointer">
<div class="absolute -top-2 left-4 px-1 bg-white dark:bg-slate-900 text-[9px] font-black text-slate-400 uppercase tracking-widest opacity-0 group-focus-within:opacity-100 transition-opacity pointer-events-none">{{ __('End Time') }}</div>
</div>
<div class="flex items-center gap-2 ml-auto sm:ml-0">
@ -435,7 +445,12 @@
<button type="button"
@click="
$el.closest('form').querySelectorAll('input[type=text], input[type=hidden]:not([name=per_page])').forEach(i => i.value = '');
$el.closest('form').querySelectorAll('input').forEach(i => {
if (i.name === 'start_date' && i._flatpickr) i._flatpickr.setDate('{{ $defaultStart }}');
else if (i.name === 'end_date' && i._flatpickr) i._flatpickr.setDate('{{ $defaultEnd }}');
else if (i._flatpickr) i._flatpickr.clear();
else if (i.name !== 'per_page') i.value = '';
});
$el.closest('form').querySelectorAll('select').forEach(s => {
s.value = ' ';
const instance = window.HSSelect.getInstance(s);
@ -450,6 +465,12 @@
</button>
</div>
</form>
<div class="flex items-center gap-2 px-1 mb-6 -mt-4">
<div class="w-1.5 h-1.5 rounded-full bg-cyan-500/50"></div>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">
{{ __('Showing last 6 months by default when no date range is selected') }}
</span>
</div>
@include('admin.warehouses.partials.table-transfers')
</div>