Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ashcroft08/provesa-web/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The AdminSidebar component provides the main navigation sidebar for the PROVESA admin panel. It features a glass-morphism design, active tab highlighting, user profile display, and logout functionality.
Import
import AdminSidebar from '$lib/components/admin/AdminSidebar.svelte';
Props
Array of navigation item objects that define the sidebar menu.NavItem Structure:{
name: string; // Display name and unique identifier
icon: string; // Material Icons icon name
badge?: number; // Optional notification badge count
}
Currently active tab name. This prop is bindable, so changes in the sidebar will update the parent component.Example:let activeTab = $state('Dashboard');
User information object for the profile section.User Structure:{
name?: string; // User's full name
email?: string; // User's email (not displayed but may be used)
}
If not provided or if name is missing, defaults to “Administrador”.
Usage
Basic Usage
<script>
import AdminSidebar from '$lib/components/admin/AdminSidebar.svelte';
let activeTab = $state('Dashboard');
const navItems = [
{ name: 'Dashboard', icon: 'dashboard' },
{ name: 'Productos', icon: 'inventory_2' },
{ name: 'Usuarios', icon: 'people', badge: 3 }
];
const user = {
name: 'Juan Pérez'
};
</script>
<AdminSidebar {navItems} bind:activeTab {user} />
Complete Admin Panel Example
<script>
import AdminSidebar from '$lib/components/admin/AdminSidebar.svelte';
let { data } = $props();
let activeTab = $state('Dashboard');
const navItems = [
{ name: 'Dashboard', icon: 'dashboard' },
{ name: 'Sliders', icon: 'view_carousel' },
{ name: 'Productos', icon: 'inventory_2' },
{ name: 'Nosotros', icon: 'info' },
{ name: 'Footer', icon: 'web' },
{ name: 'Páginas Legales', icon: 'gavel' },
{ name: 'Concursos', icon: 'emoji_events' },
{ name: 'Postulaciones', icon: 'work', badge: 5 },
{ name: 'Sugerencias', icon: 'feedback', badge: 12 },
{ name: 'Configuración', icon: 'settings' }
];
</script>
<AdminSidebar {navItems} bind:activeTab user={data.user} />
<main class="lg:pl-72">
{#if activeTab === 'Dashboard'}
<DashboardTab />
{:else if activeTab === 'Productos'}
<ProductosTab />
{/if}
<!-- More tabs... -->
</main>
Component Structure
Logo Section
Displays the PROVESA logo at the top:
<div class="flex-shrink-0 px-8 pt-6 pb-4">
<img src={logo} alt="Provesa" class="mx-auto h-12 w-auto object-contain" />
</div>
Navigation Items
Scrollable navigation menu in the middle:
<nav class="sidebar-scroll flex-1 space-y-1 overflow-y-auto px-6 py-2">
{#each navItems as item}
<button
onclick={() => (activeTab = item.name)}
class="flex w-full items-center gap-4 rounded-2xl px-4 py-2.5
{activeTab === item.name ? 'active-nav' : 'text-slate-500'}"
>
<span class="material-icons text-[20px]">{item.icon}</span>
{item.name}
{#if item.badge}
<span class="bg-accent-red ml-auto rounded-full px-2 py-0.5
text-[10px] text-white">
{item.badge}
</span>
{/if}
</button>
{/each}
</nav>
User Profile Section
Fixed at the bottom with logout button:
<div class="flex-shrink-0 border-t border-slate-100 px-6 py-4">
<div class="flex items-center gap-3 rounded-2xl bg-slate-50 p-3">
<!-- Avatar with initials -->
<div class="flex h-10 w-10 items-center justify-center rounded-full
bg-primary font-bold text-white uppercase">
{initials}
</div>
<!-- User info -->
<div class="min-w-0 flex-1">
<p class="truncate text-xs font-bold">{user?.name || 'Administrador'}</p>
<p class="truncate text-[10px] text-slate-400">Panel de Control</p>
</div>
<!-- Logout button -->
<form action="?/logout" method="POST" use:enhance>
<button class="hover:text-accent-red text-slate-400 transition-colors">
<span class="material-icons text-lg">logout</span>
</button>
</form>
</div>
</div>
User Initials
The avatar displays user initials derived from the name:
let initials = $derived(
user?.name
? user.name
.split(' ')
.map((n) => n[0])
.join('')
.toUpperCase()
.substring(0, 2)
: 'AD'
);
Examples:
- “Juan Pérez” → “JP”
- “María” → “M”
- “José Antonio López” → “JA”
- No user → “AD”
Active Tab Styling
The active navigation item receives special styling:
.active-nav {
background-color: var(--color-primary);
color: white !important;
box-shadow: 0 10px 15px -3px rgba(0, 82, 165, 0.3);
}
Inactive items:
text-slate-500 hover:bg-slate-50 hover:text-primary
Notification Badges
Optional red badges for items needing attention:
{#if item.badge}
<span class="bg-accent-red ml-auto rounded-full px-2 py-0.5
text-[10px] text-white">
{item.badge}
</span>
{/if}
Example:
{ name: 'Postulaciones', icon: 'work', badge: 5 }
Glass-Morphism Design
The sidebar uses a glass effect:
.glass-sidebar {
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(12px);
border-right: 1px solid rgba(226, 232, 240, 0.8);
}
The navigation area is scrollable with hidden scrollbar:
.sidebar-scroll {
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE/Edge */
}
.sidebar-scroll::-webkit-scrollbar {
display: none; /* Chrome/Safari */
}
This allows for many navigation items without breaking the layout.
Logout Functionality
The logout button submits a form action:
<form action="?/logout" method="POST" use:enhance>
<button title="Cerrar Sesión">
<span class="material-icons text-lg">logout</span>
</button>
</form>
The use:enhance directive provides progressive enhancement for the form submission.
Positioning
position: fixed;
inset-y-0;
left-0;
z-index: 50;
width: 18rem; /* 72 in Tailwind = 288px */
- Fixed to the left side of the viewport
- Full height
- Hidden on screens < 1024px (mobile/tablet)
- Visible on large screens (≥1024px)
Layout Compensation
When using the sidebar, add left padding to main content:
<AdminSidebar {navItems} bind:activeTab {user} />
<main class="lg:pl-72">
<!-- Content here -->
</main>
The lg:pl-72 class adds left padding equal to the sidebar width on large screens.
Material Icons
Requires Material Icons font to be loaded. Common icons used:
| Icon Name | Usage |
|---|
dashboard | Dashboard/Home |
view_carousel | Sliders |
inventory_2 | Products |
info | About/Info |
web | Footer/Web |
gavel | Legal pages |
emoji_events | Contests |
work | Job applications |
feedback | Suggestions |
settings | Settings |
logout | Logout button |
Accessibility
- Uses semantic HTML with
<aside> and <nav> elements
- Button elements for interactive items
- Proper ARIA support through semantic HTML
- Logout button has descriptive
title attribute
- Logo has descriptive
alt text
- Truncated text for long user names
Responsive Behavior
- Mobile/Tablet (< 1024px): Hidden completely
- Desktop (≥ 1024px): Visible as fixed sidebar
For mobile navigation, you would typically implement a separate mobile menu or hamburger menu.
Dependencies
$app/forms - enhance for progressive enhancement
$lib/assets/images/provesa-logo.png - PROVESA logo
- Material Icons font (must be loaded in app)
- Admin tabs (DashboardTab, ProductosTab, etc.)
- Navbar - Public site navigation