Skip to content

Commit c5ca11a

Browse files
add menu management
1 parent 381fe8f commit c5ca11a

File tree

19 files changed

+1312
-61
lines changed

19 files changed

+1312
-61
lines changed

app/Models/Menu/Menu.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function role() {
3535
return $this->belongsTo(Role::class);
3636
}
3737

38-
public function menuSubs() {
39-
return $this->hasMany(MenuSub::class);
38+
public function subMenu() {
39+
return $this->hasMany(MenuSub::class, 'menu_id')->orderBy('order', 'asc');
4040
}
4141
}

database/seeders/DatabaseSeeder.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public function run(): void
1717
$this->call([
1818
PermissionSeeder::class,
1919
UserSeeder::class,
20+
SuperadminMenuSeeder::class,
2021
]);
2122
}
2223
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace Database\Seeders;
4+
5+
use App\Models\Menu\Menu;
6+
use App\Models\Spatie\Role;
7+
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
8+
use Illuminate\Database\Seeder;
9+
10+
class SuperadminMenuSeeder extends Seeder
11+
{
12+
public $role;
13+
/**
14+
* Run the database seeds.
15+
*/
16+
public function run(): void {
17+
$this->role = Role::where('name', 'superadmin')->first();
18+
Menu::where('role_id', $this->role->id)->delete();
19+
20+
// Create menu
21+
$this->dashboardMenu();
22+
$this->managementMenu();
23+
}
24+
25+
public function dashboardMenu() {
26+
Menu::create([
27+
'role_id' => $this->role->id,
28+
'name' => 'Dashboard',
29+
'url' => 'cms.dashboard',
30+
'icon' => 'fa fa-map',
31+
'order' => 1,
32+
'active_pattern' => 'cms.dashboard',
33+
'status' => 1,
34+
]);
35+
}
36+
37+
public function managementMenu() {
38+
$management = Menu::create([
39+
'role_id' => $this->role->id,
40+
'name' => 'Managements',
41+
'url' => '#',
42+
'icon' => 'fa fa-cogs',
43+
'order' => 999,
44+
'active_pattern' => 'cms.management',
45+
'status' => 1,
46+
]);
47+
$management->subMenu()->create([
48+
'role_id' => $this->role->id,
49+
'name' => 'Permission',
50+
'url' => 'cms.management.permission',
51+
'order' => 1,
52+
'active_pattern' => 'cms.management.permission',
53+
'status' => 1,
54+
]);
55+
$management->subMenu()->create([
56+
'role_id' => $this->role->id,
57+
'name' => 'Role',
58+
'url' => 'cms.management.role',
59+
'order' => 2,
60+
'active_pattern' => 'cms.management.role',
61+
'status' => 1,
62+
]);
63+
$management->subMenu()->create([
64+
'role_id' => $this->role->id,
65+
'name' => 'Menu',
66+
'url' => 'cms.management.menu',
67+
'order' => 3,
68+
'active_pattern' => 'cms.management.menu',
69+
'status' => 1,
70+
]);
71+
$management->subMenu()->create([
72+
'role_id' => $this->role->id,
73+
'name' => 'User',
74+
'url' => 'cms.management.user',
75+
'order' => 4,
76+
'active_pattern' => 'cms.management.user',
77+
'status' => 1,
78+
]);
79+
}
80+
}

resources/views/components/cms/navigation.blade.php

Lines changed: 27 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -23,48 +23,26 @@ function showDropdown($activeRoute = []) {
2323
return '';
2424
}
2525
26-
// Superadmin Menu
27-
$superAdminMenu = [
28-
[
29-
'label' => 'Dashboard',
30-
'icon' => 'fa fa-map',
31-
'url' => route('cms.dashboard'),
32-
'active' => ['cms.dashboard'],
33-
],
34-
[
35-
'label' => 'Managements',
36-
'icon' => 'fa fa-cogs',
37-
'url' => '#',
38-
'active' => ['cms.management'],
39-
'children' => [
40-
[
41-
'label' => 'Permission',
42-
'icon' => null,
43-
'url' => route('cms.management.permission'),
44-
'active' => ['cms.management.permission'],
45-
],
46-
[
47-
'label' => 'Role',
48-
'icon' => null,
49-
'url' => route('cms.management.role'),
50-
'active' => ['cms.management.role'],
51-
],
52-
[
53-
'label' => 'User',
54-
'icon' => null,
55-
'url' => route('cms.management.user'),
56-
'active' => ['cms.management.user'],
57-
]
58-
],
59-
],
60-
];
26+
// Echo route
27+
function echoRoute($url) {
28+
try {
29+
return route($url);
30+
} catch (\Exception $e) {
31+
return '#';
32+
}
33+
}
6134
6235
// Check user roles
6336
$listMenus = [];
6437
6538
// Superadmin menu
6639
if (auth()->user()->hasRole('superadmin')) {
67-
$listMenus = $superAdminMenu;
40+
$listMenus = \App\Models\Menu\Menu::query()
41+
->with('subMenu')
42+
->where('role_id', auth()->user()->roles->first()->id)
43+
->where('status', \App\Enums\CommonStatusEnum::ACTIVE)
44+
->orderBy('order', 'asc')
45+
->get();
6846
}
6947
@endphp
7048
<aside class="sidenav navbar navbar-vertical navbar-expand-xs border-radius-lg fixed-start ms-2 bg-white my-2"
@@ -86,35 +64,35 @@ function showDropdown($activeRoute = []) {
8664
@foreach ($listMenus as $key => $menu)
8765
<li class="nav-item">
8866
<a
89-
class="nav-link {{ menuActive($menu['active']) }}"
90-
@if(isset($menu['children']))
67+
class="nav-link {{ menuActive(explode(',', $menu->active_pattern)) }}"
68+
@if(count($menu->subMenu) > 0)
9169
data-bs-toggle="collapse"
9270
href="#pages{{ $key }}"
9371
class="nav-link text-dark"
9472
role="button"
9573
aria-expanded="true"
9674
@else
97-
href="{{ $menu['url'] }}"
75+
href="{{ echoRoute($menu->url) }}"
9876
@endif
9977
>
100-
<i class="{{ $menu['icon'] }} opacity-5 me-2"></i>
78+
<i class="{{ $menu->icon }} opacity-5 me-2"></i>
10179
<span class="nav-link-text ms-1">
102-
{{ $menu['label'] }}
80+
{{ $menu->name }}
10381
</span>
10482
</a>
10583
<!-- Children menu -->
106-
@if(isset($menu['children']))
107-
<div class="collapse {{ showDropdown($menu['active']) }}" id="pages{{ $key }}">
84+
@if(count($menu->subMenu) > 0)
85+
<div class="collapse {{ showDropdown(explode(',', $menu->active_pattern)) }}" id="pages{{ $key }}">
10886
<ul class="nav">
109-
@foreach ($menu['children'] as $child)
87+
@foreach ($menu->subMenu as $child)
11088
<li class="nav-item">
111-
<a class="nav-link {{ menuActive($child['active']) }}"
112-
href="{{ $child['url'] }}">
113-
@if($child['icon'])
114-
<i class="{{ $child['icon'] }} text-dark opacity-10 me-2"></i>
89+
<a class="nav-link {{ menuActive(explode(',', $child->active_pattern)) }}"
90+
href="{{ echoRoute($child->url) }}">
91+
@if($child->icon)
92+
<i class="{{ $child->icon }} text-dark opacity-10 me-2"></i>
11593
@endif
11694
<span class="sidenav-normal ms-1 ps-1">
117-
{{ $child['label'] }}
95+
{{ $child->name }}
11896
</span>
11997
</a>
12098
</li>
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?php
2+
3+
use App\Enums\CommonStatusEnum;
4+
use App\Livewire\BaseComponent;
5+
use App\Models\Spatie\Role;
6+
use App\Models\Menu\Menu;
7+
8+
new class extends BaseComponent {
9+
public string $title = 'Create Menu';
10+
public string $description = 'Create a new menu for the system.';
11+
public string $modelInstance = Menu::class;
12+
13+
public function mount() {
14+
$this->canDo('create.' . $this->modelInstance);
15+
16+
// Get roles
17+
$this->roles = Role::all();
18+
}
19+
20+
// Define roles for the menu creation
21+
public $roles = [];
22+
23+
// Properties for menu creation
24+
public string $role_id;
25+
public string $name;
26+
public string $url;
27+
public string $icon;
28+
public int $order = 1;
29+
public string $active_pattern;
30+
public int $status = 1;
31+
32+
public function save() {
33+
$this->validate([
34+
'role_id' => 'required|exists:roles,id',
35+
'name' => 'required|string|max:255',
36+
'url' => 'nullable|string|max:255',
37+
'icon' => 'nullable|string|max:255',
38+
'order' => 'nullable|integer',
39+
'active_pattern' => 'nullable|string|max:255',
40+
'status' => 'required|in:' . implode(',', CommonStatusEnum::toArray()),
41+
]);
42+
43+
// Create a new menu with the validated name
44+
Menu::create($this->all());
45+
46+
// Redirect to the menu index page after creation
47+
to_route('cms.management.menu')->with('success', 'Menu created successfully.');
48+
}
49+
}; ?>
50+
51+
<div>
52+
<x-acc-back url="{{ route('cms.management.menu') }}" />
53+
<div class="row">
54+
<div class="col-12">
55+
<div class="card my-3">
56+
<div class="card-header">
57+
<div class="d-lg-flex">
58+
<div>
59+
<h5 class="mb-0">
60+
{{ $title }}
61+
</h5>
62+
<p class="text-sm mb-0">
63+
{{ $description }}
64+
</p>
65+
</div>
66+
</div>
67+
</div>
68+
<div class="card-body pb-4">
69+
<form wire:submit.prevent="save">
70+
<div class="row">
71+
<div class="col-md-12 mb-3">
72+
<label class="form-label fw-bold">
73+
Role
74+
</label>
75+
<x-acc-input type="select" model="role_id">
76+
<option value="">-- Select Role --</option>
77+
@foreach ($roles as $role)
78+
<option value="{{ $role->id }}">{{ $role->name }}</option>
79+
@endforeach
80+
</x-acc-input>
81+
</div>
82+
<div class="col-md-6 mb-3">
83+
<x-acc-input model="name" label="Name" />
84+
</div>
85+
<div class="col-md-6 mb-3">
86+
<x-acc-input model="url" label="URL" />
87+
</div>
88+
<div class="col-md-6 mb-3">
89+
<x-acc-input model="icon" label="Icon" />
90+
</div>
91+
<div class="col-md-6 mb-3">
92+
<x-acc-input type="number" model="order" label="Order" :filled="true" />
93+
</div>
94+
<div class="col-md-6 mb-3">
95+
<x-acc-input model="active_pattern" label="Active Pattern" />
96+
</div>
97+
<div class="col-md-12 mb-3">
98+
<label class="form-label fw-bold">
99+
Status
100+
</label>
101+
<x-acc-input type="select" model="status">
102+
<option value="">-- Select Status --</option>
103+
@foreach (CommonStatusEnum::cases() as $status)
104+
<option value="{{ $status->value }}">{{ $status->label() }}</option>
105+
@endforeach
106+
</x-acc-input>
107+
</div>
108+
</div>
109+
<div class="float-start">
110+
<button type="submit" class="btn btn-primary btn-sm">
111+
<i class="fas fa-save me-2"></i>
112+
Save
113+
</button>
114+
<a href="{{ route('cms.management.menu') }}" class="btn bg-gradient-dark btn-sm me-2">
115+
<i class="fas fa-arrow-left me-2"></i>
116+
Cancel
117+
</a>
118+
</div>
119+
</form>
120+
</div>
121+
</div>
122+
</div>
123+
</div>
124+
</div>

0 commit comments

Comments
 (0)