<template>
<GnNavigationShell
brand="SHSERV WEB CLIENT"
logo-src=""
title="Navigation"
subtitle="Smart Home"
:items="navItems"
active-match="prefix"
:current="pageTitle"
>
<template #content>
<div class="relative">
<div class="app-user-bar">
<div v-if="authStore.isAuthenticated" class="user-info">
<span v-if="authStore.user?.display_name" class="user-name">
{{ authStore.user.display_name }}
</span>
<GnButton variant="ghost" size="sm" @click="handleLogout">
<template #icon>
<i class="ph ph-sign-out" />
</template>
Logout
</GnButton>
</div>
<GnButton
v-else
variant="ghost"
size="sm"
@click="handleLogin"
>
<template #icon>
<i class="ph ph-sign-in" />
</template>
Login
</GnButton>
</div>
<slot />
</div>
</template>
</GnNavigationShell>
</template>
<script setup>
import { computed } from "vue";
import { useRoute } from "vue-router";
import { GnNavigationShell, GnButton } from "gnexus-ui-kit/vue";
import { useAuthStore } from "../../stores/auth.js";
const route = useRoute();
const authStore = useAuthStore();
const PAGE_TITLES = {
login: "Login",
"areas-favorites": "Favorites",
"areas-tree": "Areas",
"area-detail": "Area",
devices: "Devices",
"device-detail": "Device",
"devices-scanning": "Scanning",
"scripts-actions": "Actions",
"scripts-regular": "Regular",
"scripts-scopes": "Scopes",
"script-detail": "Script",
firmwares: "Firmwares",
};
const pageTitle = computed(() => {
const name = route?.name;
if (name && PAGE_TITLES[name]) {
return PAGE_TITLES[name];
}
return "";
});
const ALL_NAV_ITEMS = [
{ label: "Favorites", to: "/areas/favorites", icon: "ph-bookmarks", permission: "areas.view" },
{ label: "Areas", to: "/areas/tree", icon: "ph-map-trifold", permission: "areas.view" },
{ label: "Devices", to: "/devices", icon: "ph-cpu", permission: "devices.view" },
{ label: "Scanning", to: "/devices/scanning", icon: "ph-magnifying-glass", permission: "devices.scan" },
{ label: "Actions", to: "/scripts/actions", icon: "ph-play", permission: "scripts.run" },
{ label: "Regular", to: "/scripts/regular", icon: "ph-clock", permission: "scripts.view" },
{ label: "Scopes", to: "/scripts/scopes", icon: "ph-brackets-curly", permission: "scripts.view" },
{ label: "Firmwares", to: "/firmwares", icon: "ph-cloud-arrow-down", permission: "firmware.view" },
];
const navItems = computed(() => {
return ALL_NAV_ITEMS.filter((item) => {
if (!item.permission) {
return true;
}
return authStore.hasPermission(item.permission);
});
});
function handleLogin() {
const returnTo = window.location.hash || "#/";
window.location.href = `/auth/login?return_to=${encodeURIComponent(returnTo)}`;
}
function handleLogout() {
authStore.logout();
}
</script>
<style scoped>
.app-user-bar {
position: absolute;
top: 0.5rem;
right: 0.5rem;
z-index: 50;
display: flex;
align-items: center;
gap: 0.5rem;
}
.user-info {
display: flex;
align-items: center;
gap: 0.5rem;
}
.user-name {
font-size: 0.875rem;
font-weight: 500;
color: var(--color-text-secondary, #6b7280);
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>