star-cloud/resources/views/components/page-header.blade.php
sky121113 c3e60b8746 [FEAT] 新增商品 Excel 批量匯入與模板下載功能
1. 新增 ProductImportService 服務,實作 Excel 商品檔案解析、欄位驗證、多租戶 company_id 歸屬處理及資料批量寫入/更新邏輯。
2. 在 ProductController 新增 import 與 downloadTemplate 動作,處理檔案接收驗證與匯出,並在匯入後自動重建該公司商品目錄快取。
3. routes/web.php 新增商品下載模板與 Excel 匯入的專用路由。
4. 重構 products/index.blade.php,新增極簡奢華風商品匯入 Modal、檔案拖放/選擇區,並採用 Alpine.js 進行彈窗開啟與非同步上傳 API 交互。
5. 擴充 components/page-header.blade.php,使頁面主標頭支援渲染多個操作按鈕 (actions 插槽),以配合新增的「匯入商品」按鈕。
6. 同步更新 lang/zh_TW.json 與 lang/en.json,對齊「商品匯入成功」、「請選擇公司」等相關語系翻譯。
7. 微調 AdvertisementController,維持全站 Controller 進度對齊。
2026-05-28 11:19:00 +08:00

74 lines
2.6 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{{--
頁面標題區塊 (x-page-header)
鎖定所有頁面的 h1 標題 + 副標題 + 右側 Action 區樣式。
Props:
- $title (string) 必填 頁面主標題(建議使用 __('key') 翻譯)
- $subtitle (string) 選填 副標題描述文字
Slot:
- $slot 選填,右側 Action 按鈕區btn-luxury-primary 等)
用法:
════════════════════════════════════
1. Action 按鈕(純標題):
<x-page-header
:title="__('Machine List')"
:subtitle="__('Manage your machine fleet')"
/>
2. 帶右側 Action 按鈕:
<x-page-header
:title="__('Warehouse Overview')"
:subtitle="__('Manage your warehouses')"
>
<button @click="openCreateModal()" class="btn-luxury-primary flex items-center gap-2">
<svg class="w-4 h-4" ...>...</svg>
<span class="text-sm sm:text-base">{{ __('Add') }}</span>
</button>
</x-page-header>
3. Alpine 動態 Action Tab 控制的按鈕):
<x-page-header :title="__('Product Management')" :subtitle="__('...')">
<template x-if="activeTab === 'products'">
<a href="..." class="btn-luxury-primary ...">...</a>
</template>
</x-page-header>
════════════════════════════════════
--}}
@props([
'title' => '',
'subtitle' => '',
'containerClass' => 'flex items-center justify-between gap-4',
'actionsClass' => 'flex items-center gap-3 shrink-0',
])
<div class="{{ $containerClass }}">
{{-- 左側:標題 + 副標題 --}}
<div class="flex items-center gap-4 min-w-0">
@if(isset($back))
<div class="shrink-0">
{{ $back }}
</div>
@endif
<div class="min-w-0">
<h1 class="text-2xl sm:text-3xl font-black text-slate-800 dark:text-white tracking-tight font-display transition-all duration-300 truncate">
{{ $title }}
</h1>
@if($subtitle)
<p class="text-sm font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest truncate">
{{ $subtitle }}
</p>
@endif
</div>
</div>
{{-- 右側Action 按鈕(透過 slot 傳入,無傳入則不渲染) --}}
@if($slot->isNotEmpty())
<div class="{{ $actionsClass }}">
{{ $slot }}
</div>
@endif
</div>