Supra_App/src/lib/components/app-sidebar.svelte

183 lines
3.8 KiB
Svelte

<script lang="ts">
import * as Sidebar from '$lib/components/ui/sidebar/index';
import { onDestroy, type ComponentProps } from 'svelte';
import { asset } from '$app/paths';
import AppAccountSelect from './app-account-select.svelte';
import {
Code,
LayoutDashboard,
LucideEye,
CherryIcon,
DiamondIcon,
BugIcon,
CupSodaIcon,
Shield
} from '@lucide/svelte/icons';
import TaobinLogo from '$lib/assets/logo.svelte';
import { goto } from '$app/navigation';
import Button from '$lib/components/ui/button/button.svelte';
import { sidebarStore } from '$lib/core/stores/sidebar';
import { auth } from '$lib/core/stores/auth';
import { isUserAdmin } from '$lib/core/admin/adminService';
let sideBar: HTMLElement | null = $state(null);
let isSideBarOpen: boolean = $state(true);
let isAdmin: boolean = $state(false);
const data = {
navMain: [
{
title: 'Home',
items: [
{
title: 'Dashboard',
url: '/dashboard',
icon: LayoutDashboard
}
]
},
{
title: 'Recipe',
items: [
{
title: 'Overview',
url: '/recipe/overview',
icon: LucideEye
},
{
title: 'Topping',
url: '/recipe/topping',
icon: CherryIcon
},
{
title: 'Material',
url: '/recipe/material',
icon: DiamondIcon
}
]
},
{
title: 'Tools',
items: [
{
title: 'Brew',
url: '/tools/brew',
icon: CupSodaIcon
},
{
title: 'Debug',
url: '/tools/debug',
icon: BugIcon
}
]
}
]
};
const adminNav = {
title: 'Admin',
items: [
{
title: 'Permissions',
url: '/admin/users',
icon: Shield
}
]
};
$effect(() => {
const currentUser = $auth;
if (currentUser) {
isUserAdmin(currentUser.uid)
.then((result) => {
isAdmin = result;
})
.catch((e) => {
console.error('Error checking admin status:', e);
isAdmin = false;
});
} else {
isAdmin = false;
}
});
function onClickLogoIcon() {
goto('/departments');
}
let unsubSidebar = sidebarStore.subscribe((state) => {
isSideBarOpen = state;
});
onDestroy(() => {
unsubSidebar();
});
let {
ref = sideBar,
collapsible = 'icon',
...restProps
}: ComponentProps<typeof Sidebar.Root> = $props();
</script>
<Sidebar.Root {collapsible} {...restProps}>
<Sidebar.Header>
<div class="flex items-center justify-center">
<button class="hover:cursor-pointer" onclick={onClickLogoIcon}>
<TaobinLogo size={isSideBarOpen ? 96 : 24} fillColor={'#FFFFFF'} />
</button>
</div>
</Sidebar.Header>
<Sidebar.Content>
{#each data.navMain as nav}
<Sidebar.Group>
<Sidebar.GroupLabel>{nav.title}</Sidebar.GroupLabel>
<Sidebar.GroupContent>
<Sidebar.Menu>
{#each nav.items as sub}
<Sidebar.MenuItem>
<Sidebar.MenuButton>
{#snippet child({ props })}
<a href={sub.url} {...props}>
{#if sub.icon}
<sub.icon />
{/if}
<span>{sub.title}</span>
</a>
{/snippet}
</Sidebar.MenuButton>
</Sidebar.MenuItem>
{/each}
</Sidebar.Menu>
</Sidebar.GroupContent>
</Sidebar.Group>
{/each}
{#if isAdmin}
<Sidebar.Group>
<Sidebar.GroupLabel>{adminNav.title}</Sidebar.GroupLabel>
<Sidebar.GroupContent>
<Sidebar.Menu>
{#each adminNav.items as sub}
<Sidebar.MenuItem>
<Sidebar.MenuButton>
{#snippet child({ props })}
<a href={sub.url} {...props}>
{#if sub.icon}
<sub.icon />
{/if}
<span>{sub.title}</span>
</a>
{/snippet}
</Sidebar.MenuButton>
</Sidebar.MenuItem>
{/each}
</Sidebar.Menu>
</Sidebar.GroupContent>
</Sidebar.Group>
{/if}
</Sidebar.Content>
<Sidebar.Footer>
<AppAccountSelect />
</Sidebar.Footer>
</Sidebar.Root>