Compare commits

...

1 Commits

Author SHA1 Message Date
sky121113
9bc6450fac [FEAT] 遷移機台系統設定至機台管理模組並優化 UI
1. 修正客戶管理頁面 H1 標題與麵包屑導覽路徑。
2. 在機台編輯頁面實作分頁功能(基本、營運、機台系統設定)。
3. 實作極簡奢華風的機台系統設定 UI,按功能模組(電子發票、刷卡、支付、購物車等)進行卡片式分組。
4. 將系統設定資料從 Company JSON 遷移至 Machine 資料表獨立欄位,並更新關聯控制器與模型邏輯。
5. 清理 CompanyController 與視圖中的冗餘設定邏輯。
6. 完成現有資料遷移,確保機台正確繼承客戶層級之設定。
7. 優化倉儲管理「現有庫存」矩陣視圖與導覽功能。
2026-04-24 08:30:25 +08:00
10 changed files with 300 additions and 222 deletions

View File

@ -194,6 +194,12 @@ class MachineSettingController extends AdminController
'is_spring_slot_41_50' => 'boolean',
'is_spring_slot_51_60' => 'boolean',
'member_system_enabled' => 'boolean',
'tax_invoice_enabled' => 'boolean',
'card_terminal_enabled' => 'boolean',
'scan_pay_esun_enabled' => 'boolean',
'scan_pay_linepay_enabled' => 'boolean',
'shopping_cart_enabled' => 'boolean',
'cash_module_enabled' => 'boolean',
'machine_model_id' => 'required|exists:machine_models,id',
'payment_config_id' => 'nullable|exists:payment_configs,id',
'location' => 'nullable|string|max:255',

View File

@ -74,13 +74,6 @@ class CompanyController extends Controller
if (isset($validated['settings'])) {
$validated['settings']['enable_material_code'] = filter_var($validated['settings']['enable_material_code'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['enable_points'] = filter_var($validated['settings']['enable_points'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['tax_invoice'] = filter_var($validated['settings']['tax_invoice'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['card_terminal'] = filter_var($validated['settings']['card_terminal'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['scan_pay_esun'] = filter_var($validated['settings']['scan_pay_esun'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['scan_pay_linepay'] = filter_var($validated['settings']['scan_pay_linepay'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['shopping_cart'] = filter_var($validated['settings']['shopping_cart'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['welcome_gift'] = filter_var($validated['settings']['welcome_gift'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['cash_module'] = filter_var($validated['settings']['cash_module'] ?? false, FILTER_VALIDATE_BOOLEAN);
}
DB::transaction(function () use ($validated) {
@ -185,13 +178,6 @@ class CompanyController extends Controller
if (isset($validated['settings'])) {
$validated['settings']['enable_material_code'] = filter_var($validated['settings']['enable_material_code'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['enable_points'] = filter_var($validated['settings']['enable_points'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['tax_invoice'] = filter_var($validated['settings']['tax_invoice'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['card_terminal'] = filter_var($validated['settings']['card_terminal'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['scan_pay_esun'] = filter_var($validated['settings']['scan_pay_esun'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['scan_pay_linepay'] = filter_var($validated['settings']['scan_pay_linepay'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['shopping_cart'] = filter_var($validated['settings']['shopping_cart'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['welcome_gift'] = filter_var($validated['settings']['welcome_gift'] ?? false, FILTER_VALIDATE_BOOLEAN);
$validated['settings']['cash_module'] = filter_var($validated['settings']['cash_module'] ?? false, FILTER_VALIDATE_BOOLEAN);
}
DB::transaction(function () use ($validated, $company) {
@ -230,13 +216,6 @@ class CompanyController extends Controller
$formattedSettings = [
'enable_material_code' => filter_var($settings['enable_material_code'] ?? false, FILTER_VALIDATE_BOOLEAN),
'enable_points' => filter_var($settings['enable_points'] ?? false, FILTER_VALIDATE_BOOLEAN),
'tax_invoice' => filter_var($settings['tax_invoice'] ?? false, FILTER_VALIDATE_BOOLEAN),
'card_terminal' => filter_var($settings['card_terminal'] ?? false, FILTER_VALIDATE_BOOLEAN),
'scan_pay_esun' => filter_var($settings['scan_pay_esun'] ?? false, FILTER_VALIDATE_BOOLEAN),
'scan_pay_linepay' => filter_var($settings['scan_pay_linepay'] ?? false, FILTER_VALIDATE_BOOLEAN),
'shopping_cart' => filter_var($settings['shopping_cart'] ?? false, FILTER_VALIDATE_BOOLEAN),
'welcome_gift' => filter_var($settings['welcome_gift'] ?? false, FILTER_VALIDATE_BOOLEAN),
'cash_module' => filter_var($settings['cash_module'] ?? false, FILTER_VALIDATE_BOOLEAN),
];
// Ensure we force save the JSON cast properly

View File

@ -147,7 +147,7 @@ class WarehouseController extends Controller
public function inventory(Request $request)
{
$tab = $request->input('tab', 'stock-in');
$tab = $request->input('tab', 'stock');
$warehouses = Warehouse::active()->orderBy('name')->get();
$data = compact('warehouses', 'tab');

View File

@ -85,6 +85,12 @@ class Machine extends Model
'images',
'creator_id',
'updater_id',
'tax_invoice_enabled',
'card_terminal_enabled',
'scan_pay_esun_enabled',
'scan_pay_linepay_enabled',
'shopping_cart_enabled',
'cash_module_enabled',
];
protected $appends = ['image_urls', 'calculated_status'];
@ -177,6 +183,12 @@ class Machine extends Model
'is_spring_slot_41_50' => 'boolean',
'is_spring_slot_51_60' => 'boolean',
'member_system_enabled' => 'boolean',
'tax_invoice_enabled' => 'boolean',
'card_terminal_enabled' => 'boolean',
'scan_pay_esun_enabled' => 'boolean',
'scan_pay_linepay_enabled' => 'boolean',
'shopping_cart_enabled' => 'boolean',
'cash_module_enabled' => 'boolean',
'images' => 'array',
];

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('machines', function (Blueprint $table) {
$table->boolean('tax_invoice_enabled')->default(0)->after('invoice_status')->comment('電子發票開關');
$table->boolean('card_terminal_enabled')->default(0)->after('card_reader_no')->comment('刷卡機系統開關');
$table->boolean('scan_pay_esun_enabled')->default(0)->after('card_terminal_enabled')->comment('玉山掃碼支付開關');
$table->boolean('scan_pay_linepay_enabled')->default(0)->after('scan_pay_esun_enabled')->comment('LinePay支付開關');
$table->boolean('shopping_cart_enabled')->default(0)->after('scan_pay_linepay_enabled')->comment('購物車功能開關');
$table->boolean('cash_module_enabled')->default(0)->after('shopping_cart_enabled')->comment('現金模組開關');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('machines', function (Blueprint $table) {
$table->dropColumn([
'tax_invoice_enabled',
'card_terminal_enabled',
'scan_pay_esun_enabled',
'scan_pay_linepay_enabled',
'shopping_cart_enabled',
'cash_module_enabled',
]);
});
}
};

View File

@ -77,7 +77,8 @@
}
this.$el.submit();
}
}" @submit.prevent="submitForm" action="{{ route('admin.basic-settings.machines.update', $machine) }}" method="POST" enctype="multipart/form-data" class="space-y-6">
}" @submit.prevent="submitForm" action="{{ route('admin.basic-settings.machines.update', $machine) }}" method="POST" enctype="multipart/form-data"
x-data="{ activeTab: 'basic' }" class="space-y-6">
@csrf
@method('PUT')
@ -101,9 +102,34 @@
</div>
@endif
<!-- Tab Headers -->
<div class="flex items-center gap-1 p-1 bg-slate-100 dark:bg-slate-800/50 rounded-2xl w-fit mb-4">
<button type="button" @click="activeTab = 'basic'"
:class="activeTab === 'basic' ? 'bg-white dark:bg-slate-800 text-cyan-500 shadow-sm' : 'text-slate-500 hover:text-slate-700 dark:hover:text-slate-300'"
class="px-6 py-2.5 rounded-xl text-sm font-black uppercase tracking-widest transition-all duration-300 flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
{{ __('Basic Information') }}
</button>
<button type="button" @click="activeTab = 'operation'"
:class="activeTab === 'operation' ? 'bg-white dark:bg-slate-800 text-amber-500 shadow-sm' : 'text-slate-500 hover:text-slate-700 dark:hover:text-slate-300'"
class="px-6 py-2.5 rounded-xl text-sm font-black uppercase tracking-widest transition-all duration-300 flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" 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.5" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
{{ __('Operational Parameters') }}
</button>
<button type="button" @click="activeTab = 'system'"
:class="activeTab === 'system' ? 'bg-white dark:bg-slate-800 text-indigo-500 shadow-sm' : 'text-slate-500 hover:text-slate-700 dark:hover:text-slate-300'"
class="px-6 py-2.5 rounded-xl text-sm font-black uppercase tracking-widest transition-all duration-300 flex items-center gap-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/></svg>
{{ __('Machine System Settings') }}
</button>
</div>
<div class="flex flex-col lg:flex-row gap-8 items-start">
<!-- Main Content Area -->
<div class="flex-1 space-y-8 order-2 lg:order-1 capitalize">
<!-- Tab: Basic Information -->
<div x-show="activeTab === 'basic'" x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 translate-y-4" x-transition:enter-end="opacity-100 translate-y-0" class="space-y-6">
<!-- Left: Basic info & Hardware -->
<div class="lg:col-span-2 space-y-6">
<!-- Basic Information -->
@ -194,8 +220,14 @@
</div>
</div>
</div>
</div>
</div>
<!-- Tab: Operational Parameters -->
<div x-show="activeTab === 'operation'" x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 translate-y-4" x-transition:enter-end="opacity-100 translate-y-0" class="space-y-6">
<!-- Operational Parameters -->
<div class="luxury-card rounded-3xl p-8 animate-luxury-in relative z-10" style="animation-delay: 50ms">
<div class="luxury-card rounded-3xl p-8 animate-luxury-in relative z-10">
<div class="flex items-center gap-3 mb-8">
<div class="w-10 h-10 rounded-xl bg-amber-500/10 flex items-center justify-center text-amber-500">
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@ -230,11 +262,24 @@
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Heating End Time') }}</label>
<x-luxury-time-input name="heating_end_time" value="{{ $machine->heating_end_time }}" />
</div>
<div class="col-span-full">
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Payment Config') }}</label>
<x-searchable-select
name="payment_config_id"
:selected="old('payment_config_id', $machine->payment_config_id)"
:placeholder="__('Not Used')"
:hasSearch="false"
>
@foreach($paymentConfigs as $config)
<option value="{{ $config->id }}" {{ $machine->payment_config_id == $config->id ? 'selected' : '' }}>{{ $config->name }}</option>
@endforeach
</x-searchable-select>
</div>
</div>
</div>
<!-- hardware & slot types -->
<div class="luxury-card rounded-3xl p-7 animate-luxury-in" style="animation-delay: 150ms">
<div class="luxury-card rounded-3xl p-7 animate-luxury-in">
<div class="flex items-center gap-3 mb-8">
<div class="w-10 h-10 rounded-xl bg-amber-500/10 flex items-center justify-center text-amber-500">
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@ -271,9 +316,184 @@
</div>
</div>
</div>
<!-- Tab: Machine System Settings -->
<div x-show="activeTab === 'system'" x-transition:enter="transition ease-out duration-300" x-transition:enter-start="opacity-0 translate-y-4" x-transition:enter-end="opacity-100 translate-y-0" class="space-y-6">
<div class="luxury-card rounded-3xl p-8 animate-luxury-in relative z-10">
<div class="flex items-center gap-3 mb-8">
<div class="w-10 h-10 rounded-xl bg-indigo-500/10 flex items-center justify-center text-indigo-500">
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
</svg>
</div>
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Machine System Settings') }}</h3>
</div>
<!-- Right Column: Images & Primary System Settings -->
<div class="space-y-4">
<!-- Electronic Invoice Section -->
<div class="p-6 rounded-2xl bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800 space-y-6">
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="p-2 rounded-lg bg-emerald-500/10 text-emerald-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" 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>
</div>
<div>
<span class="block text-sm font-black text-slate-700 dark:text-slate-200">{{ __('Electronic Invoice') }}</span>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('System-wide Invoice Support') }}</span>
</div>
</div>
<div class="relative inline-flex items-center cursor-pointer">
<input type="hidden" name="tax_invoice_enabled" value="0">
<input type="checkbox" name="tax_invoice_enabled" value="1" {{ $machine->tax_invoice_enabled ? 'checked' : '' }} class="sr-only peer">
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-emerald-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-emerald-500 transition-colors"></div>
</div>
</div>
<div class="pt-4 border-t border-slate-100 dark:border-slate-800">
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Invoice Status') }}</label>
<x-searchable-select
name="invoice_status"
:selected="old('invoice_status', $machine->invoice_status)"
:hasSearch="false"
>
<option value="0" {{ $machine->invoice_status == 0 ? 'selected' : '' }}>{{ __('No Invoice') }}</option>
<option value="1" {{ $machine->invoice_status == 1 ? 'selected' : '' }}>{{ __('Default Donate') }}</option>
<option value="2" {{ $machine->invoice_status == 2 ? 'selected' : '' }}>{{ __('Default Not Donate') }}</option>
</x-searchable-select>
</div>
</div>
<!-- Card System -->
<label class="flex items-center justify-between p-6 rounded-2xl bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800 cursor-pointer group hover:border-blue-500/30 transition-all">
<div class="flex items-center gap-3">
<div class="p-2 rounded-lg bg-blue-500/10 text-blue-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" /></svg>
</div>
<div>
<span class="block text-sm font-black text-slate-700 dark:text-slate-200 group-hover:text-blue-500 transition-colors">{{ __('Card System') }}</span>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Includes Credit Card/Mobile Pay') }}</span>
</div>
</div>
<div class="relative inline-flex items-center">
<input type="hidden" name="card_terminal_enabled" value="0">
<input type="checkbox" name="card_terminal_enabled" value="1" {{ $machine->card_terminal_enabled ? 'checked' : '' }} class="sr-only peer">
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-blue-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-blue-500 transition-colors"></div>
</div>
</label>
<!-- E.SUN QR Pay -->
<label class="flex items-center justify-between p-6 rounded-2xl bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800 cursor-pointer group hover:border-emerald-500/30 transition-all">
<div class="flex items-center gap-3">
<div class="p-2 rounded-lg bg-emerald-500/10 text-emerald-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 17h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z" /></svg>
</div>
<div>
<span class="block text-sm font-black text-slate-700 dark:text-slate-200 group-hover:text-emerald-500 transition-colors">{{ __('E.SUN QR Pay') }}</span>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Scan to Pay via E.SUN') }}</span>
</div>
</div>
<div class="relative inline-flex items-center">
<input type="hidden" name="scan_pay_esun_enabled" value="0">
<input type="checkbox" name="scan_pay_esun_enabled" value="1" {{ $machine->scan_pay_esun_enabled ? 'checked' : '' }} class="sr-only peer">
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-emerald-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-emerald-500 transition-colors"></div>
</div>
</label>
<!-- LinePay -->
<label class="flex items-center justify-between p-6 rounded-2xl bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800 cursor-pointer group hover:border-green-500/30 transition-all">
<div class="flex items-center gap-3">
<div class="p-2 rounded-lg bg-green-500/10 text-green-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m2 4h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z" /></svg>
</div>
<div>
<span class="block text-sm font-black text-slate-700 dark:text-slate-200 group-hover:text-green-500 transition-colors">{{ __('LinePay Payment') }}</span>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Mobile Payment Support') }}</span>
</div>
</div>
<div class="relative inline-flex items-center">
<input type="hidden" name="scan_pay_linepay_enabled" value="0">
<input type="checkbox" name="scan_pay_linepay_enabled" value="1" {{ $machine->scan_pay_linepay_enabled ? 'checked' : '' }} class="sr-only peer">
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-green-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-green-500 transition-colors"></div>
</div>
</label>
<!-- Shopping Cart -->
<label class="flex items-center justify-between p-6 rounded-2xl bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800 cursor-pointer group hover:border-purple-500/30 transition-all">
<div class="flex items-center gap-3">
<div class="p-2 rounded-lg bg-purple-500/10 text-purple-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z" /></svg>
</div>
<div>
<span class="block text-sm font-black text-slate-700 dark:text-slate-200 group-hover:text-purple-500 transition-colors">{{ __('Shopping Cart Feature') }}</span>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Batch Purchasing Support') }}</span>
</div>
</div>
<div class="relative inline-flex items-center">
<input type="hidden" name="shopping_cart_enabled" value="0">
<input type="checkbox" name="shopping_cart_enabled" value="1" {{ $machine->shopping_cart_enabled ? 'checked' : '' }} class="sr-only peer">
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-purple-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-purple-500 transition-colors"></div>
</div>
</label>
<!-- Welcome Gift -->
<label class="flex items-center justify-between p-6 rounded-2xl bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800 cursor-pointer group hover:border-rose-500/30 transition-all">
<div class="flex items-center gap-3">
<div class="p-2 rounded-lg bg-rose-500/10 text-rose-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-14v4m0 0l8 4m-8-4l-8 4m8 4v10l8-4m0-14l-8 4" /></svg>
</div>
<div>
<span class="block text-sm font-black text-slate-700 dark:text-slate-200 group-hover:text-rose-500 transition-colors">{{ __('Welcome Gift Feature') }}</span>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Promotion & Gifting') }}</span>
</div>
</div>
<div class="relative inline-flex items-center">
<input type="hidden" name="welcome_gift_enabled" value="0">
<input type="checkbox" name="welcome_gift_enabled" value="1" {{ $machine->welcome_gift_enabled ? 'checked' : '' }} class="sr-only peer">
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-rose-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-rose-500 transition-colors"></div>
</div>
</label>
<!-- Cash Module -->
<label class="flex items-center justify-between p-6 rounded-2xl bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800 cursor-pointer group hover:border-amber-500/30 transition-all">
<div class="flex items-center gap-3">
<div class="p-2 rounded-lg bg-amber-500/10 text-amber-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M17 9V7a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2m2 4h10a2 2 0 002-2v-6a2 2 0 00-2-2H9a2 2 0 00-2 2v6a2 2 0 002 2zm7-5a2 2 0 11-4 0 2 2 0 014 0z" /></svg>
</div>
<div>
<span class="block text-sm font-black text-slate-700 dark:text-slate-200 group-hover:text-amber-500 transition-colors">{{ __('Cash Module Feature') }}</span>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Coin/Bill Acceptor Support') }}</span>
</div>
</div>
<div class="relative inline-flex items-center">
<input type="hidden" name="cash_module_enabled" value="0">
<input type="checkbox" name="cash_module_enabled" value="1" {{ $machine->cash_module_enabled ? 'checked' : '' }} class="sr-only peer">
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-amber-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-amber-500 transition-colors"></div>
</div>
</label>
<!-- Member System -->
<label class="flex items-center justify-between p-6 rounded-2xl bg-slate-50/50 dark:bg-slate-900/50 border border-slate-100 dark:border-slate-800 cursor-pointer group hover:border-indigo-500/30 transition-all">
<div class="flex items-center gap-3">
<div class="p-2 rounded-lg bg-indigo-500/10 text-indigo-500">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z"/></svg>
</div>
<div>
<span class="block text-sm font-black text-slate-700 dark:text-slate-200 group-hover:text-indigo-500 transition-colors">{{ __('Member System') }}</span>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Member Login & Points Support') }}</span>
</div>
</div>
<div class="relative inline-flex items-center">
<input type="hidden" name="member_system_enabled" value="0">
<input type="checkbox" name="member_system_enabled" value="1" {{ $machine->member_system_enabled ? 'checked' : '' }} class="sr-only peer">
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-indigo-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-500 transition-colors"></div>
</div>
</label>
</div>
</div>
</div>
</div>
<!-- Sidebar Content -->
<div class="w-full lg:w-96 space-y-8 order-1 lg:order-2 lg:sticky top-24">
<!-- Machine Images -->
<div class="luxury-card rounded-[2.5rem] p-8 animate-luxury-in">
@ -321,7 +541,7 @@
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" /></svg>
</button>
<button type="button" @click="removeImage({{ $i }})" class="p-2.5 rounded-xl bg-white text-slate-800 hover:bg-rose-500 hover:text-white transition-all duration-300 shadow-lg">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" /></svg>
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="3"><path stroke-linecap="round" stroke-linejoin="round" d="m14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.244 2.244 0 0 1-2.244 2.077H8.084a2.244 2.244 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0" /></svg>
</button>
</div>
</div>
@ -338,83 +558,6 @@
</div>
</div>
</div>
<div class="luxury-card rounded-3xl p-8 animate-luxury-in relative z-20" style="animation-delay: 200ms">
<div class="flex items-center gap-3 mb-8">
<div class="w-10 h-10 rounded-xl bg-emerald-500/10 flex items-center justify-center text-emerald-500">
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18.75a60.07 60.07 0 0 1 15.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75m0-1.5a.75.75 0 0 1 .75.75v.75m-.75 0H3m.75 0h.75m-1.5 0a.75.75 0 0 1-.75-.75V3M3 10.5v1.5m10.5-3v-4.5m0 4.5h5.25m-5.25 0V10.5m0-1.5a.75.75 0 0 1 .75-.75h.75m-1.5 0H12m.75 0h.75m-1.5 0a.75.75 0 0 1-.75-.75V3.75M12 4.5H3.75a2.25 2.25 0 0 0-2.25 2.25v10.5a2.25 2.25 0 0 0 2.25 2.25h15a2.25 2.25 0 0 0 2.25-2.25V6.75A2.25 2.25 0 0 0 18.75 4.5Z"/>
</svg>
</div>
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Payment & Invoice') }}</h3>
</div>
<div class="space-y-6">
<div>
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Payment Config') }}</label>
<x-searchable-select
name="payment_config_id"
:selected="old('payment_config_id', $machine->payment_config_id)"
:placeholder="__('Not Used')"
:hasSearch="false"
>
@foreach($paymentConfigs as $config)
<option value="{{ $config->id }}" {{ $machine->payment_config_id == $config->id ? 'selected' : '' }}>{{ $config->name }}</option>
@endforeach
</x-searchable-select>
</div>
<div>
<label class="block text-xs font-bold text-slate-400 uppercase tracking-[0.15em] mb-2">{{ __('Invoice Status') }}</label>
<x-searchable-select
name="invoice_status"
:selected="old('invoice_status', $machine->invoice_status)"
:hasSearch="false"
>
<option value="0" {{ $machine->invoice_status == 0 ? 'selected' : '' }}>{{ __('No Invoice') }}</option>
<option value="1" {{ $machine->invoice_status == 1 ? 'selected' : '' }}>{{ __('Default Donate') }}</option>
<option value="2" {{ $machine->invoice_status == 2 ? 'selected' : '' }}>{{ __('Default Not Donate') }}</option>
</x-searchable-select>
</div>
</div>
</div>
<div class="luxury-card rounded-3xl p-8 animate-luxury-in relative z-10" style="animation-delay: 300ms">
<div class="flex items-center gap-3 mb-8">
<div class="w-10 h-10 rounded-xl bg-indigo-500/10 flex items-center justify-center text-indigo-500">
<svg class="w-5 h-5 stroke-[2.5]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z"/>
</svg>
</div>
<h3 class="text-lg font-black text-slate-800 dark:text-white tracking-tight">{{ __('Member & External') }}</h3>
</div>
<div class="space-y-6">
<label class="flex items-center justify-between p-4 rounded-2xl border border-slate-100 dark:border-slate-800 bg-slate-50/30 dark:bg-slate-900/30 cursor-pointer group">
<div>
<span class="block text-sm font-black text-slate-700 dark:text-slate-200 group-hover:text-indigo-500 transition-colors">{{ __('Welcome Gift') }}</span>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Enabled/Disabled') }}</span>
</div>
<div class="relative inline-flex items-center cursor-pointer">
<input type="hidden" name="welcome_gift_enabled" value="0">
<input type="checkbox" name="welcome_gift_enabled" value="1" {{ $machine->welcome_gift_enabled ? 'checked' : '' }} class="sr-only peer">
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-indigo-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-500 transition-colors"></div>
</div>
</label>
<label class="flex items-center justify-between p-4 rounded-2xl border border-slate-100 dark:border-slate-800 bg-slate-50/30 dark:bg-slate-900/30 cursor-pointer group">
<div>
<span class="block text-sm font-black text-slate-700 dark:text-slate-200 group-hover:text-indigo-500 transition-colors">{{ __('Member System') }}</span>
<span class="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{{ __('Enabled/Disabled') }}</span>
</div>
<div class="relative inline-flex items-center cursor-pointer">
<input type="hidden" name="member_system_enabled" value="0">
<input type="checkbox" name="member_system_enabled" value="1" {{ $machine->member_system_enabled ? 'checked' : '' }} class="sr-only peer">
<div class="w-11 h-6 bg-slate-200 dark:bg-slate-700 rounded-full peer peer-focus:ring-4 peer-focus:ring-indigo-500/20 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-0.5 after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all dark:border-gray-600 peer-checked:bg-indigo-500 transition-colors"></div>
</div>
</label>
</div>
</div>
</div>
</div>
</form>

View File

@ -225,7 +225,7 @@
<div class="flex flex-col md:flex-row md:items-center justify-between gap-4">
<div>
<h1 class="text-3xl font-black text-slate-800 dark:text-white tracking-tight font-display transition-all duration-300">
{{ __('Customer List') }}
{{ __('Customer Management') }}
</h1>
<p class="text-sm font-bold text-slate-500 dark:text-slate-400 mt-1 uppercase tracking-widest">
{{ __('Manage all tenant accounts and validity') }}
@ -1012,116 +1012,6 @@
</label>
</div>
</div>
<!-- 稅務系統 (Taxation System) -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center p-4 rounded-xl bg-slate-50/50 dark:bg-slate-800/50 border border-slate-100 dark:border-slate-700/50 hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors">
<div class="md:col-span-1">
<h4 class="text-sm font-black text-slate-700 dark:text-slate-200">{{ __('Taxation System') }}</h4>
</div>
<div class="md:col-span-3 flex flex-wrap gap-x-8 gap-y-4">
<label class="flex items-center gap-3 cursor-pointer group">
<div class="relative inline-flex items-center">
<input type="hidden" name="settings[tax_invoice]" value="0">
<input type="checkbox" name="settings[tax_invoice]" value="1" x-model="currentCompany.settings.tax_invoice" class="peer sr-only">
<div class="w-9 h-5 bg-slate-200 peer-focus:outline-none rounded-full peer dark:bg-slate-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-cyan-500"></div>
</div>
<span class="text-sm font-bold text-slate-600 dark:text-slate-300 group-hover:text-slate-900 dark:group-hover:text-white transition-colors">{{ __('Electronic Invoice') }}</span>
</label>
</div>
</div>
<!-- 刷卡機系統 (Card Terminal System) -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center p-4 rounded-xl bg-slate-50/50 dark:bg-slate-800/50 border border-slate-100 dark:border-slate-700/50 hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors">
<div class="md:col-span-1">
<h4 class="text-sm font-black text-slate-700 dark:text-slate-200">{{ __('Card Terminal System') }}</h4>
</div>
<div class="md:col-span-3 flex flex-wrap gap-x-8 gap-y-4">
<label class="flex items-center gap-3 cursor-pointer group">
<div class="relative inline-flex items-center">
<input type="hidden" name="settings[card_terminal]" value="0">
<input type="checkbox" name="settings[card_terminal]" value="1" x-model="currentCompany.settings.card_terminal" class="peer sr-only">
<div class="w-9 h-5 bg-slate-200 peer-focus:outline-none rounded-full peer dark:bg-slate-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-cyan-500"></div>
</div>
<span class="text-sm font-bold text-slate-600 dark:text-slate-300 group-hover:text-slate-900 dark:group-hover:text-white transition-colors">{{ __('Includes Credit Card/Mobile Pay') }}</span>
</label>
</div>
</div>
<!-- 掃碼支付功能 (QR Scan Payment) -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center p-4 rounded-xl bg-slate-50/50 dark:bg-slate-800/50 border border-slate-100 dark:border-slate-700/50 hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors">
<div class="md:col-span-1">
<h4 class="text-sm font-black text-slate-700 dark:text-slate-200">{{ __('QR Scan Payment') }}</h4>
</div>
<div class="md:col-span-3 flex flex-wrap gap-x-8 gap-y-4">
<label class="flex items-center gap-3 cursor-pointer group">
<div class="relative inline-flex items-center">
<input type="hidden" name="settings[scan_pay_esun]" value="0">
<input type="checkbox" name="settings[scan_pay_esun]" value="1" x-model="currentCompany.settings.scan_pay_esun" class="peer sr-only">
<div class="w-9 h-5 bg-slate-200 peer-focus:outline-none rounded-full peer dark:bg-slate-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-cyan-500"></div>
</div>
<span class="text-sm font-bold text-slate-600 dark:text-slate-300 group-hover:text-slate-900 dark:group-hover:text-white transition-colors">{{ __('E.SUN QR Pay') }}</span>
</label>
<label class="flex items-center gap-3 cursor-pointer group">
<div class="relative inline-flex items-center">
<input type="hidden" name="settings[scan_pay_linepay]" value="0">
<input type="checkbox" name="settings[scan_pay_linepay]" value="1" x-model="currentCompany.settings.scan_pay_linepay" class="peer sr-only">
<div class="w-9 h-5 bg-slate-200 peer-focus:outline-none rounded-full peer dark:bg-slate-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-cyan-500"></div>
</div>
<span class="text-sm font-bold text-slate-600 dark:text-slate-300 group-hover:text-slate-900 dark:group-hover:text-white transition-colors">{{ __('LinePay Payment') }}</span>
</label>
</div>
</div>
<!-- 購物車功能 (Shopping Cart Feature) -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center p-4 rounded-xl bg-slate-50/50 dark:bg-slate-800/50 border border-slate-100 dark:border-slate-700/50 hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors">
<div class="md:col-span-1">
<h4 class="text-sm font-black text-slate-700 dark:text-slate-200">{{ __('Shopping Cart Feature') }}</h4>
</div>
<div class="md:col-span-3 flex flex-wrap gap-x-8 gap-y-4">
<label class="flex items-center gap-3 cursor-pointer group">
<div class="relative inline-flex items-center">
<input type="hidden" name="settings[shopping_cart]" value="0">
<input type="checkbox" name="settings[shopping_cart]" value="1" x-model="currentCompany.settings.shopping_cart" class="peer sr-only">
<div class="w-9 h-5 bg-slate-200 peer-focus:outline-none rounded-full peer dark:bg-slate-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-cyan-500"></div>
</div>
<span class="text-sm font-bold text-slate-600 dark:text-slate-300 group-hover:text-slate-900 dark:group-hover:text-white transition-colors">{{ __('Shopping Cart') }}</span>
</label>
</div>
</div>
<!-- 來店禮功能 (Welcome Gift Feature) -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center p-4 rounded-xl bg-slate-50/50 dark:bg-slate-800/50 border border-slate-100 dark:border-slate-700/50 hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors">
<div class="md:col-span-1">
<h4 class="text-sm font-black text-slate-700 dark:text-slate-200">{{ __('Welcome Gift Feature') }}</h4>
</div>
<div class="md:col-span-3 flex flex-wrap gap-x-8 gap-y-4">
<label class="flex items-center gap-3 cursor-pointer group">
<div class="relative inline-flex items-center">
<input type="hidden" name="settings[welcome_gift]" value="0">
<input type="checkbox" name="settings[welcome_gift]" value="1" x-model="currentCompany.settings.welcome_gift" class="peer sr-only">
<div class="w-9 h-5 bg-slate-200 peer-focus:outline-none rounded-full peer dark:bg-slate-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-cyan-500"></div>
</div>
<span class="text-sm font-bold text-slate-600 dark:text-slate-300 group-hover:text-slate-900 dark:group-hover:text-white transition-colors">{{ __('Welcome Gift') }}</span>
</label>
</div>
</div>
<!-- 現金模組功能 (Cash Module Feature) -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 items-center p-4 rounded-xl bg-slate-50/50 dark:bg-slate-800/50 border border-slate-100 dark:border-slate-700/50 hover:bg-slate-50 dark:hover:bg-slate-800 transition-colors">
<div class="md:col-span-1">
<h4 class="text-sm font-black text-slate-700 dark:text-slate-200">{{ __('Cash Module Feature') }}</h4>
</div>
<div class="md:col-span-3 flex flex-wrap gap-x-8 gap-y-4">
<label class="flex items-center gap-3 cursor-pointer group">
<div class="relative inline-flex items-center">
<input type="hidden" name="settings[cash_module]" value="0">
<input type="checkbox" name="settings[cash_module]" value="1" x-model="currentCompany.settings.cash_module" class="peer sr-only">
<div class="w-9 h-5 bg-slate-200 peer-focus:outline-none rounded-full peer dark:bg-slate-700 peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all dark:border-gray-600 peer-checked:bg-cyan-500"></div>
</div>
<span class="text-sm font-bold text-slate-600 dark:text-slate-300 group-hover:text-slate-900 dark:group-hover:text-white transition-colors">{{ __('Coin/Bill Acceptor') }}</span>
</label>
</div>
</div>
</div>
<div class="flex justify-end gap-x-4 pt-8 mt-6 border-t border-slate-100 dark:border-slate-800">

View File

@ -242,7 +242,7 @@
</p>
</div>
<div class="flex items-center gap-3">
<template x-if="activeTab === 'stock-in'">
<template x-if="activeTab === 'stock'">
<button type="button" @click="openStockInModal()"
class="btn-luxury-primary transition-all duration-300">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2.5">

View File

@ -21,16 +21,16 @@
<table class="w-full text-left border-separate border-spacing-y-0 min-w-max">
<thead>
<tr class="bg-slate-50/50 dark:bg-white/[0.02]">
<th class="px-6 py-5 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 sticky left-0 bg-white dark:bg-[#1e293b] z-20">{{ __('Product') }}</th>
<th class="px-6 py-5 text-sm font-black text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 sticky left-0 bg-white dark:bg-[#1e293b] z-20">{{ __('Product') }}</th>
@foreach($inventory_warehouses as $w)
<th class="px-6 py-5 text-xs font-bold text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 text-center">
<th class="px-6 py-5 text-sm font-black text-slate-500 dark:text-slate-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 text-center">
<div class="flex flex-col items-center">
<span class="text-slate-800 dark:text-slate-200">{{ $w->name }}</span>
<span class="text-[9px] opacity-60 tracking-normal mt-0.5">{{ $w->type === 'main' ? __('Main') : __('Branch') }}</span>
<span class="text-base font-black text-slate-800 dark:text-slate-200 tracking-tight">{{ $w->name }}</span>
<span class="text-[10px] font-bold opacity-60 tracking-widest mt-0.5 uppercase">{{ $w->type === 'main' ? __('Main') : __('Branch') }}</span>
</div>
</th>
@endforeach
<th class="px-6 py-5 text-xs font-bold text-cyan-600 dark:text-cyan-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 text-center bg-cyan-50/30 dark:bg-cyan-500/5">{{ __('Total') }}</th>
<th class="px-6 py-5 text-sm font-black text-cyan-600 dark:text-cyan-400 uppercase tracking-[0.15em] border-b border-slate-100 dark:border-slate-800 text-center bg-cyan-50/30 dark:bg-cyan-500/5">{{ __('Total') }}</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-50 dark:divide-white/[0.05]">
@ -48,7 +48,9 @@
</div>
<div class="flex flex-col">
<span class="font-extrabold text-slate-800 dark:text-slate-100 group-hover:text-cyan-600 dark:group-hover:text-cyan-400 transition-colors">{{ $product->localized_name }}</span>
<span class="text-[10px] font-bold text-slate-400 mt-0.5 tracking-tight">{{ $product->barcode ?? '-' }}</span>
@if($product->barcode)
<span class="text-[10px] font-bold text-slate-400 mt-0.5 tracking-tight">{{ $product->barcode }}</span>
@endif
</div>
</div>
</td>

View File

@ -89,6 +89,12 @@
'machine-models' => __('Machine Models'),
default => null,
},
'permission' => match($segments[2] ?? '') {
'companies' => __('Customer Management'),
'accounts' => __('Account Management'),
'roles' => __('Roles'),
default => null,
},
default => null,
},
'edit' => str_starts_with($routeName, 'profile') ? __('Profile') : __('Edit'),