102 lines
2.5 KiB
Vue
102 lines
2.5 KiB
Vue
<script setup lang="ts">
|
|
/**
|
|
* @file AppSidebar.vue
|
|
* @description Sidebar navigation for the authenticated dashboard.
|
|
* Uses Quasar QList for structure.
|
|
*/
|
|
|
|
const { t } = useI18n()
|
|
|
|
const navItems = computed(() => [
|
|
{
|
|
to: "/dashboard",
|
|
label: t('sidebar.overview'),
|
|
icon: "dashboard", // Using Material Icons names where possible or SVG paths
|
|
isSvg: false
|
|
},
|
|
{
|
|
to: "/browse/discovery",
|
|
label: t('sidebar.browseCourses'),
|
|
icon: "explore",
|
|
isSvg: false
|
|
},
|
|
{
|
|
to: "/dashboard/my-courses",
|
|
label: t('sidebar.myCourses'),
|
|
icon: "school",
|
|
isSvg: false
|
|
}
|
|
]);
|
|
|
|
const handleNavigate = (path: string) => {
|
|
if (import.meta.client) {
|
|
window.location.href = path
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex flex-col h-full bg-white dark:bg-[#1e293b] border-r border-slate-200 dark:border-slate-700">
|
|
|
|
|
|
<!-- Navigation Items -->
|
|
<q-list padding class="text-slate-600 dark:text-slate-300 flex-grow px-3 pt-6">
|
|
<q-item
|
|
v-for="item in navItems"
|
|
:key="item.to"
|
|
clickable
|
|
v-ripple
|
|
@click="handleNavigate(item.to)"
|
|
class="rounded-xl mb-1 text-slate-700 dark:text-slate-200 hover:bg-slate-100 dark:hover:bg-white/5"
|
|
:class="{ 'sidebar-item--active': $route.path === item.to || ($route.path === '/dashboard' && item.to === '/dashboard') }"
|
|
>
|
|
<q-item-section avatar>
|
|
<q-icon :name="item.icon" size="22px" />
|
|
</q-item-section>
|
|
|
|
<q-item-section>
|
|
<q-item-label class="font-bold text-sm">{{ item.label }}</q-item-label>
|
|
</q-item-section>
|
|
</q-item>
|
|
</q-list>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<style>
|
|
/* Active State styling for Sidebar items */
|
|
.sidebar-item--active {
|
|
background: rgb(239 246 255) !important; /* blue-50 */
|
|
color: rgb(29 78 216) !important; /* blue-700 */
|
|
}
|
|
|
|
.sidebar-item--active .q-icon {
|
|
color: rgb(37 99 235) !important; /* blue-600 */
|
|
}
|
|
|
|
/* Vertical indicator for active item */
|
|
.sidebar-item--active::after {
|
|
content: "";
|
|
position: absolute;
|
|
left: -12px;
|
|
top: 15%;
|
|
height: 70%;
|
|
width: 4px;
|
|
background: #2563eb;
|
|
border-radius: 0 4px 4px 0;
|
|
}
|
|
|
|
/* Dark Mode Active State */
|
|
.dark .sidebar-item--active {
|
|
background: rgba(37, 99, 235, 0.15) !important;
|
|
color: rgb(147 197 253) !important; /* blue-300 */
|
|
}
|
|
|
|
.dark .sidebar-item--active .q-icon {
|
|
color: rgb(96 165 250) !important; /* blue-400 */
|
|
}
|
|
|
|
.dark .sidebar-item--active::after {
|
|
background: #60a5fa;
|
|
}
|
|
</style>
|