97 lines
2.7 KiB
Vue
97 lines
2.7 KiB
Vue
<template>
|
|
<v-app>
|
|
<v-navigation-drawer v-model="drawer" app>
|
|
<v-list-item
|
|
prepend-icon="mdi-image-multiple"
|
|
title="Gallery Subscriber"
|
|
subtitle="Download Manager"
|
|
/>
|
|
<v-divider />
|
|
<v-list nav density="compact">
|
|
<v-list-item
|
|
v-for="item in navItems"
|
|
:key="item.path"
|
|
:to="item.path"
|
|
:prepend-icon="item.icon"
|
|
:title="item.title"
|
|
/>
|
|
</v-list>
|
|
</v-navigation-drawer>
|
|
|
|
<v-app-bar app elevation="1">
|
|
<v-app-bar-nav-icon @click="drawer = !drawer" />
|
|
<v-toolbar-title>{{ currentPageTitle }}</v-toolbar-title>
|
|
<v-spacer />
|
|
<v-btn icon @click="toggleTheme">
|
|
<v-icon>{{ isDark ? 'mdi-weather-sunny' : 'mdi-weather-night' }}</v-icon>
|
|
</v-btn>
|
|
</v-app-bar>
|
|
|
|
<v-main>
|
|
<v-container fluid>
|
|
<router-view />
|
|
</v-container>
|
|
</v-main>
|
|
|
|
<v-snackbar
|
|
v-model="notification.show"
|
|
:color="notification.color"
|
|
:timeout="3000"
|
|
>
|
|
{{ notification.message }}
|
|
<template v-slot:actions>
|
|
<v-btn variant="text" @click="notification.show = false">Close</v-btn>
|
|
</template>
|
|
</v-snackbar>
|
|
</v-app>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onMounted } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import { useTheme } from 'vuetify'
|
|
import { useNotificationStore } from './stores/notifications'
|
|
import { useWebSocketStore } from './stores/websocket'
|
|
|
|
const theme = useTheme()
|
|
const route = useRoute()
|
|
const notificationStore = useNotificationStore()
|
|
const wsStore = useWebSocketStore()
|
|
|
|
// Initialize WebSocket listeners and restore theme
|
|
onMounted(() => {
|
|
wsStore.init()
|
|
// Restore theme preference from localStorage
|
|
const savedTheme = localStorage.getItem('theme')
|
|
if (savedTheme) {
|
|
theme.global.name.value = savedTheme
|
|
}
|
|
})
|
|
|
|
const drawer = ref(true)
|
|
|
|
const navItems = [
|
|
{ title: 'Dashboard', icon: 'mdi-view-dashboard', path: '/' },
|
|
{ title: 'Subscriptions', icon: 'mdi-account-multiple', path: '/subscriptions' },
|
|
{ title: 'Downloads', icon: 'mdi-download', path: '/downloads' },
|
|
{ title: 'Credentials', icon: 'mdi-key', path: '/credentials' },
|
|
{ title: 'Logs', icon: 'mdi-text-box-outline', path: '/logs' },
|
|
{ title: 'Settings', icon: 'mdi-cog', path: '/settings' },
|
|
]
|
|
|
|
const currentPageTitle = computed(() => {
|
|
const item = navItems.find(item => item.path === route.path)
|
|
return item?.title || 'Gallery Subscriber'
|
|
})
|
|
|
|
const isDark = computed(() => theme.global.current.value.dark)
|
|
|
|
const toggleTheme = () => {
|
|
const newTheme = isDark.value ? 'light' : 'dark'
|
|
theme.global.name.value = newTheme
|
|
localStorage.setItem('theme', newTheme)
|
|
}
|
|
|
|
const notification = computed(() => notificationStore)
|
|
</script>
|