<!-- eslint-disable -->

# AppSidebar Component

A modern, responsive sidebar component for Vue 3 applications with PrimeVue icons support.

## Overview

The `AppSidebar` component provides a collapsible navigation sidebar that adapts seamlessly between desktop and mobile views. It supports customizable logos, navigation links, bottom action links, and smooth animations.

## Features

- ✅ **Responsive Design** - Adapts to desktop and mobile viewports
- ✅ **Collapsible** - Collapse to icon-only mode on desktop
- ✅ **Full-screen Mobile Menu** - Hamburger menu with full-width overlay on mobile
- ✅ **Customizable Logo** - Support for both icon and image logos
- ✅ **Navigation Links** - Main and bottom navigation sections
- ✅ **Badge Support** - Display notification counts on links
- ✅ **Smooth Animations** - Elegant transitions for all interactions
- ✅ **PrimeIcons Integration** - Uses PrimeVue icon library

---

## Installation

<script setup lang="ts">
// eslint-ignore-next-line
import AppSidebar from '@/Components/Layouts/AppSidebar.vue';
</script>

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `logo` | `LogoConfig` | `{ icon: 'pi-box', text: 'App' }` | Logo configuration object |
| `title` | `string` | `'Dashboard'` | Page title (used for accessibility) |
| `links` | `SidebarLink[]` | `[]` | Main navigation links |
| `bottomLinks` | `SidebarLink[]` | `[]` | Links displayed above the collapse button |
| `isCollapsed` | `boolean` | `false` | Whether the sidebar is collapsed |
| `isMobile` | `boolean` | `false` | Whether the viewport is mobile |
| `isMobileOpen` | `boolean` | `false` | Whether the mobile menu is open |

---

## Type Definitions

### LogoConfig

```typescript
interface LogoConfig {
    icon?: string;    // PrimeIcon class (e.g., 'pi-box')
    image?: string;   // Image URL or imported image
    text: string;     // Logo text displayed next to icon
}
```

### SidebarLink

```typescript
interface SidebarLink {
    label: string;              // Display text
    icon: string;               // PrimeIcon class (e.g., 'pi-home')
    href?: string;              // URL for navigation
    route?: string;             // Vue Router route name (optional)
    active?: boolean;           // Whether the link is currently active
    badge?: string | number;    // Badge content (e.g., notification count)
    onClick?: () => void;       // Custom click handler
}
```

---

## Events

| Event | Payload | Description |
|-------|---------|-------------|
| `toggle` | `void` | Emitted when the collapse button is clicked |
| `close` | `void` | Emitted when the mobile close button is clicked |
| `link-click` | `SidebarLink` | Emitted when any navigation link is clicked |

---

## Usage Examples

### Basic Usage

```vue
<script setup lang="ts">
import { ref } from 'vue';
import AppSidebar from '@/Components/Layouts/AppSidebar.vue';

const isCollapsed = ref(false);
const isMobile = ref(false);
const isMobileOpen = ref(false);

const navigationLinks = [
    { label: 'Dashboard', icon: 'pi-home', href: '/', active: true },
    { label: 'Users', icon: 'pi-users', href: '/users' },
    { label: 'Settings', icon: 'pi-cog', href: '/settings' },
];
</script>

<template>
    <AppSidebar
        :logo="{ icon: 'pi-box', text: 'MyApp' }"
        :links="navigationLinks"
        :is-collapsed="isCollapsed"
        :is-mobile="isMobile"
        :is-mobile-open="isMobileOpen"
        @toggle="isCollapsed = !isCollapsed"
        @close="isMobileOpen = false"
    />
</template>
```

### With Image Logo

```vue
<script setup lang="ts">
import Logo from '@/assets/images/logo.png';

const logoConfig = {
    image: Logo,
    text: 'VoM'
};
</script>

<template>
    <AppSidebar
        :logo="logoConfig"
        ... />
</template>
```

### With Badges

```vue
<script setup lang="ts">
const navigationLinks = [
    { label: 'Dashboard', icon: 'pi-home', href: '/' },
    { label: 'Messages', icon: 'pi-envelope', href: '/messages', badge: 12 },
    { label: 'Notifications', icon: 'pi-bell', href: '/notifications', badge: 'New' },
];
</script>
```

### With Bottom Links

```vue
<script setup lang="ts">
const mainLinks = [
    { label: 'Dashboard', icon: 'pi-home', href: '/' },
    { label: 'Analytics', icon: 'pi-chart-bar', href: '/analytics' },
];

const bottomLinks = [
    { label: 'Help & Support', icon: 'pi-question-circle', href: '/help' },
    { label: 'Documentation', icon: 'pi-book', href: '/docs' },
];
</script>

<template>
    <AppSidebar
        :links="mainLinks"
        :bottom-links="bottomLinks"
        ...
    />
</template>
```

### Full Implementation with Main Layout

```vue
<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref } from 'vue';
import Logo from '@/assets/images/logo.png';
import AppSidebar from '@/Components/Layouts/AppSidebar.vue';

// State
const isSidebarCollapsed = ref(false);
const isMobileMenuOpen = ref(false);
const isMobile = ref(false);

// Configuration
const logoConfig = {
    image: Logo,
    text: 'VoM'
};

const mainLinks = [
    { label: 'Dashboard', icon: 'pi-home', href: '/', active: true },
    { label: 'Analytics', icon: 'pi-chart-bar', href: '/analytics' },
    { label: 'Users', icon: 'pi-users', href: '/users', badge: 5 },
    { label: 'Settings', icon: 'pi-cog', href: '/settings' },
];

const bottomLinks = [
    { label: 'Help & Support', icon: 'pi-question-circle', href: '/help' },
    { label: 'Documentation', icon: 'pi-book', href: '/docs' },
];

// Responsive handling
function checkMobile () {
    isMobile.value = window.innerWidth < 1024;
    if (!isMobile.value) {
        isMobileMenuOpen.value = false;
    }
}

function toggleSidebar () {
    if (isMobile.value) {
        isMobileMenuOpen.value = !isMobileMenuOpen.value;
    } else {
        isSidebarCollapsed.value = !isSidebarCollapsed.value;
    }
}

function closeMobileMenu () {
    isMobileMenuOpen.value = false;
}

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

onUnmounted(() => {
    window.removeEventListener('resize', checkMobile);
});
</script>

<template>
    <div class="app-layout">
        <AppSidebar
            :logo="logoConfig"
            :links="mainLinks"
            :bottom-links="bottomLinks"
            :is-collapsed="isSidebarCollapsed"
            :is-mobile="isMobile"
            :is-mobile-open="isMobileMenuOpen"
            @toggle="toggleSidebar"
            @close="closeMobileMenu"
        />
        
        <main class="content">
            <slot />
        </main>
    </div>
</template>
```

---

## Styling

### CSS Variables

The component uses the following design tokens that can be customized:

| Variable | Default | Description |
|----------|---------|-------------|
| Sidebar Background | `#1a1f2e → #252b3d` | Dark gradient background |
| Primary Color | `#25b395` | Accent color for active states |
| Primary Dark | `#1e9077` | Darker accent for gradients |
| Expanded Width | `260px` | Sidebar width when expanded |
| Collapsed Width | `72px` | Sidebar width when collapsed |

### Customizing Styles

To customize the sidebar appearance, you can override the scoped styles in your parent component or create a global CSS file:

```css
/* Example: Change sidebar background */
.sidebar {
    background: linear-gradient(180deg, #1e3a5f 0%, #0d1b2a 100%) !important;
}

/* Example: Change primary accent color */
.nav-link.active {
    background: linear-gradient(135deg, rgba(100, 149, 237, 0.2) 0%, rgba(65, 105, 225, 0.15) 100%) !important;
    color: #6495ed !important;
}
```

---

## Breakpoints

| Breakpoint | Behavior |
|------------|----------|
| `≥ 1024px` | Desktop mode - Collapsible sidebar |
| `< 1024px` | Mobile mode - Full-width overlay menu |

---

## Accessibility

- Uses semantic HTML elements (`<aside>`, `<nav>`, `<ul>`, `<li>`)
- Keyboard navigable links
- ARIA-friendly structure
- Focus states on interactive elements

---

## Dependencies

- **Vue 3** - Composition API
- **PrimeIcons** - Icon library (`primeicons/primeicons.css`)

---

## File Location

```
resources/js/Components/Layouts/AppSidebar.vue
```

---

## Related Components

- `Main.vue` - Main layout that uses AppSidebar
- `AppNavbar.vue` - (Future) Standalone navbar component

---

## Changelog

### v1.0.0
- Initial release
- Responsive sidebar with collapse functionality
- Logo support (icon and image)
- Main and bottom navigation links
- Badge support
- Mobile full-screen overlay
