| | import React from 'react'; |
| | import type { View } from '../types'; |
| | import { |
| | BonsaiIcon, |
| | SparklesIcon, |
| | BugIcon, |
| | LeafIcon, |
| | WrenchIcon, |
| | BookUserIcon, |
| | StethoscopeIcon, |
| | PaletteIcon, |
| | ScanIcon, |
| | SnailIcon, |
| | FilterIcon, |
| | RootsIcon, |
| | PotRulerIcon, |
| | SunClockIcon, |
| | BeakerIcon, |
| | ShovelIcon, |
| | UmbrellaIcon, |
| | ScissorsIcon, |
| | SettingsIcon, |
| | ChevronsLeftIcon |
| | } from './icons'; |
| | import { AuthContext } from '../context/AuthContext'; |
| |
|
| |
|
| | interface SidebarProps { |
| | activeView: View; |
| | setActiveView: (view: View) => void; |
| | isCollapsed: boolean; |
| | setIsCollapsed: (isCollapsed: boolean) => void; |
| | } |
| |
|
| | const CATEGORIZED_NAV_ITEMS = [ |
| | { |
| | category: 'Core', |
| | items: [ |
| | { id: 'garden', name: 'My Garden', icon: BookUserIcon }, |
| | { id: 'steward', name: 'New Tree Analysis', icon: SparklesIcon }, |
| | ] |
| | }, |
| | { |
| | category: 'AI Studios', |
| | items: [ |
| | { id: 'designStudio', name: 'AI Design Studio', icon: PaletteIcon }, |
| | { id: 'wiringGuide', name: 'AI Wiring Guide', icon: SnailIcon }, |
| | { id: 'nebariDeveloper', name: 'Nebari Developer', icon: RootsIcon }, |
| | |
| | ] |
| | }, |
| | { |
| | category: 'Diagnostics', |
| | items: [ |
| | { id: 'healthCheck', name: 'Health Check-up', icon: StethoscopeIcon }, |
| | { id: 'speciesIdentifier', name: 'Species Identifier', icon: ScanIcon }, |
| | { id: 'soilAnalyzer', name: 'Soil Analyzer', icon: FilterIcon }, |
| | { id: 'weatherShield', name: 'Weather Shield', icon: UmbrellaIcon }, |
| | ] |
| | }, |
| | { |
| | category: 'Utilities', |
| | items: [ |
| | { id: 'sunTracker', name: 'Sun Tracker', icon: SunClockIcon }, |
| | { id: 'potCalculator', name: 'Pot Calculator', icon: PotRulerIcon }, |
| | { id: 'fertilizerMixer', name: 'Fertilizer Mixer', icon: BeakerIcon }, |
| | { id: 'soilVolumeCalculator', name: 'Soil Mix Calculator', icon: ShovelIcon }, |
| | { id: 'tools', name: 'Tool Guide', icon: WrenchIcon }, |
| | ] |
| | }, |
| | { |
| | category: 'Reference', |
| | items: [ |
| | { id: 'pests', name: 'Pest Library', icon: BugIcon }, |
| | { id: 'seasons', name: 'Seasonal Guides', icon: LeafIcon }, |
| | ] |
| | }, |
| | ]; |
| |
|
| |
|
| | const Sidebar: React.FC<SidebarProps> = ({ activeView, setActiveView, isCollapsed, setIsCollapsed }) => { |
| | const { logout } = React.useContext(AuthContext); |
| |
|
| | return ( |
| | <aside className={`flex-shrink-0 bg-white border-r border-stone-200 flex flex-col transition-all duration-300 ${isCollapsed ? 'w-20' : 'w-64'}`}> |
| | <div className={`h-16 flex items-center border-b border-stone-200 transition-all duration-300 ${isCollapsed ? 'justify-center' : 'justify-center px-4'}`}> |
| | <div className="flex items-center gap-2"> |
| | <BonsaiIcon className="h-8 w-8 text-green-700 flex-shrink-0" /> |
| | {!isCollapsed && <h1 className="text-xl font-bold text-stone-800">Yuki</h1>} |
| | </div> |
| | </div> |
| | <nav className="flex-1 px-2 py-4 space-y-2 overflow-y-auto"> |
| | {CATEGORIZED_NAV_ITEMS.map((category) => ( |
| | <div key={category.category}> |
| | {!isCollapsed && <h2 className="px-4 text-xs font-bold uppercase text-stone-500 tracking-wider">{category.category}</h2>} |
| | {isCollapsed && category.category === 'Core' && <div className="h-px bg-stone-200 my-2 mx-4"></div>} |
| | <div className="mt-2 space-y-1"> |
| | {category.items.map((item) => ( |
| | <button |
| | key={item.id} |
| | onClick={() => setActiveView(item.id as View)} |
| | title={item.name} |
| | className={`w-full flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm font-medium transition-colors ${isCollapsed ? 'justify-center' : ''} |
| | ${ |
| | activeView === item.id |
| | ? 'bg-green-100 text-green-800' |
| | : 'text-stone-600 hover:bg-stone-100 hover:text-stone-900' |
| | } |
| | `} |
| | > |
| | <item.icon className="h-5 w-5 flex-shrink-0" /> |
| | {!isCollapsed && <span>{item.name}</span>} |
| | </button> |
| | ))} |
| | </div> |
| | </div> |
| | ))} |
| | </nav> |
| | <div className="flex-shrink-0 p-2 border-t border-stone-200"> |
| | <button |
| | key="settings" |
| | onClick={() => setActiveView('settings')} |
| | title="Settings" |
| | className={`w-full flex items-center gap-3 px-4 py-2.5 rounded-lg text-sm font-medium transition-colors ${isCollapsed ? 'justify-center' : ''} |
| | ${ |
| | activeView === 'settings' |
| | ? 'bg-green-100 text-green-800' |
| | : 'text-stone-600 hover:bg-stone-100 hover:text-stone-900' |
| | } |
| | `} |
| | > |
| | <SettingsIcon className="h-5 w-5 flex-shrink-0" /> |
| | {!isCollapsed && <span>Settings</span>} |
| | </button> |
| | <div className="p-2 border-t border-stone-200 mt-2"> |
| | <button |
| | onClick={() => setIsCollapsed(!isCollapsed)} |
| | className={`w-full flex items-center gap-3 px-4 py-2 text-sm font-medium text-stone-600 hover:bg-stone-100 rounded-lg ${isCollapsed ? 'justify-center' : ''}`} |
| | title={isCollapsed ? 'Expand Sidebar' : 'Collapse Sidebar'} |
| | > |
| | <ChevronsLeftIcon className={`h-5 w-5 flex-shrink-0 transition-transform duration-300 ${isCollapsed ? 'rotate-180' : ''}`} /> |
| | {!isCollapsed && <span>Collapse</span>} |
| | </button> |
| | </div> |
| | </div> |
| | </aside> |
| | ); |
| | }; |
| |
|
| | export default Sidebar; |