Skip to content

Dashboard Components

God Panel's dashboard components provide comprehensive navigation and layout functionality for admin interfaces. These components work together to create responsive, accessible dashboard navigation with theme support and internationalization.

Component Categories

🧭 Navigation Components

  • DashboardHeader: Top navigation bar with breadcrumbs, notifications, and user menu
  • DashboardNav: Main sidebar navigation with collapsible groups and mini mode
  • DashboardNavMobile: Mobile-optimized navigation drawer

🎨 Layout Features

  • Responsive Design: Adapts to desktop, tablet, and mobile
  • RTL Support: Right-to-left language support
  • Theme Integration: Dark/light mode compatibility
  • Mini Mode: Collapsible sidebar for space efficiency

DashboardHeader Component

The main navigation header component with breadcrumbs, search, notifications, and user menu.

vue
<template>
  <!-- Main dashboard header -->
  <DashboardHeader
    :mobile="isMobile"
    @toggle-nav="handleNavToggle"
  />
</template>

<script setup>
const isMobile = ref(false)
const navigationOpen = ref(false)

const handleNavToggle = () => {
  navigationOpen.value = !navigationOpen.value
}
</script>

Props

PropTypeDefaultDescription
mobilebooleanfalseEnable mobile-specific styling
isHorizontalbooleanfalseHorizontal layout mode

Events

EventPayloadDescription
toggle-nav-Emitted when mobile nav toggle is clicked

Features

  • Breadcrumbs: Dynamic breadcrumb navigation based on current route
  • Search Field: Integrated search functionality (commented in current implementation)
  • Notification Dropdown: Real-time notifications with badge counter
  • User Menu: Profile access, settings, and logout options
  • Theme Integration: Language switcher and settings button
  • Responsive Design: Mobile-friendly layout with collapsible elements

The header automatically generates breadcrumbs from the current route:

vue
<script setup>
// Breadcrumbs are generated from route path
// Example: /dashboard/users/edit -> Dashboard > Users > Edit
const breadcrumbItems = [
  { title: 'Dashboard', to: '/dashboard' },
  { title: 'Users', to: '/dashboard/users' },
  { title: 'Edit', disabled: true }
]
</script>

DashboardNav Component

The main sidebar navigation with advanced features for desktop and tablet interfaces.

vue
<template>
  <DashboardNav
    :mini="sidebarMini"
    :mobile="false"
    @toggle-mini="handleMiniToggle"
  />
</template>

<script setup>
const sidebarMini = ref(false)

const handleMiniToggle = () => {
  sidebarMini.value = !sidebarMini.value
}
</script>

Props

PropTypeDefaultDescription
minibooleanfalseCollapsed mini mode
mobilebooleanfalseMobile navigation style

Events

EventPayloadDescription
toggle-mini-Emitted when mini mode toggle is clicked
open-mobile-Emitted when mobile menu is opened

Features

  • Collapsible Groups: Expandable navigation sections
  • Mini Mode: Space-efficient collapsed state
  • Active Route Detection: Automatic highlighting of current page
  • Badge Support: Notification badges on navigation items
  • RTL Support: Right-to-left text direction support
  • Theme Integration: Respects current theme and layout settings
vue
<script setup>
// Navigation items are defined in ~/utils/routes
const navItems = [
  {
    key: 'dashboard',
    title: 'nav.dashboard',
    path: '/dashboard',
    icon: 'mdi-view-dashboard'
  },
  {
    key: 'users',
    title: 'nav.users',
    path: '/dashboard/users',
    icon: 'mdi-account-group',
    badge: '3'
  },
  {
    key: 'settings',
    title: 'nav.settings',
    icon: 'mdi-cog',
    children: [
      { key: 'profile', title: 'nav.profile', path: '/dashboard/profile', icon: 'mdi-account' },
      { key: 'preferences', title: 'nav.preferences', path: '/dashboard/preferences', icon: 'mdi-tune' }
    ]
  }
]
</script>

Responsive Behavior

vue
<template>
  <!-- Desktop: Always visible sidebar -->
  <DashboardNav v-if="!mobile" :mini="mini" />

  <!-- Tablet/Mobile: Overlay drawer -->
  <DashboardNavMobile v-else :open="navOpen" @close="closeNav" />
</template>

DashboardNavMobile Component

Mobile-optimized navigation drawer with user profile and quick actions.

vue
<template>
  <DashboardNavMobile
    :open="navOpen"
    @update:open="navOpen = $event"
    @close="handleClose"
  />
</template>

<script setup>
const navOpen = ref(false)

const handleClose = () => {
  navOpen.value = false
}
</script>

Props

PropTypeDefaultDescription
openbooleanfalseControls drawer visibility

Events

EventPayloadDescription
update:openbooleanDrawer open state changed
close-Emitted when close is requested

Features

  • User Profile Section: Avatar, name, and role display
  • Full Navigation: Complete navigation menu for mobile
  • Quick Actions: Settings and logout buttons in footer
  • Touch Optimized: Mobile-friendly touch targets
  • Accessibility: ARIA labels and keyboard navigation

Navigation items are centrally managed in the routes utility:

typescript
// ~/utils/routes.ts
export interface NavItem {
  key: string
  title: string
  path: string
  icon: string
  badge?: string
  children?: NavItem[]
}

export const dashboardNavItems: NavItem[] = [
  {
    key: 'overview',
    title: 'nav.overview',
    path: '/dashboard',
    icon: 'mdi-view-dashboard'
  },
  {
    key: 'analytics',
    title: 'nav.analytics',
    path: '/dashboard/analytics',
    icon: 'mdi-chart-line',
    badge: 'new'
  },
  // ... more items
]

Theme Integration

All dashboard components integrate with the theme system:

vue
<script setup>
import { useSettingsStore } from '~/stores/settings'

const settingsStore = useSettingsStore()

// Components automatically adapt to theme changes
// - Dark/light mode support
// - Compact layout mode
// - RTL text direction
// - Custom color schemes
</script>

Responsive Breakpoints

The components adapt to different screen sizes:

css
/* Mobile (< 960px) */
.dashboard-header .search-field {
  display: none;
}

/* Tablet (960px - 1263px) */
.dashboard-nav {
  width: 260px; /* Standard width */
}

/* Desktop (≥ 1264px) */
.dashboard-nav {
  width: 300px; /* Full width */
}

.nav-mini {
  width: 88px; /* Collapsed width */
}

Internationalization

Navigation supports full i18n integration:

vue
<script setup>
import { useI18n } from 'vue-i18n'

const { t } = useI18n()

// Navigation titles use translation keys
// nav.dashboard -> "Dashboard"
// nav.users -> "Users"
// nav.settings -> "Settings"
</script>

Integration Examples

Complete Dashboard Layout

vue
<template>
  <div class="dashboard-layout">
    <!-- Top header -->
    <DashboardHeader
      :mobile="mobile"
      @toggle-nav="toggleMobileNav"
    />

    <!-- Main navigation -->
    <DashboardNav
      v-if="!mobile"
      :mini="sidebarMini"
      @toggle-mini="toggleMiniMode"
    />

    <!-- Mobile navigation -->
    <DashboardNavMobile
      v-else
      :open="mobileNavOpen"
      @close="closeMobileNav"
    />

    <!-- Main content -->
    <main class="dashboard-content">
      <slot />
    </main>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useSettingsStore } from '~/stores/settings'

const settingsStore = useSettingsStore()
const mobile = ref(false)
const sidebarMini = ref(false)
const mobileNavOpen = ref(false)

const toggleMobileNav = () => {
  mobileNavOpen.value = !mobileNavOpen.value
}

const toggleMiniMode = () => {
  sidebarMini.value = !sidebarMini.value
}

const closeMobileNav = () => {
  mobileNavOpen.value = false
}

// Responsive detection
const checkMobile = () => {
  mobile.value = window.innerWidth < 960
}

onMounted(() => {
  checkMobile()
  window.addEventListener('resize', checkMobile)
})

onUnmounted(() => {
  window.removeEventListener('resize', checkMobile)
})
</script>
vue
<script setup>
import { computed } from 'vue'
import { useAuthStore } from '~/stores/auth'

const authStore = useAuthStore()

// Filter navigation items based on permissions
const allowedNavItems = computed(() => {
  return dashboardNavItems.filter(item => {
    // Check if user has permission for this navigation item
    return authStore.hasPermission(item.permission) || !item.permission
  })
})

// Show admin-only sections
const showAdminSection = computed(() => {
  return authStore.hasRole('admin')
})
</script>

Custom Navigation Items

vue
<script setup>
// Add custom navigation items
const customNavItems = [
  {
    key: 'custom-reports',
    title: 'nav.customReports',
    path: '/dashboard/reports',
    icon: 'mdi-file-chart',
    badge: 'beta'
  }
]

// Combine with default navigation
const allNavItems = computed(() => {
  return [...dashboardNavItems, ...customNavItems]
})
</script>

Customization

Custom Styling

css
/* Custom navigation colors */
.dashboard-nav {
  --nav-bg: rgb(var(--v-theme-surface));
  --nav-border: rgb(var(--v-theme-surface-variant));
  --nav-text: rgb(var(--v-theme-on-surface));
  --nav-active: rgb(var(--v-theme-primary));
}

.nav-item-active {
  background: rgba(var(--nav-active-rgb), 0.12);
  color: var(--nav-active);
}

/* Custom header styling */
.dashboard-header {
  --header-bg: rgb(var(--v-theme-surface));
  --header-border: rgb(var(--v-theme-surface-variant));
  --header-text: rgb(var(--v-theme-on-surface));
}
vue
<script setup>
// Different navigation themes
const navThemes = {
  light: {
    background: '#ffffff',
    border: '#e5e7eb',
    text: '#374151'
  },
  dark: {
    background: '#1f2937',
    border: '#374151',
    text: '#f9fafb'
  },
  colorful: {
    background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
    border: 'transparent',
    text: '#ffffff'
  }
}
</script>

Accessibility Features

All dashboard components are built with accessibility in mind:

Keyboard Navigation

  • Tab Navigation: Full keyboard navigation support
  • Enter/Space: Activate buttons and links
  • Escape: Close mobile navigation and dropdowns
  • Arrow Keys: Navigate through menu items

Screen Reader Support

vue
<template>
  <DashboardNav
    aria-label="Main navigation"
    role="navigation"
  >
    <v-list-item
      v-for="item in navItems"
      :key="item.key"
      :aria-label="t(item.title)"
      role="menuitem"
    >
      {{ t(item.title) }}
    </v-list-item>
  </DashboardNav>
</template>

ARIA Attributes

  • aria-label: Descriptive labels for screen readers
  • role: Proper semantic roles (navigation, menuitem, etc.)
  • aria-expanded: Group expansion state
  • aria-current: Current page indication

Performance Considerations

vue
<script setup>
// Lazy load navigation items
const navItems = ref([])

onMounted(async () => {
  // Load navigation based on user permissions
  const userNav = await fetchNavigationForUser()
  navItems.value = userNav
})
</script>

Mobile Performance

vue
<script setup>
// Optimize mobile navigation
const mobileNavItems = computed(() => {
  // Limit items for mobile performance
  return navItems.value.slice(0, 10)
})
</script>

Best Practices

  1. Keep navigation shallow: Limit nesting to 2-3 levels
  2. Use descriptive icons: Choose icons that clearly represent functionality
  3. Group related items: Use navigation groups for related features
  4. Consider user workflows: Order items by frequency of use

Mobile Experience

  1. Test touch targets: Ensure buttons are at least 44px
  2. Optimize for thumb navigation: Place important items in easy reach
  3. Provide quick actions: Include common actions in mobile header
  4. Consider one-handed use: Design for comfortable interaction

Performance

  1. Lazy load navigation items: Load only when needed
  2. Cache permissions: Avoid repeated permission checks
  3. Debounce resize events: Optimize responsive behavior
  4. Use computed properties: Efficient reactive navigation state

Troubleshooting

Common Issues

Navigation not responsive:

  • Check CSS media queries are working
  • Verify viewport meta tag is set
  • Test on actual devices, not just browser dev tools

Active states not working:

  • Ensure route paths match navigation item paths
  • Check isActiveRoute utility function
  • Verify router configuration

Theme not applying:

  • Check if theme store is properly configured
  • Verify CSS custom properties are defined
  • Test theme switching functionality

Mobile navigation not opening:

  • Check if open prop is properly bound
  • Verify event handlers are working
  • Test touch events on mobile devices

RTL layout issues:

  • Verify direction settings in theme store
  • Check RTL-specific CSS rules
  • Test with actual RTL languages

Integration with Layout System

vue
<!-- In your dashboard layout -->
<template>
  <div class="dashboard-container">
    <!-- Navigation components -->
    <DashboardHeader />
    <DashboardNav />
    <DashboardNavMobile />

    <!-- Content area -->
    <div class="dashboard-content">
      <!-- Page content with proper spacing -->
      <div class="content-wrapper">
        <slot />
      </div>
    </div>
  </div>
</template>

<style>
.dashboard-container {
  display: flex;
  min-height: 100vh;
}

.dashboard-content {
  flex: 1;
  margin-left: var(--nav-width, 300px);
  padding: 24px;
}

@media (max-width: 959px) {
  .dashboard-content {
    margin-left: 0;
  }
}
</style>

Next Steps

Released under the MIT License.