import { useState, useEffect, useCallback, useMemo, useRef } from 'react' import { ClipboardList, FileText, Pill, AlertTriangle, FlaskConical, FolderOpen, Send, Search, X, } from 'lucide-react' import type { ViewId } from '../types/pmr' import { useAccessibility } from '../contexts/AccessibilityContext' interface NavItem { id: ViewId label: string icon: React.ReactNode } interface ClinicalSidebarProps { activeView: ViewId onViewChange: (view: ViewId) => void isTablet?: boolean } const navItems: NavItem[] = [ { id: 'summary', label: 'Summary', icon: }, { id: 'consultations', label: 'Consultations', icon: }, { id: 'medications', label: 'Medications', icon: }, { id: 'problems', label: 'Problems', icon: }, { id: 'investigations', label: 'Investigations', icon: }, { id: 'documents', label: 'Documents', icon: }, { id: 'referrals', label: 'Referrals', icon: }, ] function getCurrentTime(): string { const now = new Date() return now.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit', }) } export function ClinicalSidebar({ activeView, onViewChange, isTablet = false }: ClinicalSidebarProps) { const [currentTime, setCurrentTime] = useState(getCurrentTime) const [searchQuery, setSearchQuery] = useState('') const [isSearchFocused, setIsSearchFocused] = useState(false) const [focusedIndex, setFocusedIndex] = useState(null) const [hoveredItem, setHoveredItem] = useState(null) const navButtonRefs = useRef<(HTMLButtonElement | null)[]>([]) const { focusAfterLoginRef } = useAccessibility() const handleNavClick = useCallback( (view: ViewId) => { onViewChange(view) window.location.hash = view }, [onViewChange] ) const handleNavKeyDown = useCallback((e: React.KeyboardEvent, index: number) => { switch (e.key) { case 'ArrowDown': e.preventDefault() if (index < navItems.length - 1) { setFocusedIndex(index + 1) navButtonRefs.current[index + 1]?.focus() } break case 'ArrowUp': e.preventDefault() if (index > 0) { setFocusedIndex(index - 1) navButtonRefs.current[index - 1]?.focus() } break case 'Enter': case ' ': e.preventDefault() handleNavClick(navItems[index].id) break case 'Home': e.preventDefault() setFocusedIndex(0) navButtonRefs.current[0]?.focus() break case 'End': e.preventDefault() setFocusedIndex(navItems.length - 1) navButtonRefs.current[navItems.length - 1]?.focus() break } }, [handleNavClick]) useEffect(() => { const interval = setInterval(() => { setCurrentTime(getCurrentTime()) }, 60000) return () => clearInterval(interval) }, []) useEffect(() => { const handleHashChange = () => { const hash = window.location.hash.slice(1) as ViewId if (navItems.some(item => item.id === hash)) { onViewChange(hash) } } handleHashChange() window.addEventListener('hashchange', handleHashChange) return () => window.removeEventListener('hashchange', handleHashChange) }, [onViewChange]) useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.altKey && e.key >= '1' && e.key <= '7') { e.preventDefault() const index = parseInt(e.key) - 1 if (navItems[index]) { const view = navItems[index].id onViewChange(view) window.location.hash = view } } if (e.key === '/' && !isSearchFocused && document.activeElement?.tagName !== 'INPUT') { e.preventDefault() const searchInput = document.getElementById('sidebar-search') searchInput?.focus() } } window.addEventListener('keydown', handleKeyDown) return () => window.removeEventListener('keydown', handleKeyDown) }, [onViewChange, isSearchFocused]) useEffect(() => { if (navButtonRefs.current[0]) { ;(focusAfterLoginRef as React.MutableRefObject).current = navButtonRefs.current[0] } }, [focusAfterLoginRef]) const handleSearchKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Escape') { setSearchQuery('') ;(e.target as HTMLInputElement).blur() } } const clearSearch = () => { setSearchQuery('') const searchInput = document.getElementById('sidebar-search') searchInput?.focus() } const filteredItems = useMemo(() => { if (!searchQuery.trim()) return [] const query = searchQuery.toLowerCase() return navItems.filter(item => item.label.toLowerCase().includes(query) ) }, [searchQuery]) if (isTablet) { return ( ) } return ( ) }