import React, { useState, useEffect } from 'react'; import { navItems } from '../data/sondelaData'; const Sidebar = ({ onToggle }) => { const [activeItem, setActiveItem] = useState('dashboard'); const [collapsed, setCollapsed] = useState(false); const [expandedSection, setExpandedSection] = useState(null); useEffect(() => { if (onToggle) { onToggle(collapsed); } }, [collapsed, onToggle]); const toggleSidebar = () => { setCollapsed(!collapsed); // Reset expanded section when collapsing sidebar if (!collapsed) { setExpandedSection(null); } }; // Group navigation items by section const navSections = navItems.reduce((acc, item) => { if (!acc[item.section]) { acc[item.section] = []; } acc[item.section].push(item); return acc; }, {}); // Toggle section expansion const toggleSection = (section) => { if (collapsed) return; // Don't toggle when sidebar is collapsed setExpandedSection(expandedSection === section ? null : section); }; return ( <div className={`sidebar bg-gradient-to-b from-blue-900 to-blue-800 text-white shadow-xl ${collapsed ? 'collapsed w-20' : 'w-64'} flex flex-col h-screen transition-all duration-300`} > {/* Logo */} <div className="p-4 flex items-center justify-between border-b border-blue-800"> <div className="flex items-center"> <div className="bg-white p-2 rounded-lg"> <i className="fas fa-shield-alt text-blue-800 text-xl"></i> </div> {!collapsed && ( <h1 className="logo-text text-xl font-bold ml-3">Sondela</h1> )} </div> {/* Collapse Button */} <button className="text-blue-200 hover:text-white hover:bg-blue-700 p-1.5 rounded-md transition-colors" onClick={toggleSidebar} aria-label={collapsed ? "Expand sidebar" : "Collapse sidebar"} > <i className={`fas fa-chevron-${collapsed ? 'right' : 'left'}`}></i> </button> </div> {/* User Profile */} <div className="p-4 flex items-center border-b border-blue-800"> <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="User" className={`${collapsed ? 'w-10 h-10 mx-auto' : 'w-10 h-10'} rounded-full border-2 border-white shadow-md`} /> {!collapsed && ( <div className="ml-3"> <p className="font-semibold">Cmdt. Williams</p> <div className="flex items-center"> <span className="inline-block w-2 h-2 bg-green-500 rounded-full mr-1.5"></span> <p className="text-blue-200 text-xs">Online</p> </div> </div> )} </div> {/* Navigation */} <nav className="flex-1 overflow-y-auto custom-scrollbar pt-2"> {Object.keys(navSections).map((section) => ( <div key={section} className="mb-2"> {/* Section Header */} {!collapsed && ( <div className="flex items-center justify-between px-4 py-2 text-blue-300 text-xs uppercase font-semibold cursor-pointer hover:text-white" onClick={() => toggleSection(section)} > <span>{section}</span> {section !== 'Main' && ( <i className={`fas fa-chevron-${expandedSection === section ? 'down' : 'right'} text-xs`}></i> )} </div> )} {/* Section Items */} <ul className={`${ collapsed || section === 'Main' || expandedSection === section ? 'max-h-96' : 'max-h-0' } overflow-hidden transition-all duration-300`}> {navSections[section].map((item) => ( <li key={item.id} className="px-2"> <a href="#" className={`nav-item flex items-center rounded-lg ${ collapsed ? 'justify-center mx-auto py-3 px-1' : 'py-2.5 px-4' } hover:bg-blue-800/50 transition-all duration-200 ${ activeItem === item.id ? 'bg-blue-800 text-white' : 'text-blue-100 hover:text-white' }`} onClick={() => setActiveItem(item.id)} > <div className="relative"> <i className={`fas fa-${item.icon} ${collapsed ? 'text-xl' : ''}`}></i> {item.badge && ( <span className="absolute -right-2 -top-2 bg-red-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center"> {item.badge} </span> )} </div> {!collapsed && ( <> <span className="ml-3 flex-grow">{item.name}</span> {item.badge && ( <span className="bg-red-500 text-xs text-white px-2 py-0.5 rounded-full"> {item.badge} </span> )} </> )} </a> </li> ))} </ul> </div> ))} </nav> {/* Footer */} <div className="p-4 border-t border-blue-800"> {collapsed ? ( <div className="text-center"> <button className="text-blue-200 hover:text-white p-2 rounded-full hover:bg-blue-700"> <i className="fas fa-sign-out-alt"></i> </button> </div> ) : ( <div className="flex items-center justify-between"> <div> <p className="text-sm text-blue-200">System Status</p> <p className="text-xs flex items-center"> <span className="w-2 h-2 bg-green-500 rounded-full inline-block mr-1"></span> Online </p> </div> <button className="text-blue-200 hover:text-white p-2 rounded hover:bg-blue-700"> <i className="fas fa-sign-out-alt mr-1"></i> {!collapsed && <span>Logout</span>} </button> </div> )} </div> </div> ); }; export default Sidebar; - Initial Deployment
8900547
verified
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Sondela Sidebar</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .sidebar { | |
| transition: all 0.3s ease; | |
| } | |
| .nav-item.active { | |
| background-color: rgba(30, 58, 138, 1); | |
| color: white; | |
| } | |
| .nav-item:not(.active) { | |
| color: rgb(191, 219, 254); | |
| } | |
| .nav-item:not(.active):hover { | |
| background-color: rgba(30, 58, 138, 0.5); | |
| color: white; | |
| } | |
| .custom-scrollbar::-webkit-scrollbar { | |
| width: 4px; | |
| } | |
| .custom-scrollbar::-webkit-scrollbar-track { | |
| background: rgba(30, 58, 138, 0.3); | |
| } | |
| .custom-scrollbar::-webkit-scrollbar-thumb { | |
| background-color: rgba(191, 219, 254, 0.5); | |
| border-radius: 20px; | |
| } | |
| @media (max-width: 768px) { | |
| .sidebar { | |
| position: fixed; | |
| z-index: 50; | |
| transform: translateX(-100%); | |
| } | |
| .sidebar.open { | |
| transform: translateX(0); | |
| } | |
| .sidebar.collapsed { | |
| transform: translateX(-100%); | |
| } | |
| .overlay { | |
| display: none; | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background-color: rgba(0, 0, 0, 0.5); | |
| z-index: 40; | |
| } | |
| .overlay.active { | |
| display: block; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100"> | |
| <div class="flex h-screen"> | |
| <!-- Overlay for mobile --> | |
| <div class="overlay" id="overlay"></div> | |
| <!-- Sidebar --> | |
| <div class="sidebar bg-gradient-to-b from-blue-900 to-blue-800 text-white shadow-xl w-64 flex flex-col h-screen transition-all duration-300" id="sidebar"> | |
| <!-- Logo --> | |
| <div class="p-4 flex items-center justify-between border-b border-blue-800"> | |
| <div class="flex items-center"> | |
| <div class="bg-white p-2 rounded-lg"> | |
| <i class="fas fa-shield-alt text-blue-800 text-xl"></i> | |
| </div> | |
| <h1 class="logo-text text-xl font-bold ml-3">Sondela</h1> | |
| </div> | |
| <!-- Collapse Button --> | |
| <button class="text-blue-200 hover:text-white hover:bg-blue-700 p-1.5 rounded-md transition-colors lg:block hidden" onclick="toggleSidebar()"> | |
| <i class="fas fa-chevron-left"></i> | |
| </button> | |
| <!-- Mobile close button --> | |
| <button class="text-blue-200 hover:text-white hover:bg-blue-700 p-1.5 rounded-md transition-colors lg:hidden" onclick="closeMobileSidebar()"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <!-- User Profile --> | |
| <div class="p-4 flex items-center border-b border-blue-800"> | |
| <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="User" class="w-10 h-10 rounded-full border-2 border-white shadow-md"> | |
| <div class="ml-3"> | |
| <p class="font-semibold">Cmdt. Williams</p> | |
| <div class="flex items-center"> | |
| <span class="inline-block w-2 h-2 bg-green-500 rounded-full mr-1.5"></span> | |
| <p class="text-blue-200 text-xs">Online</p> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Navigation --> | |
| <nav class="flex-1 overflow-y-auto custom-scrollbar pt-2" id="nav"> | |
| <!-- Main Section --> | |
| <div class="mb-2"> | |
| <div class="flex items-center justify-between px-4 py-2 text-blue-300 text-xs uppercase font-semibold"> | |
| <span>Main</span> | |
| </div> | |
| <ul class="max-h-96"> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item active flex items-center py-2.5 px-4 rounded-lg hover:bg-blue-800/50 transition-all duration-200"> | |
| <div class="relative"> | |
| <i class="fas fa-tachometer-alt"></i> | |
| </div> | |
| <span class="ml-3 flex-grow">Dashboard</span> | |
| </a> | |
| </li> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center py-2.5 px-4 rounded-lg hover:bg-blue-800/50 transition-all duration-200"> | |
| <div class="relative"> | |
| <i class="fas fa-envelope"></i> | |
| <span class="absolute -right-2 -top-2 bg-red-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center">3</span> | |
| </div> | |
| <span class="ml-3 flex-grow">Messages</span> | |
| <span class="bg-red-500 text-xs text-white px-2 py-0.5 rounded-full">3</span> | |
| </a> | |
| </li> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center py-2.5 px-4 rounded-lg hover:bg-blue-800/50 transition-all duration-200"> | |
| <div class="relative"> | |
| <i class="fas fa-calendar"></i> | |
| </div> | |
| <span class="ml-3 flex-grow">Calendar</span> | |
| </a> | |
| </li> | |
| </ul> | |
| </div> | |
| <!-- Operations Section --> | |
| <div class="mb-2"> | |
| <div class="flex items-center justify-between px-4 py-2 text-blue-300 text-xs uppercase font-semibold cursor-pointer hover:text-white" onclick="toggleSection('operations')"> | |
| <span>Operations</span> | |
| <i class="fas fa-chevron-down text-xs" id="operations-chevron"></i> | |
| </div> | |
| <ul class="max-h-96 overflow-hidden" id="operations-section"> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center py-2.5 px-4 rounded-lg hover:bg-blue-800/50 transition-all duration-200"> | |
| <div class="relative"> | |
| <i class="fas fa-users"></i> | |
| </div> | |
| <span class="ml-3 flex-grow">Personnel</span> | |
| </a> | |
| </li> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center py-2.5 px-4 rounded-lg hover:bg-blue-800/50 transition-all duration-200"> | |
| <div class="relative"> | |
| <i class="fas fa-map-marked-alt"></i> | |
| </div> | |
| <span class="ml-3 flex-grow">Locations</span> | |
| </a> | |
| </li> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center py-2.5 px-4 rounded-lg hover:bg-blue-800/50 transition-all duration-200"> | |
| <div class="relative"> | |
| <i class="fas fa-tasks"></i> | |
| </div> | |
| <span class="ml-3 flex-grow">Tasks</span> | |
| <span class="bg-yellow-500 text-xs text-white px-2 py-0.5 rounded-full">5</span> | |
| </a> | |
| </li> | |
| </ul> | |
| </div> | |
| <!-- Reports Section --> | |
| <div class="mb-2"> | |
| <div class="flex items-center justify-between px-4 py-2 text-blue-300 text-xs uppercase font-semibold cursor-pointer hover:text-white" onclick="toggleSection('reports')"> | |
| <span>Reports</span> | |
| <i class="fas fa-chevron-right text-xs" id="reports-chevron"></i> | |
| </div> | |
| <ul class="max-h-0 overflow-hidden" id="reports-section"> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center py-2.5 px-4 rounded-lg hover:bg-blue-800/50 transition-all duration-200"> | |
| <div class="relative"> | |
| <i class="fas fa-chart-line"></i> | |
| </div> | |
| <span class="ml-3 flex-grow">Analytics</span> | |
| </a> | |
| </li> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center py-2.5 px-4 rounded-lg hover:bg-blue-800/50 transition-all duration-200"> | |
| <div class="relative"> | |
| <i class="fas fa-file-alt"></i> | |
| </div> | |
| <span class="ml-3 flex-grow">Documents</span> | |
| </a> | |
| </li> | |
| </ul> | |
| </div> | |
| </nav> | |
| <!-- Footer --> | |
| <div class="p-4 border-t border-blue-800"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <p class="text-sm text-blue-200">System Status</p> | |
| <p class="text-xs flex items-center"> | |
| <span class="w-2 h-2 bg-green-500 rounded-full inline-block mr-1"></span> | |
| Online | |
| </p> | |
| </div> | |
| <button class="text-blue-200 hover:text-white p-2 rounded hover:bg-blue-700"> | |
| <i class="fas fa-sign-out-alt mr-1"></i> | |
| <span>Logout</span> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Collapsed Sidebar --> | |
| <div class="sidebar bg-gradient-to-b from-blue-900 to-blue-800 text-white shadow-xl w-20 flex flex-col h-screen transition-all duration-300 hidden" id="collapsed-sidebar"> | |
| <!-- Logo --> | |
| <div class="p-4 flex items-center justify-center border-b border-blue-800"> | |
| <div class="bg-white p-2 rounded-lg"> | |
| <i class="fas fa-shield-alt text-blue-800 text-xl"></i> | |
| </div> | |
| </div> | |
| <!-- User Profile --> | |
| <div class="p-4 flex items-center justify-center border-b border-blue-800"> | |
| <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="User" class="w-10 h-10 rounded-full border-2 border-white shadow-md"> | |
| </div> | |
| <!-- Navigation --> | |
| <nav class="flex-1 overflow-y-auto custom-scrollbar pt-2"> | |
| <!-- Main Section --> | |
| <div class="mb-2"> | |
| <ul class="max-h-96"> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item active flex items-center justify-center py-3 px-1 rounded-lg hover:bg-blue-800/50 transition-all duration-200 mx-auto"> | |
| <div class="relative"> | |
| <i class="fas fa-tachometer-alt text-xl"></i> | |
| </div> | |
| </a> | |
| </li> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center justify-center py-3 px-1 rounded-lg hover:bg-blue-800/50 transition-all duration-200 mx-auto"> | |
| <div class="relative"> | |
| <i class="fas fa-envelope text-xl"></i> | |
| <span class="absolute -right-2 -top-2 bg-red-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center">3</span> | |
| </div> | |
| </a> | |
| </li> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center justify-center py-3 px-1 rounded-lg hover:bg-blue-800/50 transition-all duration-200 mx-auto"> | |
| <div class="relative"> | |
| <i class="fas fa-calendar text-xl"></i> | |
| </div> | |
| </a> | |
| </li> | |
| </ul> | |
| </div> | |
| <!-- Operations Section --> | |
| <div class="mb-2"> | |
| <ul class="max-h-96"> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center justify-center py-3 px-1 rounded-lg hover:bg-blue-800/50 transition-all duration-200 mx-auto"> | |
| <div class="relative"> | |
| <i class="fas fa-users text-xl"></i> | |
| </div> | |
| </a> | |
| </li> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center justify-center py-3 px-1 rounded-lg hover:bg-blue-800/50 transition-all duration-200 mx-auto"> | |
| <div class="relative"> | |
| <i class="fas fa-map-marked-alt text-xl"></i> | |
| </div> | |
| </a> | |
| </li> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center justify-center py-3 px-1 rounded-lg hover:bg-blue-800/50 transition-all duration-200 mx-auto"> | |
| <div class="relative"> | |
| <i class="fas fa-tasks text-xl"></i> | |
| </div> | |
| </a> | |
| </li> | |
| </ul> | |
| </div> | |
| <!-- Reports Section --> | |
| <div class="mb-2"> | |
| <ul> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center justify-center py-3 px-1 rounded-lg hover:bg-blue-800/50 transition-all duration-200 mx-auto"> | |
| <div class="relative"> | |
| <i class="fas fa-chart-line text-xl"></i> | |
| </div> | |
| </a> | |
| </li> | |
| <li class="px-2"> | |
| <a href="#" class="nav-item flex items-center justify-center py-3 px-1 rounded-lg hover:bg-blue-800/50 transition-all duration-200 mx-auto"> | |
| <div class="relative"> | |
| <i class="fas fa-file-alt text-xl"></i> | |
| </div> | |
| </a> | |
| </li> | |
| </ul> | |
| </div> | |
| </nav> | |
| <!-- Footer --> | |
| <div class="p-4 border-t border-blue-800"> | |
| <div class="text-center"> | |
| <button class="text-blue-200 hover:text-white p-2 rounded-full hover:bg-blue-700"> | |
| <i class="fas fa-sign-out-alt"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="flex-1 overflow-auto"> | |
| <!-- Mobile menu button --> | |
| <div class="lg:hidden p-4"> | |
| <button class="text-blue-900 p-2 rounded-md" onclick="openMobileSidebar()"> | |
| <i class="fas fa-bars text-xl"></i> | |
| </button> | |
| </div> | |
| <div class="p-8"> | |
| <h1 class="text-3xl font-bold text-blue-900 mb-6">Dashboard</h1> | |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> | |
| <div class="bg-white p-6 rounded-lg shadow-md"> | |
| <h2 class="text-xl font-semibold mb-4">Recent Activity</h2> | |
| <p class="text-gray-600">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> | |
| </div> | |
| <div class="bg-white p-6 rounded-lg shadow-md"> | |
| <h2 class="text-xl font-semibold mb-4">Notifications</h2> | |
| <p class="text-gray-600">Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> | |
| </div> | |
| <div class="bg-white p-6 rounded-lg shadow-md"> | |
| <h2 class="text-xl font-semibold mb-4">Quick Actions</h2> | |
| <p class="text-gray-600">Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Toggle sidebar between expanded and collapsed states | |
| function toggleSidebar() { | |
| const sidebar = document.getElementById('sidebar'); | |
| const collapsedSidebar = document.getElementById('collapsed-sidebar'); | |
| if (sidebar.classList.contains('hidden')) { | |
| sidebar.classList.remove('hidden'); | |
| collapsedSidebar.classList.add('hidden'); | |
| } else { | |
| sidebar.classList.add('hidden'); | |
| collapsedSidebar.classList.remove('hidden'); | |
| } | |
| } | |
| // Toggle section expansion | |
| function toggleSection(section) { | |
| const sectionElement = document.getElementById(`${section}-section`); | |
| const chevron = document.getElementById(`${section}-chevron`); | |
| if (sectionElement.classList.contains('max-h-96')) { | |
| sectionElement.classList.remove('max-h-96'); | |
| sectionElement.classList.add('max-h-0'); | |
| chevron.classList.remove('fa-chevron-down'); | |
| chevron.classList.add('fa-chevron-right'); | |
| } else { | |
| sectionElement.classList.remove('max-h-0'); | |
| sectionElement.classList.add('max-h-96'); | |
| chevron.classList.remove('fa-chevron-right'); | |
| chevron.classList.add('fa-chevron-down'); | |
| } | |
| } | |
| // Mobile sidebar functions | |
| function openMobileSidebar() { | |
| document.getElementById('sidebar').classList.add('open'); | |
| document.getElementById('overlay').classList.add('active'); | |
| } | |
| function closeMobileSidebar() { | |
| document.getElementById('sidebar').classList.remove('open'); | |
| document.getElementById('overlay').classList.remove('active'); | |
| } | |
| // Close sidebar when clicking on overlay | |
| document.getElementById('overlay').addEventListener('click', closeMobileSidebar); | |
| // Set active nav item | |
| document.querySelectorAll('.nav-item').forEach(item => { | |
| item.addEventListener('click', function() { | |
| document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('active')); | |
| this.classList.add('active'); | |
| // Close mobile sidebar after selection | |
| if (window.innerWidth < 768) { | |
| closeMobileSidebar(); | |
| } | |
| }); | |
| }); | |
| // Responsive behavior | |
| function handleResize() { | |
| if (window.innerWidth >= 768) { | |
| document.getElementById('sidebar').classList.remove('open'); | |
| document.getElementById('overlay').classList.remove('active'); | |
| } | |
| } | |
| window.addEventListener('resize', handleResize); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=BUYELELE/sondela" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |