All checks were successful
star-cloud-deploy-demo / deploy-demo (push) Successful in 1m7s
1. 新增廣告管理列表與機台配置介面,包含多語系 (zh_TW, en, ja) 與完整 CRUD 2. 實作基於 Alpine 的廣告素材預覽輪播功能 3. 優化廣告素材下拉選單,強制綁定所屬公司以達成多租戶資料隔離 4. 重構廣告配置中廣告影片的縮圖渲染邏輯,移除 <video> 標籤以大幅提升頁面載入速度與節省頻寬 5. 放寬個人檔案頭像上傳限制,支援 WebP 格式
238 lines
11 KiB
PHP
238 lines
11 KiB
PHP
@props(['links' => null])
|
|
|
|
@php
|
|
if (is_null($links)) {
|
|
$routeName = Route::currentRouteName();
|
|
$links = [];
|
|
|
|
// 預設首頁 (Dashboard)
|
|
$links[] = [
|
|
'label' => __('Dashboard'),
|
|
'url' => route('admin.dashboard'),
|
|
'active' => $routeName === 'admin.dashboard'
|
|
];
|
|
|
|
if ($routeName && $routeName !== 'admin.dashboard') {
|
|
// 定義大模組映射表 (路由前綴 => 大模組名稱)
|
|
$moduleMap = [
|
|
'profile' => __('Profile Settings'),
|
|
'admin.members' => __('Member Management'),
|
|
'admin.membership-tiers' => __('Member Management'),
|
|
'admin.deposit-bonus-rules' => __('Member Management'),
|
|
'admin.point-rules' => __('Member Management'),
|
|
'admin.gift-definitions' => __('Member Management'),
|
|
'admin.machines' => __('Machine Management'),
|
|
'admin.app' => __('APP Management'),
|
|
'admin.warehouses' => __('Warehouse Management'),
|
|
'admin.sales' => __('Sales Management'),
|
|
'admin.analysis' => __('Analysis Management'),
|
|
'admin.audit' => __('Audit Management'),
|
|
'admin.data-config' => __('Data Configuration'),
|
|
'admin.remote' => __('Remote Management'),
|
|
'admin.line' => __('Line Management'),
|
|
'admin.reservation' => __('Reservation System'),
|
|
'admin.special-permission' => __('Special Permission'),
|
|
'admin.permission' => __('Permission Settings'),
|
|
'admin.basic-settings' => __('Basic Settings'),
|
|
'admin.maintenance' => __('Machine Management'),
|
|
];
|
|
|
|
// 1. 找出所屬大模組
|
|
$foundModule = null;
|
|
foreach ($moduleMap as $prefix => $label) {
|
|
if (str_starts_with($routeName, $prefix)) {
|
|
$foundModule = [
|
|
'label' => $label,
|
|
'url' => '#',
|
|
'active' => false
|
|
];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($foundModule) {
|
|
$links[] = $foundModule;
|
|
}
|
|
|
|
// 2. 處理中間層級與具體頁面
|
|
$segments = explode('.', $routeName);
|
|
$lastSegment = end($segments);
|
|
|
|
// 如果路由有四段以上 (如 admin.permission.companies.index),則處理中間一段
|
|
if (count($segments) >= 4) {
|
|
$midSegment = $segments[2];
|
|
$midLabel = match($midSegment) {
|
|
'companies' => __('Customer Management'),
|
|
'members' => __('Member List'),
|
|
'machines' => __('Machine Settings'),
|
|
'products' => __('Product Management'),
|
|
'machine-models' => __('Machine Model Settings'),
|
|
'accounts' => __('Account Management'),
|
|
'sub-accounts' => __('Account Management'),
|
|
'roles' => __('Roles'),
|
|
'sub-account-roles' => __('Sub Account Roles'),
|
|
'payment-configs' => __('Customer Payment Config'),
|
|
'warehouses' => __('Warehouse List'),
|
|
'sales' => __('Sales Records'),
|
|
'maintenance' => __('Maintenance Records'),
|
|
default => null,
|
|
};
|
|
|
|
if ($midLabel) {
|
|
$links[] = [
|
|
'label' => $midLabel,
|
|
'url' => match($midSegment) {
|
|
'maintenance' => route('admin.maintenance.index'),
|
|
'machines' => str_contains($routeName, 'basic-settings') ? route('admin.basic-settings.machines.index') : '#',
|
|
'products' => route('admin.data-config.products.index'),
|
|
'accounts' => route('admin.permission.accounts'),
|
|
'sub-accounts' => route('admin.data-config.sub-accounts'),
|
|
'sub-account-roles' => route('admin.data-config.sub-account-roles'),
|
|
default => '#',
|
|
},
|
|
'active' => $lastSegment === 'index'
|
|
];
|
|
}
|
|
}
|
|
|
|
// 特殊處理:當只有三段且第二段是 maintenance 時,增加中間層級
|
|
if (count($segments) === 3 && $segments[1] === 'maintenance' && $lastSegment !== 'index') {
|
|
$links[] = [
|
|
'label' => __('Maintenance Records'),
|
|
'url' => route('admin.maintenance.index'),
|
|
'active' => false
|
|
];
|
|
}
|
|
|
|
// 3. 處理最後一個動作/頁面
|
|
$pageLabel = match($lastSegment) {
|
|
'index' => match($segments[1] ?? '') {
|
|
'members' => __('Member List'),
|
|
'machines' => __('Machine List'),
|
|
'warehouses' => __('Warehouse List (All)'),
|
|
'sales' => __('Sales Records'),
|
|
'analysis' => __('Analysis Management'),
|
|
'audit' => __('Audit Management'),
|
|
'maintenance' => __('Maintenance Records'),
|
|
'data-config' => match($segments[2] ?? '') {
|
|
'products' => __('Product Management'),
|
|
'advertisements' => __('Advertisement Management'),
|
|
default => null,
|
|
},
|
|
default => null,
|
|
},
|
|
'edit' => str_starts_with($routeName, 'profile') ? null : __('Edit'),
|
|
'create' => __('Create'),
|
|
'show' => __('Detail'),
|
|
'logs' => __('Machine Logs'),
|
|
'permissions' => __('Machine Permissions'),
|
|
'utilization' => __('Utilization Rate'),
|
|
'expiry' => __('Expiry Management'),
|
|
'maintenance' => __('Maintenance Records'),
|
|
'ui-elements' => __('UI Elements'),
|
|
'helper' => __('Helper'),
|
|
'questionnaire' => __('Questionnaire'),
|
|
'games' => __('Games'),
|
|
'timer' => __('Timer'),
|
|
'personal' => __('Warehouse List (Individual)'),
|
|
'stock-management' => __('Stock Management'),
|
|
'transfers' => __('Transfers'),
|
|
'purchases' => __('Purchases'),
|
|
'replenishments' => __('Replenishments'),
|
|
'replenishment-records' => __('Replenishment Records'),
|
|
'machine-stock' => __('Machine Stock'),
|
|
'staff-stock' => __('Staff Stock'),
|
|
'returns' => __('Returns'),
|
|
'pickup-codes' => __('Pickup Codes'),
|
|
'orders' => __('Orders'),
|
|
'promotions' => __('Promotions'),
|
|
'pass-codes' => __('Pass Codes'),
|
|
'store-gifts' => __('Store Gifts'),
|
|
'change-stock' => __('Change Stock'),
|
|
'machine-reports' => __('Machine Reports'),
|
|
'product-reports' => __('Product Reports'),
|
|
'survey-analysis' => __('Survey Analysis'),
|
|
'products' => __('Product Management'),
|
|
'advertisements' => __('Advertisement Management'),
|
|
'accounts' => __('Account Management'),
|
|
'sub-accounts' => __('Sub Accounts'),
|
|
'sub-account-roles' => __('Sub Account Roles'),
|
|
'points' => __('Point Settings'),
|
|
'badges' => __('Badge Settings'),
|
|
'restart' => __('Machine Restart'),
|
|
'restart-card-reader' => __('Card Reader Restart'),
|
|
'checkout' => __('Remote Checkout'),
|
|
'lock' => __('Remote Lock'),
|
|
'change' => __('Remote Change'),
|
|
'dispense' => __('Remote Dispense'),
|
|
'official-account' => __('Line Official Account'),
|
|
'coupons' => __('Line Coupons'),
|
|
'stores' => __('Store Management'),
|
|
'time-slots' => __('Time Slots'),
|
|
'venues' => __('Venue Management'),
|
|
'reservations' => __('Reservations'),
|
|
'clear-stock' => __('Clear Stock'),
|
|
'apk-versions' => __('APK Versions'),
|
|
'discord-notifications' => __('Discord Notifications'),
|
|
'app-features' => __('APP Features'),
|
|
'roles' => __('Roles'),
|
|
'others' => __('Others'),
|
|
'ai-prediction' => __('AI Prediction'),
|
|
'data-config' => __('Data Configuration Permissions'),
|
|
'sales' => __('Sales Permissions'),
|
|
'machines' => __('Machine Management Permissions'),
|
|
'warehouses' => __('Warehouse Permissions'),
|
|
'analysis' => __('Analysis Permissions'),
|
|
'audit' => __('Audit Permissions'),
|
|
'remote' => __('Remote Permissions'),
|
|
'line' => __('Line Permissions'),
|
|
default => null,
|
|
};
|
|
|
|
if ($pageLabel) {
|
|
$links[] = [
|
|
'label' => $pageLabel,
|
|
'active' => true
|
|
];
|
|
}
|
|
|
|
// 確保最後一個 link 是 active 的
|
|
if (!empty($links)) {
|
|
$links[count($links) - 1]['active'] = true;
|
|
// 檢查是否有相鄰重複的 Label (例如 Dashboard > Dashboard)
|
|
if (count($links) > 1 && $links[count($links)-1]['label'] === $links[count($links)-2]['label']) {
|
|
array_pop($links);
|
|
$links[count($links)-1]['active'] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
@endphp
|
|
|
|
<nav {{ $attributes->merge(['class' => 'flex', 'aria-label' => 'Breadcrumb']) }}>
|
|
<ol class="flex items-center whitespace-nowrap min-w-0 w-full">
|
|
@foreach($links as $link)
|
|
@php
|
|
$isActive = $link['active'] ?? false;
|
|
$url = $link['url'] ?? '#';
|
|
@endphp
|
|
<li class="flex items-center text-sm {{ $isActive ? 'font-semibold text-slate-800 dark:text-slate-200' : 'text-slate-500 dark:text-slate-400' }} {{ !$loop->last ? 'shrink-0' : 'truncate' }}">
|
|
@if(!$isActive && $url !== '#')
|
|
<a class="hover:text-cyan-600 transition-colors" href="{{ $url }}">
|
|
{{ $link['label'] }}
|
|
</a>
|
|
@else
|
|
{{ $link['label'] }}
|
|
@endif
|
|
|
|
@if(!$loop->last)
|
|
<svg class="flex-shrink-0 mx-3 overflow-visible h-2.5 w-2.5 text-slate-500 dark:text-slate-400" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M5 1L10.6869 7.16086C10.8637 7.35239 10.8637 7.64761 10.6869 7.83914L5 14" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
|
|
</svg>
|
|
@endif
|
|
</li>
|
|
@endforeach
|
|
</ol>
|
|
</nav>
|