Add Permission

master
sundayenglish 4 weeks ago
parent 9b6cd32b0c
commit 258ebeff69
  1. 44
      app/Components/Permission/Form.php
  2. 31
      app/Components/Permission/Index.php
  3. 80
      app/Components/Permission/Manager.php
  4. 17
      app/Http/Controllers/PermissionController.php
  5. 8
      resources/views/admin/permissions/form.blade.php
  6. 2
      resources/views/admin/permissions/manager.blade.php
  7. 40
      resources/views/components/permission/form.blade.php
  8. 65
      resources/views/components/permission/index.blade.php
  9. 104
      resources/views/components/permission/manager.blade.php
  10. 8
      routes/web.php

@ -1,44 +0,0 @@
<?php
namespace App\Components\Permission;
use Livewire\Component;
use Spatie\Permission\Models\Permission;
class Form extends Component
{
public $permissionId;
public $name;
protected function rules()
{
return [
'name' => 'required|string|unique:permissions,name' .
($this->permissionId ? ",{$this->permissionId}" : ''),
];
}
public function mount($permissionId = null)
{
$this->permissionId = $permissionId;
if ($permissionId) {
$perm = Permission::findOrFail($permissionId);
$this->name = $perm->name;
}
}
public function save()
{
$this->validate();
Permission::updateOrCreate(
['id' => $this->permissionId],
['name' => $this->name]
);
session()->flash('message', 'Permission saved.');
$this->emitUp('permissionSaved');
}
public function render()
{
return view('components.permission.form');
}
}

@ -1,31 +0,0 @@
<?php
namespace App\Components\Permission;
use Livewire\Component;
use Livewire\WithPagination;
use Spatie\Permission\Models\Permission;
class Index extends Component
{
use WithPagination;
protected string $paginationTheme = 'bootstrap';
public $search = '';
protected $listeners = ['permissionSaved' => '$refresh'];
public function updatingSearch() { $this->resetPage(); }
public function delete($id)
{
Permission::findOrFail($id)->delete();
session()->flash('message', 'Permission deleted.');
}
public function render()
{
$permissions = Permission::where('name', 'like', "%{$this->search}%")
->orderByDesc('id')
->paginate(10);
return view('components.permission.index', compact('permissions'));
}
}

@ -0,0 +1,80 @@
<?php
namespace App\Components\Permission;
use Livewire\Component;
use Livewire\WithPagination;
use Spatie\Permission\Models\Permission;
class Manager extends Component
{
use WithPagination;
protected string $paginationTheme = 'bootstrap';
public string $mode = 'index'; // 'index' hoặc 'form'
public ?int $editingId = null; // id đang edit
public string $search = ''; // search query
public string $name = ''; // dùng cho form
protected $listeners = [
'permissionSaved' => 'showIndex',
];
// Khi search thay đổi, reset pagination
public function updatingSearch()
{
$this->resetPage();
}
// Chuyển sang form (create/edit)
public function showForm(int $id = null)
{
$this->mode = 'form';
$this->editingId = $id;
$this->name = $id
? Permission::findOrFail($id)->name
: '';
}
// Quay về index, refresh list
public function showIndex()
{
$this->mode = 'index';
$this->resetPage();
$this->name = '';
$this->editingId = null;
}
// Xóa
public function delete(int $id)
{
Permission::findOrFail($id)->delete();
session()->flash('message', 'Permission deleted.');
$this->resetPage();
}
// Lưu form
public function save()
{
$rules = ['name' => 'required|string|unique:permissions,name'
.($this->editingId ? ",{$this->editingId}" : '')];
$this->validate($rules);
Permission::updateOrCreate(
['id' => $this->editingId],
['name' => $this->name]
);
session()->flash('message', 'Permission saved.');
$this->emit('permissionSaved');
}
public function render()
{
$permissions = Permission::where('name', 'like', "%{$this->search}%")
->orderByDesc('id')
->paginate(10);
return view('components.permission.manager', compact('permissions'));
}
}

@ -6,21 +6,8 @@ use Spatie\Permission\Models\Permission;
class PermissionController extends Controller
{
public function index()
public function manager()
{
return view('admin.permissions.index');
}
public function create()
{
return view('admin.permissions.form');
}
public function edit(Permission $permission)
{
// truyền permissionId vào wrapper
return view('admin.permissions.form', [
'permissionId' => $permission->id,
]);
return view('admin.permissions.manager');
}
}

@ -1,8 +0,0 @@
@extends('layouts.app')
@section('title', isset($permissionId) ? 'Edit Permission' : 'Create Permission')
@section('content')
{{-- truyền permissionId nếu có --}}
<livewire:permission.form :permission-id="$permissionId ?? null" />
@endsection

@ -3,5 +3,5 @@
@section('title', 'Permissions')
@section('content')
<livewire:permission.index />
<livewire:permission.manager />
@endsection

@ -1,40 +0,0 @@
<div class="row justify-content-center">
<div class="col-lg col-md-8">
<div class="card mb-4">
{{-- Card Header --}}
<div class="card-header pb-0">
<h6 class="mb-0">
{{ $permissionId ? 'Edit Permission' : 'Create Permission' }}
</h6>
</div>
{{-- Card Body --}}
<div class="card-body">
@if (session()->has('message'))
<div class="alert alert-success mb-3">
{{ session('message') }}
</div>
@endif
<form wire:submit.prevent="save">
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input id="name" type="text" wire:model.defer="name" class="form-control"
placeholder="Enter permission name">
@error('name')
<div class="text-danger text-xs mt-1">{{ $message }}</div>
@enderror
</div>
<div class="d-flex justify-content-end">
<a href="{{ route('permissions.index') }}" class="btn btn-secondary btn-sm me-2">
Cancel
</a>
<button type="submit" class="btn btn-primary btn-sm">
{{ $permissionId ? 'Update' : 'Create' }}
</button>
</div>
</form>
</div>
</div>
</div>
</div>

@ -1,65 +0,0 @@
<div class="row">
<div class="col-12">
<div class="card mb-4">
<!-- Card Header -->
<div class="card-header pb-0 d-flex justify-content-between align-items-center">
<h6 class="mb-0">Permissions</h6>
<div class="d-flex align-items-center">
{{-- Search field with Soft UI outline style --}}
<div class="input-group input-group-outline me-2">
<input type="text" wire:model.debounce.500ms="search" wire:keydown.enter="resetPage"
class="form-control" placeholder="Search permissions...">
</div>
{{-- Search button --}}
<button wire:click="resetPage" class="btn btn-sm btn-outline-secondary m-0" type="button">
<i class="fa-solid fa-magnifying-glass"></i>
</button>
{{-- New Permission button --}}
<a href="{{ route('permissions.create') }}" class="btn btn-sm btn-primary ms-2 m-0">Create</a>
</div>
</div>
<!-- Card Body -->
<div class="card-body p-3">
@if (session()->has('message'))
<div class="alert alert-success">{{ session('message') }}</div>
@endif
<div class="table-responsive">
<table class="table align-items-center mb-0">
<thead>
<tr>
<th class="text-center">ID</th>
<th>Name</th>
<th class="text-center">Actions</th>
</tr>
</thead>
<tbody>
@forelse($permissions as $p)
<tr>
<td class="text-center">{{ $p->id }}</td>
<td>{{ $p->name }}</td>
<td class="text-center">
<a href="{{ route('permissions.edit', $p) }}"
class="btn btn-sm btn-info me-1">Edit</a>
<button wire:click="delete({{ $p->id }})"
class="btn btn-sm btn-danger">Delete</button>
</td>
</tr>
@empty
<tr>
<td colspan="3" class="text-center">No permissions found.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
{{-- Pagination --}}
<div class="mt-3">
{{ $permissions->links('pagination::bootstrap-5') }}
</div>
</div>
</div>
</div>
</div>

@ -0,0 +1,104 @@
<div class="row">
<div class="col-12">
<div class="card mb-4">
{{-- Header --}}
<div class="card-header d-flex justify-content-between align-items-center pb-0">
<h6 class="mb-0">Permissions</h6>
@if ($mode === 'index')
<div class="d-flex align-items-center">
<div class="input-group input-group-outline me-2">
<input type="text" wire:model.debounce.500ms="search" wire:keydown.enter="resetPage"
class="form-control" placeholder="Search...">
</div>
<button wire:click="showForm" class="btn btn-sm btn-outline-secondary me-2">
+ New
</button>
</div>
@else
<button wire:click="showIndex" class="btn btn-sm btn-secondary">
← Back to list
</button>
@endif
</div>
{{-- Body --}}
<div class="card-body p-3">
@if (session()->has('message'))
<div class="alert alert-success">{{ session('message') }}</div>
@endif
@if ($mode === 'index')
<div class="table-responsive">
<table class="table align-items-center mb-0">
<thead>
<tr>
<th class="text-center">ID</th>
<th>Name</th>
<th class="text-center">Actions</th>
</tr>
</thead>
<tbody>
@forelse($permissions as $p)
<tr>
<td class="text-center">{{ $p->id }}</td>
<td>{{ $p->name }}</td>
<td class="text-center">
<button wire:click="showForm({{ $p->id }})"
class="btn btn-sm btn-info me-1">
Edit
</button>
<button wire:click="delete({{ $p->id }})"
class="btn btn-sm btn-danger">
Delete
</button>
</td>
</tr>
@empty
<tr>
<td colspan="3" class="text-center">No permissions found.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="mt-3">{{ $permissions->links('pagination::bootstrap-5') }}</div>
@else
{{-- Form --}}
<div class="row justify-content-center">
<div class="col-lg-6">
<div class="card">
<div class="card-header pb-0">
<h6 class="mb-0">
{{ $editingId ? 'Edit Permission' : 'Create Permission' }}
</h6>
</div>
<div class="card-body">
<form wire:submit.prevent="save">
<div class="mb-3">
<label class="form-label">Name</label>
<input type="text" wire:model.defer="name" class="form-control"
placeholder="Enter permission name">
@error('name')
<div class="text-danger text-xs mt-1">{{ $message }}</div>
@enderror
</div>
<div class="d-flex justify-content-end">
<button wire:click="showIndex" type="button"
class="btn btn-secondary btn-sm me-2">
Cancel
</button>
<button type="submit" class="btn btn-primary btn-sm">
{{ $editingId ? 'Update' : 'Create' }}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
@endif
</div>
</div>
</div>
</div>

@ -4,11 +4,11 @@ use App\Http\Controllers\Auth\LoginController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\DashboardController;
use App\Http\Controllers\PermissionController;
use App\Components\Permission\Manager as PermissionManager;
// Dashboard route (Livewire) for authenticated users only
Route::get('dashboard', [DashboardController::class, 'index'])->name('dashboard');
Route::middleware(['auth'])->group(function () {
Route::get('/permissions', [PermissionController::class, 'index'])->name('permissions.index');
Route::get('/permissions/create', [PermissionController::class, 'create'])->name('permissions.create');
Route::get('/permissions/{permission}/edit', [PermissionController::class, 'edit'])->name('permissions.edit');
Route::middleware('auth')->group(function () {
Route::get('/permissions', [PermissionController::class, 'manager'])
->name('permissions.index');
});

Loading…
Cancel
Save