Refactor: Extract sidebar navigation from individual views into a new AppSidebar component.

This commit is contained in:
xds
2026-02-07 15:04:12 +03:00
parent 7f8ce19cb1
commit 1b9fddd209
8 changed files with 774 additions and 948 deletions

View File

@@ -0,0 +1,89 @@
<script setup>
import { computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import Button from 'primevue/button'
const router = useRouter()
const route = useRoute()
const handleLogout = () => {
localStorage.removeItem('auth_code')
router.push('/login')
}
// Check active route for styling
const isActive = (path) => {
// Exact match for home, startsWith for others
if (path === '/') return route.path === '/'
return route.path.startsWith(path)
}
const navItems = [
{ path: '/', icon: '🏠', tooltip: 'Home' },
{ path: '/assets', icon: '📂', tooltip: 'Assets' },
{ path: '/generation', icon: '🎨', tooltip: 'Image Generation' },
{ path: '/flexible-generation', icon: '🖌️', tooltip: 'Flexible Generation' },
{ path: '/characters', icon: '👥', tooltip: 'Characters' },
{ path: '/image-to-prompt', icon: '✨', tooltip: 'Image to Prompt' }
]
</script>
<template>
<div class="contents">
<!-- Sidebar (Desktop) -->
<nav
class="hidden md:flex glass-panel w-20 m-4 flex-col items-center py-6 rounded-3xl z-40 border border-white/5 bg-slate-900/50 backdrop-blur-md h-[calc(100vh-2rem)]">
<div class="mb-12">
<div
class="w-10 h-10 bg-gradient-to-br from-violet-600 to-cyan-500 rounded-xl flex items-center justify-center font-bold text-white text-xl shadow-lg shadow-violet-500/20">
AI
</div>
</div>
<div class="flex-1 flex flex-col gap-6 w-full items-center">
<div v-for="item in navItems" :key="item.path" :class="[
'w-12 h-12 flex items-center justify-center rounded-xl cursor-pointer transition-all duration-300',
isActive(item.path)
? 'bg-white/10 text-slate-50 shadow-inner'
: 'text-slate-400 hover:bg-white/10 hover:text-slate-50'
]" @click="router.push(item.path)" v-tooltip.right="item.tooltip">
<span class="text-2xl">{{ item.icon }}</span>
</div>
</div>
<div class="mt-auto flex flex-col items-center gap-4">
<div @click="handleLogout"
class="w-10 h-10 rounded-xl bg-red-500/10 text-red-400 flex items-center justify-center cursor-pointer hover:bg-red-500/20 transition-all font-bold"
v-tooltip.right="'Logout'">
<i class="pi pi-power-off"></i>
</div>
<!-- Profile Avatar Placeholder -->
<div class="w-10 h-10 rounded-full bg-slate-800 border-2 border-violet-600 flex items-center justify-center font-bold text-slate-50 cursor-pointer hover:scale-105 transition-all"
title="Profile">
U
</div>
</div>
</nav>
<!-- Mobile Bottom Nav -->
<nav
class="md:hidden fixed bottom-0 left-0 right-0 h-16 bg-slate-900/90 backdrop-blur-xl border-t border-white/10 z-50 flex justify-around items-center px-2">
<div v-for="item in navItems" :key="item.path" :class="[
'flex flex-col items-center gap-1 p-2 rounded-xl transition-all',
isActive(item.path)
? 'text-white bg-white/10 relative top-[-10px] shadow-lg shadow-violet-500/20 border border-violet-500/30'
: 'text-slate-400 hover:text-slate-200'
]" @click="router.push(item.path)">
<span class="text-xl">{{ item.icon }}</span>
</div>
</nav>
</div>
</template>
<style scoped>
.glass-panel {
background: rgba(255, 255, 255, 0.03);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
</style>