Skip to content

Commit 43bdef5

Browse files
authored
Merge pull request #62 from ugunNet21/develop
Develop
2 parents 4a89f2f + da141e7 commit 43bdef5

File tree

15 files changed

+438
-4
lines changed

15 files changed

+438
-4
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<?php
2+
namespace App\Http\Controllers\admin;
3+
4+
use App\Http\Controllers\Controller;
5+
use App\Models\User;
6+
use Illuminate\Http\Request;
7+
use Spatie\Permission\Models\Permission;
8+
use Spatie\Permission\Models\Role;
9+
use Yajra\DataTables\Facades\DataTables;
10+
11+
class PermissionController extends Controller
12+
{
13+
public function index()
14+
{
15+
$permissions = Permission::with(['users', 'roles'])->get();
16+
$users = User::all();
17+
$roles = Role::all();
18+
return view('admin.pages.Permissions.index', compact('permissions', 'users', 'roles'));
19+
}
20+
21+
public function create()
22+
{
23+
$roles = Role::all();
24+
return view('admin.pages.Permissions.create', compact('roles'));
25+
}
26+
27+
public function store(Request $request)
28+
{
29+
$request->validate([
30+
'name' => 'required|string|unique:permissions,name',
31+
'roles' => 'nullable|array',
32+
'roles.*' => 'exists:roles,id',
33+
]);
34+
35+
$permission = Permission::create(['name' => $request->name]);
36+
37+
if ($request->filled('roles')) {
38+
$roles = Role::whereIn('id', $request->roles)->get();
39+
foreach ($roles as $role) {
40+
$role->givePermissionTo($permission);
41+
}
42+
}
43+
44+
return redirect()->route('permissions.index')->with('success', 'Permission created.');
45+
}
46+
47+
public function show(Permission $permission)
48+
{
49+
$users = User::all();
50+
$roles = $permission->roles;
51+
return view('admin.pages.Permissions.show', compact('permission', 'users', 'roles'));
52+
}
53+
54+
public function edit(Permission $permission)
55+
{
56+
$roles = Role::all();
57+
$assignedRoles = $permission->roles->pluck('id')->toArray();
58+
return view('admin.pages.Permissions.edit', compact('permission', 'roles', 'assignedRoles'));
59+
}
60+
61+
public function update(Request $request, Permission $permission)
62+
{
63+
$request->validate([
64+
'name' => 'required|string|unique:permissions,name,' . $permission->id,
65+
'roles' => 'nullable|array',
66+
'roles.*' => 'exists:roles,id',
67+
]);
68+
69+
$permission->update(['name' => $request->name]);
70+
71+
// Sinkronisasi ulang permission ke role
72+
if ($request->filled('roles')) {
73+
// Ambil semua role yang sebelumnya punya permission ini
74+
$oldRoles = $permission->roles;
75+
foreach ($oldRoles as $oldRole) {
76+
$oldRole->revokePermissionTo($permission);
77+
}
78+
79+
// Assign ke role baru
80+
$newRoles = Role::whereIn('id', $request->roles)->get();
81+
foreach ($newRoles as $role) {
82+
$role->givePermissionTo($permission);
83+
}
84+
} else {
85+
// Jika tidak ada role, revoke semuanya
86+
foreach ($permission->roles as $role) {
87+
$role->revokePermissionTo($permission);
88+
}
89+
}
90+
91+
return redirect()->route('permissions.index')->with('success', 'Permission updated.');
92+
}
93+
94+
public function destroy(Permission $permission)
95+
{
96+
$permission->delete();
97+
98+
return redirect()->route('permissions.index')->with('success', 'Permission deleted.');
99+
}
100+
101+
public function assignToUser(Request $request, Permission $permission)
102+
{
103+
$request->validate([
104+
'user_id' => 'required|exists:users,id',
105+
]);
106+
107+
$user = User::findOrFail($request->user_id);
108+
$user->givePermissionTo($permission);
109+
110+
return back()->with('success', "Permission '{$permission->name}' assigned to user '{$user->name}'.");
111+
}
112+
113+
public function revokeFromUser(Request $request, Permission $permission)
114+
{
115+
$request->validate([
116+
'user_id' => 'required|exists:users,id',
117+
]);
118+
119+
$user = User::findOrFail($request->user_id);
120+
$user->revokePermissionTo($permission);
121+
122+
return back()->with('success', "Permission '{$permission->name}' revoked from user '{$user->name}'.");
123+
}
124+
125+
public function assignToRole(Request $request, Permission $permission)
126+
{
127+
$request->validate([
128+
'role_id' => 'required|exists:roles,id',
129+
]);
130+
131+
$role = Role::findOrFail($request->role_id);
132+
$role->givePermissionTo($permission);
133+
134+
return back()->with('success', "Permission '{$permission->name}' assigned to role '{$role->name}'.");
135+
}
136+
137+
public function revokeFromRole(Request $request, Permission $permission)
138+
{
139+
$request->validate([
140+
'role_id' => 'required|exists:roles,id',
141+
]);
142+
143+
$role = Role::findOrFail($request->role_id);
144+
$role->revokePermissionTo($permission);
145+
146+
return back()->with('success', "Permission '{$permission->name}' revoked from role '{$role->name}'.");
147+
}
148+
public function datatable(Request $request)
149+
{
150+
$permissions = Permission::with(['users', 'roles'])->select('permissions.*');
151+
152+
return DataTables::of($permissions)
153+
->addIndexColumn()
154+
->addColumn('assigned_users', fn($permission) => $permission->users->count() . ' user(s)')
155+
->addColumn('roles', function ($permission) {
156+
// return $permission->roles->map(fn($r) => '<span class="badge bg-secondary">' . $r->name . '</span>')->implode(' ');
157+
return $permission->roles->map(fn($r) => '<span class="badge bg-secondary me-1 mb-1 d-inline-block">' . $r->name . '</span>')->implode('');
158+
159+
})
160+
->addColumn('actions', function ($permission) {
161+
return view('admin.pages.Permissions.partials.actions', compact('permission'))->render();
162+
})
163+
->rawColumns(['roles', 'actions']) // roles pakai HTML
164+
->make(true);
165+
}
166+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace App\Http\Controllers\admin;
4+
5+
use App\Http\Controllers\Controller;
6+
use Illuminate\Http\Request;
7+
use Spatie\Permission\Models\Role;
8+
9+
class RoleController extends Controller
10+
{
11+
public function list()
12+
{
13+
return Role::select(['id', 'name'])->get();
14+
}
15+
}

web-sch-12/app/Http/Controllers/admin/UserController.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,9 @@ public function destroy($id)
180180
->withErrors(['error' => 'Failed to delete user.']);
181181
}
182182
}
183+
public function list()
184+
{
185+
return User::select(['id', 'name', 'email'])->get();
186+
}
187+
183188
}

web-sch-12/public/backend/assets/css/data-table.responsive.bootstrap5.min.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web-sch-12/resources/views/admin/includes/scripts.blade.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
<!--alert session-->
1111
<script src="{{ asset('backend/assets/js/alert-session.js') }}"></script>
1212

13+
<!--data table responsive-->
14+
<script src="https://cdn.datatables.net/responsive/2.5.0/js/dataTables.responsive.min.js"></script>
15+
1316
<script>
1417
document.addEventListener('DOMContentLoaded', function() {
1518
const themeToggle = document.getElementById('theme-toggle');

web-sch-12/resources/views/admin/includes/sidebar.blade.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,20 +200,31 @@
200200
</li>
201201

202202
<!-- Administrasi -->
203-
<li class="nav-item nav-item-has-children {{ request()->routeIs('users.*') ? 'show' : '' }}">
204-
<a href="#0" class="{{ request()->routeIs('users.*') ? '' : 'collapsed' }}"
203+
<li class="nav-item nav-item-has-children {{ request()->routeIs('users.*', 'permissions.*') ? 'show' : '' }}">
204+
<a href="#0" class="{{ request()->routeIs('users.*', 'permissions.*') ? '' : 'collapsed' }}"
205205
data-bs-toggle="collapse" data-bs-target="#ddmenu_13" aria-controls="ddmenu_13"
206-
aria-expanded="{{ request()->routeIs('users.*') ? 'true' : 'false' }}" aria-label="Toggle navigation">
206+
aria-expanded="{{ request()->routeIs('users.*', 'permissions.*') ? 'true' : 'false' }}"
207+
aria-label="Toggle navigation">
207208
<span class="icon"><i class="lni lni-cog"></i></span>
208209
<span class="text">Administrasi</span>
209210
</a>
210-
<ul id="ddmenu_13" class="collapse dropdown-nav {{ request()->routeIs('users.*') ? 'show' : '' }}">
211+
<ul id="ddmenu_13"
212+
class="collapse dropdown-nav {{ request()->routeIs('users.*', 'permissions.*') ? 'show' : '' }}">
211213
<li><a href="#">Pengaturan Sistem</a></li>
214+
212215
<li>
213216
<a href="{{ route('users.index') }}" class="{{ request()->routeIs('users.*') ? 'active' : '' }}">
214217
Manajemen User
215218
</a>
216219
</li>
220+
221+
<li>
222+
<a href="{{ route('permissions.index') }}"
223+
class="{{ request()->routeIs('permissions.*') ? 'active' : '' }}">
224+
Manajemen Permission
225+
</a>
226+
</li>
227+
217228
<li><a href="#">Template Landing Page</a></li>
218229
<li><a href="#">Integrasi API</a></li>
219230
<li><a href="#">Backup Data</a></li>

web-sch-12/resources/views/admin/includes/styles.blade.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
22
<!--<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">-->
3+
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">
4+
35
<link rel="stylesheet" href="{{ asset('backend/assets/css/bootstrap.min.css') }}" />
46
<link rel="stylesheet" href="{{ asset('backend/assets/css/lineicons.css') }}" rel="stylesheet" type="text/css" />
57
<link rel="stylesheet" href="{{ asset('backend/assets/css/materialdesignicons.min.css') }}" rel="stylesheet"
@@ -18,6 +20,10 @@
1820
<!--<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.css">
1921
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.js"></script>-->
2022

23+
<!--data table responsive-->
24+
<link rel="stylesheet" href="{{ asset('backend/assets/css/data-table.responsive.bootstrap5.min.css') }}">
25+
<link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.5.0/css/responsive.bootstrap5.min.css">
26+
2127
<style>
2228
.sidebar {
2329
transition: transform 0.3s ease;

web-sch-12/resources/views/admin/layouts/app.blade.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
<!-- ========== All CSS files linkup ========= -->
1515
@include('admin.includes.styles')
1616
<!-- ========== All CSS files linkup ========= -->
17+
@stack('styles')
18+
1719
</head>
1820

1921
<body>
@@ -60,6 +62,8 @@
6062
<script src="{{ asset('backend/assets/js/admin-common.js') }}"></script>
6163
<!-- ========== admin common script ========== -->
6264

65+
@stack('scripts')
66+
6367
</body>
6468

6569
</html>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
@extends('admin.layouts.app')
2+
@section('title', 'Create Permission')
3+
4+
@section('content')
5+
<div class="container py-4">
6+
<h4>Create Permission</h4>
7+
8+
<form action="{{ route('permissions.store') }}" method="POST">
9+
@csrf
10+
11+
<div class="mb-3">
12+
<label for="name" class="form-label">Permission Name</label>
13+
<input type="text" class="form-control" id="name" name="name" placeholder="e.g. view_reports" required>
14+
</div>
15+
16+
<div class="mb-3">
17+
<label class="form-label">Assign to Roles</label>
18+
<div class="row">
19+
@foreach ($roles as $role)
20+
<div class="col-md-3 col-6">
21+
<div class="form-check">
22+
<input class="form-check-input" type="checkbox" name="roles[]" value="{{ $role->id }}" id="role_{{ $role->id }}">
23+
<label class="form-check-label" for="role_{{ $role->id }}">
24+
{{ $role->name }}
25+
</label>
26+
</div>
27+
</div>
28+
@endforeach
29+
</div>
30+
</div>
31+
32+
<button class="btn btn-success">Create</button>
33+
<a href="{{ route('permissions.index') }}" class="btn btn-secondary">Cancel</a>
34+
</form>
35+
</div>
36+
@endsection
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
@extends('admin.layouts.app')
2+
@section('title', 'Edit Permission')
3+
4+
@section('content')
5+
<div class="container py-4">
6+
<h4>Edit Permission</h4>
7+
8+
<form action="{{ route('permissions.update', $permission) }}" method="POST">
9+
@csrf
10+
@method('PUT')
11+
12+
<div class="mb-3">
13+
<label for="name" class="form-label">Permission Name</label>
14+
<input type="text" class="form-control" id="name" name="name" value="{{ $permission->name }}" required>
15+
</div>
16+
17+
<div class="mb-3">
18+
<label class="form-label">Assign to Roles</label>
19+
<div class="row">
20+
@foreach ($roles as $role)
21+
<div class="col-md-3 col-6">
22+
<div class="form-check">
23+
<input class="form-check-input" type="checkbox" name="roles[]" value="{{ $role->id }}"
24+
id="role_{{ $role->id }}" {{ $permission->roles->contains($role->id) ? 'checked' : '' }}>
25+
<label class="form-check-label" for="role_{{ $role->id }}">
26+
{{ $role->name }}
27+
</label>
28+
</div>
29+
</div>
30+
@endforeach
31+
</div>
32+
</div>
33+
34+
<button class="btn btn-primary">Update</button>
35+
<a href="{{ route('permissions.index') }}" class="btn btn-secondary">Cancel</a>
36+
</form>
37+
</div>
38+
@endsection

0 commit comments

Comments
 (0)