Skip to content

Commit

Permalink
chore: 使用新布局
Browse files Browse the repository at this point in the history
  • Loading branch information
BrendanEichDisciple committed Sep 12, 2024
1 parent ce9ceac commit 1693475
Show file tree
Hide file tree
Showing 9 changed files with 973 additions and 62 deletions.
815 changes: 766 additions & 49 deletions src/app.css

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions src/lib/components/layout/Navbar.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<script>
import { Input } from '$lib/components/ui/input/index.js';
import { Search, Bell, Mail, AlignJustify } from 'lucide-svelte';
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import NavAvatar from '../NavAvatar.svelte';
import { sidebarOpen } from '../../../stores/sidebarStore';
</script>

<header class="fixed left-0 right-0 top-0 z-50 flex border-border/40 bg-background/95 pr-4 md:pr-8 print:hidden">
<a class="flex-1 content-center px-4 text-center text-2xl no-underline md:block md:w-60 md:flex-shrink-0 md:flex-grow-0 md:basis-auto" href="/">Vue</a>
<a class="-order-1 content-center px-4 text-white transition-all md:order-none" href="#" data-toggle="sidebar" aria-label="Hide Sidebar" on:click={() => sidebarOpen.update((n) => !n)}>
<AlignJustify />
</a>
<ul class="app-nav">
<li class="app-search">
<Input type="search" placeholder="search..." />
<Search />
</li>
<li class="dropdown">
<DropdownMenu.Root>
<DropdownMenu.Trigger><Bell /></DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Group>
<DropdownMenu.Label>You have 4 new notifications.</DropdownMenu.Label>
<DropdownMenu.Separator />
<DropdownMenu.Item>
<Mail class="mr-2 h-4 w-4" />
<span>Lisa sent you a mail</span>
</DropdownMenu.Item>
</DropdownMenu.Group>
<DropdownMenu.Separator />
<DropdownMenu.Label>You have 4 new notifications.</DropdownMenu.Label>
</DropdownMenu.Content>
</DropdownMenu.Root>
</li>
<li class="dropdown">
<NavAvatar></NavAvatar>
</li>
</ul>
</header>
109 changes: 109 additions & 0 deletions src/lib/components/layout/Sidebar.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<script>
import { page } from '$app/stores';
import { onMount } from 'svelte';
import { sidebarOpen } from '../../../stores/sidebarStore';
// Fungsi untuk memeriksa apakah suatu elemen menu aktif
$: isActive = (/** @type {any} */ item) => {
const currentPath = $page.url.pathname;
return item.link === currentPath || (item.submenu && item.submenu.some((/** @type {{ link: string; }} */ subitem) => subitem.link === currentPath));
};
const dataMenu = [
{
label: 'Dashboard',
icon: 'bi bi-speedometer',
link: '/dashboard'
},
{
label: 'UI Elements',
icon: 'bi bi-laptop',
submenu: [
{
label: 'Bootstrap Elements',
icon: 'bi bi-circle-fill',
link: '/bootstrap-components'
},
{
label: 'Font Icons',
icon: 'bi bi-circle-fill',
link: 'https://icons.getbootstrap.com/',
target: '_blank',
rel: 'noopener'
},
{
label: 'Cards',
icon: 'bi bi-circle-fill',
link: '/cards'
},
{
label: 'Widgets',
icon: 'bi bi-circle-fill',
link: '/widgets'
}
]
},
{
label: 'Docs',
icon: 'bi bi-code-square',
link: '/docs'
}
];
onMount(async () => {
// Activate sidebar treeview toggle
const treeviewToggleElements = document.querySelectorAll("[data-toggle='treeview']");
treeviewToggleElements.forEach(function (element) {
element.addEventListener('click', function (event) {
event.preventDefault();
const parentElement = element.parentElement;
// @ts-ignore
if (!parentElement.classList.contains('is-expanded')) {
// @ts-ignore
var allTreeViewElements = treeviewMenu.querySelectorAll("[data-toggle='treeview']");
allTreeViewElements.forEach(function (treeviewElement) {
// @ts-ignore
treeviewElement.parentElement.classList.remove('is-expanded');
});
}
// @ts-ignore
parentElement.classList.toggle('is-expanded');
});
});
});
</script>

<div class="app-sidebar__overlay" data-toggle="sidebar"></div>
<aside class="fixed bottom-0 left-0 top-0 z-10 w-60 border-border/40 bg-background/95 pt-20 shadow transition-all" class:'w-4'={$sidebarOpen ? 'translate-x-0' : '-translate-x-full'}>
<!-- svelte-ignore a11y-invalid-attribute -->
<ul class="app-menu">
{#each dataMenu as item (item.label)}
{#if item.submenu}
<div class={isActive(item) ? 'treeview is-expanded' : 'treeview'}>
<a class="app-menu__item" href="#" data-toggle="treeview">
<i class="app-menu__icon {item.icon}"></i>
<span class="app-menu__label">{item.label}</span>
<i class="treeview-indicator bi bi-chevron-right"></i>
</a>
<ul class="treeview-menu">
{#each item.submenu as subitem (subitem.label)}
<li>
<a class={isActive(subitem) ? 'treeview-item active' : 'treeview-item'} href={subitem.link} target={subitem.target} rel={subitem.rel}>
<i class="icon {subitem.icon}"></i>
{subitem.label}
</a>
</li>
{/each}
</ul>
</div>
{:else}
<a class={isActive(item) ? 'app-menu__item active' : 'app-menu__item'} href={item.link}>
<i class="app-menu__icon {item.icon}"></i>
<span class="app-menu__label">{item.label}</span>
</a>
{/if}
{/each}
</ul>
</aside>
13 changes: 13 additions & 0 deletions src/lib/components/layout/Transition.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script>
import { cubicInOut } from 'svelte/easing';
import { fade } from 'svelte/transition';
export let key = '';
export let duration = 300;
</script>

{#key key}
<div in:fade={{ easing: cubicInOut, duration, delay: duration }} out:fade={{ easing: cubicInOut, duration }}>
<slot />
</div>
{/key}
21 changes: 21 additions & 0 deletions src/lib/components/layout/app-title.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script>
import { page } from '$app/stores';
export let title = '';
export let desc = '';
export let iconTitle = '';
const url = $page.url.pathname;
</script>

<div>
<div>
<h1></h1>
<p>{desc}</p>
</div>
<ul>
<li>
<a href={url}>{title}</a>
</li>
</ul>
</div>
5 changes: 5 additions & 0 deletions src/routes/(admin)/+layout.server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @type {import('./$types').LayoutServerLoad} */
export async function load({ url }) {
const pathname = url.pathname;
return { pathname };
}
22 changes: 13 additions & 9 deletions src/routes/(admin)/+layout.svelte
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
<script>
import { navigating } from '$app/stores';
import Nav from '$lib/components/Nav.svelte';
import PreloadingIndicator from '$lib/components/PreloadingIndicator.svelte';
import Navbar from '$lib/components/layout/Navbar.svelte';
import Sidebar from '$lib/components/layout/Sidebar.svelte';
import Transition from '$lib/components/layout/Transition.svelte';
export let data;
</script>

{#if $navigating}
<PreloadingIndicator />
{/if}

<Nav>
<svelte:fragment slot="brand">
<img src="https://www.gov.cn/images/gtrs_logo_lt.png" class="mr-3 h-6 sm:h-9" alt="Svelte Logo" />
<span class="self-center whitespace-nowrap text-xl font-semibold dark:text-white">医保</span>
</svelte:fragment>
</Nav>
<!-- Navbar -->
<Navbar />

<main class="container mx-auto py-10">
<slot />
<!-- Sidebar -->
<Sidebar />
<main>
<Transition key={data.pathname} duration={400}>
<slot />
</Transition>
</main>
6 changes: 2 additions & 4 deletions src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,5 @@
<PreloadingIndicator />
{/if}

<div class="max-h-dvh overflow-auto">
<ModeWatcher />
<slot />
</div>
<ModeWatcher />
<slot />
4 changes: 4 additions & 0 deletions src/stores/sidebarStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// src/stores/sidebarStore.js
import { writable } from 'svelte/store';

export const sidebarOpen = writable(false);

0 comments on commit 1693475

Please sign in to comment.