From 157d805555a573fd9a0f16aa8f309dcad4c3d600 Mon Sep 17 00:00:00 2001 From: sundayenglish Date: Tue, 24 Jun 2025 16:28:54 +0700 Subject: [PATCH] Add Module Role --- app/Components/Role/Manager.php | 88 +++++----- app/Http/Controllers/DashboardController.php | 1 - resources/views/admin/dashboard.blade.php | 1 - .../components/permission/manager.blade.php | 6 +- .../views/components/role/manager.blade.php | 152 ++++++++---------- .../views/components/skeleton-form.blade.php | 30 ++-- .../views/components/skeleton-table.blade.php | 44 ++--- 7 files changed, 152 insertions(+), 170 deletions(-) diff --git a/app/Components/Role/Manager.php b/app/Components/Role/Manager.php index 5d9fdfe..256d5ba 100644 --- a/app/Components/Role/Manager.php +++ b/app/Components/Role/Manager.php @@ -6,51 +6,30 @@ use Livewire\Component; use Livewire\Attributes\On; use Livewire\WithPagination; use Spatie\Permission\Models\Role; +use Spatie\Permission\Models\Permission; class Manager extends Component { use WithPagination; - /** - * Các tùy chọn số bản ghi mỗi trang. - * - * @var int[] - */ - public array $perPageOptions = [5, 10, 25, 50, 100]; - - /** - * Số bản ghi mỗi trang (mặc định). - */ - public int $perPage = 10; - - /** - * Giao diện phân trang (bootstrap hoặc tailwind). - */ - protected string $paginationTheme = 'bootstrap'; + public array $perPageOptions = [5, 10, 25, 50, 100]; + public int $perPage = 10; + protected string $paginationTheme = 'bootstrap'; + public string $mode = 'index'; + public ?int $editingId = null; + public string $search = ''; + public string $name = ''; - /** - * Chế độ UI: 'index' (danh sách) hoặc 'form' (tạo/sửa). - */ - public string $mode = 'index'; + public array $allPermissions = []; + public array $assignedPermissions = []; - /** - * ID của role đang sửa (null khi tạo mới). - */ - public ?int $editingId = null; - - /** - * Chuỗi tìm kiếm hiện tại. - */ - public string $search = ''; - - /** - * Tên role dùng trong form. - */ - public string $name = ''; + public function mount() + { + $this->allPermissions = Permission::orderBy('name') + ->get(['id', 'name']) + ->toArray(); + } - /** - * Khi thay đổi số bản ghi mỗi trang, reset về trang 1. - */ public function updatedPerPage(int $value): void { $this->resetPage(); @@ -59,10 +38,11 @@ class Manager extends Component #[On('roleSaved')] public function showIndex(): void { - $this->mode = 'index'; + $this->mode = 'index'; $this->resetPage(); - $this->name = ''; - $this->editingId = null; + $this->name = ''; + $this->editingId = null; + $this->assignedPermissions = []; } public function updatedSearch(string $value): void @@ -74,11 +54,23 @@ class Manager extends Component { $this->mode = 'form'; $this->editingId = $id; - $this->name = $id - ? Role::findOrFail($id)->name - : ''; + + if ($id) { + $role = Role::findOrFail($id); + $this->name = $role->name; + $this->assignedPermissions = $role + ->permissions + ->pluck('id') + ->toArray(); + } else { + $this->name = ''; + $this->assignedPermissions = []; + } } + /** + * Delete a role by its ID. + */ public function delete(int $id): void { Role::findOrFail($id)->delete(); @@ -92,14 +84,18 @@ class Manager extends Component . ($this->editingId ? ',' . $this->editingId : ''); $this->validate([ - 'name' => "required|string|{$uniqueRule}", + 'name' => "required|string|{$uniqueRule}", + 'assignedPermissions.*' => 'integer|exists:permissions,id', ]); - Role::updateOrCreate( + $role = Role::updateOrCreate( ['id' => $this->editingId], ['name' => $this->name] ); + // Sync permissions theo ID + $role->permissions()->sync($this->assignedPermissions); + session()->flash('message', 'Role saved.'); $this->dispatch('roleSaved'); } @@ -124,7 +120,7 @@ class Manager extends Component public function render() { - $roles = Role::query() + $roles = Role::with('permissions') // ← Eager-load permissions ->when($this->search, fn($q) => $q->where('name', 'like', "%{$this->search}%")) ->orderByDesc('id') ->paginate($this->perPage); diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index fa1899f..c4a44ec 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -7,7 +7,6 @@ class DashboardController extends Controller { public function index() { - // Trả về Blade wrapper, Livewire component sẽ được gọi trong đó return view('admin.dashboard'); } } diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php index 5504cd1..eeac3fd 100644 --- a/resources/views/admin/dashboard.blade.php +++ b/resources/views/admin/dashboard.blade.php @@ -3,6 +3,5 @@ @section('title', 'Dashboard') @section('content') - {{-- Đây chính là chỗ Livewire inject component --}} @endsection diff --git a/resources/views/components/permission/manager.blade.php b/resources/views/components/permission/manager.blade.php index cca6dba..6387884 100644 --- a/resources/views/components/permission/manager.blade.php +++ b/resources/views/components/permission/manager.blade.php @@ -11,7 +11,7 @@ @if ($mode === 'index')
- {{-- 1. Dropdown chọn số bản ghi --}} + {{-- 1. Dropdown --}}
+
- - {{-- 2. Search box --}} + {{-- search --}}
- +
- - - {{-- 3. Create button --}} -
@else - @endif @@ -67,103 +44,114 @@ @endif @if ($mode === 'index') - {{-- SKELETON TABLE --}} - - - {{-- ACTUAL TABLE --}} -
- + {{-- index --}} + +
+
+ {{-- cột mới --}} @forelse($roles as $r) - - - + + + @empty - + @endforelse
ID NamePermissionsActions
{{ $r->id }}{{ $r->name }} - {{ $r->id }}{{ $r->name }} + @forelse($r->permissions as $p) + {{ $p->name }} + @empty + + @endforelse + + -
No roles found.No roles found.
- - {{-- Pagination --}}
@if ($roles->lastPage() > 1) {{ $roles->links() }} @endif
@else - {{-- SKELETON FORM --}} + {{-- form edit/create --}} - - {{-- ACTUAL FORM --}} -
+
- + @error('name') -
{{ $message }}
+
{{ $message }}
@enderror
+ + {{-- checkbox list permissions --}} +
+ +
+ @foreach ($allPermissions as $perm) +
+
+ + +
+
+ @endforeach +
+ @error('assignedPermissions') +
{{ $message }}
+ @enderror +
+
- -
@endif -
+ diff --git a/resources/views/components/skeleton-form.blade.php b/resources/views/components/skeleton-form.blade.php index 3758e40..5719db3 100644 --- a/resources/views/components/skeleton-form.blade.php +++ b/resources/views/components/skeleton-form.blade.php @@ -1,22 +1,22 @@ @props(['fields', 'buttonCount'])
-
- {{-- Title --}} -
+
+ {{-- Title --}} +
- {{-- Fields --}} -
- @for ($i = 0; $i < $fields; $i++) -
- @endfor -
+ {{-- Fields --}} +
+ @for ($i = 0; $i < $fields; $i++) +
+ @endfor +
- {{-- Buttons --}} -
- @for ($i = 0; $i < $buttonCount; $i++) -
- @endfor + {{-- Buttons --}} +
+ @for ($i = 0; $i < $buttonCount; $i++) +
+ @endfor +
-
diff --git a/resources/views/components/skeleton-table.blade.php b/resources/views/components/skeleton-table.blade.php index 4ee3f5d..df6bee8 100644 --- a/resources/views/components/skeleton-table.blade.php +++ b/resources/views/components/skeleton-table.blade.php @@ -1,26 +1,26 @@ @props(['columns', 'rows', 'height'])
-
- - - - @for ($i = 0; $i < $columns; $i++) - - @endfor - - - - @for ($r = 0; $r < $rows; $r++) - - @for ($c = 0; $c < $columns; $c++) - - @endfor - - @endfor - -
 
-
-
-
+
+ + + + @for ($i = 0; $i < $columns; $i++) + + @endfor + + + + @for ($r = 0; $r < $rows; $r++) + + @for ($c = 0; $c < $columns; $c++) + + @endfor + + @endfor + +
 
+
+
+