add project selector to sidebar

main
TZGyn 1 year ago
parent d21a80dc36
commit 01bc8be518
Signed by: TZGyn
GPG Key ID: 122EAF77AE81FD4A

@ -1,60 +0,0 @@
<script lang="ts">
import { page } from '$app/stores'
import { Button } from '$lib/components/ui/button'
import { cn } from '$lib/utils'
import { Blocks, Home, Link, Settings } from 'lucide-svelte'
let className: string | undefined = undefined
export { className as class }
const routes = [
{
href: '/dashboard',
name: 'Home',
match: (path: string) => path === '/dashboard',
icon: Home,
},
{
href: '/dashboard/links',
name: 'Links',
match: (path: string) => path.startsWith('/dashboard/links'),
icon: Link,
},
{
href: '/dashboard/projects',
name: 'Projects',
match: (path: string) => path.startsWith('/dashboard/projects'),
icon: Blocks,
},
{
href: '/dashboard/settings/account',
name: 'Settings',
match: (path: string) => path.startsWith('/dashboard/settings'),
icon: Settings,
},
] as const
</script>
<div
class={cn(
'flex h-full flex-col justify-between lg:min-w-[300px]',
className,
)}>
<div>
<div class="flex flex-col gap-4 p-2 lg:p-4">
{#each routes as route}
<Button
variant={route.match($page.url.pathname)
? 'secondary'
: 'ghost'}
href={route.href}
class="hover:bg-secondary/50 flex items-center justify-start gap-4 text-base">
<svelte:component this={route.icon} class="h-4 w-4" />
<div class="hidden lg:flex">
{route.name}
</div>
</Button>
{/each}
</div>
</div>
</div>

@ -1,9 +1,14 @@
import { env } from '$env/dynamic/public' import { env } from '$env/dynamic/public'
import { db } from '$lib/db'
import type { LayoutServerLoad } from './$types' import type { LayoutServerLoad } from './$types'
export const load = (async (event) => { export const load = (async (event) => {
const user = event.locals.user const user = event.locals.user
const projects = await db.query.project.findMany({
where: (project, { eq }) => eq(project.userId, user.id),
})
const breadcrumbs = [{ name: 'Home', path: '/dashboard' }] const breadcrumbs = [{ name: 'Home', path: '/dashboard' }]
const page_title = 'Home' const page_title = 'Home'
@ -13,5 +18,6 @@ export const load = (async (event) => {
user: user, user: user,
breadcrumbs, breadcrumbs,
page_title, page_title,
projects,
} }
}) satisfies LayoutServerLoad }) satisfies LayoutServerLoad

@ -1,17 +1,46 @@
<script lang="ts"> <script lang="ts">
import Sidebar from '$lib/components/sidebar.svelte' import * as Select from '$lib/components/ui/select/index.js'
import type { PageData } from './$types' import type { PageData } from './$types'
import UserIcon from '$lib/components/UserIcon.svelte' import UserIcon from '$lib/components/UserIcon.svelte'
import ThemeToggle from '$lib/components/theme-toggle.svelte' import ThemeToggle from '$lib/components/theme-toggle.svelte'
import * as Breadcrumb from '$lib/components/ui/breadcrumb' import * as Breadcrumb from '$lib/components/ui/breadcrumb'
import { page } from '$app/stores' import { page } from '$app/stores'
import { Button } from '$lib/components/ui/button'
import { Blocks, Home, Link, Settings } from 'lucide-svelte'
export let data: PageData export let data: PageData
const routes = [
{
href: '/dashboard',
name: 'Home',
match: (path: string) => path === '/dashboard',
icon: Home,
},
{
href: '/dashboard/links',
name: 'Links',
match: (path: string) => path.startsWith('/dashboard/links'),
icon: Link,
},
{
href: '/dashboard/projects',
name: 'Projects',
match: (path: string) => path.startsWith('/dashboard/projects'),
icon: Blocks,
},
{
href: '/dashboard/settings/account',
name: 'Settings',
match: (path: string) => path.startsWith('/dashboard/settings'),
icon: Settings,
},
] as const
</script> </script>
<div <div
class="max-w-screen flex h-screen max-h-screen w-screen overflow-hidden"> class="max-w-screen flex h-screen max-h-screen w-screen overflow-hidden">
<div class="flex max-w-[300px] flex-col border-r bg-muted/40"> <div class="bg-muted/40 flex max-w-[300px] flex-col border-r">
<div <div
class="flex w-full items-center justify-center gap-4 border-b px-2 py-2 lg:px-4"> class="flex w-full items-center justify-center gap-4 border-b px-2 py-2 lg:px-4">
<UserIcon email={data.user.email} /> <UserIcon email={data.user.email} />
@ -48,7 +77,57 @@
</div> </div>
</div> </div>
<Sidebar /> <div
class={'flex h-full flex-col justify-between lg:min-w-[300px]'}>
<div>
<div class="flex flex-col gap-4 p-2 lg:p-4">
<Select.Root
selected={{
label: $page.data.project?.name || 'None',
value: $page.data.project?.id || 'none',
}}>
<Select.Trigger>
<Select.Value placeholder="Select a project" />
</Select.Trigger>
<Select.Content>
<Select.Group>
<Select.Label>Projects</Select.Label>
<Select.Separator />
<a href={`/dashboard/links`}>
<Select.Item value={'none'} label={'None'}>
None
</Select.Item>
</a>
<Select.Separator />
{#each data.projects as project}
<a href={`/dashboard/projects/${project.uuid}`}>
<Select.Item
value={project.id}
label={project.name}>
{project.name}
</Select.Item>
</a>
{/each}
</Select.Group>
</Select.Content>
<Select.Input name="favoriteFruit" />
</Select.Root>
{#each routes as route}
<Button
variant={route.match($page.url.pathname)
? 'secondary'
: 'ghost'}
href={route.href}
class="hover:bg-secondary/50 flex items-center justify-start gap-4 text-base">
<svelte:component this={route.icon} class="h-4 w-4" />
<div class="hidden lg:flex">
{route.name}
</div>
</Button>
{/each}
</div>
</div>
</div>
<div <div
class="flex items-center justify-center border-t px-2 py-4 lg:justify-end lg:px-4"> class="flex items-center justify-center border-t px-2 py-4 lg:justify-end lg:px-4">
<ThemeToggle /> <ThemeToggle />

Loading…
Cancel
Save