115 lines
4.1 KiB
Vue
115 lines
4.1 KiB
Vue
<script setup lang="ts">
|
|
import { Link } from '@inertiajs/vue3';
|
|
import {
|
|
GitBranch,
|
|
KeyRound,
|
|
Palette,
|
|
Settings2,
|
|
ShieldCheck,
|
|
UserRound,
|
|
} from 'lucide-vue-next';
|
|
import { computed } from 'vue';
|
|
import { useCurrentUrl } from '@/composables/useCurrentUrl';
|
|
import { useLocalization } from '@/composables/useLocalization';
|
|
import { toUrl } from '@/lib/utils';
|
|
import { edit as editAppearance } from '@/routes/appearance/index';
|
|
import { edit as editApplications } from '@/routes/applications/index';
|
|
import { edit as editGitConnections } from '@/routes/git-connections/index';
|
|
import { edit as editProfile } from '@/routes/profile/index';
|
|
import { edit as editSecurity } from '@/routes/security/index';
|
|
import type { NavItem } from '@/types';
|
|
|
|
const { t } = useLocalization();
|
|
const sidebarNavItems = computed<NavItem[]>(() => [
|
|
{
|
|
title: t('navigation.profile'),
|
|
href: editProfile(),
|
|
icon: UserRound,
|
|
},
|
|
{
|
|
title: t('navigation.security'),
|
|
href: editSecurity(),
|
|
icon: ShieldCheck,
|
|
},
|
|
{
|
|
title: t('navigation.gitConnections'),
|
|
href: editGitConnections(),
|
|
icon: GitBranch,
|
|
},
|
|
{
|
|
title: t('navigation.applications'),
|
|
href: editApplications(),
|
|
icon: KeyRound,
|
|
},
|
|
{
|
|
title: t('navigation.appearance'),
|
|
href: editAppearance(),
|
|
icon: Palette,
|
|
},
|
|
]);
|
|
|
|
const { isCurrentOrParentUrl } = useCurrentUrl();
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
class="gap-page md:p-page mx-auto flex w-full min-w-0 max-w-6xl flex-1 flex-col p-4"
|
|
>
|
|
<header class="gap-stack grid min-w-0">
|
|
<div class="text-primary flex items-center gap-2">
|
|
<Settings2 class="size-4" aria-hidden="true" />
|
|
<p class="text-label text-muted-foreground uppercase">
|
|
{{ t('settings.eyebrow') }}
|
|
</p>
|
|
</div>
|
|
<h1 class="text-headline-mobile md:text-headline break-words">
|
|
{{ t('navigation.settings') }}
|
|
</h1>
|
|
<p class="text-muted-foreground max-w-2xl">
|
|
{{ t('navigation.settingsDescription') }}
|
|
</p>
|
|
</header>
|
|
|
|
<div
|
|
class="bg-card grid min-w-0 overflow-hidden rounded-xl border shadow-sm lg:grid-cols-[15rem_minmax(0,1fr)]"
|
|
>
|
|
<aside
|
|
class="bg-muted/35 border-b p-3 lg:border-b-0 lg:border-r lg:p-4"
|
|
>
|
|
<nav
|
|
class="flex gap-2 overflow-x-auto pb-1 lg:flex-col lg:overflow-visible lg:pb-0"
|
|
:aria-label="t('navigation.settings')"
|
|
>
|
|
<Link
|
|
v-for="item in sidebarNavItems"
|
|
:key="toUrl(item.href)"
|
|
:href="item.href"
|
|
:aria-current="
|
|
isCurrentOrParentUrl(item.href) ? 'page' : undefined
|
|
"
|
|
:class="[
|
|
'text-body focus-visible:ring-ring/40 flex min-h-11 shrink-0 items-center gap-2 rounded-lg border px-3 font-medium outline-none transition-colors focus-visible:ring-2 lg:w-full',
|
|
isCurrentOrParentUrl(item.href)
|
|
? 'border-primary/25 bg-accent text-accent-foreground shadow-xs'
|
|
: 'text-muted-foreground hover:border-border hover:bg-background hover:text-foreground border-transparent',
|
|
]"
|
|
>
|
|
<component
|
|
:is="item.icon"
|
|
class="size-4 shrink-0"
|
|
aria-hidden="true"
|
|
/>
|
|
<span class="whitespace-nowrap">{{ item.title }}</span>
|
|
</Link>
|
|
</nav>
|
|
</aside>
|
|
|
|
<div class="min-w-0 p-4 sm:p-6 lg:p-8">
|
|
<section class="mx-auto grid max-w-3xl gap-8">
|
|
<slot />
|
|
</section>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|