penambahan fungsi role dan mapping role serta logout

This commit is contained in:
AJISETIAJI
2025-06-03 23:13:36 +07:00
parent f13b728f81
commit 839b676ccf
6 changed files with 728 additions and 57 deletions

View File

@@ -1,8 +1,8 @@
<script lang="ts">
import { goto } from "$app/navigation";
import { onMount } from "svelte";
import { supabase } from "$lib/supabaseClient";
// get local storage user
let user: any = null;
onMount(() => {
const userStr = localStorage.getItem("user");
@@ -27,6 +27,7 @@
name: string;
icon: string;
url: string;
roles?: string[];
};
type MenuItem = {
@@ -34,76 +35,149 @@
icon: string;
url: string;
sub?: SubMenuItem[];
roles?: string[]; // <- tambahkan ini
roles?: string[];
};
// Contoh role yang sedang aktif (bisa dari Supabase atau session)
let userRole: "admin" | "user" | "guest" = "user";
let userRole:
| "it"
| "guest"
| "accounting"
| "ga"
| "hr"
| "s&m"
| "office"
| "hm"
| "vm" = "it";
// Semua menu
const fullMenu: MenuItem[] = [
{
name: "Beranda",
icon: "🏠",
url: "/",
roles: ["admin", "user", "guest"],
roles: [
"it",
"guest",
"accounting",
"ga",
"hr",
"s&m",
"office",
"hm",
"vm",
],
},
{
name: "Profile",
icon: "🧑",
url: "/profile",
roles: ["admin", "user"],
roles: ["it", "ga", "hr", "s&m", "office", "hm", "vm"],
},
{
name: "Issues",
icon: "📂",
url: "/backoffice/issue",
roles: ["admin", "user"],
roles: ["it", "ga", "office", "hm", "vm", "accounting"],
},
{
name: "Projects",
icon: "📂",
url: "/backoffice/project",
roles: ["admin"],
roles: ["it", "ga", "office", "hm", "vm", "accounting"],
},
{
name: "Purchase Orders",
icon: "📦",
url: "/backoffice/purchaseorder",
roles: ["admin", "user"],
roles: ["it", "guest", "accounting", "ga", "office", "hm", "vm"],
sub: [
{
name: "Approval",
icon: "✅",
url: "/backoffice/purchaseorder/approval",
roles: ["it", "user", "ga", "office", "hm", "vm"],
},
{
name: "Acknowledged",
icon: "📋",
url: "/backoffice/purchaseorder/acknowledged",
roles: ["it", "user", "ga", "office", "hm", "vm"],
},
{
name: "Complete",
icon: "✔️",
url: "/backoffice/purchaseorder/complete",
roles: [
"it",
"user",
"accounting",
"ga",
"office",
"hm",
"vm",
],
},
{
name: "Received",
icon: "📥",
url: "/backoffice/purchaseorder/received",
roles: [
"it",
"user",
"accounting",
"ga",
"office",
"hm",
"vm",
],
},
],
},
{
name: "Timesheets",
icon: "⏰",
url: "/backoffice/timesheets",
roles: ["it", "ga", "hr", "office", "hm", "vm"],
},
{
name: "Vendors",
icon: "🏢",
url: "/backoffice/vendor",
roles: ["it", "ga", "office", "hm", "vm"],
},
{
name: "Inventory",
icon: "📋",
url: "/backoffice/inventory",
roles: ["it", "ga", "s&m", "office", "hm", "vm"],
},
{
name: "Villa",
icon: "🏡",
url: "/backoffice/villa",
roles: ["it", "ga", "s&m", "office", "hm", "vm"],
},
{
name: "Users",
icon: "👤",
url: "/backoffice/account",
roles: ["admin"],
roles: ["it", "ga", "office", "hm", "vm"],
},
{
name: "Logout",
icon: "🚪",
url: "/logout",
roles: ["admin", "user", "guest"],
roles: [
"it",
"guest",
"accounting",
"ga",
"hr",
"s&m",
"office",
"hm",
"vm",
],
},
];
@@ -115,14 +189,18 @@
});
function handleMenuClick(item: MenuItem) {
console.log(`Menu item clicked: ${item.name}`);
console.log(`URL: ${item.url}`);
if (item.sub) {
goto(item.url);
activeUrl = item.url;
openMenus[item.name] = !openMenus[item.name];
} else {
if (item.url === "/logout") {
if (confirm("Are you sure you want to logout?")) {
logout();
}
return;
}
activeUrl = item.url;
goto(item.url);
}
@@ -132,6 +210,34 @@
activeUrl = sub.url;
goto(sub.url);
}
// Filter menu dan submenu sesuai role
$: filteredMenu = fullMenu
.filter((item) => !item.roles || item.roles.includes(userRole))
.map((item) => ({
...item,
sub: item.sub
? item.sub.filter(
(sub) => !sub.roles || sub.roles.includes(userRole),
)
: undefined,
}));
// logout
async function logout() {
const { error } = await supabase.auth.signOut();
if (error) {
console.error("Logout failed:", error.message);
} else {
localStorage.removeItem("user");
goto("/login");
}
}
// Handle logout click
function handleLogoutClick() {
logout();
}
</script>
<div class="w-64 h-screen bg-white border-r shadow-sm">
@@ -140,7 +246,7 @@
<p class="text-sm text-gray-500">Manage your application</p>
</div>
<ul class="p-2 space-y-1">
{#each fullMenu as item}
{#each filteredMenu as item}
<li>
<a
href={item.url}
@@ -154,11 +260,11 @@
<span class="text-xl">{item.icon}</span>
<span class="truncate">{item.name}</span>
</span>
{#if item.sub}
{#if item.sub && item.sub.length}
<span>{openMenus[item.name] ? "▲" : "▼"}</span>
{/if}
</a>
{#if item.sub && openMenus[item.name]}
{#if item.sub && openMenus[item.name] && item.sub.length}
<ul class="ml-8 mt-1 space-y-1">
{#each item.sub as sub}
<li>