feat: Tambahkan fitur pengecekan izin pengguna
parent
9579f140eb
commit
a61eb18e42
|
@ -5,11 +5,24 @@ namespace App\Http\Controllers\Admin;
|
|||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\RoleRequest;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Inertia\Inertia;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
class RoleController extends Controller
|
||||
{
|
||||
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
try {
|
||||
$kategori = Role::latest()->get();
|
||||
return Inertia::render('admin/kategori/index_kategori', ['kategori' => $kategori]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error fetching Kategori: ' . $e->getMessage());
|
||||
return back()->with('error', 'Something went wrong.');
|
||||
}
|
||||
}
|
||||
public function index()
|
||||
{
|
||||
$roles = Role::with('permissions')
|
||||
|
@ -17,7 +30,7 @@ class RoleController extends Controller
|
|||
->paginate(10);
|
||||
|
||||
// Kembalikan data ke komponen Inertia 'Admin/Roles/Index'
|
||||
return inertia('Admin/Roles/Index', compact('roles'));
|
||||
return Inertia::render('admin/roles/index_roles', compact('roles'));
|
||||
}
|
||||
public function create()
|
||||
{
|
||||
|
@ -25,7 +38,7 @@ class RoleController extends Controller
|
|||
$permissions = Permission::all();
|
||||
|
||||
// Kembalikan ke Inertia 'Admin/Roles/Create' dengan data permissions
|
||||
return inertia('Admin/Roles/Create', [
|
||||
return Inertia::render('admin/roles/create_roles', [
|
||||
'permissions' => $permissions,
|
||||
]);
|
||||
}
|
||||
|
@ -66,7 +79,7 @@ class RoleController extends Controller
|
|||
});
|
||||
|
||||
// Kembalikan data ke Inertia 'Admin/Roles/Edit' dengan data role, permissions, dan rolePermissions
|
||||
return inertia('Admin/Roles/Edit', [
|
||||
return Inertia::render('admin/roles/edit_roles', [
|
||||
'permissions' => $permissions,
|
||||
'role' => $role,
|
||||
'rolePermissions' => $rolePermissions,
|
||||
|
|
|
@ -15,17 +15,82 @@ class PermissionsTableSeeder extends Seeder
|
|||
{
|
||||
|
||||
$resources = [
|
||||
'users' => ['index', 'create', 'edit', 'delete'],
|
||||
'roles' => ['index', 'create', 'edit', 'delete'],
|
||||
'kategori' => ['index', 'create', 'edit', 'delete'],
|
||||
'subkategori' => ['index', 'create', 'edit', 'delete'],
|
||||
'Dashboard' => [
|
||||
'index' => 'Lihat Dashboard',
|
||||
],
|
||||
'Pelaporan' => [
|
||||
'index' => 'Melihat Daftar Pelaporan',
|
||||
],
|
||||
'Verifikasi' => [
|
||||
'index' => 'Mengakses Verifikasi Pelaporan',
|
||||
],
|
||||
'Hukum' => [
|
||||
'index' => 'Melihat Data Penegakan Hukum',
|
||||
],
|
||||
'Perizinan' => [
|
||||
'index' => 'Melihat Data Perizinan Lingkungan',
|
||||
],
|
||||
'History' => [
|
||||
'index' => 'Melihat History Perusahaan',
|
||||
],
|
||||
'Post' => [
|
||||
'index' => 'Mengakses Data Postingan',
|
||||
],
|
||||
'Kategori' => [
|
||||
'index' => 'Melihat Kategori Post',
|
||||
],
|
||||
'SubKategori' => [
|
||||
'index' => 'Melihat Sub Kategori Post',
|
||||
],
|
||||
'Verifikator' => [
|
||||
'index' => 'Mengakses Data Dinas LH / Verifikator',
|
||||
],
|
||||
'JenisKegiatan' => [
|
||||
'index' => 'Melihat Daftar Jenis Kegiatan',
|
||||
],
|
||||
'JenisDokil' => [
|
||||
'index' => 'Melihat Daftar Jenis Dokumen Izin',
|
||||
],
|
||||
'Perusahaan' => [
|
||||
'index' => 'Mengakses Data Perusahaan',
|
||||
],
|
||||
'HistoryKegiatan' => [
|
||||
'index' => 'Melihat History Kegiatan',
|
||||
],
|
||||
'JenisSanksi' => [
|
||||
'index' => 'Melihat Jenis Sanksi',
|
||||
],
|
||||
'Penaatan' => [
|
||||
'index' => 'Melihat Status Penaatan',
|
||||
],
|
||||
'Pengguna' => [
|
||||
'index' => 'Melihat Daftar Pengguna',
|
||||
],
|
||||
'Role' => [
|
||||
'index' => 'Melihat Kelompok Pengguna',
|
||||
],
|
||||
'Tentang' => [
|
||||
'index' => 'Melihat Informasi Tentang Aplikasi',
|
||||
],
|
||||
'Catatan' => [
|
||||
'index' => 'Melihat Catatan Sistem',
|
||||
],
|
||||
'Backup' => [
|
||||
'index' => 'Mengakses Fitur Backup Data',
|
||||
],
|
||||
'Restore' => [
|
||||
'index' => 'Mengakses Fitur Restore Data',
|
||||
],
|
||||
];
|
||||
foreach ($resources as $resource => $actions) {
|
||||
foreach ($actions as $action) {
|
||||
foreach ($actions as $action => $description) {
|
||||
$permissionName = "{$resource}.{$action}";
|
||||
|
||||
Permission::firstOrCreate(['name' => $permissionName, 'guard_name' => 'web']);
|
||||
Permission::updateOrCreate(
|
||||
['name' => $permissionName, 'guard_name' => 'web'],
|
||||
['description' => $description]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,23 @@ class RolesTableSeeder extends Seeder
|
|||
public function run(): void
|
||||
{
|
||||
$admin = Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']);
|
||||
$user = Role::firstOrCreate(['name' => 'user', 'guard_name' => 'web']);
|
||||
// $user = Role::firstOrCreate(['name' => 'user', 'guard_name' => 'web']);
|
||||
|
||||
// Assign permissions ke role
|
||||
// // Assign permissions ke role
|
||||
$admin->syncPermissions(Permission::all()); // Admin mendapatkan semua akses
|
||||
|
||||
// Assign role `admin` ke user
|
||||
$user->assignRole($admin);
|
||||
// // Assign role `admin` ke user
|
||||
// $user->assignRole($admin);
|
||||
|
||||
Role::firstOrCreate(['name' => 'Admin']);
|
||||
Role::firstOrCreate(['name' => 'Verifikator']);
|
||||
Role::firstOrCreate(['name' => 'Perusahaan']);
|
||||
Role::firstOrCreate(['name' => 'Admin Suku Dinas LH']);
|
||||
Role::firstOrCreate(['name' => 'Pedal']);
|
||||
Role::firstOrCreate(['name' => 'Admin Bidang']);
|
||||
Role::firstOrCreate(['name' => 'Admin PPU']);
|
||||
Role::firstOrCreate(['name' => 'Kajian Dampak Lingkungan']);
|
||||
Role::firstOrCreate(['name' => 'Instansi Umum']);
|
||||
Role::firstOrCreate(['name' => 'Gakkum']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import {
|
|||
} from "@/components/ui/sidebar";
|
||||
import { Link, usePage } from "@inertiajs/react";
|
||||
import { PageProps } from "@/types";
|
||||
import hasAnyPermission from "@/utils/hasAnyPermission";
|
||||
|
||||
const data = {
|
||||
user: {
|
||||
|
@ -47,36 +48,43 @@ const data = {
|
|||
{
|
||||
title: "Dashboard",
|
||||
url: "/dashboard",
|
||||
permissions: ["Dashboard.index"],
|
||||
icon: Home,
|
||||
},
|
||||
{
|
||||
title: "Pelaporan",
|
||||
url: "/admin/pelaporan",
|
||||
permissions: ["Pelaporan.index"],
|
||||
icon: BookMarked,
|
||||
},
|
||||
{
|
||||
title: "Verifikasi Pelaporan",
|
||||
url: "/admin/verifikasi",
|
||||
permissions: ["Verifikasi.index"],
|
||||
icon: BookCheck,
|
||||
},
|
||||
{
|
||||
title: "Penegakan Hukum",
|
||||
url: "/admin/hukum",
|
||||
permissions: ["Hukum.index"],
|
||||
icon: Scale,
|
||||
},
|
||||
{
|
||||
title: "Perizinan Lingkungan",
|
||||
url: "/admin/perizinan-lingkungan",
|
||||
url: "/admin/perizinan_lingkungan",
|
||||
permissions: ["Perizinan.index"],
|
||||
icon: FileKey2,
|
||||
},
|
||||
{
|
||||
title: "History Perusahaan",
|
||||
url: "/admin/history-perusahaan",
|
||||
url: "/admin/history_perusahaan",
|
||||
permissions: ["History.index"],
|
||||
icon: GalleryVertical,
|
||||
},
|
||||
{
|
||||
title: "Post",
|
||||
url: "/admin/post",
|
||||
permissions: ["Post.index"],
|
||||
icon: Frame,
|
||||
},
|
||||
{
|
||||
|
@ -116,38 +124,47 @@ const data = {
|
|||
{
|
||||
title: "Kategori Post",
|
||||
url: "/admin/kategori",
|
||||
permissions: ["Kategori.index"],
|
||||
},
|
||||
{
|
||||
title: "Sub Kategori Post",
|
||||
url: "/admin/subkategori",
|
||||
permissions: ["SubKategori.index"],
|
||||
},
|
||||
{
|
||||
title: "Dinas LH",
|
||||
url: "/admin/verifikator",
|
||||
permissions: ["Verifikator.index"],
|
||||
},
|
||||
{
|
||||
title: "Jenis Kegiatan",
|
||||
url: "/admin/jeniskegiatan",
|
||||
permissions: ["JenisKegiatan.index"],
|
||||
},
|
||||
{
|
||||
title: "Jenis Dokumen Izin",
|
||||
url: "/admin/jenisdokil",
|
||||
permissions: ["JenisDokil.index"],
|
||||
},
|
||||
{
|
||||
title: "Perusahaan",
|
||||
title: "Data Perusahaan",
|
||||
url: "/admin/perusahaan",
|
||||
permissions: ["Perusahaan.index"],
|
||||
},
|
||||
{
|
||||
title: "History Kegiatan",
|
||||
url: "/admin/historykegiatan",
|
||||
permissions: ["HistoryKegiatan.index"],
|
||||
},
|
||||
{
|
||||
title: "Jenis Sanksi",
|
||||
url: "/admin/jenissanksi",
|
||||
permissions: ["JenisSanksi.index"],
|
||||
},
|
||||
{
|
||||
title: "Status Penaatan",
|
||||
url: "/admin/penaatan",
|
||||
permissions: ["Penaatan.index"],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -160,10 +177,12 @@ const data = {
|
|||
{
|
||||
title: "Pengguna",
|
||||
url: "/admin/pengguna",
|
||||
permissions: ["Pengguna.index"],
|
||||
},
|
||||
{
|
||||
title: "Role",
|
||||
url: "/admin/role",
|
||||
title: "Kelompok Pengguna",
|
||||
url: "/admin/roles",
|
||||
permissions: ["Role.index"],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -173,27 +192,71 @@ const data = {
|
|||
title: "Tentang",
|
||||
url: "/admin/tentang",
|
||||
icon: LifeBuoy,
|
||||
permissions: ["Tentang.index"],
|
||||
},
|
||||
{
|
||||
title: "Catatan Sistem",
|
||||
url: "#",
|
||||
icon: NotepadText,
|
||||
permissions: ["Catatan.index"],
|
||||
},
|
||||
{
|
||||
title: "Backup",
|
||||
url: "#",
|
||||
icon: Archive,
|
||||
permissions: ["Backup.index"],
|
||||
},
|
||||
{
|
||||
title: "Restore",
|
||||
url: "#",
|
||||
icon: DatabaseBackup,
|
||||
permissions: ["Restore.index"],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
const { auth } = usePage<PageProps>().props;
|
||||
const userPermissions = auth?.user?.permissions ?? [];
|
||||
|
||||
const filterMenu = (menu) => {
|
||||
return menu
|
||||
.map((item) => {
|
||||
if (item.items) {
|
||||
const filteredItems = item.items.filter((subItem) =>
|
||||
subItem.permissions
|
||||
? hasAnyPermission(
|
||||
Array.isArray(subItem.permissions)
|
||||
? subItem.permissions
|
||||
: Object.keys(subItem.permissions) // Pastikan selalu array
|
||||
)
|
||||
: true
|
||||
);
|
||||
|
||||
if (filteredItems.length > 0) {
|
||||
return { ...item, items: filteredItems };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (item.permissions) {
|
||||
// **PERBAIKAN UTAMA**: Pastikan item.permissions selalu dalam bentuk array
|
||||
const permissionsArray = Array.isArray(item.permissions)
|
||||
? item.permissions
|
||||
: Object.keys(item.permissions);
|
||||
|
||||
const hasPermission = hasAnyPermission(permissionsArray);
|
||||
|
||||
return hasPermission ? item : null;
|
||||
}
|
||||
|
||||
return item;
|
||||
})
|
||||
.filter(Boolean);
|
||||
};
|
||||
|
||||
const navMain = filterMenu(data.navMain);
|
||||
const navSecondary = filterMenu(data.navSecondary);
|
||||
|
||||
return (
|
||||
<Sidebar variant="inset" {...props}>
|
||||
|
@ -201,6 +264,7 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
|||
<SidebarMenu>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton size="lg" asChild>
|
||||
{/* {hasAnyPermission(["Dashboard.index"]) && ( */}
|
||||
<Link href={route("dashboard")}>
|
||||
<div className="flex aspect-square size-8 items-center justify-center rounded-lg text-sidebar-primary-foreground">
|
||||
{/* <Command className="size-4" /> */}
|
||||
|
@ -219,13 +283,14 @@ export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
|||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
{/* )} */}
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
</SidebarHeader>
|
||||
<SidebarContent>
|
||||
<NavMain items={data.navMain} />
|
||||
<NavSecondary items={data.navSecondary} className="mt-auto" />
|
||||
<NavMain items={navMain} />
|
||||
<NavSecondary items={navSecondary} className="mt-auto" />
|
||||
</SidebarContent>
|
||||
<SidebarFooter>
|
||||
<NavUser user={auth.user} />
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
SidebarMenuSubItem,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { Link } from "@inertiajs/react";
|
||||
import hasAnyPermission from "@/utils/hasAnyPermission";
|
||||
|
||||
export function NavMain({
|
||||
items,
|
||||
|
@ -28,6 +29,7 @@ export function NavMain({
|
|||
url: string;
|
||||
icon: LucideIcon;
|
||||
isActive?: boolean;
|
||||
permissions?: string[];
|
||||
items?: {
|
||||
title: string;
|
||||
url: string;
|
||||
|
@ -46,10 +48,19 @@ export function NavMain({
|
|||
>
|
||||
<SidebarMenuItem>
|
||||
<SidebarMenuButton asChild tooltip={item.title}>
|
||||
{item.permissions ? (
|
||||
hasAnyPermission(item.permissions) ? (
|
||||
<Link href={item.url}>
|
||||
<item.icon />
|
||||
<div>{item.title}</div>
|
||||
</Link>
|
||||
) : null
|
||||
) : (
|
||||
<Link href={item.url}>
|
||||
<item.icon />
|
||||
<div>{item.title}</div>
|
||||
</Link>
|
||||
)}
|
||||
</SidebarMenuButton>
|
||||
{item.items?.length ? (
|
||||
<>
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
SidebarMenuItem,
|
||||
} from "@/components/ui/sidebar";
|
||||
import { Link } from "@inertiajs/react";
|
||||
import hasAnyPermission from "@/utils/hasAnyPermission";
|
||||
|
||||
export function NavSecondary({
|
||||
items,
|
||||
|
@ -18,6 +19,7 @@ export function NavSecondary({
|
|||
title: string;
|
||||
url: string;
|
||||
icon: LucideIcon;
|
||||
permissions?: string[];
|
||||
}[];
|
||||
} & React.ComponentPropsWithoutRef<typeof SidebarGroup>) {
|
||||
return (
|
||||
|
@ -27,10 +29,19 @@ export function NavSecondary({
|
|||
{items.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<SidebarMenuButton asChild size="sm">
|
||||
{item.permissions ? (
|
||||
hasAnyPermission(item.permissions) ? (
|
||||
<Link href={item.url}>
|
||||
<item.icon />
|
||||
<span>{item.title}</span>
|
||||
<div>{item.title}</div>
|
||||
</Link>
|
||||
) : null
|
||||
) : (
|
||||
<Link href={item.url}>
|
||||
<item.icon />
|
||||
<div>{item.title}</div>
|
||||
</Link>
|
||||
)}
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import { usePage } from "@inertiajs/react";
|
||||
export default function hasAnyPermission(permissions = []) {
|
||||
const { auth } = usePage().props;
|
||||
const allPermissions = auth?.user?.permissions ?? {};
|
||||
|
||||
if (typeof allPermissions !== "object" || allPermissions === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Array.isArray(permissions) || permissions.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const result = permissions.some(
|
||||
(permission) => allPermissions?.[permission] === true
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
Loading…
Reference in New Issue