79 lines
3.3 KiB
Vue
79 lines
3.3 KiB
Vue
<script setup lang="ts">
|
|
import { useRoute } from 'vue-router'
|
|
import { Activity, RadioReceiver, Clock, Settings, LogOut } from 'lucide-vue-next'
|
|
|
|
const route = useRoute()
|
|
|
|
const navItems = [
|
|
{ name: 'Dashboard', path: '/dashboard', icon: Activity },
|
|
{ name: 'Radar', path: '/radar', icon: RadioReceiver },
|
|
{ name: 'History', path: '/history', icon: Clock }
|
|
]
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex h-screen w-full bg-[#0B1120] text-zinc-300 font-sans overflow-hidden">
|
|
<!-- Sidebar -->
|
|
<aside v-if="route.path !== '/login'" class="w-64 border-r border-white/10 bg-[#0F172A] flex flex-col shrink-0">
|
|
<div class="p-6 flex items-center gap-3">
|
|
<div class="w-8 h-8 rounded-lg bg-gradient-to-br from-brand-primary to-blue-600 flex items-center justify-center shrink-0">
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg>
|
|
</div>
|
|
<span class="font-bold text-lg text-white tracking-wide">InsightReply</span>
|
|
</div>
|
|
|
|
<nav class="flex-1 px-4 py-6 space-y-2">
|
|
<router-link
|
|
v-for="item in navItems"
|
|
:key="item.path"
|
|
:to="item.path"
|
|
class="flex items-center gap-3 px-4 py-3 rounded-xl transition-all duration-200"
|
|
:class="[
|
|
route.path === item.path
|
|
? 'bg-brand-primary/10 text-brand-primary font-medium'
|
|
: 'text-zinc-400 hover:text-white hover:bg-white/5'
|
|
]"
|
|
>
|
|
<component :is="item.icon" :size="18" :stroke-width="route.path === item.path ? 2.5 : 2" />
|
|
{{ item.name }}
|
|
</router-link>
|
|
</nav>
|
|
|
|
<div class="p-4 border-t border-white/10">
|
|
<button class="flex items-center gap-3 px-4 py-3 w-full rounded-xl text-zinc-400 hover:text-white hover:bg-white/5 transition-all">
|
|
<Settings :size="18" />
|
|
<span>Settings</span>
|
|
</button>
|
|
<button class="flex items-center gap-3 px-4 py-3 w-full rounded-xl text-red-400/80 hover:text-red-400 hover:bg-red-500/10 transition-all mt-1">
|
|
<LogOut :size="18" />
|
|
<span>Logout</span>
|
|
</button>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- Main Content Area -->
|
|
<main class="flex-1 flex flex-col h-full overflow-hidden relative">
|
|
<div class="absolute inset-0 bg-[url('https://grainy-gradients.vercel.app/noise.svg')] opacity-[0.03] mix-blend-overlay pointer-events-none"></div>
|
|
|
|
<!-- Topbar (Optional, currently just acts as spacing/header area handled inside views) -->
|
|
|
|
<!-- Page Content -->
|
|
<div class="flex-1 overflow-y-auto px-8 py-8 relative z-10">
|
|
<router-view v-slot="{ Component }">
|
|
<transition
|
|
enter-active-class="transition duration-300 ease-out"
|
|
enter-from-class="transform translate-y-4 opacity-0"
|
|
enter-to-class="transform translate-y-0 opacity-100"
|
|
leave-active-class="transition duration-200 ease-in"
|
|
leave-from-class="transform translate-y-0 opacity-100"
|
|
leave-to-class="transform translate-y-4 opacity-0"
|
|
mode="out-in"
|
|
>
|
|
<component :is="Component" />
|
|
</transition>
|
|
</router-view>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
</template>
|