feat: Preline UI 改版與深色模式修復
This commit is contained in:
@@ -137,7 +137,7 @@ docker compose exec laravel.test php artisan migrate --seed
|
|||||||
```
|
```
|
||||||
|
|
||||||
> **預設管理員帳號**:
|
> **預設管理員帳號**:
|
||||||
> - Email: `admin@star-cloud.com`
|
> - Email: `admin`
|
||||||
> - Password: `password`
|
> - Password: `password`
|
||||||
|
|
||||||
**4.4 安裝前端依賴**
|
**4.4 安裝前端依賴**
|
||||||
|
|||||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -12,7 +12,7 @@
|
|||||||
"axios": "^1.6.4",
|
"axios": "^1.6.4",
|
||||||
"laravel-vite-plugin": "^1.0.0",
|
"laravel-vite-plugin": "^1.0.0",
|
||||||
"postcss": "^8.4.31",
|
"postcss": "^8.4.31",
|
||||||
"preline": "^3.2.0",
|
"preline": "^3.2.3",
|
||||||
"tailwindcss": "^3.1.0",
|
"tailwindcss": "^3.1.0",
|
||||||
"vite": "^5.0.0"
|
"vite": "^5.0.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"axios": "^1.6.4",
|
"axios": "^1.6.4",
|
||||||
"laravel-vite-plugin": "^1.0.0",
|
"laravel-vite-plugin": "^1.0.0",
|
||||||
"postcss": "^8.4.31",
|
"postcss": "^8.4.31",
|
||||||
"preline": "^3.2.0",
|
"preline": "^3.2.3",
|
||||||
"tailwindcss": "^3.1.0",
|
"tailwindcss": "^3.1.0",
|
||||||
"vite": "^5.0.0"
|
"vite": "^5.0.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,10 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@php
|
@php
|
||||||
$theme = request()->cookie('theme', 'dark-blue');
|
|
||||||
$isLight = in_array($theme, ['light-blue', 'light-green']);
|
|
||||||
$cardBg = $isLight ? 'bg-white' : 'bg-gray-800';
|
|
||||||
$textPrimary = $isLight ? 'text-gray-900' : 'text-gray-200';
|
|
||||||
$textSecondary = $isLight ? 'text-gray-600' : 'text-gray-400';
|
|
||||||
$borderColor = $isLight ? 'border-gray-200' : 'border-gray-700';
|
|
||||||
$inputBg = $isLight ? 'bg-gray-50 border-gray-300' : 'bg-gray-700 border-gray-600';
|
|
||||||
$inputText = $isLight ? 'text-gray-900' : 'text-gray-300';
|
$inputText = $isLight ? 'text-gray-900' : 'text-gray-300';
|
||||||
@endphp
|
@endphp
|
||||||
<div class="container mx-auto px-6 py-8">
|
<div class="container mx-auto px-6 py-8">
|
||||||
<h3 class="{{ $textPrimary }} text-3xl font-medium">APP 管理設定</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">APP 管理設定</h3>
|
||||||
|
|
||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
<form action="{{ route('admin.app-configs.update') }}" method="POST">
|
<form action="{{ route('admin.app-configs.update') }}" method="POST">
|
||||||
@@ -21,44 +14,44 @@
|
|||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<!-- UI Settings -->
|
<!-- UI Settings -->
|
||||||
<div class="{{ $cardBg }} rounded-lg shadow-xl overflow-hidden p-6">
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl overflow-hidden p-6">
|
||||||
<h4 class="text-xl font-semibold {{ $textPrimary }} mb-4">UI 元素設定</h4>
|
<h4 class="text-xl font-semibold text-gray-900 dark:text-gray-200 mb-4">UI 元素設定</h4>
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label for="ui_primary_color" class="block text-sm font-medium {{ $textSecondary }}">主色調 (Hex)</label>
|
<label for="ui_primary_color" class="block text-sm font-medium text-gray-600 dark:text-gray-400">主色調 (Hex)</label>
|
||||||
<input type="text" name="ui_primary_color" id="ui_primary_color" value="{{ $configs['ui']->where('key', 'ui_primary_color')->first()->value ?? '' }}" class="mt-1 block w-full {{ $inputBg }} rounded-md shadow-sm py-2 px-3 {{ $inputText }} focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="text" name="ui_primary_color" id="ui_primary_color" value="{{ $configs['ui']->where('key', 'ui_primary_color')->first()->value ?? '' }}" class="mt-1 block w-full bg-white dark:bg-gray-700 rounded-md shadow-sm py-2 px-3 {{ $inputText }} focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="ui_logo_url" class="block text-sm font-medium {{ $textSecondary }}">Logo URL</label>
|
<label for="ui_logo_url" class="block text-sm font-medium text-gray-600 dark:text-gray-400">Logo URL</label>
|
||||||
<input type="text" name="ui_logo_url" id="ui_logo_url" value="{{ $configs['ui']->where('key', 'ui_logo_url')->first()->value ?? '' }}" class="mt-1 block w-full {{ $inputBg }} rounded-md shadow-sm py-2 px-3 {{ $inputText }} focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="text" name="ui_logo_url" id="ui_logo_url" value="{{ $configs['ui']->where('key', 'ui_logo_url')->first()->value ?? '' }}" class="mt-1 block w-full bg-white dark:bg-gray-700 rounded-md shadow-sm py-2 px-3 {{ $inputText }} focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Helper Settings -->
|
<!-- Helper Settings -->
|
||||||
<div class="{{ $cardBg }} rounded-lg shadow-xl overflow-hidden p-6">
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl overflow-hidden p-6">
|
||||||
<h4 class="text-xl font-semibold {{ $textPrimary }} mb-4">小幫手設定</h4>
|
<h4 class="text-xl font-semibold text-gray-900 dark:text-gray-200 mb-4">小幫手設定</h4>
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<input type="hidden" name="helper_enabled" value="0">
|
<input type="hidden" name="helper_enabled" value="0">
|
||||||
<input type="checkbox" name="helper_enabled" id="helper_enabled" value="1" {{ ($configs['helper']->where('key', 'helper_enabled')->first()->value ?? '0') == '1' ? 'checked' : '' }} class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded">
|
<input type="checkbox" name="helper_enabled" id="helper_enabled" value="1" {{ ($configs['helper']->where('key', 'helper_enabled')->first()->value ?? '0') == '1' ? 'checked' : '' }} class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded">
|
||||||
<label for="helper_enabled" class="ml-2 block text-sm {{ $textPrimary }}">啟用小幫手</label>
|
<label for="helper_enabled" class="ml-2 block text-sm text-gray-900 dark:text-gray-200">啟用小幫手</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Game Settings -->
|
<!-- Game Settings -->
|
||||||
<div class="{{ $cardBg }} rounded-lg shadow-xl overflow-hidden p-6">
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl overflow-hidden p-6">
|
||||||
<h4 class="text-xl font-semibold {{ $textPrimary }} mb-4">問卷與互動遊戲</h4>
|
<h4 class="text-xl font-semibold text-gray-900 dark:text-gray-200 mb-4">問卷與互動遊戲</h4>
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<input type="hidden" name="game_enabled" value="0">
|
<input type="hidden" name="game_enabled" value="0">
|
||||||
<input type="checkbox" name="game_enabled" id="game_enabled" value="1" {{ ($configs['game']->where('key', 'game_enabled')->first()->value ?? '0') == '1' ? 'checked' : '' }} class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded">
|
<input type="checkbox" name="game_enabled" id="game_enabled" value="1" {{ ($configs['game']->where('key', 'game_enabled')->first()->value ?? '0') == '1' ? 'checked' : '' }} class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded">
|
||||||
<label for="game_enabled" class="ml-2 block text-sm {{ $textPrimary }}">啟用互動遊戲</label>
|
<label for="game_enabled" class="ml-2 block text-sm text-gray-900 dark:text-gray-200">啟用互動遊戲</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="questionnaire_url" class="block text-sm font-medium {{ $textSecondary }}">問卷 URL</label>
|
<label for="questionnaire_url" class="block text-sm font-medium text-gray-600 dark:text-gray-400">問卷 URL</label>
|
||||||
<input type="text" name="questionnaire_url" id="questionnaire_url" value="{{ $configs['game']->where('key', 'questionnaire_url')->first()->value ?? '' }}" class="mt-1 block w-full {{ $inputBg }} rounded-md shadow-sm py-2 px-3 {{ $inputText }} focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="text" name="questionnaire_url" id="questionnaire_url" value="{{ $configs['game']->where('key', 'questionnaire_url')->first()->value ?? '' }}" class="mt-1 block w-full bg-white dark:bg-gray-700 rounded-md shadow-sm py-2 px-3 {{ $inputText }} focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,111 +1,165 @@
|
|||||||
@extends('layouts.admin')
|
@extends('layouts.admin')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@php
|
<div class="space-y-4 sm:space-y-6">
|
||||||
$theme = request()->cookie('theme', 'dark-blue');
|
<!-- Grid -->
|
||||||
$isLight = in_array($theme, ['light-blue', 'light-green']);
|
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-4 sm:gap-6">
|
||||||
$cardBg = $isLight ? 'bg-white' : 'bg-gray-800';
|
<!-- Card -->
|
||||||
$textPrimary = $isLight ? 'text-gray-900' : 'text-gray-200';
|
<div class="flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
$textSecondary = $isLight ? 'text-gray-600' : 'text-gray-400';
|
<div class="p-4 md:p-5">
|
||||||
$borderColor = $isLight ? 'border-gray-200' : 'border-gray-700';
|
<div class="flex items-center gap-x-2">
|
||||||
@endphp
|
<p class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
||||||
<div class="container mx-auto px-6 py-8">
|
總銷售額
|
||||||
<h3 class="{{ $textPrimary }} text-3xl font-medium">儀表板</h3>
|
</p>
|
||||||
|
<div class="hs-tooltip">
|
||||||
<div class="mt-4">
|
<div class="hs-tooltip-toggle">
|
||||||
<div class="flex flex-wrap -mx-6">
|
<svg class="flex-shrink-0 w-4 h-4 text-gray-500" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><path d="M12 17h.01"/></svg>
|
||||||
<!-- Total Machines -->
|
<span class="hs-tooltip-content hs-tooltip-shown:opacity-100 hs-tooltip-shown:visible opacity-0 transition-opacity inline-block absolute invisible z-10 py-1 px-2 bg-gray-900 text-xs font-medium text-white rounded shadow-sm dark:bg-slate-700" role="tooltip">
|
||||||
<div class="w-full px-6 sm:w-1/2 xl:w-1/4">
|
本月累計銷售總額
|
||||||
<div class="flex items-center px-5 py-6 shadow-sm rounded-md {{ $cardBg }}">
|
</span>
|
||||||
<div class="p-3 rounded-full bg-indigo-600 bg-opacity-75">
|
|
||||||
<svg class="h-8 w-8 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div class="mx-5">
|
|
||||||
<h4 class="text-2xl font-semibold {{ $textPrimary }}">{{ $totalMachines }}</h4>
|
|
||||||
<div class="{{ $textSecondary }}">總機台數</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Online Machines -->
|
|
||||||
<div class="w-full px-6 sm:w-1/2 xl:w-1/4 mt-6 sm:mt-0">
|
|
||||||
<div class="flex items-center px-5 py-6 shadow-sm rounded-md {{ $cardBg }}">
|
|
||||||
<div class="p-3 rounded-full bg-green-600 bg-opacity-75">
|
|
||||||
<svg class="h-8 w-8 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div class="mx-5">
|
|
||||||
<h4 class="text-2xl font-semibold {{ $textPrimary }}">{{ $onlineMachines }}</h4>
|
|
||||||
<div class="{{ $textSecondary }}">連線中</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Offline Machines -->
|
|
||||||
<div class="w-full px-6 sm:w-1/2 xl:w-1/4 mt-6 xl:mt-0">
|
|
||||||
<div class="flex items-center px-5 py-6 shadow-sm rounded-md {{ $cardBg }}">
|
|
||||||
<div class="p-3 rounded-full bg-gray-600 bg-opacity-75">
|
|
||||||
<svg class="h-8 w-8 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div class="mx-5">
|
|
||||||
<h4 class="text-2xl font-semibold {{ $textPrimary }}">{{ $offlineMachines }}</h4>
|
|
||||||
<div class="{{ $textSecondary }}">離線</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Error Machines -->
|
|
||||||
<div class="w-full px-6 sm:w-1/2 xl:w-1/4 mt-6 xl:mt-0">
|
|
||||||
<div class="flex items-center px-5 py-6 shadow-sm rounded-md {{ $cardBg }}">
|
|
||||||
<div class="p-3 rounded-full bg-red-600 bg-opacity-75">
|
|
||||||
<svg class="h-8 w-8 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div class="mx-5">
|
|
||||||
<h4 class="text-2xl font-semibold {{ $textPrimary }}">{{ $errorMachines }}</h4>
|
|
||||||
<div class="{{ $textSecondary }}">異常</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-8">
|
<div class="mt-1 flex items-center gap-x-2">
|
||||||
<div class="flex flex-col mt-8">
|
<h3 class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
$72,540
|
||||||
<div class="align-middle inline-block min-w-full shadow overflow-hidden sm:rounded-lg border-b {{ $borderColor }}">
|
</h3>
|
||||||
<!-- 這裡可以放最近的銷售紀錄或日誌 -->
|
<span class="flex items-center gap-x-1 text-green-600">
|
||||||
<table class="min-w-full">
|
<svg class="inline-block w-4 h-4 self-center" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg>
|
||||||
<thead>
|
<span class="inline-block text-sm">
|
||||||
<tr>
|
1.7%
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $cardBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">標題</th>
|
</span>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $cardBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">狀態</th>
|
</span>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $cardBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">時間</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody class="{{ $cardBg }}">
|
|
||||||
<tr>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
|
||||||
<div class="text-sm leading-5 {{ $textPrimary }}">系統初始化</div>
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
|
||||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">正常</span>
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }} text-sm leading-5 {{ $textSecondary }}">
|
|
||||||
剛剛
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<div class="p-4 md:p-5">
|
||||||
|
<div class="flex items-center gap-x-2">
|
||||||
|
<p class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
||||||
|
活躍機台
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-1 flex items-center gap-x-2">
|
||||||
|
<h3 class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
124
|
||||||
|
</h3>
|
||||||
|
<span class="flex items-center gap-x-1 text-red-600">
|
||||||
|
<svg class="inline-block w-4 h-4 self-center" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 17 13.5 8.5 8.5 13.5 2 7"/><polyline points="16 17 22 17 22 11"/></svg>
|
||||||
|
<span class="inline-block text-sm">
|
||||||
|
0.3%
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<div class="p-4 md:p-5">
|
||||||
|
<div class="flex items-center gap-x-2">
|
||||||
|
<p class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
||||||
|
庫存警告
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-1 flex items-center gap-x-2">
|
||||||
|
<h3 class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
12
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<div class="p-4 md:p-5">
|
||||||
|
<div class="flex items-center gap-x-2">
|
||||||
|
<p class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
||||||
|
本月新增會員
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-1 flex items-center gap-x-2">
|
||||||
|
<h3 class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
28
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
</div>
|
||||||
|
<!-- End Grid -->
|
||||||
|
|
||||||
|
<div class="grid lg:grid-cols-2 gap-4 sm:gap-6">
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="p-4 md:p-5 min-h-[410px] flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<div>
|
||||||
|
<h2 class="text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
營收趨勢
|
||||||
|
</h2>
|
||||||
|
<p class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
$123,450
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<span class="py-[5px] px-1.5 inline-flex items-center gap-x-1 text-xs font-medium rounded-md bg-teal-100 text-teal-800 dark:bg-teal-500/10 dark:text-teal-500">
|
||||||
|
<svg class="inline-block w-3.5 h-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14"/><path d="m19 12-7 7-7-7"/></svg>
|
||||||
|
25%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Header -->
|
||||||
|
|
||||||
|
<div id="hs-multiple-bar-charts"></div>
|
||||||
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="p-4 md:p-5 min-h-[410px] flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<div>
|
||||||
|
<h2 class="text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
訪客分析
|
||||||
|
</h2>
|
||||||
|
<p class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
92,913
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<span class="py-[5px] px-1.5 inline-flex items-center gap-x-1 text-xs font-medium rounded-md bg-red-100 text-red-800 dark:bg-red-500/10 dark:text-red-500">
|
||||||
|
<svg class="inline-block w-3.5 h-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14"/><path d="m19 12-7 7-7-7"/></svg>
|
||||||
|
11%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Header -->
|
||||||
|
|
||||||
|
<div id="hs-single-area-chart"></div>
|
||||||
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
@section('scripts')
|
||||||
|
<script>
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
// Here you would initialize charts using ApexCharts or similar,
|
||||||
|
// as Preline examples often use ApexCharts.
|
||||||
|
// For now, placeholders are sufficient.
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endsection
|
||||||
|
|||||||
@@ -2,15 +2,6 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@php
|
@php
|
||||||
$theme = request()->cookie('theme', 'dark-blue');
|
|
||||||
$isLight = in_array($theme, ['light-blue', 'light-green']);
|
|
||||||
$cardBg = $isLight ? 'bg-white' : 'bg-gray-800';
|
|
||||||
$textPrimary = $isLight ? 'text-gray-900' : 'text-gray-200';
|
|
||||||
$textSecondary = $isLight ? 'text-gray-600' : 'text-gray-400';
|
|
||||||
$borderColor = $isLight ? 'border-gray-200' : 'border-gray-700';
|
|
||||||
$thBg = $isLight ? 'bg-gray-50' : 'bg-gray-700';
|
|
||||||
$inputBg = $isLight ? 'bg-white' : 'bg-gray-700';
|
|
||||||
$inputBorder = $isLight ? 'border-gray-300' : 'border-gray-600';
|
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
{{-- Toast 通知 --}}
|
{{-- Toast 通知 --}}
|
||||||
@@ -35,31 +26,31 @@
|
|||||||
|
|
||||||
<div class="container mx-auto px-6 py-8">
|
<div class="container mx-auto px-6 py-8">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h3 class="{{ $textPrimary }} text-3xl font-medium">儲值回饋設定</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">儲值回饋設定</h3>
|
||||||
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">
|
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">
|
||||||
新增規則
|
新增規則
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<table class="min-w-full {{ $cardBg }} rounded-lg overflow-hidden">
|
<table class="min-w-full bg-white dark:bg-gray-800 rounded-lg overflow-hidden">
|
||||||
<thead class="{{ $thBg }}">
|
<thead class="bg-gray-100 dark:bg-gray-700">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">名稱</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">名稱</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">最低儲值</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">最低儲值</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">回饋類型</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">回饋類型</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">回饋值</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">回饋值</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">狀態</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">狀態</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">操作</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y {{ $borderColor }}">
|
<tbody class="divide-y border-gray-200 dark:border-gray-700">
|
||||||
@forelse($rules as $rule)
|
@forelse($rules as $rule)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $rule->name }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $rule->name }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">${{ number_format($rule->min_amount) }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">${{ number_format($rule->min_amount) }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $rule->bonus_type == 'fixed' ? '固定金額' : '百分比' }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $rule->bonus_type == 'fixed' ? '固定金額' : '百分比' }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $rule->bonus_type == 'fixed' ? '$'.number_format($rule->bonus_value) : $rule->bonus_value.'%' }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $rule->bonus_type == 'fixed' ? '$'.number_format($rule->bonus_value) : $rule->bonus_value.'%' }}</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
@if($rule->is_active)
|
@if($rule->is_active)
|
||||||
<span class="px-2 py-1 rounded-full bg-green-100 text-green-800 text-xs">啟用</span>
|
<span class="px-2 py-1 rounded-full bg-green-100 text-green-800 text-xs">啟用</span>
|
||||||
@@ -77,7 +68,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="px-6 py-4 text-center {{ $textSecondary }}">尚無資料</td>
|
<td colspan="6" class="px-6 py-4 text-center text-gray-600 dark:text-gray-400">尚無資料</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -90,39 +81,39 @@
|
|||||||
<div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:p-0">
|
<div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:p-0">
|
||||||
<div class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" onclick="document.getElementById('createModal').classList.add('hidden')"></div>
|
<div class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" onclick="document.getElementById('createModal').classList.add('hidden')"></div>
|
||||||
|
|
||||||
<div class="relative {{ $cardBg }} rounded-lg shadow-xl transform transition-all sm:max-w-lg sm:w-full mx-4">
|
<div class="relative bg-white dark:bg-gray-800 rounded-lg shadow-xl transform transition-all sm:max-w-lg sm:w-full mx-4">
|
||||||
<div class="px-6 py-4 border-b {{ $borderColor }}">
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
||||||
<h3 class="{{ $textPrimary }} text-lg font-semibold">新增儲值回饋規則</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-lg font-semibold">新增儲值回饋規則</h3>
|
||||||
</div>
|
</div>
|
||||||
<form action="{{ route('admin.deposit-bonus-rules.store') }}" method="POST">
|
<form action="{{ route('admin.deposit-bonus-rules.store') }}" method="POST">
|
||||||
@csrf
|
@csrf
|
||||||
<div class="px-6 py-4 space-y-4">
|
<div class="px-6 py-4 space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">名稱</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">名稱</label>
|
||||||
<input type="text" name="name" required class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="text" name="name" required class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">最低儲值金額</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">最低儲值金額</label>
|
||||||
<input type="number" name="min_amount" value="0" step="0.01" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="number" name="min_amount" value="0" step="0.01" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">回饋類型</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">回饋類型</label>
|
||||||
<select name="bonus_type" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<select name="bonus_type" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
<option value="fixed">固定金額</option>
|
<option value="fixed">固定金額</option>
|
||||||
<option value="percentage">百分比</option>
|
<option value="percentage">百分比</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">回饋值</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">回饋值</label>
|
||||||
<input type="number" name="bonus_value" value="0" step="0.01" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="number" name="bonus_value" value="0" step="0.01" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<input type="checkbox" name="is_active" value="1" checked id="is_active" class="mr-2 rounded text-indigo-600 focus:ring-indigo-500">
|
<input type="checkbox" name="is_active" value="1" checked id="is_active" class="mr-2 rounded text-indigo-600 focus:ring-indigo-500">
|
||||||
<label for="is_active" class="{{ $textSecondary }} text-sm">啟用</label>
|
<label for="is_active" class="text-gray-600 dark:text-gray-400 text-sm">啟用</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="px-6 py-4 border-t {{ $borderColor }} flex justify-end space-x-3">
|
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 flex justify-end space-x-3">
|
||||||
<button type="button" onclick="document.getElementById('createModal').classList.add('hidden')" class="px-4 py-2 {{ $textSecondary }} border {{ $inputBorder }} rounded-md hover:bg-gray-100 dark:hover:bg-gray-700">取消</button>
|
<button type="button" onclick="document.getElementById('createModal').classList.add('hidden')" class="px-4 py-2 text-gray-600 dark:text-gray-400 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700">取消</button>
|
||||||
<button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700">建立</button>
|
<button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700">建立</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -2,16 +2,6 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@php
|
@php
|
||||||
$theme = request()->cookie('theme', 'dark-blue');
|
|
||||||
$isLight = in_array($theme, ['light-blue', 'light-green']);
|
|
||||||
$cardBg = $isLight ? 'bg-white' : 'bg-gray-800';
|
|
||||||
$textPrimary = $isLight ? 'text-gray-900' : 'text-gray-200';
|
|
||||||
$textSecondary = $isLight ? 'text-gray-600' : 'text-gray-400';
|
|
||||||
$borderColor = $isLight ? 'border-gray-200' : 'border-gray-700';
|
|
||||||
$thBg = $isLight ? 'bg-gray-50' : 'bg-gray-700';
|
|
||||||
$inputBg = $isLight ? 'bg-white' : 'bg-gray-700';
|
|
||||||
$inputBorder = $isLight ? 'border-gray-300' : 'border-gray-600';
|
|
||||||
|
|
||||||
$typeLabels = [
|
$typeLabels = [
|
||||||
'points' => '點數',
|
'points' => '點數',
|
||||||
'coupon' => '優惠券',
|
'coupon' => '優惠券',
|
||||||
@@ -51,33 +41,33 @@
|
|||||||
|
|
||||||
<div class="container mx-auto px-6 py-8">
|
<div class="container mx-auto px-6 py-8">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h3 class="{{ $textPrimary }} text-3xl font-medium">禮品設定</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">禮品設定</h3>
|
||||||
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">
|
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">
|
||||||
新增禮品
|
新增禮品
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<table class="min-w-full {{ $cardBg }} rounded-lg overflow-hidden">
|
<table class="min-w-full bg-white dark:bg-gray-800 rounded-lg overflow-hidden">
|
||||||
<thead class="{{ $thBg }}">
|
<thead class="bg-gray-100 dark:bg-gray-700">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">名稱</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">名稱</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">類型</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">類型</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">數值</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">數值</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">適用等級</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">適用等級</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">觸發條件</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">觸發條件</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">狀態</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">狀態</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">操作</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y {{ $borderColor }}">
|
<tbody class="divide-y border-gray-200 dark:border-gray-700">
|
||||||
@forelse($gifts as $gift)
|
@forelse($gifts as $gift)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $gift->name }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $gift->name }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $typeLabels[$gift->type] ?? $gift->type }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $typeLabels[$gift->type] ?? $gift->type }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $gift->value }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $gift->value }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $gift->tier?->name ?? '全部' }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $gift->tier?->name ?? '全部' }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $triggerLabels[$gift->trigger] ?? $gift->trigger }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $triggerLabels[$gift->trigger] ?? $gift->trigger }}</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
@if($gift->is_active)
|
@if($gift->is_active)
|
||||||
<span class="px-2 py-1 rounded-full bg-green-100 text-green-800 text-xs">啟用</span>
|
<span class="px-2 py-1 rounded-full bg-green-100 text-green-800 text-xs">啟用</span>
|
||||||
@@ -95,7 +85,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="7" class="px-6 py-4 text-center {{ $textSecondary }}">尚無資料</td>
|
<td colspan="7" class="px-6 py-4 text-center text-gray-600 dark:text-gray-400">尚無資料</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -108,32 +98,32 @@
|
|||||||
<div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:p-0">
|
<div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:p-0">
|
||||||
<div class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" onclick="document.getElementById('createModal').classList.add('hidden')"></div>
|
<div class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" onclick="document.getElementById('createModal').classList.add('hidden')"></div>
|
||||||
|
|
||||||
<div class="relative {{ $cardBg }} rounded-lg shadow-xl transform transition-all sm:max-w-lg sm:w-full mx-4">
|
<div class="relative bg-white dark:bg-gray-800 rounded-lg shadow-xl transform transition-all sm:max-w-lg sm:w-full mx-4">
|
||||||
<div class="px-6 py-4 border-b {{ $borderColor }}">
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
||||||
<h3 class="{{ $textPrimary }} text-lg font-semibold">新增禮品</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-lg font-semibold">新增禮品</h3>
|
||||||
</div>
|
</div>
|
||||||
<form action="{{ route('admin.gift-definitions.store') }}" method="POST">
|
<form action="{{ route('admin.gift-definitions.store') }}" method="POST">
|
||||||
@csrf
|
@csrf
|
||||||
<div class="px-6 py-4 space-y-4">
|
<div class="px-6 py-4 space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">名稱</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">名稱</label>
|
||||||
<input type="text" name="name" required class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="text" name="name" required class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">類型</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">類型</label>
|
||||||
<select name="type" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<select name="type" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
@foreach($typeLabels as $key => $label)
|
@foreach($typeLabels as $key => $label)
|
||||||
<option value="{{ $key }}">{{ $label }}</option>
|
<option value="{{ $key }}">{{ $label }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">數值</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">數值</label>
|
||||||
<input type="number" name="value" value="0" step="0.01" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="number" name="value" value="0" step="0.01" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">適用等級</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">適用等級</label>
|
||||||
<select name="tier_id" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<select name="tier_id" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
<option value="">全部</option>
|
<option value="">全部</option>
|
||||||
@foreach($tiers as $tier)
|
@foreach($tiers as $tier)
|
||||||
<option value="{{ $tier->id }}">{{ $tier->name }}</option>
|
<option value="{{ $tier->id }}">{{ $tier->name }}</option>
|
||||||
@@ -141,24 +131,24 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">觸發條件</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">觸發條件</label>
|
||||||
<select name="trigger" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<select name="trigger" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
@foreach($triggerLabels as $key => $label)
|
@foreach($triggerLabels as $key => $label)
|
||||||
<option value="{{ $key }}">{{ $label }}</option>
|
<option value="{{ $key }}">{{ $label }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">有效天數</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">有效天數</label>
|
||||||
<input type="number" name="validity_days" value="30" min="1" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="number" name="validity_days" value="30" min="1" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<input type="checkbox" name="is_active" value="1" checked id="is_active" class="mr-2 rounded text-indigo-600 focus:ring-indigo-500">
|
<input type="checkbox" name="is_active" value="1" checked id="is_active" class="mr-2 rounded text-indigo-600 focus:ring-indigo-500">
|
||||||
<label for="is_active" class="{{ $textSecondary }} text-sm">啟用</label>
|
<label for="is_active" class="text-gray-600 dark:text-gray-400 text-sm">啟用</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="px-6 py-4 border-t {{ $borderColor }} flex justify-end space-x-3">
|
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 flex justify-end space-x-3">
|
||||||
<button type="button" onclick="document.getElementById('createModal').classList.add('hidden')" class="px-4 py-2 {{ $textSecondary }} border {{ $inputBorder }} rounded-md hover:bg-gray-100 dark:hover:bg-gray-700">取消</button>
|
<button type="button" onclick="document.getElementById('createModal').classList.add('hidden')" class="px-4 py-2 text-gray-600 dark:text-gray-400 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700">取消</button>
|
||||||
<button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700">建立</button>
|
<button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700">建立</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -2,27 +2,27 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="container mx-auto px-6 py-8">
|
<div class="container mx-auto px-6 py-8">
|
||||||
<h3 class="text-gray-300 text-3xl font-medium">新增機台</h3>
|
<h3 class="text-gray-900 dark:text-gray-300 text-3xl font-medium">新增機台</h3>
|
||||||
|
|
||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
<form action="{{ route('admin.machines.store') }}" method="POST" class="bg-gray-800 rounded-lg shadow-xl overflow-hidden p-6 space-y-6">
|
<form action="{{ route('admin.machines.store') }}" method="POST" class="bg-white dark:bg-gray-800 rounded-lg shadow-xl overflow-hidden p-6 space-y-6">
|
||||||
@csrf
|
@csrf
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="name" class="block text-sm font-medium text-gray-400">機台名稱</label>
|
<label for="name" class="block text-sm font-medium text-gray-700 dark:text-gray-400">機台名稱</label>
|
||||||
<input type="text" name="name" id="name" class="mt-1 block w-full bg-gray-700 border border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
|
<input type="text" name="name" id="name" class="mt-1 block w-full bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-900 dark:text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
|
||||||
@error('name') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
@error('name') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="location" class="block text-sm font-medium text-gray-400">位置</label>
|
<label for="location" class="block text-sm font-medium text-gray-700 dark:text-gray-400">位置</label>
|
||||||
<input type="text" name="location" id="location" class="mt-1 block w-full bg-gray-700 border border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="text" name="location" id="location" class="mt-1 block w-full bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-900 dark:text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||||
@error('location') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
@error('location') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="status" class="block text-sm font-medium text-gray-400">狀態</label>
|
<label for="status" class="block text-sm font-medium text-gray-700 dark:text-gray-400">狀態</label>
|
||||||
<select name="status" id="status" class="mt-1 block w-full bg-gray-700 border border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<select name="status" id="status" class="mt-1 block w-full bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-900 dark:text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||||
<option value="offline">離線</option>
|
<option value="offline">離線</option>
|
||||||
<option value="online">連線中</option>
|
<option value="online">連線中</option>
|
||||||
<option value="error">異常</option>
|
<option value="error">異常</option>
|
||||||
@@ -31,19 +31,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="temperature" class="block text-sm font-medium text-gray-400">溫度 (°C)</label>
|
<label for="temperature" class="block text-sm font-medium text-gray-700 dark:text-gray-400">溫度 (°C)</label>
|
||||||
<input type="number" step="0.1" name="temperature" id="temperature" class="mt-1 block w-full bg-gray-700 border border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="number" step="0.1" name="temperature" id="temperature" class="mt-1 block w-full bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-900 dark:text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||||
@error('temperature') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
@error('temperature') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="firmware_version" class="block text-sm font-medium text-gray-400">韌體版本</label>
|
<label for="firmware_version" class="block text-sm font-medium text-gray-700 dark:text-gray-400">韌體版本</label>
|
||||||
<input type="text" name="firmware_version" id="firmware_version" class="mt-1 block w-full bg-gray-700 border border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="text" name="firmware_version" id="firmware_version" class="mt-1 block w-full bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-900 dark:text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||||
@error('firmware_version') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
@error('firmware_version') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
<a href="{{ route('admin.machines.index') }}" class="bg-gray-600 hover:bg-gray-500 text-white font-bold py-2 px-4 rounded mr-2">取消</a>
|
<a href="{{ route('admin.machines.index') }}" class="bg-gray-200 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500 text-gray-800 dark:text-white font-bold py-2 px-4 rounded mr-2">取消</a>
|
||||||
<button type="submit" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-2 px-4 rounded">建立</button>
|
<button type="submit" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-2 px-4 rounded">建立</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -2,28 +2,28 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="container mx-auto px-6 py-8">
|
<div class="container mx-auto px-6 py-8">
|
||||||
<h3 class="text-gray-300 text-3xl font-medium">編輯機台</h3>
|
<h3 class="text-gray-900 dark:text-gray-300 text-3xl font-medium">編輯機台</h3>
|
||||||
|
|
||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
<form action="{{ route('admin.machines.update', $machine) }}" method="POST" class="bg-gray-800 rounded-lg shadow-xl overflow-hidden p-6 space-y-6">
|
<form action="{{ route('admin.machines.update', $machine) }}" method="POST" class="bg-white dark:bg-gray-800 rounded-lg shadow-xl overflow-hidden p-6 space-y-6">
|
||||||
@csrf
|
@csrf
|
||||||
@method('PUT')
|
@method('PUT')
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="name" class="block text-sm font-medium text-gray-400">機台名稱</label>
|
<label for="name" class="block text-sm font-medium text-gray-700 dark:text-gray-400">機台名稱</label>
|
||||||
<input type="text" name="name" id="name" value="{{ old('name', $machine->name) }}" class="mt-1 block w-full bg-gray-700 border border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
|
<input type="text" name="name" id="name" value="{{ old('name', $machine->name) }}" class="mt-1 block w-full bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-900 dark:text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" required>
|
||||||
@error('name') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
@error('name') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="location" class="block text-sm font-medium text-gray-400">位置</label>
|
<label for="location" class="block text-sm font-medium text-gray-700 dark:text-gray-400">位置</label>
|
||||||
<input type="text" name="location" id="location" value="{{ old('location', $machine->location) }}" class="mt-1 block w-full bg-gray-700 border border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="text" name="location" id="location" value="{{ old('location', $machine->location) }}" class="mt-1 block w-full bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-900 dark:text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||||
@error('location') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
@error('location') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="status" class="block text-sm font-medium text-gray-400">狀態</label>
|
<label for="status" class="block text-sm font-medium text-gray-700 dark:text-gray-400">狀態</label>
|
||||||
<select name="status" id="status" class="mt-1 block w-full bg-gray-700 border border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<select name="status" id="status" class="mt-1 block w-full bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-900 dark:text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||||
<option value="offline" {{ $machine->status == 'offline' ? 'selected' : '' }}>離線</option>
|
<option value="offline" {{ $machine->status == 'offline' ? 'selected' : '' }}>離線</option>
|
||||||
<option value="online" {{ $machine->status == 'online' ? 'selected' : '' }}>連線中</option>
|
<option value="online" {{ $machine->status == 'online' ? 'selected' : '' }}>連線中</option>
|
||||||
<option value="error" {{ $machine->status == 'error' ? 'selected' : '' }}>異常</option>
|
<option value="error" {{ $machine->status == 'error' ? 'selected' : '' }}>異常</option>
|
||||||
@@ -32,19 +32,19 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="temperature" class="block text-sm font-medium text-gray-400">溫度 (°C)</label>
|
<label for="temperature" class="block text-sm font-medium text-gray-700 dark:text-gray-400">溫度 (°C)</label>
|
||||||
<input type="number" step="0.1" name="temperature" id="temperature" value="{{ old('temperature', $machine->temperature) }}" class="mt-1 block w-full bg-gray-700 border border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="number" step="0.1" name="temperature" id="temperature" value="{{ old('temperature', $machine->temperature) }}" class="mt-1 block w-full bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-900 dark:text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||||
@error('temperature') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
@error('temperature') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="firmware_version" class="block text-sm font-medium text-gray-400">韌體版本</label>
|
<label for="firmware_version" class="block text-sm font-medium text-gray-700 dark:text-gray-400">韌體版本</label>
|
||||||
<input type="text" name="firmware_version" id="firmware_version" value="{{ old('firmware_version', $machine->firmware_version) }}" class="mt-1 block w-full bg-gray-700 border border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
<input type="text" name="firmware_version" id="firmware_version" value="{{ old('firmware_version', $machine->firmware_version) }}" class="mt-1 block w-full bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 text-gray-900 dark:text-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm">
|
||||||
@error('firmware_version') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
@error('firmware_version') <span class="text-red-500 text-sm">{{ $message }}</span> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
<a href="{{ route('admin.machines.index') }}" class="bg-gray-600 hover:bg-gray-500 text-white font-bold py-2 px-4 rounded mr-2">取消</a>
|
<a href="{{ route('admin.machines.index') }}" class="bg-gray-200 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500 text-gray-800 dark:text-white font-bold py-2 px-4 rounded mr-2">取消</a>
|
||||||
<button type="submit" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-2 px-4 rounded">更新</button>
|
<button type="submit" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-2 px-4 rounded">更新</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -2,16 +2,10 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@php
|
@php
|
||||||
$theme = request()->cookie('theme', 'dark-blue');
|
|
||||||
$isLight = in_array($theme, ['light-blue', 'light-green']);
|
|
||||||
$cardBg = $isLight ? 'bg-white' : 'bg-gray-800';
|
|
||||||
$textPrimary = $isLight ? 'text-gray-900' : 'text-gray-200';
|
|
||||||
$textSecondary = $isLight ? 'text-gray-600' : 'text-gray-400';
|
|
||||||
$borderColor = $isLight ? 'border-gray-200' : 'border-gray-700';
|
|
||||||
@endphp
|
@endphp
|
||||||
<div class="container mx-auto px-6 py-8">
|
<div class="container mx-auto px-6 py-8">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<h3 class="{{ $textPrimary }} text-3xl font-medium">機台管理</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">機台管理</h3>
|
||||||
<a href="{{ route('admin.machines.create') }}" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-2 px-4 rounded">
|
<a href="{{ route('admin.machines.create') }}" class="bg-indigo-600 hover:bg-indigo-700 text-white font-bold py-2 px-4 rounded">
|
||||||
新增機台
|
新增機台
|
||||||
</a>
|
</a>
|
||||||
@@ -20,28 +14,28 @@
|
|||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
||||||
<div class="align-middle inline-block min-w-full shadow overflow-hidden sm:rounded-lg border-b {{ $borderColor }}">
|
<div class="align-middle inline-block min-w-full shadow overflow-hidden sm:rounded-lg border-b border-gray-200 dark:border-gray-700">
|
||||||
<table class="min-w-full">
|
<table class="min-w-full">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $cardBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">名稱</th>
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">名稱</th>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $cardBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">位置</th>
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">位置</th>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $cardBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">狀態</th>
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">狀態</th>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $cardBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">溫度</th>
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">溫度</th>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $cardBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">最後心跳</th>
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">最後心跳</th>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $cardBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">操作</th>
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="{{ $cardBg }}">
|
<tbody class="bg-white dark:bg-gray-800">
|
||||||
@foreach($machines as $machine)
|
@foreach($machines as $machine)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700">
|
||||||
<div class="text-sm leading-5 font-medium {{ $textPrimary }}">{{ $machine->name }}</div>
|
<div class="text-sm leading-5 font-medium text-gray-900 dark:text-gray-200">{{ $machine->name }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700">
|
||||||
<div class="text-sm leading-5 {{ $textSecondary }}">{{ $machine->location ?? '-' }}</div>
|
<div class="text-sm leading-5 text-gray-600 dark:text-gray-400">{{ $machine->location ?? '-' }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700">
|
||||||
@if($machine->status === 'online')
|
@if($machine->status === 'online')
|
||||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">連線中</span>
|
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">連線中</span>
|
||||||
@elseif($machine->status === 'offline')
|
@elseif($machine->status === 'offline')
|
||||||
@@ -50,13 +44,13 @@
|
|||||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">異常</span>
|
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">異常</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700">
|
||||||
<div class="text-sm leading-5 {{ $textSecondary }}">{{ $machine->temperature ? $machine->temperature . '°C' : '-' }}</div>
|
<div class="text-sm leading-5 text-gray-600 dark:text-gray-400">{{ $machine->temperature ? $machine->temperature . '°C' : '-' }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700">
|
||||||
<div class="text-sm leading-5 {{ $textSecondary }}">{{ $machine->last_heartbeat_at ? $machine->last_heartbeat_at->diffForHumans() : '-' }}</div>
|
<div class="text-sm leading-5 text-gray-600 dark:text-gray-400">{{ $machine->last_heartbeat_at ? $machine->last_heartbeat_at->diffForHumans() : '-' }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }} text-sm leading-5 font-medium">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700 text-sm leading-5 font-medium">
|
||||||
<a href="{{ route('admin.machines.show', $machine) }}" class="text-indigo-400 hover:text-indigo-600 mr-3">查看</a>
|
<a href="{{ route('admin.machines.show', $machine) }}" class="text-indigo-400 hover:text-indigo-600 mr-3">查看</a>
|
||||||
<a href="{{ route('admin.machines.edit', $machine) }}" class="text-yellow-400 hover:text-yellow-600 mr-3">編輯</a>
|
<a href="{{ route('admin.machines.edit', $machine) }}" class="text-yellow-400 hover:text-yellow-600 mr-3">編輯</a>
|
||||||
<form action="{{ route('admin.machines.destroy', $machine) }}" method="POST" class="inline-block" onsubmit="return confirm('確定要刪除嗎?');">
|
<form action="{{ route('admin.machines.destroy', $machine) }}" method="POST" class="inline-block" onsubmit="return confirm('確定要刪除嗎?');">
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
@section('content')
|
@section('content')
|
||||||
<div class="container mx-auto px-6 py-8">
|
<div class="container mx-auto px-6 py-8">
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<h3 class="text-gray-300 text-3xl font-medium">機台詳情:{{ $machine->name }}</h3>
|
<h3 class="text-gray-900 dark:text-gray-300 text-3xl font-medium">機台詳情:{{ $machine->name }}</h3>
|
||||||
<div>
|
<div>
|
||||||
<a href="{{ route('admin.machines.edit', $machine) }}" class="bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-2 px-4 rounded mr-2">
|
<a href="{{ route('admin.machines.edit', $machine) }}" class="bg-yellow-600 hover:bg-yellow-700 text-white font-bold py-2 px-4 rounded mr-2">
|
||||||
編輯
|
編輯
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ route('admin.machines.index') }}" class="bg-gray-600 hover:bg-gray-500 text-white font-bold py-2 px-4 rounded">
|
<a href="{{ route('admin.machines.index') }}" class="bg-gray-200 dark:bg-gray-600 hover:bg-gray-300 dark:hover:bg-gray-500 text-gray-800 dark:text-white font-bold py-2 px-4 rounded">
|
||||||
返回列表
|
返回列表
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -16,15 +16,15 @@
|
|||||||
|
|
||||||
<div class="mt-8 grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="mt-8 grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<!-- Basic Info -->
|
<!-- Basic Info -->
|
||||||
<div class="bg-gray-800 rounded-lg shadow-xl overflow-hidden p-6">
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl overflow-hidden p-6">
|
||||||
<h4 class="text-xl font-semibold text-gray-200 mb-4">基本資訊</h4>
|
<h4 class="text-xl font-semibold text-gray-200 mb-4">基本資訊</h4>
|
||||||
<div class="grid grid-cols-2 gap-4">
|
<div class="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm text-gray-400">位置</p>
|
<p class="text-sm text-gray-700 dark:text-gray-400">位置</p>
|
||||||
<p class="text-lg text-gray-200">{{ $machine->location ?? '-' }}</p>
|
<p class="text-lg text-gray-200">{{ $machine->location ?? '-' }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm text-gray-400">狀態</p>
|
<p class="text-sm text-gray-700 dark:text-gray-400">狀態</p>
|
||||||
@if($machine->status === 'online')
|
@if($machine->status === 'online')
|
||||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">連線中</span>
|
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">連線中</span>
|
||||||
@elseif($machine->status === 'offline')
|
@elseif($machine->status === 'offline')
|
||||||
@@ -34,22 +34,22 @@
|
|||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm text-gray-400">溫度</p>
|
<p class="text-sm text-gray-700 dark:text-gray-400">溫度</p>
|
||||||
<p class="text-lg text-gray-200">{{ $machine->temperature ? $machine->temperature . '°C' : '-' }}</p>
|
<p class="text-lg text-gray-200">{{ $machine->temperature ? $machine->temperature . '°C' : '-' }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm text-gray-400">韌體版本</p>
|
<p class="text-sm text-gray-700 dark:text-gray-400">韌體版本</p>
|
||||||
<p class="text-lg text-gray-200">{{ $machine->firmware_version ?? '-' }}</p>
|
<p class="text-lg text-gray-200">{{ $machine->firmware_version ?? '-' }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm text-gray-400">最後心跳</p>
|
<p class="text-sm text-gray-700 dark:text-gray-400">最後心跳</p>
|
||||||
<p class="text-lg text-gray-200">{{ $machine->last_heartbeat_at ? $machine->last_heartbeat_at->diffForHumans() : '-' }}</p>
|
<p class="text-lg text-gray-200">{{ $machine->last_heartbeat_at ? $machine->last_heartbeat_at->diffForHumans() : '-' }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Logs -->
|
<!-- Logs -->
|
||||||
<div class="bg-gray-800 rounded-lg shadow-xl overflow-hidden p-6">
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl overflow-hidden p-6">
|
||||||
<h4 class="text-xl font-semibold text-gray-200 mb-4">最近日誌</h4>
|
<h4 class="text-xl font-semibold text-gray-200 mb-4">最近日誌</h4>
|
||||||
<div class="overflow-y-auto max-h-64">
|
<div class="overflow-y-auto max-h-64">
|
||||||
<ul class="divide-y divide-gray-700">
|
<ul class="divide-y divide-gray-700">
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
@else
|
@else
|
||||||
<span class="h-2 w-2 rounded-full bg-blue-500 mr-2"></span>
|
<span class="h-2 w-2 rounded-full bg-blue-500 mr-2"></span>
|
||||||
@endif
|
@endif
|
||||||
<p class="text-sm text-gray-300">{{ $log->message }}</p>
|
<p class="text-sm text-gray-900 dark:text-gray-300">{{ $log->message }}</p>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-xs text-gray-500">{{ $log->created_at->format('m/d H:i') }}</span>
|
<span class="text-xs text-gray-500">{{ $log->created_at->format('m/d H:i') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,62 +2,55 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@php
|
@php
|
||||||
$theme = request()->cookie('theme', 'dark-blue');
|
|
||||||
$isLight = in_array($theme, ['light-blue', 'light-green']);
|
|
||||||
$cardBg = $isLight ? 'bg-white' : 'bg-gray-800';
|
|
||||||
$textPrimary = $isLight ? 'text-gray-900' : 'text-gray-200';
|
|
||||||
$textSecondary = $isLight ? 'text-gray-600' : 'text-gray-400';
|
|
||||||
$borderColor = $isLight ? 'border-gray-200' : 'border-gray-700';
|
|
||||||
$thBg = $isLight ? 'bg-gray-50' : 'bg-gray-700';
|
|
||||||
@endphp
|
@endphp
|
||||||
<div class="container mx-auto px-6 py-8">
|
<div class="container mx-auto px-6 py-8">
|
||||||
<h3 class="{{ $textPrimary }} text-3xl font-medium">會員列表</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">會員列表</h3>
|
||||||
|
|
||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
{{-- 搜尋與篩選 (預留空間) --}}
|
{{-- 搜尋與篩選 (預留空間) --}}
|
||||||
|
|
||||||
<div class="flex flex-col mt-4">
|
<div class="flex flex-col mt-4">
|
||||||
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
<div class="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
|
||||||
<div class="align-middle inline-block min-w-full shadow overflow-hidden sm:rounded-lg border-b {{ $borderColor }}">
|
<div class="align-middle inline-block min-w-full shadow overflow-hidden sm:rounded-lg border-b border-gray-200 dark:border-gray-700">
|
||||||
<table class="min-w-full">
|
<table class="min-w-full">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $thBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-100 dark:bg-gray-700 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">
|
||||||
UUID
|
UUID
|
||||||
</th>
|
</th>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $thBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-100 dark:bg-gray-700 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">
|
||||||
姓名
|
姓名
|
||||||
</th>
|
</th>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $thBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-100 dark:bg-gray-700 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">
|
||||||
Email
|
Email
|
||||||
</th>
|
</th>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $thBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-100 dark:bg-gray-700 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">
|
||||||
手機
|
手機
|
||||||
</th>
|
</th>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $thBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-100 dark:bg-gray-700 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">
|
||||||
狀態
|
狀態
|
||||||
</th>
|
</th>
|
||||||
<th class="px-6 py-3 border-b {{ $borderColor }} {{ $thBg }} text-left text-xs leading-4 font-medium {{ $textSecondary }} uppercase tracking-wider">
|
<th class="px-6 py-3 border-b border-gray-200 dark:border-gray-700 bg-gray-100 dark:bg-gray-700 text-left text-xs leading-4 font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wider">
|
||||||
註冊時間
|
註冊時間
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="{{ $cardBg }}">
|
<tbody class="bg-white dark:bg-gray-800">
|
||||||
@forelse ($members as $member)
|
@forelse ($members as $member)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700">
|
||||||
<div class="text-sm leading-5 font-medium {{ $textSecondary }}">{{ $member->uuid }}</div>
|
<div class="text-sm leading-5 font-medium text-gray-600 dark:text-gray-400">{{ $member->uuid }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700">
|
||||||
<div class="text-sm leading-5 font-bold {{ $textPrimary }}">{{ $member->name }}</div>
|
<div class="text-sm leading-5 font-bold text-gray-900 dark:text-gray-200">{{ $member->name }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700">
|
||||||
<div class="text-sm leading-5 {{ $textPrimary }}">{{ $member->email ?? '-' }}</div>
|
<div class="text-sm leading-5 text-gray-900 dark:text-gray-200">{{ $member->email ?? '-' }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700">
|
||||||
<div class="text-sm leading-5 {{ $textPrimary }}">{{ $member->phone ?? '-' }}</div>
|
<div class="text-sm leading-5 text-gray-900 dark:text-gray-200">{{ $member->phone ?? '-' }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }}">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700">
|
||||||
@if($member->is_active)
|
@if($member->is_active)
|
||||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
|
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
|
||||||
啟用
|
啟用
|
||||||
@@ -68,13 +61,13 @@
|
|||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }} text-sm leading-5 {{ $textSecondary }}">
|
<td class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700 text-sm leading-5 text-gray-600 dark:text-gray-400">
|
||||||
{{ $member->created_at->format('Y-m-d H:i') }}
|
{{ $member->created_at->format('Y-m-d H:i') }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="px-6 py-4 whitespace-no-wrap border-b {{ $borderColor }} text-center {{ $textSecondary }}">
|
<td colspan="6" class="px-6 py-4 whitespace-no-wrap border-b border-gray-200 dark:border-gray-700 text-center text-gray-600 dark:text-gray-400">
|
||||||
尚無會員資料
|
尚無會員資料
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -2,15 +2,6 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@php
|
@php
|
||||||
$theme = request()->cookie('theme', 'dark-blue');
|
|
||||||
$isLight = in_array($theme, ['light-blue', 'light-green']);
|
|
||||||
$cardBg = $isLight ? 'bg-white' : 'bg-gray-800';
|
|
||||||
$textPrimary = $isLight ? 'text-gray-900' : 'text-gray-200';
|
|
||||||
$textSecondary = $isLight ? 'text-gray-600' : 'text-gray-400';
|
|
||||||
$borderColor = $isLight ? 'border-gray-200' : 'border-gray-700';
|
|
||||||
$thBg = $isLight ? 'bg-gray-50' : 'bg-gray-700';
|
|
||||||
$inputBg = $isLight ? 'bg-white' : 'bg-gray-700';
|
|
||||||
$inputBorder = $isLight ? 'border-gray-300' : 'border-gray-600';
|
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
{{-- Toast 通知 --}}
|
{{-- Toast 通知 --}}
|
||||||
@@ -35,31 +26,31 @@
|
|||||||
|
|
||||||
<div class="container mx-auto px-6 py-8">
|
<div class="container mx-auto px-6 py-8">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h3 class="{{ $textPrimary }} text-3xl font-medium">會員等級設定</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">會員等級設定</h3>
|
||||||
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">
|
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">
|
||||||
新增等級
|
新增等級
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<table class="min-w-full {{ $cardBg }} rounded-lg overflow-hidden">
|
<table class="min-w-full bg-white dark:bg-gray-800 rounded-lg overflow-hidden">
|
||||||
<thead class="{{ $thBg }}">
|
<thead class="bg-gray-100 dark:bg-gray-700">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">名稱</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">名稱</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">年費</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">年費</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">折扣</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">折扣</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">點數倍率</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">點數倍率</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">預設</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">預設</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">操作</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y {{ $borderColor }}">
|
<tbody class="divide-y border-gray-200 dark:border-gray-700">
|
||||||
@forelse($tiers as $tier)
|
@forelse($tiers as $tier)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $tier->name }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $tier->name }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $tier->annual_fee == 0 ? '免費' : '$'.number_format($tier->annual_fee) }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $tier->annual_fee == 0 ? '免費' : '$'.number_format($tier->annual_fee) }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $tier->discount_rate * 100 }}%</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $tier->discount_rate * 100 }}%</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $tier->point_multiplier }}x</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $tier->point_multiplier }}x</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
@if($tier->is_default)
|
@if($tier->is_default)
|
||||||
<span class="px-2 py-1 rounded-full bg-green-100 text-green-800 text-xs">預設</span>
|
<span class="px-2 py-1 rounded-full bg-green-100 text-green-800 text-xs">預設</span>
|
||||||
@@ -75,7 +66,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="px-6 py-4 text-center {{ $textSecondary }}">尚無資料</td>
|
<td colspan="6" class="px-6 py-4 text-center text-gray-600 dark:text-gray-400">尚無資料</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -90,36 +81,36 @@
|
|||||||
<div class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" onclick="document.getElementById('createModal').classList.add('hidden')"></div>
|
<div class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" onclick="document.getElementById('createModal').classList.add('hidden')"></div>
|
||||||
|
|
||||||
{{-- Modal 內容 --}}
|
{{-- Modal 內容 --}}
|
||||||
<div class="relative {{ $cardBg }} rounded-lg shadow-xl transform transition-all sm:max-w-lg sm:w-full mx-4">
|
<div class="relative bg-white dark:bg-gray-800 rounded-lg shadow-xl transform transition-all sm:max-w-lg sm:w-full mx-4">
|
||||||
<div class="px-6 py-4 border-b {{ $borderColor }}">
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
||||||
<h3 class="{{ $textPrimary }} text-lg font-semibold">新增會員等級</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-lg font-semibold">新增會員等級</h3>
|
||||||
</div>
|
</div>
|
||||||
<form action="{{ route('admin.membership-tiers.store') }}" method="POST">
|
<form action="{{ route('admin.membership-tiers.store') }}" method="POST">
|
||||||
@csrf
|
@csrf
|
||||||
<div class="px-6 py-4 space-y-4">
|
<div class="px-6 py-4 space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">名稱</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">名稱</label>
|
||||||
<input type="text" name="name" required class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
<input type="text" name="name" required class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500 focus:border-transparent">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">年費</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">年費</label>
|
||||||
<input type="number" name="annual_fee" value="0" step="0.01" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="number" name="annual_fee" value="0" step="0.01" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">折扣比例 (0.95 = 95折)</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">折扣比例 (0.95 = 95折)</label>
|
||||||
<input type="number" name="discount_rate" value="1.00" step="0.01" min="0" max="1" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="number" name="discount_rate" value="1.00" step="0.01" min="0" max="1" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">點數倍率</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">點數倍率</label>
|
||||||
<input type="number" name="point_multiplier" value="1.00" step="0.01" min="0" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="number" name="point_multiplier" value="1.00" step="0.01" min="0" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<input type="checkbox" name="is_default" value="1" id="is_default" class="mr-2 rounded text-indigo-600 focus:ring-indigo-500">
|
<input type="checkbox" name="is_default" value="1" id="is_default" class="mr-2 rounded text-indigo-600 focus:ring-indigo-500">
|
||||||
<label for="is_default" class="{{ $textSecondary }} text-sm">設為預設等級</label>
|
<label for="is_default" class="text-gray-600 dark:text-gray-400 text-sm">設為預設等級</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="px-6 py-4 border-t {{ $borderColor }} flex justify-end space-x-3">
|
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 flex justify-end space-x-3">
|
||||||
<button type="button" onclick="document.getElementById('createModal').classList.add('hidden')" class="px-4 py-2 {{ $textSecondary }} border {{ $inputBorder }} rounded-md hover:bg-gray-100 dark:hover:bg-gray-700">取消</button>
|
<button type="button" onclick="document.getElementById('createModal').classList.add('hidden')" class="px-4 py-2 text-gray-600 dark:text-gray-400 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700">取消</button>
|
||||||
<button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700">建立</button>
|
<button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700">建立</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,39 +1,26 @@
|
|||||||
@php
|
|
||||||
$theme = request()->cookie('theme', 'dark-blue');
|
|
||||||
$themes = [
|
|
||||||
'dark-blue' => ['card' => 'bg-gray-800', 'accent' => 'indigo'],
|
|
||||||
'dark-purple' => ['card' => 'bg-slate-800', 'accent' => 'purple'],
|
|
||||||
'dark-green' => ['card' => 'bg-zinc-800', 'accent' => 'emerald'],
|
|
||||||
'light-blue' => ['card' => 'bg-white', 'accent' => 'blue'],
|
|
||||||
'light-green' => ['card' => 'bg-white', 'accent' => 'green'],
|
|
||||||
];
|
|
||||||
$currentTheme = $themes[$theme] ?? $themes['dark-blue'];
|
|
||||||
$isLight = in_array($theme, ['light-blue', 'light-green']);
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
@extends('layouts.admin')
|
@extends('layouts.admin')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="max-w-7xl mx-auto">
|
<div class="max-w-7xl mx-auto">
|
||||||
<div class="{{ $currentTheme['card'] }} rounded-lg shadow-lg p-8 text-center border {{ $isLight ? 'border-gray-200' : 'border-gray-700' }}">
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-lg p-8 text-center border border-gray-200 dark:border-gray-700">
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<svg class="mx-auto h-24 w-24 text-{{ $currentTheme['accent'] }}-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg class="mx-auto h-24 w-24 text-gray-400 dark:text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-3xl font-bold {{ $isLight ? 'text-gray-900' : 'text-white' }} mb-4">{{ $title ?? '功能頁面' }}</h1>
|
<h1 class="text-3xl font-bold text-gray-900 dark:text-white mb-4">{{ $title ?? '功能頁面' }}</h1>
|
||||||
<p class="{{ $isLight ? 'text-gray-600' : 'text-gray-400' }} mb-6 text-lg">{{ $description ?? '此功能正在開發中' }}</p>
|
<p class="text-gray-600 dark:text-gray-400 mb-6 text-lg">{{ $description ?? '此功能正在開發中' }}</p>
|
||||||
<div class="inline-block px-6 py-3 bg-{{ $currentTheme['accent'] }}-600 text-white rounded-lg font-semibold">
|
<div class="inline-block px-6 py-3 bg-blue-600 text-white rounded-lg font-semibold">
|
||||||
🚧 功能開發中
|
🚧 功能開發中
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if(isset($features) && count($features) > 0)
|
@if(isset($features) && count($features) > 0)
|
||||||
<div class="mt-8 text-left max-w-2xl mx-auto">
|
<div class="mt-8 text-left max-w-2xl mx-auto">
|
||||||
<h3 class="text-xl font-semibold {{ $isLight ? 'text-gray-900' : 'text-white' }} mb-4">規劃功能:</h3>
|
<h3 class="text-xl font-semibold text-gray-900 dark:text-white mb-4">規劃功能:</h3>
|
||||||
<ul class="space-y-2 {{ $isLight ? 'text-gray-700' : 'text-gray-300' }}">
|
<ul class="space-y-2 text-gray-700 dark:text-gray-300">
|
||||||
@foreach($features as $feature)
|
@foreach($features as $feature)
|
||||||
<li class="flex items-start">
|
<li class="flex items-start">
|
||||||
<svg class="h-6 w-6 text-{{ $currentTheme['accent'] }}-500 mr-2 flex-shrink-0" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
<svg class="h-6 w-6 text-blue-500 mr-2 flex-shrink-0" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>{{ $feature }}</span>
|
<span>{{ $feature }}</span>
|
||||||
|
|||||||
@@ -2,15 +2,6 @@
|
|||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@php
|
@php
|
||||||
$theme = request()->cookie('theme', 'dark-blue');
|
|
||||||
$isLight = in_array($theme, ['light-blue', 'light-green']);
|
|
||||||
$cardBg = $isLight ? 'bg-white' : 'bg-gray-800';
|
|
||||||
$textPrimary = $isLight ? 'text-gray-900' : 'text-gray-200';
|
|
||||||
$textSecondary = $isLight ? 'text-gray-600' : 'text-gray-400';
|
|
||||||
$borderColor = $isLight ? 'border-gray-200' : 'border-gray-700';
|
|
||||||
$thBg = $isLight ? 'bg-gray-50' : 'bg-gray-700';
|
|
||||||
$inputBg = $isLight ? 'bg-white' : 'bg-gray-700';
|
|
||||||
$inputBorder = $isLight ? 'border-gray-300' : 'border-gray-600';
|
|
||||||
|
|
||||||
$triggerLabels = [
|
$triggerLabels = [
|
||||||
'purchase' => '消費',
|
'purchase' => '消費',
|
||||||
@@ -43,33 +34,33 @@
|
|||||||
|
|
||||||
<div class="container mx-auto px-6 py-8">
|
<div class="container mx-auto px-6 py-8">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex justify-between items-center mb-6">
|
||||||
<h3 class="{{ $textPrimary }} text-3xl font-medium">點數規則設定</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-3xl font-medium">點數規則設定</h3>
|
||||||
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">
|
<button onclick="document.getElementById('createModal').classList.remove('hidden')" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700">
|
||||||
新增規則
|
新增規則
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<table class="min-w-full {{ $cardBg }} rounded-lg overflow-hidden">
|
<table class="min-w-full bg-white dark:bg-gray-800 rounded-lg overflow-hidden">
|
||||||
<thead class="{{ $thBg }}">
|
<thead class="bg-gray-100 dark:bg-gray-700">
|
||||||
<tr>
|
<tr>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">名稱</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">名稱</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">觸發條件</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">觸發條件</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">每單位點數</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">每單位點數</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">單位金額</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">單位金額</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">有效天數</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">有效天數</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">狀態</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">狀態</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium {{ $textSecondary }} uppercase">操作</th>
|
<th class="px-6 py-3 text-left text-xs font-medium text-gray-600 dark:text-gray-400 uppercase">操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="divide-y {{ $borderColor }}">
|
<tbody class="divide-y border-gray-200 dark:border-gray-700">
|
||||||
@forelse($rules as $rule)
|
@forelse($rules as $rule)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $rule->name }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $rule->name }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $triggerLabels[$rule->trigger] ?? $rule->trigger }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $triggerLabels[$rule->trigger] ?? $rule->trigger }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $rule->points_per_unit }} 點</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $rule->points_per_unit }} 點</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">${{ number_format($rule->unit_amount) }}</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">${{ number_format($rule->unit_amount) }}</td>
|
||||||
<td class="px-6 py-4 {{ $textPrimary }}">{{ $rule->validity_days }} 天</td>
|
<td class="px-6 py-4 text-gray-900 dark:text-gray-200">{{ $rule->validity_days }} 天</td>
|
||||||
<td class="px-6 py-4">
|
<td class="px-6 py-4">
|
||||||
@if($rule->is_active)
|
@if($rule->is_active)
|
||||||
<span class="px-2 py-1 rounded-full bg-green-100 text-green-800 text-xs">啟用</span>
|
<span class="px-2 py-1 rounded-full bg-green-100 text-green-800 text-xs">啟用</span>
|
||||||
@@ -87,7 +78,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
@empty
|
@empty
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="7" class="px-6 py-4 text-center {{ $textSecondary }}">尚無資料</td>
|
<td colspan="7" class="px-6 py-4 text-center text-gray-600 dark:text-gray-400">尚無資料</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforelse
|
@endforelse
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -100,44 +91,44 @@
|
|||||||
<div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:p-0">
|
<div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:p-0">
|
||||||
<div class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" onclick="document.getElementById('createModal').classList.add('hidden')"></div>
|
<div class="fixed inset-0 transition-opacity bg-gray-500 bg-opacity-75" onclick="document.getElementById('createModal').classList.add('hidden')"></div>
|
||||||
|
|
||||||
<div class="relative {{ $cardBg }} rounded-lg shadow-xl transform transition-all sm:max-w-lg sm:w-full mx-4">
|
<div class="relative bg-white dark:bg-gray-800 rounded-lg shadow-xl transform transition-all sm:max-w-lg sm:w-full mx-4">
|
||||||
<div class="px-6 py-4 border-b {{ $borderColor }}">
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
||||||
<h3 class="{{ $textPrimary }} text-lg font-semibold">新增點數規則</h3>
|
<h3 class="text-gray-900 dark:text-gray-200 text-lg font-semibold">新增點數規則</h3>
|
||||||
</div>
|
</div>
|
||||||
<form action="{{ route('admin.point-rules.store') }}" method="POST">
|
<form action="{{ route('admin.point-rules.store') }}" method="POST">
|
||||||
@csrf
|
@csrf
|
||||||
<div class="px-6 py-4 space-y-4">
|
<div class="px-6 py-4 space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">名稱</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">名稱</label>
|
||||||
<input type="text" name="name" required class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="text" name="name" required class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">觸發條件</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">觸發條件</label>
|
||||||
<select name="trigger" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<select name="trigger" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
@foreach($triggerLabels as $key => $label)
|
@foreach($triggerLabels as $key => $label)
|
||||||
<option value="{{ $key }}">{{ $label }}</option>
|
<option value="{{ $key }}">{{ $label }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">每單位獲得點數</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">每單位獲得點數</label>
|
||||||
<input type="number" name="points_per_unit" value="1" min="1" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="number" name="points_per_unit" value="1" min="1" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">單位金額</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">單位金額</label>
|
||||||
<input type="number" name="unit_amount" value="100" step="0.01" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="number" name="unit_amount" value="100" step="0.01" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label class="{{ $textSecondary }} text-sm block mb-1">有效天數</label>
|
<label class="text-gray-600 dark:text-gray-400 text-sm block mb-1">有效天數</label>
|
||||||
<input type="number" name="validity_days" value="365" min="1" class="w-full px-3 py-2 {{ $inputBg }} {{ $inputBorder }} border rounded-md {{ $textPrimary }} focus:ring-2 focus:ring-indigo-500">
|
<input type="number" name="validity_days" value="365" min="1" class="w-full px-3 py-2 bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 border rounded-md text-gray-900 dark:text-gray-200 focus:ring-2 focus:ring-indigo-500">
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<input type="checkbox" name="is_active" value="1" checked id="is_active" class="mr-2 rounded text-indigo-600 focus:ring-indigo-500">
|
<input type="checkbox" name="is_active" value="1" checked id="is_active" class="mr-2 rounded text-indigo-600 focus:ring-indigo-500">
|
||||||
<label for="is_active" class="{{ $textSecondary }} text-sm">啟用</label>
|
<label for="is_active" class="text-gray-600 dark:text-gray-400 text-sm">啟用</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="px-6 py-4 border-t {{ $borderColor }} flex justify-end space-x-3">
|
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700 flex justify-end space-x-3">
|
||||||
<button type="button" onclick="document.getElementById('createModal').classList.add('hidden')" class="px-4 py-2 {{ $textSecondary }} border {{ $inputBorder }} rounded-md hover:bg-gray-100 dark:hover:bg-gray-700">取消</button>
|
<button type="button" onclick="document.getElementById('createModal').classList.add('hidden')" class="px-4 py-2 text-gray-600 dark:text-gray-400 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700">取消</button>
|
||||||
<button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700">建立</button>
|
<button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700">建立</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,47 +1,123 @@
|
|||||||
<x-guest-layout>
|
<!DOCTYPE html>
|
||||||
<!-- Session Status -->
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||||
<x-auth-session-status class="mb-4" :status="session('status')" />
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||||
|
<title>{{ config('app.name', 'Laravel') }}</title>
|
||||||
|
<!-- Fonts -->
|
||||||
|
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||||
|
<link href="https://fonts.bunny.net/css?family=inter:400,500,600,700&display=swap" rel="stylesheet" />
|
||||||
|
<script>
|
||||||
|
// Dark mode
|
||||||
|
const html = document.querySelector('html');
|
||||||
|
const isLightOrAuto = localStorage.getItem('hs_theme') === 'light' || (localStorage.getItem('hs_theme') !== 'dark' && !window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||||
|
const isDarkOrAuto = localStorage.getItem('hs_theme') === 'dark' || (localStorage.getItem('hs_theme') !== 'light' && window.matchMedia('(prefers-color-scheme: dark)').matches);
|
||||||
|
|
||||||
<form method="POST" action="{{ route('login') }}">
|
if (isLightOrAuto && html.classList.contains('dark')) html.classList.remove('dark');
|
||||||
@csrf
|
else if (isDarkOrAuto && html.classList.contains('light')) html.classList.remove('light');
|
||||||
|
else if (isDarkOrAuto && !html.classList.contains('dark')) html.classList.add('dark');
|
||||||
|
else if (isLightOrAuto && !html.classList.contains('light')) html.classList.add('light');
|
||||||
|
</script>
|
||||||
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||||
|
</head>
|
||||||
|
<body class="font-sans antialiased bg-white dark:bg-slate-900">
|
||||||
|
<div class="flex h-screen">
|
||||||
|
<!-- Sidebar - Image Section -->
|
||||||
|
<div class="hidden md:flex md:w-1/2 lg:w-3/5 bg-gray-50 border-r border-gray-200 dark:bg-slate-800 dark:border-slate-700 justify-center items-center relative overflow-hidden">
|
||||||
|
<!-- Background Pattern or Gradient -->
|
||||||
|
<div class="absolute inset-0 bg-gradient-to-tr from-blue-600 to-purple-500 opacity-90 dark:from-blue-900 dark:to-purple-900"></div>
|
||||||
|
|
||||||
<!-- 帳號 -->
|
<div class="relative z-10 text-center px-6">
|
||||||
<div>
|
<h2 class="text-3xl font-bold text-white sm:text-4xl">
|
||||||
<x-input-label for="username" :value="__('帳號')" />
|
{{ config('app.name', 'Star Cloud') }}
|
||||||
<x-text-input id="username" class="block mt-1 w-full" type="text" name="username" :value="old('username')" required autofocus autocomplete="username" />
|
</h2>
|
||||||
<x-input-error :messages="$errors->get('username')" class="mt-2" />
|
<p class="mt-3 text-lg text-blue-100">
|
||||||
|
智能販賣機管理平台
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Password -->
|
<!-- Main Content - Login Form -->
|
||||||
<div class="mt-4">
|
<div class="w-full md:w-1/2 lg:w-2/5 flex flex-col justify-center px-4 sm:px-6 md:px-8 lg:px-10 py-8">
|
||||||
<x-input-label for="password" :value="__('Password')" />
|
<div class="max-w-md w-full mx-auto">
|
||||||
|
<div class="text-center mb-8">
|
||||||
|
<h1 class="block text-2xl font-bold text-gray-800 dark:text-white">登入</h1>
|
||||||
|
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">
|
||||||
|
請輸入您的帳號密碼以繼續
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<x-text-input id="password" class="block mt-1 w-full"
|
<!-- Session Status -->
|
||||||
type="password"
|
@if (session('status'))
|
||||||
name="password"
|
<div class="mb-4 text-sm font-medium text-green-600">
|
||||||
required autocomplete="current-password" />
|
{{ session('status') }}
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<x-input-error :messages="$errors->get('password')" class="mt-2" />
|
<form method="POST" action="{{ route('login') }}">
|
||||||
|
@csrf
|
||||||
|
|
||||||
|
<div class="grid gap-y-4">
|
||||||
|
<!-- Form Group -->
|
||||||
|
<div>
|
||||||
|
<label for="username" class="block text-sm mb-2 dark:text-white">帳號</label>
|
||||||
|
<div class="relative">
|
||||||
|
<input type="text" id="username" name="username" value="{{ old('username') }}" class="py-3 px-4 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-slate-700 dark:text-gray-400 dark:focus:ring-gray-600" required autofocus autocomplete="username">
|
||||||
|
<div class="hidden absolute inset-y-0 end-0 flex items-center pointer-events-none pe-3">
|
||||||
|
<svg class="h-5 w-5 text-red-500" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
|
||||||
|
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if ($errors->get('username'))
|
||||||
|
<p class="text-xs text-red-600 mt-2" id="username-error">{{ $errors->first('username') }}</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<!-- End Form Group -->
|
||||||
|
|
||||||
|
<!-- Form Group -->
|
||||||
|
<div>
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<label for="password" class="block text-sm mb-2 dark:text-white">密碼</label>
|
||||||
|
@if (Route::has('password.request'))
|
||||||
|
<a class="text-sm text-blue-600 decoration-2 hover:underline font-medium dark:text-blue-500" href="{{ route('password.request') }}">
|
||||||
|
忘記密碼?
|
||||||
|
</a>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<div class="relative">
|
||||||
|
<input type="password" id="password" name="password" class="py-3 px-4 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-slate-700 dark:text-gray-400 dark:focus:ring-gray-600" required autocomplete="current-password">
|
||||||
|
<div class="hidden absolute inset-y-0 end-0 flex items-center pointer-events-none pe-3">
|
||||||
|
<svg class="h-5 w-5 text-red-500" width="16" height="16" fill="currentColor" viewBox="0 0 16 16" aria-hidden="true">
|
||||||
|
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@if ($errors->get('password'))
|
||||||
|
<p class="text-xs text-red-600 mt-2" id="password-error">{{ $errors->first('password') }}</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<!-- End Form Group -->
|
||||||
|
|
||||||
|
<!-- Checkbox -->
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="flex">
|
||||||
|
<input id="remember-me" name="remember" type="checkbox" class="shrink-0 mt-0.5 border-gray-200 rounded text-blue-600 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-700 dark:checked:bg-blue-500 dark:checked:border-blue-500 dark:focus:ring-offset-gray-800">
|
||||||
|
</div>
|
||||||
|
<div class="ms-3">
|
||||||
|
<label for="remember-me" class="text-sm dark:text-white">記住我</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Checkbox -->
|
||||||
|
|
||||||
|
<button type="submit" class="w-full py-3 px-4 inline-flex justify-center items-center gap-x-2 text-sm font-semibold rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600">
|
||||||
|
登入
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<!-- Remember Me -->
|
</body>
|
||||||
<div class="block mt-4">
|
</html>
|
||||||
<label for="remember_me" class="inline-flex items-center">
|
|
||||||
<input id="remember_me" type="checkbox" class="rounded dark:bg-gray-900 border-gray-300 dark:border-gray-700 text-indigo-600 shadow-sm focus:ring-indigo-500 dark:focus:ring-indigo-600 dark:focus:ring-offset-gray-800" name="remember">
|
|
||||||
<span class="ms-2 text-sm text-gray-600 dark:text-gray-400">{{ __('Remember me') }}</span>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center justify-end mt-4">
|
|
||||||
@if (Route::has('password.request'))
|
|
||||||
<a class="underline text-sm text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-800" href="{{ route('password.request') }}">
|
|
||||||
{{ __('Forgot your password?') }}
|
|
||||||
</a>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<x-primary-button class="ms-3">
|
|
||||||
{{ __('Log in') }}
|
|
||||||
</x-primary-button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</x-guest-layout>
|
|
||||||
|
|||||||
@@ -1,17 +1,165 @@
|
|||||||
<x-app-layout>
|
@extends('layouts.admin')
|
||||||
<x-slot name="header">
|
|
||||||
<h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight">
|
|
||||||
{{ __('Dashboard') }}
|
|
||||||
</h2>
|
|
||||||
</x-slot>
|
|
||||||
|
|
||||||
<div class="py-12">
|
@section('content')
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
<div class="space-y-4 sm:space-y-6">
|
||||||
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
|
<!-- Grid -->
|
||||||
<div class="p-6 text-gray-900 dark:text-gray-100">
|
<div class="grid sm:grid-cols-2 lg:grid-cols-4 gap-4 sm:gap-6">
|
||||||
{{ __("You're logged in!") }}
|
<!-- Card -->
|
||||||
</div>
|
<div class="flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<div class="p-4 md:p-5">
|
||||||
|
<div class="flex items-center gap-x-2">
|
||||||
|
<p class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
||||||
|
總銷售額
|
||||||
|
</p>
|
||||||
|
<div class="hs-tooltip">
|
||||||
|
<div class="hs-tooltip-toggle">
|
||||||
|
<svg class="flex-shrink-0 w-4 h-4 text-gray-500" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><path d="M12 17h.01"/></svg>
|
||||||
|
<span class="hs-tooltip-content hs-tooltip-shown:opacity-100 hs-tooltip-shown:visible opacity-0 transition-opacity inline-block absolute invisible z-10 py-1 px-2 bg-gray-900 text-xs font-medium text-white rounded shadow-sm dark:bg-slate-700" role="tooltip">
|
||||||
|
本月累計銷售總額
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-1 flex items-center gap-x-2">
|
||||||
|
<h3 class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
$72,540
|
||||||
|
</h3>
|
||||||
|
<span class="flex items-center gap-x-1 text-green-600">
|
||||||
|
<svg class="inline-block w-4 h-4 self-center" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg>
|
||||||
|
<span class="inline-block text-sm">
|
||||||
|
1.7%
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</x-app-layout>
|
<!-- End Card -->
|
||||||
|
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<div class="p-4 md:p-5">
|
||||||
|
<div class="flex items-center gap-x-2">
|
||||||
|
<p class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
||||||
|
活躍機台
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-1 flex items-center gap-x-2">
|
||||||
|
<h3 class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
124
|
||||||
|
</h3>
|
||||||
|
<span class="flex items-center gap-x-1 text-red-600">
|
||||||
|
<svg class="inline-block w-4 h-4 self-center" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 17 13.5 8.5 8.5 13.5 2 7"/><polyline points="16 17 22 17 22 11"/></svg>
|
||||||
|
<span class="inline-block text-sm">
|
||||||
|
0.3%
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<div class="p-4 md:p-5">
|
||||||
|
<div class="flex items-center gap-x-2">
|
||||||
|
<p class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
||||||
|
庫存警告
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-1 flex items-center gap-x-2">
|
||||||
|
<h3 class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
12
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<div class="p-4 md:p-5">
|
||||||
|
<div class="flex items-center gap-x-2">
|
||||||
|
<p class="text-xs uppercase tracking-wide text-gray-500 dark:text-gray-400">
|
||||||
|
本月新增會員
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-1 flex items-center gap-x-2">
|
||||||
|
<h3 class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
28
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
</div>
|
||||||
|
<!-- End Grid -->
|
||||||
|
|
||||||
|
<div class="grid lg:grid-cols-2 gap-4 sm:gap-6">
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="p-4 md:p-5 min-h-[410px] flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<div>
|
||||||
|
<h2 class="text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
營收趨勢
|
||||||
|
</h2>
|
||||||
|
<p class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
$123,450
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<span class="py-[5px] px-1.5 inline-flex items-center gap-x-1 text-xs font-medium rounded-md bg-teal-100 text-teal-800 dark:bg-teal-500/10 dark:text-teal-500">
|
||||||
|
<svg class="inline-block w-3.5 h-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14"/><path d="m19 12-7 7-7-7"/></svg>
|
||||||
|
25%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Header -->
|
||||||
|
|
||||||
|
<div id="hs-multiple-bar-charts"></div>
|
||||||
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
|
||||||
|
<!-- Card -->
|
||||||
|
<div class="p-4 md:p-5 min-h-[410px] flex flex-col bg-white border shadow-sm rounded-xl dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<!-- Header -->
|
||||||
|
<div class="flex justify-between items-center">
|
||||||
|
<div>
|
||||||
|
<h2 class="text-sm text-gray-500 dark:text-gray-400">
|
||||||
|
訪客分析
|
||||||
|
</h2>
|
||||||
|
<p class="text-xl sm:text-2xl font-medium text-gray-800 dark:text-gray-200">
|
||||||
|
92,913
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<span class="py-[5px] px-1.5 inline-flex items-center gap-x-1 text-xs font-medium rounded-md bg-red-100 text-red-800 dark:bg-red-500/10 dark:text-red-500">
|
||||||
|
<svg class="inline-block w-3.5 h-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5v14"/><path d="m19 12-7 7-7-7"/></svg>
|
||||||
|
11%
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- End Header -->
|
||||||
|
|
||||||
|
<div id="hs-single-area-chart"></div>
|
||||||
|
</div>
|
||||||
|
<!-- End Card -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('scripts')
|
||||||
|
<script>
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
// Here you would initialize charts using ApexCharts or similar,
|
||||||
|
// as Preline examples often use ApexCharts.
|
||||||
|
// For now, placeholders are sufficient.
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endsection
|
||||||
|
|||||||
@@ -1,55 +1,5 @@
|
|||||||
@php
|
|
||||||
$theme = request()->cookie('theme', 'dark-blue');
|
|
||||||
|
|
||||||
// 主題配置
|
|
||||||
$themes = [
|
|
||||||
'dark-blue' => [
|
|
||||||
'name' => '深色藍',
|
|
||||||
'body' => 'bg-gray-900 text-gray-100',
|
|
||||||
'sidebar' => 'bg-gray-800 border-gray-700',
|
|
||||||
'header' => 'bg-gray-800 border-gray-700',
|
|
||||||
'card' => 'bg-gray-800',
|
|
||||||
'accent' => 'indigo',
|
|
||||||
],
|
|
||||||
'dark-purple' => [
|
|
||||||
'name' => '深色紫',
|
|
||||||
'body' => 'bg-slate-900 text-slate-100',
|
|
||||||
'sidebar' => 'bg-slate-800 border-slate-700',
|
|
||||||
'header' => 'bg-slate-800 border-slate-700',
|
|
||||||
'card' => 'bg-slate-800',
|
|
||||||
'accent' => 'purple',
|
|
||||||
],
|
|
||||||
'dark-green' => [
|
|
||||||
'name' => '深色綠',
|
|
||||||
'body' => 'bg-zinc-900 text-zinc-100',
|
|
||||||
'sidebar' => 'bg-zinc-800 border-zinc-700',
|
|
||||||
'header' => 'bg-zinc-800 border-zinc-700',
|
|
||||||
'card' => 'bg-zinc-800',
|
|
||||||
'accent' => 'emerald',
|
|
||||||
],
|
|
||||||
'light-blue' => [
|
|
||||||
'name' => '亮色藍',
|
|
||||||
'body' => 'bg-gray-50 text-gray-900',
|
|
||||||
'sidebar' => 'bg-white border-gray-200',
|
|
||||||
'header' => 'bg-white border-gray-200',
|
|
||||||
'card' => 'bg-white',
|
|
||||||
'accent' => 'blue',
|
|
||||||
],
|
|
||||||
'light-green' => [
|
|
||||||
'name' => '亮色綠',
|
|
||||||
'body' => 'bg-green-50 text-gray-900',
|
|
||||||
'sidebar' => 'bg-white border-green-200',
|
|
||||||
'header' => 'bg-white border-green-200',
|
|
||||||
'card' => 'bg-white',
|
|
||||||
'accent' => 'green',
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
$currentTheme = $themes[$theme] ?? $themes['dark-blue'];
|
|
||||||
$isLight = in_array($theme, ['light-blue', 'light-green']);
|
|
||||||
@endphp
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="{{ $isLight ? '' : 'dark' }}">
|
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" class="h-full" x-data="{ darkMode: localStorage.getItem('darkMode') === 'true' }" :class="{ 'dark': darkMode }">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@@ -62,88 +12,168 @@
|
|||||||
<link href="https://fonts.bunny.net/css?family=inter:400,500,600,700&display=swap" rel="stylesheet" />
|
<link href="https://fonts.bunny.net/css?family=inter:400,500,600,700&display=swap" rel="stylesheet" />
|
||||||
|
|
||||||
<!-- Scripts -->
|
<!-- Scripts -->
|
||||||
|
<script>
|
||||||
|
// Dark Mode Initialization (before Alpine loads)
|
||||||
|
if (localStorage.getItem('darkMode') === 'true' || (!('darkMode' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
localStorage.setItem('darkMode', 'true');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove('dark');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||||
</head>
|
</head>
|
||||||
<body class="font-sans antialiased {{ $currentTheme['body'] }}" x-data="{ sidebarOpen: false, themeOpen: false, dropdownOpen: false }" x-cloak>
|
<body class="bg-gray-50 dark:bg-slate-900 antialiased font-sans h-full" x-data="{ sidebarOpen: false, userDropdownOpen: false }">
|
||||||
<div class="min-h-screen flex">
|
|
||||||
<!-- Mobile Sidebar Backdrop -->
|
|
||||||
<div x-show="sidebarOpen"
|
|
||||||
x-cloak
|
|
||||||
@click="sidebarOpen = false"
|
|
||||||
x-transition:enter="transition-opacity ease-linear duration-300"
|
|
||||||
x-transition:enter-start="opacity-0"
|
|
||||||
x-transition:enter-end="opacity-100"
|
|
||||||
x-transition:leave="transition-opacity ease-linear duration-300"
|
|
||||||
x-transition:leave-start="opacity-100"
|
|
||||||
x-transition:leave-end="opacity-0"
|
|
||||||
class="fixed inset-0 bg-black bg-opacity-50 z-40 lg:hidden">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Sidebar -->
|
<!-- Sidebar Overlay (Mobile) -->
|
||||||
<aside class="fixed inset-y-0 left-0 z-50 w-64 {{ $currentTheme['sidebar'] }} border-r overflow-y-auto transition-transform duration-300 ease-in-out lg:translate-x-0 lg:static lg:inset-0"
|
<div x-show="sidebarOpen"
|
||||||
:class="{'translate-x-0': sidebarOpen, '-translate-x-full': !sidebarOpen}"
|
x-transition:enter="transition-opacity ease-linear duration-300"
|
||||||
x-cloak>
|
x-transition:enter-start="opacity-0"
|
||||||
<div class="flex items-center justify-center h-16 {{ $currentTheme['header'] }} border-b">
|
x-transition:enter-end="opacity-100"
|
||||||
<span class="text-2xl font-bold text-{{ $currentTheme['accent'] }}-500">Star Cloud</span>
|
x-transition:leave="transition-opacity ease-linear duration-300"
|
||||||
|
x-transition:leave-start="opacity-100"
|
||||||
|
x-transition:leave-end="opacity-0"
|
||||||
|
@click="sidebarOpen = false"
|
||||||
|
class="fixed inset-0 z-[55] bg-gray-900/50 lg:hidden"
|
||||||
|
x-cloak></div>
|
||||||
|
|
||||||
|
<!-- ========== HEADER ========== -->
|
||||||
|
<header class="sticky top-0 inset-x-0 flex flex-wrap sm:justify-start sm:flex-nowrap z-[48] w-full bg-white border-b text-sm py-2.5 sm:py-4 lg:pl-64 dark:bg-gray-800 dark:border-gray-700">
|
||||||
|
<nav class="flex basis-full items-center w-full mx-auto px-4 sm:px-6 md:px-8" aria-label="Global">
|
||||||
|
<div class="mr-5 lg:mr-0 lg:hidden">
|
||||||
|
<a class="flex-none text-xl font-semibold dark:text-white" href="#" aria-label="Brand">Star Cloud</a>
|
||||||
</div>
|
</div>
|
||||||
<nav class="mt-5 px-2 space-y-1 pb-4">
|
|
||||||
@include('layouts.partials.sidebar-menu')
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
|
|
||||||
<!-- Content -->
|
<div class="w-full flex items-center justify-end ml-auto sm:justify-between sm:gap-x-3 sm:order-3">
|
||||||
<div class="flex-1 flex flex-col overflow-hidden">
|
<div class="sm:hidden">
|
||||||
<!-- Topbar -->
|
<button type="button" class="inline-flex flex-shrink-0 justify-center items-center gap-2 h-[2.375rem] w-[2.375rem] rounded-full font-medium bg-white text-gray-700 align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition-all text-xs dark:bg-gray-800 dark:hover:bg-slate-800 dark:text-gray-400 dark:hover:text-white dark:focus:ring-gray-700 dark:focus:ring-offset-gray-800">
|
||||||
<header class="flex items-center justify-between h-16 {{ $currentTheme['header'] }} border-b px-6">
|
<svg class="w-3.5 h-3.5" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||||
<div class="flex items-center">
|
<path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"/>
|
||||||
<button @click="sidebarOpen = !sidebarOpen" class="{{ $isLight ? 'text-gray-600' : 'text-gray-400' }} focus:outline-none lg:hidden">
|
|
||||||
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center space-x-4">
|
|
||||||
<!-- Theme Selector -->
|
|
||||||
<div class="relative">
|
|
||||||
<button @click="themeOpen = !themeOpen" class="relative block h-8 w-8 rounded-full overflow-hidden shadow focus:outline-none {{ $isLight ? 'bg-gray-200' : 'bg-gray-700' }}">
|
|
||||||
<svg class="h-5 w-5 m-auto mt-1.5 {{ $isLight ? 'text-gray-600' : 'text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<div x-show="themeOpen" x-cloak @click.away="themeOpen = false" class="absolute right-0 w-48 mt-2 {{ $currentTheme['card'] }} rounded-md shadow-lg py-1 ring-1 ring-black ring-opacity-5 z-50">
|
|
||||||
@foreach($themes as $key => $themeData)
|
|
||||||
<form method="POST" action="{{ route('admin.theme.update') }}">
|
|
||||||
@csrf
|
|
||||||
<input type="hidden" name="theme" value="{{ $key }}">
|
|
||||||
<button type="submit" class="block w-full text-left px-4 py-2 text-sm {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700' }} {{ $theme === $key ? 'font-bold' : '' }}">
|
|
||||||
{{ $themeData['name'] }} {{ $theme === $key ? '✓' : '' }}
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- User Menu -->
|
<div class="hidden sm:block">
|
||||||
<div class="ml-3 relative">
|
<!-- Search Input (Optional) -->
|
||||||
<button @click="dropdownOpen = !dropdownOpen" class="relative block h-8 w-8 rounded-full overflow-hidden shadow focus:outline-none">
|
</div>
|
||||||
<img class="h-full w-full object-cover" src="https://ui-avatars.com/api/?name={{ Auth::user()->name }}&background=random" alt="Avatar">
|
|
||||||
|
<div class="flex flex-row items-center justify-end gap-2">
|
||||||
|
<!-- Dark Mode Toggle -->
|
||||||
|
<button type="button"
|
||||||
|
@click="darkMode = !darkMode; localStorage.setItem('darkMode', darkMode); document.documentElement.classList.toggle('dark', darkMode)"
|
||||||
|
class="inline-flex flex-shrink-0 justify-center items-center gap-2 h-[2.375rem] w-[2.375rem] rounded-full font-medium bg-white text-gray-700 align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition-all text-xs dark:bg-gray-800 dark:hover:bg-slate-800 dark:text-gray-400 dark:hover:text-white dark:focus:ring-gray-700 dark:focus:ring-offset-gray-800">
|
||||||
|
<!-- Moon Icon (shown in light mode) -->
|
||||||
|
<svg x-show="!darkMode" class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path d="M6 .278a.768.768 0 0 1 .08.858 7.208 7.208 0 0 0-.878 3.46c0 4.021 3.278 7.277 7.318 7.277.527 0 1.04-.055 1.533-.16a.787.787 0 0 1 .81.316.733.733 0 0 1-.031.893A8.349 8.349 0 0 1 8.344 16C3.734 16 0 12.286 0 7.71 0 4.266 2.114 1.312 5.124.06A.752.752 0 0 1 6 .278zM4.858 1.311A7.269 7.269 0 0 0 1.025 7.71c0 4.02 3.279 7.276 7.319 7.276a7.316 7.316 0 0 0 5.205-2.162c-.337.042-.68.063-1.029.063-4.61 0-8.343-3.714-8.343-8.29 0-1.167.242-2.278.681-3.286z"/>
|
||||||
|
</svg>
|
||||||
|
<!-- Sun Icon (shown in dark mode) -->
|
||||||
|
<svg x-show="darkMode" class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path d="M8 11a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0 1a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Profile Dropdown -->
|
||||||
|
<div class="relative inline-flex" x-data="{ open: false }">
|
||||||
|
<button id="hs-dropdown-with-header" type="button" @click="open = !open" @click.away="open = false" class="inline-flex flex-shrink-0 justify-center items-center gap-2 h-[2.375rem] w-[2.375rem] rounded-full font-medium bg-white text-gray-700 align-middle hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-white transition-all text-xs dark:bg-gray-800 dark:hover:bg-slate-800 dark:text-gray-400 dark:hover:text-white dark:focus:ring-gray-700 dark:focus:ring-offset-gray-800">
|
||||||
|
<img class="inline-block h-[2.375rem] w-[2.375rem] rounded-full ring-2 ring-white dark:ring-gray-800" src="https://ui-avatars.com/api/?name={{ Auth::user()->name }}&background=0D8ABC&color=fff" alt="Image Description">
|
||||||
</button>
|
</button>
|
||||||
<div x-show="dropdownOpen" x-cloak @click.away="dropdownOpen = false" class="absolute right-0 w-48 mt-2 {{ $currentTheme['card'] }} rounded-md shadow-lg py-1 ring-1 ring-black ring-opacity-5 z-50">
|
|
||||||
<a href="{{ route('profile.edit') }}" class="block px-4 py-2 text-sm {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700' }}">個人檔案</a>
|
<div x-show="open"
|
||||||
<form method="POST" action="{{ route('logout') }}">
|
x-transition:enter="transition ease-out duration-100"
|
||||||
@csrf
|
x-transition:enter-start="transform opacity-0 scale-95"
|
||||||
<button type="submit" class="block w-full text-left px-4 py-2 text-sm {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700' }}">登出</button>
|
x-transition:enter-end="transform opacity-100 scale-100"
|
||||||
</form>
|
x-transition:leave="transition ease-in duration-75"
|
||||||
|
x-transition:leave-start="transform opacity-100 scale-100"
|
||||||
|
x-transition:leave-end="transform opacity-0 scale-95"
|
||||||
|
class="absolute right-0 top-full mt-2 min-w-[15rem] bg-white shadow-md rounded-lg p-2 dark:bg-gray-800 dark:border dark:border-gray-700 z-50"
|
||||||
|
x-cloak>
|
||||||
|
<div class="py-3 px-5 -m-2 bg-gray-100 rounded-t-lg dark:bg-gray-700">
|
||||||
|
<p class="text-sm text-gray-500 dark:text-gray-400">Signed in as</p>
|
||||||
|
<p class="text-sm font-medium text-gray-800 dark:text-gray-300">{{ Auth::user()->email }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="mt-2 py-2 first:pt-0 last:pb-0">
|
||||||
|
<a class="flex items-center gap-x-3.5 py-2 px-3 rounded-md text-sm text-gray-800 hover:bg-gray-100 focus:ring-2 focus:ring-blue-500 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300" href="{{ route('profile.edit') }}">
|
||||||
|
<svg class="flex-shrink-0 w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
||||||
|
個人檔案
|
||||||
|
</a>
|
||||||
|
<form method="POST" action="{{ route('logout') }}">
|
||||||
|
@csrf
|
||||||
|
<button type="submit" class="w-full flex items-center gap-x-3.5 py-2 px-3 rounded-md text-sm text-gray-800 hover:bg-gray-100 focus:ring-2 focus:ring-blue-500 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300">
|
||||||
|
<svg class="flex-shrink-0 w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/></svg>
|
||||||
|
登出
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<!-- ========== END HEADER ========== -->
|
||||||
|
|
||||||
<!-- Main Content -->
|
<!-- ========== MAIN CONTENT ========== -->
|
||||||
<main class="flex-1 overflow-x-hidden overflow-y-auto {{ $currentTheme['body'] }} p-6">
|
<!-- Sidebar Toggle (Mobile) -->
|
||||||
@yield('content')
|
<div class="sticky top-[3.75rem] inset-x-0 z-20 bg-white border-y px-4 sm:px-6 md:px-8 lg:hidden dark:bg-gray-800 dark:border-gray-700">
|
||||||
</main>
|
<div class="flex items-center py-4">
|
||||||
|
<!-- Navigation Toggle -->
|
||||||
|
<button type="button" class="text-gray-500 hover:text-gray-600" @click="sidebarOpen = !sidebarOpen">
|
||||||
|
<span class="sr-only">Toggle Navigation</span>
|
||||||
|
<svg class="w-5 h-5" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd" d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<!-- End Navigation Toggle -->
|
||||||
|
|
||||||
|
<!-- Breadcrumb -->
|
||||||
|
<ol class="ms-3 flex items-center whitespace-nowrap" aria-label="Breadcrumb">
|
||||||
|
<li class="flex items-center text-sm text-gray-800 dark:text-gray-400">
|
||||||
|
Star Cloud
|
||||||
|
<svg class="flex-shrink-0 mx-3 overflow-visible h-2.5 w-2.5 text-gray-400 dark:text-gray-600" 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>
|
||||||
|
</li>
|
||||||
|
<li class="text-sm font-semibold text-gray-800 truncate dark:text-gray-200" aria-current="page">
|
||||||
|
Dashboard
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
<!-- End Breadcrumb -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- End Sidebar Toggle -->
|
||||||
|
|
||||||
|
<!-- Sidebar -->
|
||||||
|
<div id="application-sidebar"
|
||||||
|
class="fixed top-0 left-0 bottom-0 z-[60] w-64 bg-white border-r border-gray-200 pt-7 pb-10 overflow-y-auto transition-transform duration-300 transform lg:translate-x-0 dark:bg-gray-800 dark:border-gray-700"
|
||||||
|
:class="sidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'">
|
||||||
|
<!-- Close Button (Mobile) -->
|
||||||
|
<button type="button" @click="sidebarOpen = false" class="absolute top-4 right-4 text-gray-500 hover:text-gray-700 lg:hidden dark:text-gray-400 dark:hover:text-gray-200">
|
||||||
|
<span class="sr-only">Close sidebar</span>
|
||||||
|
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="px-6">
|
||||||
|
<a class="flex-none text-xl font-semibold dark:text-white" href="#" aria-label="Brand">Star Cloud</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="p-6 w-full flex flex-col flex-wrap">
|
||||||
|
<ul class="space-y-1.5">
|
||||||
|
@include('layouts.partials.sidebar-menu')
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<!-- End Sidebar -->
|
||||||
|
|
||||||
|
<!-- Content -->
|
||||||
|
<div class="w-full pt-10 px-4 sm:px-6 md:px-8 lg:pl-72">
|
||||||
|
<main>
|
||||||
|
@yield('content')
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
<!-- End Content -->
|
||||||
|
|
||||||
|
@yield('scripts')
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,374 +1,278 @@
|
|||||||
{{-- 1. 儀表板 (獨立項目) --}}
|
{{-- 1. 儀表板 --}}
|
||||||
<a href="{{ route('admin.dashboard') }}"
|
<li>
|
||||||
@click="if (window.innerWidth < 1024) sidebarOpen = false"
|
<a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 text-gray-700 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.dashboard') ? 'bg-gray-100 dark:bg-gray-900 text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.dashboard') }}">
|
||||||
class="group flex items-center px-2 py-2 text-sm font-medium rounded-md {{ request()->routeIs('admin.dashboard') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}">
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="7" height="9" x="3" y="3" rx="1"/><rect width="7" height="5" x="14" y="3" rx="1"/><rect width="7" height="9" x="14" y="12" rx="1"/><rect width="7" height="5" x="3" y="16" rx="1"/></svg>
|
||||||
<svg class="mr-3 h-5 w-5 {{ request()->routeIs('admin.dashboard') ? 'text-white' : ($isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300') }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
儀表板
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" />
|
</a>
|
||||||
</svg>
|
</li>
|
||||||
儀表板
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{{-- 2. 應用程式 --}}
|
{{-- 2. 應用程式 (個人) --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_profile') === 'true' || {{ request()->routeIs('profile.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_profile') === 'true' || {{ request()->routeIs('profile.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_profile', open)"
|
||||||
init() {
|
class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
this.$watch('open', value => localStorage.setItem('menu_profile', value))
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
||||||
}
|
個人設定
|
||||||
}">
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">應用程式</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('profile.edit') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('profile.edit') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">個人檔案</a>
|
<ul class="pt-2 ps-2">
|
||||||
|
<li>
|
||||||
|
<a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('profile.edit') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('profile.edit') }}">
|
||||||
|
個人檔案
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 會員管理 (新增) --}}
|
{{-- 3. 會員管理 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_members') === 'true' || {{ request()->routeIs('admin.members.*') || request()->routeIs('admin.membership-tiers.*') || request()->routeIs('admin.deposit-bonus-rules.*') || request()->routeIs('admin.point-rules.*') || request()->routeIs('admin.gift-definitions.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_members') === 'true' || {{ request()->routeIs('admin.members.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_members', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" /></svg>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_members', value))
|
會員管理
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">會員管理</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.members.index') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.members.index') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">會員列表</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.membership-tiers.index') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.membership-tiers.*') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">會員等級設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.members.index') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.members.index') }}">會員列表</a></li>
|
||||||
<a href="{{ route('admin.deposit-bonus-rules.index') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.deposit-bonus-rules.*') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">儲值回饋設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.membership-tiers.*') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.membership-tiers.index') }}">會員等級</a></li>
|
||||||
<a href="{{ route('admin.point-rules.index') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.point-rules.*') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">點數規則設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.deposit-bonus-rules.*') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.deposit-bonus-rules.index') }}">儲值回饋</a></li>
|
||||||
<a href="{{ route('admin.gift-definitions.index') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.gift-definitions.*') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">禮品設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.point-rules.*') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.point-rules.index') }}">點數規則</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.gift-definitions.*') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.gift-definitions.index') }}">禮品設定</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 3. 機台管理 --}}
|
{{-- 4. 機台管理 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_machines') === 'true' || {{ request()->routeIs('admin.machines.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_machines') === 'true' || {{ request()->routeIs('admin.machines.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_machines', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 01-2 2v4a2 2 0 012 2h14a2 2 0 012-2v-4a2 2 0 01-2-2m-2-4h.01M17 16h.01" /></svg>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_machines', value))
|
機台管理
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 01-2 2v4a2 2 0 012 2h14a2 2 0 012-2v-4a2 2 0 01-2-2m-2-4h.01M17 16h.01" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">機台管理</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.machines.logs') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.machines.logs') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台日誌</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.machines.index') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.machines.index') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台列表</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.machines.logs') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.machines.logs') }}">機台日誌</a></li>
|
||||||
<a href="{{ route('admin.machines.permissions') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.machines.permissions') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台權限</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.machines.index') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.machines.index') }}">機台列表</a></li>
|
||||||
<a href="{{ route('admin.machines.utilization') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.machines.utilization') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台稼動率</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.machines.permissions') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.machines.permissions') }}">機台權限</a></li>
|
||||||
<a href="{{ route('admin.machines.expiry') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.machines.expiry') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">效期管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.machines.utilization') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.machines.utilization') }}">機台稼動率</a></li>
|
||||||
<a href="{{ route('admin.machines.maintenance') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.machines.maintenance') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">維修管理單</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.machines.expiry') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.machines.expiry') }}">效期管理</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.machines.maintenance') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.machines.maintenance') }}">維修管理單</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 4. APP管理 --}}
|
{{-- 5. APP管理 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_app') === 'true' || {{ request()->routeIs('admin.app.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_app') === 'true' || {{ request()->routeIs('admin.app.*') || request()->routeIs('admin.app-configs.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_app', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z" /></svg>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_app', value))
|
APP管理
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">APP管理</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.app.ui-elements') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.app.ui-elements') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">UI元素設定</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.app.helper') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.app.helper') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">小幫手設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.app.ui-elements') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.app.ui-elements') }}">UI元素</a></li>
|
||||||
<a href="{{ route('admin.app.questionnaire') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.app.questionnaire') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">問卷設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.app.helper') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.app.helper') }}">小幫手</a></li>
|
||||||
<a href="{{ route('admin.app.games') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.app.games') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">互動遊戲設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.app.questionnaire') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.app.questionnaire') }}">問卷</a></li>
|
||||||
<a href="{{ route('admin.app.timer') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.app.timer') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">計時器</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.app.games') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.app.games') }}">互動遊戲</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.app.timer') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.app.timer') }}">計時器</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 5. 倉庫管理 --}}
|
{{-- 6. 倉庫管理 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_warehouses') === 'true' || {{ request()->routeIs('admin.warehouses.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_warehouses') === 'true' || {{ request()->routeIs('admin.warehouses.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_warehouses', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" /></svg>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_warehouses', value))
|
倉庫管理
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">倉庫管理</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.warehouses.index') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.warehouses.index') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">倉庫列表(全部)</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.warehouses.personal') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.warehouses.personal') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">倉庫列表(個人)</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.warehouses.index') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.warehouses.index') }}">倉庫列表(全)</a></li>
|
||||||
<a href="{{ route('admin.warehouses.stock-management') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.warehouses.stock-management') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">庫存管理單</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.warehouses.personal') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.warehouses.personal') }}">倉庫列表(個)</a></li>
|
||||||
<a href="{{ route('admin.warehouses.transfers') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.warehouses.transfers') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">調撥單</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.warehouses.stock-management') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.warehouses.stock-management') }}">庫存管理單</a></li>
|
||||||
<a href="{{ route('admin.warehouses.purchases') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.warehouses.purchases') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">採購單</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.warehouses.transfers') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.warehouses.transfers') }}">調撥單</a></li>
|
||||||
<a href="{{ route('admin.warehouses.replenishments') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.warehouses.replenishments') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台補貨單</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.warehouses.purchases') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.warehouses.purchases') }}">採購單</a></li>
|
||||||
<a href="{{ route('admin.warehouses.replenishment-records') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.warehouses.replenishment-records') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台補貨紀錄</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.warehouses.replenishments') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.warehouses.replenishments') }}">機台補貨單</a></li>
|
||||||
<a href="{{ route('admin.warehouses.replenishment-records-all') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.warehouses.replenishment-records-all') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台補貨紀錄(總)</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.warehouses.replenishment-records') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.warehouses.replenishment-records') }}">機台補貨紀錄</a></li>
|
||||||
<a href="{{ route('admin.warehouses.machine-stock') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.warehouses.machine-stock') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台庫存</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.warehouses.machine-stock') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.warehouses.machine-stock') }}">機台庫存</a></li>
|
||||||
<a href="{{ route('admin.warehouses.staff-stock') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.warehouses.staff-stock') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">人員庫存</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.warehouses.staff-stock') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.warehouses.staff-stock') }}">人員庫存</a></li>
|
||||||
<a href="{{ route('admin.warehouses.returns') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.warehouses.returns') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">回庫單</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.warehouses.returns') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.warehouses.returns') }}">回庫單</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 6. 銷售管理 --}}
|
{{-- 7. 銷售管理 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_sales') === 'true' || {{ request()->routeIs('admin.sales.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_sales') === 'true' || {{ request()->routeIs('admin.sales.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_sales', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_sales', value))
|
銷售管理
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">銷售管理</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.sales.index') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.sales.index') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">銷售&金流紀錄</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.sales.pickup-codes') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.sales.pickup-codes') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">取貨碼設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.sales.index') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.sales.index') }}">銷售紀錄</a></li>
|
||||||
<a href="{{ route('admin.sales.orders') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.sales.orders') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">購買單</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.sales.pickup-codes') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.sales.pickup-codes') }}">取貨碼</a></li>
|
||||||
<a href="{{ route('admin.sales.promotions') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.sales.promotions') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">促銷時段設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.sales.orders') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.sales.orders') }}">購買單</a></li>
|
||||||
<a href="{{ route('admin.sales.pass-codes') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.sales.pass-codes') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">通行碼設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.sales.promotions') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.sales.promotions') }}">促銷時段</a></li>
|
||||||
<a href="{{ route('admin.sales.store-gifts') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.sales.store-gifts') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">來店禮設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.sales.pass-codes') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.sales.pass-codes') }}">通行碼</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.sales.store-gifts') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.sales.store-gifts') }}">來店禮</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 7. 分析管理 --}}
|
{{-- 8. 分析管理 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_analysis') === 'true' || {{ request()->routeIs('admin.analysis.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_analysis') === 'true' || {{ request()->routeIs('admin.analysis.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_analysis', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z" /></svg>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_analysis', value))
|
分析管理
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 12l3-3 3 3 4-4M8 21l4-4 4 4M3 4h18M4 4h16v12a1 1 0 01-1 1H5a1 1 0 01-1-1V4z" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">分析管理</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.analysis.change-stock') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.analysis.change-stock') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">零錢庫存分析</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.analysis.machine-reports') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.analysis.machine-reports') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台報表分析</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.analysis.change-stock') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.analysis.change-stock') }}">零錢庫存</a></li>
|
||||||
<a href="{{ route('admin.analysis.product-reports') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.analysis.product-reports') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">商品報表分析</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.analysis.machine-reports') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.analysis.machine-reports') }}">機台報表</a></li>
|
||||||
<a href="{{ route('admin.analysis.survey-analysis') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.analysis.survey-analysis') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">互動問卷分析</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.analysis.product-reports') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.analysis.product-reports') }}">商品報表</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.analysis.survey-analysis') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.analysis.survey-analysis') }}">問卷分析</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 8. 稽核管理 --}}
|
{{-- 9. 稽核管理 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_audit') === 'true' || {{ request()->routeIs('admin.audit.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_audit') === 'true' || {{ request()->routeIs('admin.audit.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_audit', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_audit', value))
|
稽核管理
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">稽核管理</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.audit.purchases') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.audit.purchases') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">採購單稽核</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.audit.transfers') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.audit.transfers') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">調撥單稽核</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.audit.purchases') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.audit.purchases') }}">採購單</a></li>
|
||||||
<a href="{{ route('admin.audit.replenishments') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.audit.replenishments') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">補貨單稽核</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.audit.transfers') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.audit.transfers') }}">調撥單</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.audit.replenishments') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.audit.replenishments') }}">補貨單</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 9. 資料設定 --}}
|
{{-- 10. 資料設定 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_data_config') === 'true' || {{ request()->routeIs('admin.data-config.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_data_config') === 'true' || {{ request()->routeIs('admin.data-config.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_data_config', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" /><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /></svg>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_data_config', value))
|
資料設定
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">資料設定</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.data-config.products') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.data-config.products') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">商品管理</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.data-config.advertisements') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.data-config.advertisements') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">廣告管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.data-config.products') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.data-config.products') }}">商品管理</a></li>
|
||||||
<a href="{{ route('admin.data-config.admin-products') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.data-config.admin-products') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">管理者可賣商品</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.data-config.advertisements') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.data-config.advertisements') }}">廣告管理</a></li>
|
||||||
<a href="{{ route('admin.data-config.accounts') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.data-config.accounts') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">帳號管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.data-config.admin-products') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.data-config.admin-products') }}">管理者可賣</a></li>
|
||||||
<a href="{{ route('admin.data-config.sub-accounts') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.data-config.sub-accounts') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">子帳號管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.data-config.accounts') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.data-config.accounts') }}">帳號管理</a></li>
|
||||||
<a href="{{ route('admin.data-config.sub-account-roles') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.data-config.sub-account-roles') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">子帳號角色管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.data-config.sub-accounts') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.data-config.sub-accounts') }}">子帳號</a></li>
|
||||||
<a href="{{ route('admin.data-config.points') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.data-config.points') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">點數設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.data-config.sub-account-roles') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.data-config.sub-account-roles') }}">子帳號角色</a></li>
|
||||||
<a href="{{ route('admin.data-config.badges') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.data-config.badges') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">識別證管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.data-config.points') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.data-config.points') }}">點數設定</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.data-config.badges') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.data-config.badges') }}">識別證</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 10. 遠端管理 --}}
|
|
||||||
<div x-data="{
|
|
||||||
open: localStorage.getItem('menu_remote') === 'true' || {{ request()->routeIs('admin.remote.*') ? 'true' : 'false' }},
|
|
||||||
init() {
|
|
||||||
this.$watch('open', value => localStorage.setItem('menu_remote', value))
|
|
||||||
}
|
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5.636 18.364a9 9 0 010-12.728m12.728 0a9 9 0 010 12.728m-9.9-2.829a5 5 0 010-7.07m7.072 0a5 5 0 010 7.07M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">遠端管理</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
|
||||||
<a href="{{ route('admin.remote.stock') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.remote.stock') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台庫存</a>
|
|
||||||
<a href="{{ route('admin.remote.restart') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.remote.restart') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台重啟</a>
|
|
||||||
<a href="{{ route('admin.remote.restart-card-reader') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.remote.restart-card-reader') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">卡機重啟</a>
|
|
||||||
<a href="{{ route('admin.remote.checkout') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.remote.checkout') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">遠端結帳</a>
|
|
||||||
<a href="{{ route('admin.remote.lock') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.remote.lock') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">遠端鎖定頁</a>
|
|
||||||
<a href="{{ route('admin.remote.change') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.remote.change') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">遠端找零</a>
|
|
||||||
<a href="{{ route('admin.remote.dispense') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.remote.dispense') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">遠端出貨</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{-- 11. Line管理 --}}
|
{{-- 11. 遠端管理 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_remote') === 'true' || {{ request()->routeIs('admin.remote.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_line') === 'true' || {{ request()->routeIs('admin.line.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_remote', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5.636 18.364a9 9 0 010-12.728m12.728 0a9 9 0 010 12.728m-9.9-2.829a5 5 0 010-7.07m7.072 0a5 5 0 010 7.07M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_line', value))
|
遠端管理
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">Line管理</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.line.members') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.line.members') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line會員管理</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.line.machines') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.line.machines') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line機台管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.remote.stock') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.remote.stock') }}">機台庫存</a></li>
|
||||||
<a href="{{ route('admin.line.products') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.line.products') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line商城商品</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.remote.restart') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.remote.restart') }}">機台重啟</a></li>
|
||||||
<a href="{{ route('admin.line.official-account') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.line.official-account') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line生活圈</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.remote.restart-card-reader') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.remote.restart-card-reader') }}">卡機重啟</a></li>
|
||||||
<a href="{{ route('admin.line.orders') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.line.orders') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line商城訂單</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.remote.checkout') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.remote.checkout') }}">遠端結帳</a></li>
|
||||||
<a href="{{ route('admin.line.coupons') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.line.coupons') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line優惠券</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.remote.lock') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.remote.lock') }}">遠端鎖定</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.remote.change') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.remote.change') }}">遠端找零</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.remote.dispense') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.remote.dispense') }}">遠端出貨</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 12. 預約系統 --}}
|
{{-- 12. Line管理 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_line') === 'true' || {{ request()->routeIs('admin.line.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_reservation') === 'true' || {{ request()->routeIs('admin.reservation.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_line', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" /></svg>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_reservation', value))
|
Line管理
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<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="flex-1 text-left">預約系統</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.reservation.members') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.reservation.members') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line會員管理</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.reservation.stores') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.reservation.stores') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line店家管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.line.members') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.line.members') }}">Line會員</a></li>
|
||||||
<a href="{{ route('admin.reservation.time-slots') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.reservation.time-slots') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line時段組合</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.line.machines') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.line.machines') }}">Line機台</a></li>
|
||||||
<a href="{{ route('admin.reservation.venues') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.reservation.venues') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line場地管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.line.products') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.line.products') }}">Line商品</a></li>
|
||||||
<a href="{{ route('admin.reservation.coupons') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.reservation.coupons') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line優惠券管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.line.official-account') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.line.official-account') }}">Line生活圈</a></li>
|
||||||
<a href="{{ route('admin.reservation.reservations') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.reservation.reservations') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line預約管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.line.orders') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.line.orders') }}">Line訂單</a></li>
|
||||||
<a href="{{ route('admin.reservation.orders') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.reservation.orders') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line訂單管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.line.coupons') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.line.coupons') }}">Line優惠券</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 13. 特殊權限管理 --}}
|
{{-- 13. 預約系統 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_reservation') === 'true' || {{ request()->routeIs('admin.reservation.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_special_permission') === 'true' || {{ request()->routeIs('admin.special-permission.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_reservation', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" 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>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_special_permission', value))
|
預約系統
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">特殊權限管理</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.special-permission.clear-stock') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.special-permission.clear-stock') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">庫存清空</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.special-permission.apk-versions') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.special-permission.apk-versions') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">APK版本管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.reservation.members') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.reservation.members') }}">預約會員</a></li>
|
||||||
<a href="{{ route('admin.special-permission.discord-notifications') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.special-permission.discord-notifications') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Discord通知設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.reservation.stores') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.reservation.stores') }}">店家管理</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.reservation.time-slots') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.reservation.time-slots') }}">時段組合</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.reservation.venues') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.reservation.venues') }}">場地管理</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.reservation.coupons') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.reservation.coupons') }}">優惠券</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.reservation.reservations') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.reservation.reservations') }}">預約管理</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.reservation.orders') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.reservation.orders') }}">訂單管理</a></li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
{{-- 14. 權限設定 --}}
|
{{-- 14. 特殊權限 --}}
|
||||||
<div x-data="{
|
<li x-data="{ open: localStorage.getItem('menu_special_permission') === 'true' || {{ request()->routeIs('admin.special-permission.*') ? 'true' : 'false' }} }">
|
||||||
open: localStorage.getItem('menu_permissions') === 'true' || {{ request()->routeIs('admin.permission.*') ? 'true' : 'false' }},
|
<button type="button" @click="open = !open; localStorage.setItem('menu_special_permission', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
init() {
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" /></svg>
|
||||||
this.$watch('open', value => localStorage.setItem('menu_permissions', value))
|
特殊權限
|
||||||
}
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
}">
|
|
||||||
<button @click="open = !open" class="group flex items-center w-full px-2 py-2 text-sm font-medium rounded-md {{ $isLight ? 'text-gray-700 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white' }}">
|
|
||||||
<svg class="mr-3 h-5 w-5 {{ $isLight ? 'text-gray-400 group-hover:text-gray-500' : 'text-gray-400 group-hover:text-gray-300' }}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" />
|
|
||||||
</svg>
|
|
||||||
<span class="flex-1 text-left">權限設定</span>
|
|
||||||
<svg class="ml-auto h-5 w-5 transform transition-transform duration-200" :class="{'rotate-90': open}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" x-collapse.duration.500ms class="mt-1 space-y-1">
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
<a href="{{ route('admin.permission.app-features') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.app-features') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">APP功能管理</a>
|
<ul class="pt-2 ps-2">
|
||||||
<a href="{{ route('admin.permission.data-config') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.data-config') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">資料設定</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.special-permission.clear-stock') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.special-permission.clear-stock') }}">庫存清空</a></li>
|
||||||
<a href="{{ route('admin.permission.sales') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.sales') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">銷售管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.special-permission.apk-versions') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.special-permission.apk-versions') }}">APK版本</a></li>
|
||||||
<a href="{{ route('admin.permission.machines') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.machines') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">機台管理</a>
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.special-permission.discord-notifications') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.special-permission.discord-notifications') }}">Discord通知</a></li>
|
||||||
<a href="{{ route('admin.permission.warehouses') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.warehouses') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">倉庫管理</a>
|
</ul>
|
||||||
<a href="{{ route('admin.permission.analysis') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.analysis') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">分析管理</a>
|
|
||||||
<a href="{{ route('admin.permission.audit') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.audit') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">稽核管理</a>
|
|
||||||
<a href="{{ route('admin.permission.remote') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.remote') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">遠端管理</a>
|
|
||||||
<a href="{{ route('admin.permission.line') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.line') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">Line管理</a>
|
|
||||||
<a href="{{ route('admin.permission.roles') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.roles') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">權限角色設定</a>
|
|
||||||
<a href="{{ route('admin.permission.others') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.others') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">其他功能管理</a>
|
|
||||||
<a href="{{ route('admin.permission.ai-prediction') }}" @click="if (window.innerWidth < 1024) sidebarOpen = false" class="group flex items-center pl-14 pr-2 py-2 text-sm rounded-md {{ request()->routeIs('admin.permission.ai-prediction') ? 'bg-'.$currentTheme['accent'].'-600 text-white' : ($isLight ? 'text-gray-600 hover:bg-gray-100' : 'text-gray-300 hover:bg-gray-700 hover:text-white') }}" style="padding-left: 3.5rem;">AI智能預測</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
|
{{-- 15. 權限設定 --}}
|
||||||
|
<li x-data="{ open: localStorage.getItem('menu_permissions') === 'true' || {{ request()->routeIs('admin.permission.*') ? 'true' : 'false' }} }">
|
||||||
|
<button type="button" @click="open = !open; localStorage.setItem('menu_permissions', open)" class="w-full text-start flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300">
|
||||||
|
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z" /></svg>
|
||||||
|
權限設定
|
||||||
|
<svg class="ms-auto w-4 h-4 transition-transform duration-300" :class="{ 'rotate-180': open, 'rotate-0': !open }" xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
|
||||||
|
</button>
|
||||||
|
<div x-show="open" x-collapse class="w-full overflow-hidden transition-[height] duration-300">
|
||||||
|
<ul class="pt-2 ps-2">
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.app-features') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.app-features') }}">APP功能</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.data-config') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.data-config') }}">資料設定</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.sales') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.sales') }}">銷售管理</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.machines') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.machines') }}">機台管理</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.warehouses') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.warehouses') }}">倉庫管理</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.analysis') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.analysis') }}">分析管理</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.audit') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.audit') }}">稽核管理</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.remote') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.remote') }}">遠端管理</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.line') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.line') }}">Line管理</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.roles') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.roles') }}">角色設定</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.others') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.others') }}">其他功能</a></li>
|
||||||
|
<li><a class="flex items-center gap-x-3.5 py-2 px-2.5 text-sm text-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-900 dark:text-gray-400 dark:hover:text-gray-300 {{ request()->routeIs('admin.permission.ai-prediction') ? 'text-blue-600 dark:text-blue-500' : '' }}" href="{{ route('admin.permission.ai-prediction') }}">AI智能預測</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export default {
|
|||||||
'./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
|
'./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php',
|
||||||
'./storage/framework/views/*.php',
|
'./storage/framework/views/*.php',
|
||||||
'./resources/views/**/*.blade.php',
|
'./resources/views/**/*.blade.php',
|
||||||
'./node_modules/preline/preline.js',
|
'./node_modules/preline/dist/*.js',
|
||||||
],
|
],
|
||||||
|
|
||||||
safelist: [
|
safelist: [
|
||||||
@@ -30,5 +30,7 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
plugins: [forms],
|
plugins: [
|
||||||
|
forms,
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user