enhance navigation with database submenu
This commit is contained in:
parent
a5ffdcb68a
commit
0b771fc405
1 changed files with 180 additions and 38 deletions
|
|
@ -3,6 +3,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { localizeHref } from '$lib/paraglide/runtime'
|
import { localizeHref } from '$lib/paraglide/runtime'
|
||||||
import { m } from '$lib/paraglide/messages'
|
import { m } from '$lib/paraglide/messages'
|
||||||
|
import { page } from '$app/stores'
|
||||||
import Button from './ui/button/Button.svelte'
|
import Button from './ui/button/Button.svelte'
|
||||||
import Icon from './Icon.svelte'
|
import Icon from './Icon.svelte'
|
||||||
import DropdownItem from './ui/dropdown/DropdownItem.svelte'
|
import DropdownItem from './ui/dropdown/DropdownItem.svelte'
|
||||||
|
|
@ -31,50 +32,101 @@
|
||||||
const settingsHref = $derived(localizeHref('/settings'))
|
const settingsHref = $derived(localizeHref('/settings'))
|
||||||
const databaseHref = $derived(localizeHref('/database'))
|
const databaseHref = $derived(localizeHref('/database'))
|
||||||
const newTeamHref = $derived(localizeHref('/teams/new'))
|
const newTeamHref = $derived(localizeHref('/teams/new'))
|
||||||
|
|
||||||
|
// Database-specific links
|
||||||
|
const databaseCharactersHref = $derived(localizeHref('/database/characters'))
|
||||||
|
const databaseWeaponsHref = $derived(localizeHref('/database/weapons'))
|
||||||
|
const databaseSummonsHref = $derived(localizeHref('/database/summons'))
|
||||||
|
|
||||||
|
// Database route detection
|
||||||
|
const isDatabaseRoute = $derived($page.url.pathname.startsWith(localizeHref('/database')))
|
||||||
|
|
||||||
|
// Function to check if a database nav item is selected
|
||||||
|
function isDatabaseNavSelected(href: string): boolean {
|
||||||
|
return $page.url.pathname === href || $page.url.pathname.startsWith(href + '/')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<nav aria-label="Global">
|
<nav aria-label="Global">
|
||||||
<ul role="list">
|
{#if isDatabaseRoute}
|
||||||
<li><a href={galleryHref}>{m.nav_gallery()}</a></li>
|
<!-- Database navigation mode -->
|
||||||
<li><a href={collectionHref}>{m.nav_collection()}</a></li>
|
<div class="database-nav">
|
||||||
|
<!-- Back button and Database label -->
|
||||||
|
<ul role="list" class="database-back-section">
|
||||||
|
<li>
|
||||||
|
<a href={galleryHref} class="database-back-button" aria-label="Back to gallery">
|
||||||
|
<Icon name="arrow-left" size={14} />
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span class="database-label">Database</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<li>
|
<!-- Database sub-navigation -->
|
||||||
{#if isAuth}
|
<ul role="list" class="database-subnav">
|
||||||
<a href={meHref} aria-label="Your account">{username}</a>
|
<li>
|
||||||
{:else}
|
<a
|
||||||
<a href={loginHref} aria-label="Login">{m.nav_login()}</a>
|
href={databaseCharactersHref}
|
||||||
{/if}
|
class:selected={isDatabaseNavSelected(databaseCharactersHref)}
|
||||||
</li>
|
>
|
||||||
|
Characters
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href={databaseWeaponsHref} class:selected={isDatabaseNavSelected(databaseWeaponsHref)}>
|
||||||
|
Weapons
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href={databaseSummonsHref} class:selected={isDatabaseNavSelected(databaseSummonsHref)}>
|
||||||
|
Summons
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<!-- Normal navigation mode -->
|
||||||
|
<ul role="list">
|
||||||
|
<li><a href={galleryHref}>{m.nav_gallery()}</a></li>
|
||||||
|
<li><a href={collectionHref}>{m.nav_collection()}</a></li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<DropdownMenu.Root>
|
{#if isAuth}
|
||||||
<DropdownMenu.Trigger class="nav-more-trigger">
|
<a href={meHref} aria-label="Your account">{username}</a>
|
||||||
<Icon name="ellipsis" size={14} />
|
{:else}
|
||||||
</DropdownMenu.Trigger>
|
<a href={loginHref} aria-label="Login">{m.nav_login()}</a>
|
||||||
|
{/if}
|
||||||
|
</li>
|
||||||
|
|
||||||
<DropdownMenu.Portal>
|
<li>
|
||||||
<DropdownMenu.Content class="dropdown-content" sideOffset={5}>
|
<DropdownMenu.Root>
|
||||||
<DropdownItem href={settingsHref}>
|
<DropdownMenu.Trigger class="nav-more-trigger">
|
||||||
{m.nav_settings()}
|
<Icon name="ellipsis" size={14} />
|
||||||
</DropdownItem>
|
</DropdownMenu.Trigger>
|
||||||
{#if role !== null && role >= 7}
|
|
||||||
<DropdownItem href={databaseHref}>
|
<DropdownMenu.Portal>
|
||||||
Database
|
<DropdownMenu.Content class="dropdown-content" sideOffset={5}>
|
||||||
|
<DropdownItem href={settingsHref}>
|
||||||
|
{m.nav_settings()}
|
||||||
</DropdownItem>
|
</DropdownItem>
|
||||||
{/if}
|
{#if role !== null && role >= 7}
|
||||||
{#if isAuth}
|
<DropdownItem href={databaseHref}>Database</DropdownItem>
|
||||||
<DropdownMenu.Separator class="dropdown-separator" />
|
{/if}
|
||||||
<DropdownItem asChild>
|
{#if isAuth}
|
||||||
<form method="post" action="/auth/logout">
|
<DropdownMenu.Separator class="dropdown-separator" />
|
||||||
<button type="submit">{m.nav_logout()}</button>
|
<DropdownItem asChild>
|
||||||
</form>
|
<form method="post" action="/auth/logout">
|
||||||
</DropdownItem>
|
<button type="submit">{m.nav_logout()}</button>
|
||||||
{/if}
|
</form>
|
||||||
</DropdownMenu.Content>
|
</DropdownItem>
|
||||||
</DropdownMenu.Portal>
|
{/if}
|
||||||
</DropdownMenu.Root>
|
</DropdownMenu.Content>
|
||||||
</li>
|
</DropdownMenu.Portal>
|
||||||
</ul>
|
</DropdownMenu.Root>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{/if}
|
||||||
<Button
|
<Button
|
||||||
icon="plus"
|
icon="plus"
|
||||||
iconOnly
|
iconOnly
|
||||||
|
|
@ -86,6 +138,7 @@
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@use '$src/themes/colors' as colors;
|
||||||
@use '$src/themes/themes' as themes;
|
@use '$src/themes/themes' as themes;
|
||||||
@use '$src/themes/layout' as layout;
|
@use '$src/themes/layout' as layout;
|
||||||
@use '$src/themes/spacing' as spacing;
|
@use '$src/themes/spacing' as spacing;
|
||||||
|
|
@ -101,7 +154,6 @@
|
||||||
background-color: var(--menu-bg);
|
background-color: var(--menu-bg);
|
||||||
border-radius: layout.$full-corner;
|
border-radius: layout.$full-corner;
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: spacing.$unit-half;
|
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
padding: spacing.$unit-half;
|
padding: spacing.$unit-half;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
@ -125,6 +177,96 @@
|
||||||
&:visited {
|
&:visited {
|
||||||
color: var(--menu-text);
|
color: var(--menu-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background-color: var(--menu-bg-item-selected, var(--menu-bg-item-hover));
|
||||||
|
font-weight: typography.$bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Database navigation mode
|
||||||
|
.database-nav {
|
||||||
|
display: flex;
|
||||||
|
gap: spacing.$unit;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.database-back-section {
|
||||||
|
ul {
|
||||||
|
background-color: var(--menu-bg);
|
||||||
|
border-radius: layout.$full-corner;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: spacing.$unit-half;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.database-back-button {
|
||||||
|
border-radius: layout.$full-corner;
|
||||||
|
color: colors.$grey-50;
|
||||||
|
font-size: typography.$font-small;
|
||||||
|
font-weight: typography.$medium;
|
||||||
|
text-decoration: none;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: spacing.$unit (spacing.$unit * 1.5);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: colors.$grey-30;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.database-label {
|
||||||
|
border-radius: layout.$full-corner;
|
||||||
|
color: var(--menu-text);
|
||||||
|
font-size: typography.$font-small;
|
||||||
|
font-weight: typography.$medium;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: spacing.$unit calc(spacing.$unit * 1.5) spacing.$unit spacing.$unit;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background-color: var(--menu-bg-item-selected, var(--menu-bg-item-hover));
|
||||||
|
font-weight: typography.$bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.database-subnav {
|
||||||
|
background-color: var(--menu-bg);
|
||||||
|
border-radius: layout.$full-corner;
|
||||||
|
display: flex;
|
||||||
|
gap: spacing.$unit-half;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: spacing.$unit-half;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
a {
|
||||||
|
border-radius: layout.$full-corner;
|
||||||
|
color: var(--menu-text);
|
||||||
|
font-size: typography.$font-small;
|
||||||
|
font-weight: typography.$medium;
|
||||||
|
text-decoration: none;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: spacing.$unit (spacing.$unit * 1.5);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--menu-bg-item-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:visited {
|
||||||
|
color: var(--menu-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background-color: var(--menu-bg-item-selected, var(--menu-bg-item-hover));
|
||||||
|
font-weight: typography.$bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue