diff --git a/.agents/skills/ui-minimal-luxury/SKILL.md b/.agents/skills/ui-minimal-luxury/SKILL.md index 967dc39..27002bc 100644 --- a/.agents/skills/ui-minimal-luxury/SKILL.md +++ b/.agents/skills/ui-minimal-luxury/SKILL.md @@ -177,7 +177,36 @@ description: 定義 Star Cloud 管理後台的「極簡奢華風」設計規範 - **指示文字**: - 行動端隱藏多餘詞彙,僅保留「1 - 10 / 50」格式。 - 數字顏色對齊 `text-slate-600` (深色: `text-slate-300`)。 -``` +## 9. 系統兼容性與標準化 (Compatibility & Standardization) + +為了確保在不同版本的開發環境中(如目前專案使用的 Tailwind CSS v3.1)UI 都能正確呈現,並維持全站操作感一致,必須遵守以下額外規範。 + +### Tailwind CSS 版本兼容性 (v3.1) +- **禁止使用 `size-` 屬性**: 舊版不支援 `size-4` 等語法,請一律分拆寫作 `w-4 h-4`。 +- **避免非標準間距**: 避免使用 `4.5` (`18px`) 等任意值,優先使用標準等級如 `4` (`16px`) 或 `5` (`20px`)。 + +### 標準操作按鈕 (Standard Action Icons) +表格內的操作欄位(如「編輯」、「刪除」)必須使用以下定義之標準: + +- **共同樣式**: + - 容器: `p-2 rounded-lg bg-slate-50 dark:bg-slate-800` + - 主色: `text-slate-400` + - 圖示粗細: `stroke-width="2.5"` + - 尺寸: `w-4 h-4` + +- **編輯按鈕 (Edit)**: + - 懸停特效: `hover:text-cyan-500 hover:bg-cyan-500/10 hover:border-cyan-500/20` + - SVG 路徑: + ```html + + ``` + +- **刪除按鈕 (Delete)**: + - 懸停特效: `hover:text-rose-500 hover:bg-rose-500/10 hover:border-rose-500/20` + - SVG 路徑: + ```html + + ``` --- > [!IMPORTANT] diff --git a/app/Http/Controllers/Admin/CompanyController.php b/app/Http/Controllers/Admin/CompanyController.php index a3ebdb3..b7d03b1 100644 --- a/app/Http/Controllers/Admin/CompanyController.php +++ b/app/Http/Controllers/Admin/CompanyController.php @@ -29,8 +29,8 @@ class CompanyController extends Controller $query->where('status', $request->status); } - $limit = $request->input('limit', 10); - $companies = $query->latest()->paginate($limit)->withQueryString(); + $per_page = $request->input('per_page', 10); + $companies = $query->latest()->paginate($per_page)->withQueryString(); return view('admin.companies.index', compact('companies')); } diff --git a/app/Http/Controllers/Admin/DashboardController.php b/app/Http/Controllers/Admin/DashboardController.php index 6000d50..60b355a 100644 --- a/app/Http/Controllers/Admin/DashboardController.php +++ b/app/Http/Controllers/Admin/DashboardController.php @@ -11,8 +11,9 @@ class DashboardController extends Controller public function index(Request $request) { // 每頁顯示筆數限制 (預設為 10) - $perPage = $request->get('limit', 10); - + $perPage = (int) request()->input('per_page', 10); + if ($perPage <= 0) $perPage = 10; + // 從資料庫獲取真實統計數據 $totalRevenue = \App\Models\Member\MemberWallet::sum('balance'); $activeMachines = Machine::where('status', 'online')->count(); diff --git a/app/Http/Controllers/Admin/DataConfigController.php b/app/Http/Controllers/Admin/DataConfigController.php index 61793f8..cbe0c1c 100644 --- a/app/Http/Controllers/Admin/DataConfigController.php +++ b/app/Http/Controllers/Admin/DataConfigController.php @@ -29,7 +29,7 @@ class DataConfigController extends Controller public function adminProducts() { return view('admin.placeholder', [ - 'title' => '管理者可賣商品', + 'title' => '商品狀態', 'description' => '管理者商品銷售權限', ]); } diff --git a/app/Http/Controllers/Admin/MachineController.php b/app/Http/Controllers/Admin/MachineController.php index 5a622e0..f7eb53f 100644 --- a/app/Http/Controllers/Admin/MachineController.php +++ b/app/Http/Controllers/Admin/MachineController.php @@ -13,13 +13,13 @@ class MachineController extends AdminController */ public function index(Request $request): View { - $limit = $request->input('limit', 10); + $per_page = $request->input('per_page', 10); $machines = Machine::query() ->when($request->status, function ($query, $status) { return $query->where('status', $status); }) ->latest() - ->paginate($limit) + ->paginate($per_page) ->withQueryString(); return view('admin.machines.index', compact('machines')); @@ -42,7 +42,7 @@ class MachineController extends AdminController */ public function logs(Request $request): View { - $limit = $request->input('limit', 20); + $per_page = $request->input('per_page', 20); $logs = \App\Models\Machine\MachineLog::with('machine') ->when($request->level, function ($query, $level) { return $query->where('level', $level); @@ -51,7 +51,7 @@ class MachineController extends AdminController return $query->where('machine_id', $machineId); }) ->latest() - ->paginate($limit)->withQueryString(); + ->paginate($per_page)->withQueryString(); $machines = Machine::select('id', 'name')->get(); diff --git a/app/Http/Controllers/Admin/PermissionController.php b/app/Http/Controllers/Admin/PermissionController.php index 0703d71..3b452fe 100644 --- a/app/Http/Controllers/Admin/PermissionController.php +++ b/app/Http/Controllers/Admin/PermissionController.php @@ -7,93 +7,19 @@ use Illuminate\Http\Request; class PermissionController extends Controller { - // APP功能管理 - public function appFeatures() - { - return view('admin.placeholder', [ - 'title' => 'APP功能管理', - 'description' => 'APP功能權限設定', - ]); - } - - // 資料設定權限 - public function dataConfig() - { - return view('admin.placeholder', [ - 'title' => '資料設定權限', - 'description' => '資料設定功能權限', - ]); - } - - // 銷售管理權限 - public function sales() - { - return view('admin.placeholder', [ - 'title' => '銷售管理權限', - 'description' => '銷售管理功能權限', - ]); - } - - // 機台管理權限 - public function machines() - { - return view('admin.placeholder', [ - 'title' => '機台管理權限', - 'description' => '機台管理功能權限', - ]); - } - - // 倉庫管理權限 - public function warehouses() - { - return view('admin.placeholder', [ - 'title' => '倉庫管理權限', - 'description' => '倉庫管理功能權限', - ]); - } - - // 分析管理權限 - public function analysis() - { - return view('admin.placeholder', [ - 'title' => '分析管理權限', - 'description' => '分析管理功能權限', - ]); - } - - // 稽核管理權限 - public function audit() - { - return view('admin.placeholder', [ - 'title' => '稽核管理權限', - 'description' => '稽核管理功能權限', - ]); - } - - // 遠端管理權限 - public function remote() - { - return view('admin.placeholder', [ - 'title' => '遠端管理權限', - 'description' => '遠端管理功能權限', - ]); - } - - // Line管理權限 - public function line() - { - return view('admin.placeholder', [ - 'title' => 'Line管理權限', - 'description' => 'Line管理功能權限', - ]); - } - // 權限角色設定 public function roles() { - $limit = request()->input('limit', 10); - $roles = \Spatie\Permission\Models\Role::withCount('users')->latest()->paginate($limit)->withQueryString(); - return view('admin.permission.roles', compact('roles')); + $per_page = request()->input('per_page', 10); + $roles = \Spatie\Permission\Models\Role::with(['permissions', 'users'])->latest()->paginate($per_page)->withQueryString(); + $all_permissions = \Spatie\Permission\Models\Permission::all()->groupBy(function($perm) { + if (str_starts_with($perm->name, 'menu.')) { + return 'menu'; + } + return 'other'; + }); + + return view('admin.permission.roles', compact('roles', 'all_permissions')); } /** @@ -103,14 +29,20 @@ class PermissionController extends Controller { $validated = $request->validate([ 'name' => 'required|string|max:255|unique:roles,name', + 'permissions' => 'nullable|array', + 'permissions.*' => 'string|exists:permissions,name', ]); - \Spatie\Permission\Models\Role::create([ + $role = \Spatie\Permission\Models\Role::create([ 'name' => $validated['name'], 'guard_name' => 'web', 'is_system' => false, ]); + if (!empty($validated['permissions'])) { + $role->syncPermissions($validated['permissions']); + } + return redirect()->back()->with('success', __('Role created successfully.')); } @@ -121,15 +53,17 @@ class PermissionController extends Controller { $role = \Spatie\Permission\Models\Role::findOrFail($id); - if ($role->is_system) { - return redirect()->back()->with('error', __('System roles cannot be renamed.')); - } - $validated = $request->validate([ 'name' => 'required|string|max:255|unique:roles,name,' . $id, + 'permissions' => 'nullable|array', + 'permissions.*' => 'string|exists:permissions,name', ]); - $role->update(['name' => $validated['name']]); + if (!$role->is_system) { + $role->update(['name' => $validated['name']]); + } + + $role->syncPermissions($validated['permissions'] ?? []); return redirect()->back()->with('success', __('Role updated successfully.')); } @@ -154,15 +88,6 @@ class PermissionController extends Controller return redirect()->back()->with('success', __('Role deleted successfully.')); } - // 其他功能管理 - public function others() - { - return view('admin.placeholder', [ - 'title' => '其他功能管理', - 'description' => '其他特殊功能權限', - ]); - } - // 帳號管理 public function accounts(Request $request) { @@ -187,11 +112,12 @@ class PermissionController extends Controller $query->where('company_id', $request->company_id); } - $limit = $request->input('limit', 10); - $users = $query->latest()->paginate($limit)->withQueryString(); + $per_page = $request->input('per_page', 10); + $users = $query->latest()->paginate($per_page)->withQueryString(); $companies = auth()->user()->isSystemAdmin() ? \App\Models\System\Company::all() : collect(); + $roles = \Spatie\Permission\Models\Role::all(); - return view('admin.data-config.accounts', compact('users', 'companies')); + return view('admin.data-config.accounts', compact('users', 'companies', 'roles')); } /** @@ -281,13 +207,4 @@ class PermissionController extends Controller return redirect()->back()->with('success', __('Account deleted successfully.')); } - - // AI智能預測 - public function aiPrediction() - { - return view('admin.placeholder', [ - 'title' => 'AI智能預測', - 'description' => 'AI功能權限設定', - ]); - } } diff --git a/database/seeders/RoleSeeder.php b/database/seeders/RoleSeeder.php index 7fd7233..1f466fe 100644 --- a/database/seeders/RoleSeeder.php +++ b/database/seeders/RoleSeeder.php @@ -17,11 +17,35 @@ class RoleSeeder extends Seeder // 重設快取 app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions(); + // 建立權限 + $permissions = [ + 'menu.members', + 'menu.machines', + 'menu.app', + 'menu.warehouses', + 'menu.sales', + 'menu.analysis', + 'menu.audit', + 'menu.data-config', + 'menu.remote', + 'menu.line', + 'menu.reservation', + 'menu.special-permission', + 'menu.companies', + 'menu.accounts', + 'menu.roles', + ]; + + foreach ($permissions as $permission) { + Permission::updateOrCreate(['name' => $permission, 'guard_name' => 'web']); + } + // 建立角色 - Role::updateOrCreate( + $superAdmin = Role::updateOrCreate( ['name' => 'super-admin'], ['is_system' => true] ); + $superAdmin->syncPermissions(Permission::all()); Role::updateOrCreate( ['name' => 'tenant-admin'], diff --git a/lang/en.json b/lang/en.json index 4906b7a..df4e203 100644 --- a/lang/en.json +++ b/lang/en.json @@ -148,22 +148,37 @@ "AI Prediction": "AI Prediction", "Roles": "Roles", "Role Management": "Role Management", - "Define and manage security roles for the system.": "Define and manage security roles for the system.", - "Add Role": "Add Role", - "Role Name": "Role Name", - "Type": "Type", - "Users": "Users", - "System Role": "System Role", - "System": "System", - "Custom": "Custom", - "Edit": "Edit", - "Are you sure you want to delete this role?": "Are you sure you want to delete this role?", - "Delete": "Delete", - "Protected": "Protected", + "Define and manage security roles and permissions.": "Define and manage security roles and permissions.", + "Search roles...": "Search roles...", + "No permissions": "No permissions", "No roles found.": "No roles found.", "Create Role": "Create Role", "Edit Role": "Edit Role", + "Update existing role and permissions.": "Update existing role and permissions.", + "Create a new role and assign permissions.": "Create a new role and assign permissions.", "Enter role name": "Enter role name", + "Add Role": "Add Role", + "Role Name": "Role Name", + "Type": "Type", + "Permissions": "Permissions", + "Users": "Users", + "System role name cannot be modified.": "System role name cannot be modified.", + "members": "Member Management", + "machines": "Machine Management", + "app": "APP Management", + "warehouses": "Warehouse Management", + "sales": "Sales Management", + "analysis": "Analysis Management", + "audit": "Audit Management", + "data-config": "Data Configuration", + "remote": "Remote Management", + "line": "Line Management", + "reservation": "Reservation System", + "special-permission": "Special Permission", + "companies": "Customer Management", + "accounts": "Account Management", + "roles": "Role Settings", + "Role Settings": "Role Settings", "No login history yet": "No login history yet", "Signed in as": "Signed in as", "Logout": "Logout", diff --git a/lang/ja.json b/lang/ja.json index c8a3657..7327ac1 100644 --- a/lang/ja.json +++ b/lang/ja.json @@ -148,22 +148,39 @@ "AI Prediction": "AI予測", "Roles": "ロール", "Role Management": "ロール管理", - "Define and manage security roles for the system.": "システムのセキュリティロールを定義および管理します。", + "Define and manage security roles and permissions.": "システムのセキュリティロールと権限を定義および管理します。", + "Search roles...": "ロールを検索...", + "No permissions": "権限項目なし", + "No roles found.": "ロールが見つかりませんでした。", + "Create Role": "ロール作成", + "Edit Role": "ロール編集", + "Update existing role and permissions.": "既存のロールと権限を更新します。", + "Create a new role and assign permissions.": "新しいロールを作成し、権限を割り当てます。", + "Enter role name": "ロール名を入力してください", "Add Role": "ロールを追加", "Role Name": "ロール名", "Type": "タイプ", + "Permissions": "権限", "Users": "ユーザー数", - "System Role": "システムロール", - "System": "システム", - "Custom": "カスタム", - "Edit": "編集", - "Are you sure you want to delete this role?": "このロールを削除してもよろしいですか?", - "Delete": "削除", - "Protected": "保護済み", - "No roles found.": "ロールが見見つかりません。", - "Create Role": "ロールの作成", - "Edit Role": "ロールの編集", - "Enter role name": "ロール名を入力してください", + "System role name cannot be modified.": "システムロール名は変更できません。", + "Menu Permissions": "メニュー権限", + "Save Changes": "変更を保存", + "members": "会員管理", + "machines": "機台管理", + "app": "APP管理", + "warehouses": "倉庫管理", + "sales": "販売管理", + "analysis": "分析管理", + "audit": "監査管理", + "data-config": "データ設定", + "remote": "リモート管理", + "line": "Line管理", + "reservation": "予約システム", + "special-permission": "特別権限", + "companies": "顧客管理", + "accounts": "アカウント管理", + "roles": "ロール設定", + "Role Settings": "ロール設定", "No login history yet": "ログイン履歴はまだありません", "Signed in as": "ログイン中", "Logout": "ログアウト", @@ -172,23 +189,23 @@ "Total Logins": "総ログイン数", "Account Status": "アカウント状態", "Active": "アクティブ", - "Customer Management": "客戶管理", + "Customer Management": "顧客管理", "Manage all tenant accounts and validity": "すべてのテナントアカウントと有効期限を管理します", - "Add Customer": "客戶を追加", - "Total Customers": "客戶総数", + "Add Customer": "顧客を追加", + "Total Customers": "顧客総数", "Expired / Disabled": "期限切れ / 停止中", - "Search customers...": "客戶を検索...", + "Search customers...": "顧客を検索...", "All": "すべて", "Disabled": "停止中", - "Customer Info": "客戶情報", + "Customer Info": "顧客情報", "Accounts / Machines": "アカウント / 機台", "Valid Until": "有効期限", "Actions": "操作", "Permanent": "永久認可", - "Are you sure to delete this customer?": "この客戶を削除してもよろしいですか?", - "No customers found": "客戶が見つかりません", - "Edit Customer": "客戶を編集", - "Update Customer": "客戶を更新", + "Are you sure to delete this customer?": "この顧客を削除してもよろしいですか?", + "No customers found": "顧客が見つかりません", + "Edit Customer": "顧客を編集", + "Update Customer": "顧客を更新", "Create": "作成", "Company Name": "会社名", "Company Code": "会社コード", @@ -198,9 +215,9 @@ "Contact Phone": "連絡先電話番号", "Contact Email": "連絡先メールアドレス", "Notes": "備考", - "Customer created successfully.": "客戶が正常に作成されました。", - "Customer updated successfully.": "客戶が正常に更新されました。", - "Customer deleted successfully.": "客戶が正常に削除されました。", + "Customer created successfully.": "顧客が正常に作成されました。", + "Customer updated successfully.": "顧客が正常に更新されました。", + "Customer deleted successfully.": "顧客が正常に削除されました。", "Cannot delete company with active accounts.": "アクティブなアカウントを持つ会社は削除できません。", "Contract Until (Optional)": "契約期限 (任意)", "Company Information": "会社情報", @@ -229,8 +246,7 @@ "Audit Permissions": "監査管理權限", "Remote Permissions": "リモート管理權限", "Line Permissions": "Line管理權限", - "Company": "所属客戶", - "Save Changes": "変更を保存", + "Company": "所属顧客", "User": "一般ユーザー", "Admin": "管理者", "Super Admin": "スーパー管理者", diff --git a/lang/zh_TW.json b/lang/zh_TW.json index a867888..e88d22f 100644 --- a/lang/zh_TW.json +++ b/lang/zh_TW.json @@ -25,7 +25,6 @@ "Permanently Delete Account": "永久刪除帳號", "Password": "密碼", "Enter your password to confirm": "請輸入您的密碼以確認", - "Dashboard": "儀表板", "Connectivity Status": "連線狀態概況", "Real-time status monitoring": "即時監控機台連線動態", @@ -148,22 +147,37 @@ "AI Prediction": "AI智能預測", "Roles": "角色設定", "Role Management": "角色管理", - "Define and manage security roles for the system.": "定義與管理系統的安全角色。", - "Add Role": "新增角色", - "Role Name": "角色名稱", - "Type": "類型", - "Users": "使用者人數", - "System Role": "系統角色", - "System": "系統", - "Custom": "自定義", - "Edit": "編輯", - "Are you sure you want to delete this role?": "您確定要刪除此角色嗎?", - "Delete": "刪除", - "Protected": "受保護", + "Define and manage security roles and permissions.": "定義並管理系統安全角色與權限。", + "Search roles...": "搜尋角色...", + "No permissions": "無權限項目", "No roles found.": "找不到角色資料。", "Create Role": "建立角色", "Edit Role": "編輯角色", + "Update existing role and permissions.": "更新現有角色與權限設定。", + "Create a new role and assign permissions.": "建立新角色並分配對應權限。", "Enter role name": "請輸入角色名稱", + "Add Role": "新增角色", + "Role Name": "角色名稱", + "Type": "類型", + "Permissions": "權限", + "Users": "帳號數", + "System role name cannot be modified.": "內建系統角色的名稱無法修改。", + "members": "會員管理", + "machines": "機台管理", + "app": "APP 管理", + "warehouses": "倉庫管理", + "sales": "銷售管理", + "analysis": "分析管理", + "audit": "稽核管理", + "data-config": "資料設定", + "remote": "遠端管理", + "line": "Line 管理", + "reservation": "預約系統", + "special-permission": "特殊權限", + "companies": "客戶管理", + "accounts": "帳號管理", + "roles": "角色設定", + "Role Settings": "角色設定", "No login history yet": "尚無登入紀錄", "Signed in as": "登入身份", "Logout": "登出", @@ -244,5 +258,10 @@ "to": "至", "of": "總計", "items": "筆項目", - "Showing": "顯示第" -} + "Showing": "顯示第", + "Full Name": "全名", + "super-admin": "超級管理員", + "admin": "管理員", + "user": "一般用戶", + "Product Status": "商品狀態" +} \ No newline at end of file diff --git a/resources/views/admin/companies/index.blade.php b/resources/views/admin/companies/index.blade.php index 80dfcfe..5321a16 100644 --- a/resources/views/admin/companies/index.blade.php +++ b/resources/views/admin/companies/index.blade.php @@ -73,19 +73,9 @@ + -
| {{ __('Role Name') }} | {{ __('Type') }} | +{{ __('Permissions') }} | {{ __('Users') }} | {{ __('Actions') }} | ||||
|---|---|---|---|---|---|---|---|---|
|
+
@@ -88,31 +85,41 @@
@endif
+
+
{{ $role->name }}
@if($role->is_system)
-
+
@endif
|
+
+
+ @forelse($role->permissions->take(5) as $permission)
+ {{ __(str_replace('menu.', '', $permission->name)) }}
+ @empty
+ {{ __('No permissions') }}
+ @endforelse
+ @if($role->permissions->count() > 5)
+ +{{ $role->permissions->count() - 5 }}
+ @endif
+
+ |
- {{ $role->users_count }} + {{ $role->users()->count() }} |
-
- @if(!$role->is_system)
-
+
|
|||||
| + |
{{ __('No roles found.') }} @@ -134,26 +141,87 @@
-
+@endcan
+
+@can('menu.audit')
{{-- 9. 稽核管理 --}}
-
+@endcan
+
+@can('menu.analysis')
{{-- 8. 分析管理 --}}
-
-
+@endcan
+
+@can('menu.sales')
{{-- 7. 銷售管理 --}}
+
+@endcan
+
+@can('menu.warehouses')
{{-- 6. 倉庫管理 --}}
+
-
+
+
+
+
- {{-- Total Items Info --}}
-
- +@if ($paginator->total() > 0) +
+ {{-- Left Side: Limit Selector & Info --}}
+
+ {{-- Limit Selector --}}
+
-
+ {{ __('Show') }}
+
+
+ {{-- Total Items Info --}}
+
+ @php
+ $currentLimit = request('per_page', 10);
+ $limits = [10, 25, 50, 100];
+ @endphp
+
+
+
+
+ {{ __('Showing') }} {{ $paginator->firstItem() }} {{ __('to') }} @@ -14,7 +35,7 @@
+
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
@@ -30,7 +51,9 @@
{{-- Unified Quick Jump Selection (Desktop & Mobile) --}}
- | |||||||