a
File size: 3,471 Bytes
2c8ae4e
687cd77
2c8ae4e
 
9f17309
 
2c8ae4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5afb157
 
 
 
76b8a0b
5afb157
 
2c8ae4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9f17309
 
 
 
 
 
2c8ae4e
 
 
 
 
5afb157
b7f1d5d
687cd77
2c8ae4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9f17309
 
 
 
 
 
 
2c8ae4e
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<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>