a / web /src /components /AppSidebar.vue
FTA7700
Add dark-mode-only glow hover effect to Rating Order rows (opt-in class, doesn't affect shared rating-row-hover elsewhere)
b7f1d5d
Raw History Blame Contribute Delete
3.47 kB
<script setup lang="ts">
import { version } from '../../package.json'
import { useRoute, useRouter } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import { LayoutDashboard, Image, Stamp, Wallpaper, Clapperboard, KeyRound, Settings, LogOut, Trash2, Sun, Moon } from 'lucide-vue-next'
import { ref } from 'vue'
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarRail,
useSidebar,
} from '@/components/ui/sidebar'
import { Button } from '@/components/ui/button'
const route = useRoute()
const router = useRouter()
const auth = useAuthStore()
const { state, isMobile, setOpenMobile } = useSidebar()
const items = [
{ title: 'Dashboard', icon: LayoutDashboard, to: '/admin' },
{ title: 'Posters', icon: Image, to: '/admin/posters' },
{ title: 'Logos', icon: Stamp, to: '/admin/logos' },
{ title: 'Backdrops', icon: Wallpaper, to: '/admin/backdrops' },
{ title: 'Episodes', icon: Clapperboard, to: '/admin/episodes' },
{ title: 'API Keys', icon: KeyRound, to: '/admin/keys' },
{ title: 'Settings', icon: Settings, to: '/admin/settings' },
]
function isActive(path: string) {
return route.path === path
}
function onNavigate() {
if (isMobile.value) setOpenMobile(false)
}
function handleLogout() {
if (isMobile.value) setOpenMobile(false)
auth.logout()
router.push('/login')
}
const isDark = ref(document.documentElement.classList.contains('dark'))
function toggleTheme() {
isDark.value = !isDark.value
document.documentElement.classList.toggle('dark', isDark.value)
localStorage.setItem('theme', isDark.value ? 'dark' : 'light')
}
</script>
<template>
<Sidebar variant="inset" collapsible="icon">
<SidebarHeader>
<router-link to="/admin" class="flex flex-col items-center py-1 group-data-[state=expanded]/sidebar-wrapper:items-start hover:opacity-80 transition-opacity" @click="onNavigate">
<span class="font-normal text-lg whitespace-nowrap">{{ state === 'collapsed' ? 'OPDB' : 'OpenPosterDB' }}</span>
<span class="text-xs text-muted-foreground whitespace-nowrap">v{{ version }}</span>
</router-link>
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarMenu>
<SidebarMenuItem v-for="item in items" :key="item.title">
<SidebarMenuButton
as-child
:is-active="isActive(item.to)"
:tooltip="item.title"
>
<router-link :to="item.to" @click="onNavigate">
<component :is="item.icon" />
<span>{{ item.title }}</span>
</router-link>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton :tooltip="isDark ? 'Switch to light mode' : 'Switch to dark mode'" @click="toggleTheme">
<Sun v-if="isDark" />
<Moon v-else />
<span>{{ isDark ? 'Light mode' : 'Dark mode' }}</span>
</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton tooltip="Sign out" @click="handleLogout">
<LogOut />
<span>Sign out</span>
</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarFooter>
<SidebarRail />
</Sidebar>
</template>