|
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; |