import { useState, useEffect, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; import { Search, Bell, Menu, Calendar, X, BookOpen, Bus, Users, Calendar as ClubIcon, Code2, Trophy, Bot, } from 'lucide-react'; import { useAuth } from '@/context/AuthContext'; import { BUS_ROUTES, FACULTY_DATA, CLUBS_DATA } from '@/constants'; interface HeaderProps { onToggleSidebar: () => void; } interface NotificationItem { id: string; title: string; message: string; time: string; read: boolean; type: 'academic' | 'dev' | 'campus' | 'bus'; } export default function Header({ onToggleSidebar }: HeaderProps) { const [searchQuery, setSearchQuery] = useState(''); const [isSearchOpen, setIsSearchOpen] = useState(false); const [isNotifOpen, setIsNotifOpen] = useState(false); const [currentDate, setCurrentDate] = useState(''); const navigate = useNavigate(); const { user, isAuthenticated, isVerifiedStudent } = useAuth(); const notifRef = useRef(null); const searchRef = useRef(null); const [notifications, setNotifications] = useState([ { id: '1', title: 'Moodle Notes & PYQs Updated', message: '1st to 8th Semester notes and previous year question papers are published on Moodle.', time: '10m ago', read: false, type: 'academic', }, { id: '2', title: 'Dev Collab Hub Open', message: 'Post open-source project ideas or find co-developers across departments.', time: '1h ago', read: false, type: 'dev', }, { id: '3', title: 'LeetCode Campus Rankings Live', message: 'Monthly competitive programming leaderboard has been updated.', time: '3h ago', read: false, type: 'academic', }, { id: '4', title: 'Campus Bus Schedule Confirmed', message: 'All 4 campus bus routes operating on 7:00 AM morning schedule.', time: '1d ago', read: true, type: 'bus', }, ]); const unreadCount = notifications.filter((n) => !n.read).length; useEffect(() => { const now = new Date(); const formatted = now.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric', }); setCurrentDate(formatted); }, []); // Listen for ⌘K shortcut useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); setIsSearchOpen((prev) => !prev); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, []); // Close dropdowns on outside click useEffect(() => { const handleClickOutside = (e: MouseEvent) => { if (notifRef.current && !notifRef.current.contains(e.target as Node)) { setIsNotifOpen(false); } if (searchRef.current && !searchRef.current.contains(e.target as Node)) { setIsSearchOpen(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); const markAllAsRead = () => { setNotifications((prev) => prev.map((n) => ({ ...n, read: true }))); }; const clearNotifications = () => { setNotifications([]); }; // Search indexing & results calculation const searchResults = (() => { if (!searchQuery.trim()) return []; const q = searchQuery.toLowerCase(); const results: { title: string; desc: string; path: string; icon: any; category: string }[] = []; // Check modules if ('notes pyqs moodle syllabus question paper'.includes(q)) { results.push({ title: 'Academic Notes & PYQs', desc: 'Semester course notes & past papers', path: '/notes', icon: BookOpen, category: 'Academics' }); } if ('bus route timing transport travel pickup'.includes(q)) { results.push({ title: 'Campus Bus Routes', desc: 'Schedules and stops for all campus buses', path: '/bus-routes', icon: Bus, category: 'Utilities' }); } if ('chatbot assistant question help contact rules'.includes(q)) { results.push({ title: 'Campus Chatbot', desc: 'Instant Q&A about campus life & rules', path: '/ai-assistant', icon: Bot, category: 'Academics' }); } if ('collab dev project developer team coding github'.includes(q)) { results.push({ title: 'Dev Collab Hub', desc: 'Find co-developers & build projects', path: '/collab', icon: Code2, category: 'Dev' }); } if ('leetcode ranking leaderboard coding rank'.includes(q)) { results.push({ title: 'LeetCode Leaderboard', desc: 'Campus competitive coding rankings', path: '/leetcode', icon: Trophy, category: 'Dev' }); } // Search Bus Routes BUS_ROUTES.forEach((r) => { if (r.name.toLowerCase().includes(q) || r.number.toLowerCase().includes(q) || r.from.toLowerCase().includes(q)) { results.push({ title: `${r.number}: ${r.name}`, desc: `Departure: ${r.departureTime} from ${r.from}`, path: '/bus-routes', icon: Bus, category: 'Bus Route' }); } }); // Search Faculty FACULTY_DATA.forEach((f) => { if (f.name.toLowerCase().includes(q) || f.department.toLowerCase().includes(q) || (f.specialization && f.specialization.toLowerCase().includes(q))) { results.push({ title: f.name, desc: `${f.designation} — ${f.department}`, path: '/faculty', icon: Users, category: 'Faculty' }); } }); // Search Clubs CLUBS_DATA.forEach((c) => { if (c.name.toLowerCase().includes(q) || c.description.toLowerCase().includes(q)) { results.push({ title: c.name, desc: c.description, path: '/events', icon: ClubIcon, category: 'Club' }); } }); return results.slice(0, 6); })(); const handleSelectResult = (path: string) => { setIsSearchOpen(false); setSearchQuery(''); navigate(path); }; return (
{/* Mobile Toggle */} {/* Global Interactive Search Input Container */}
setIsSearchOpen(true)} className="relative w-full cursor-text" > { setSearchQuery(e.target.value); setIsSearchOpen(true); }} onFocus={() => setIsSearchOpen(true)} placeholder="Search notes, faculty, bus routes..." className="w-full pl-9 pr-8 sm:pr-12 py-2 text-xs font-medium bg-slate-100/90 hover:bg-slate-100 focus:bg-white border border-transparent focus:border-indigo-500/40 rounded-xl text-slate-800 placeholder-slate-400 outline-none transition-all shadow-inner truncate" style={{ fontFamily: 'Inter, sans-serif' }} /> ⌘K
{/* Search Live Results Dropdown Overlay */} {isSearchOpen && (
{searchQuery.trim() ? 'Search Results' : 'Quick Navigation'}
{searchResults.length > 0 ? ( searchResults.map((res, i) => { const Icon = res.icon; return (
handleSelectResult(res.path)} className="flex items-center justify-between p-2.5 rounded-xl hover:bg-indigo-50/70 cursor-pointer transition-colors group" >
{res.title} {res.desc}
{res.category}
); }) ) : (
{searchQuery.trim() ? `No matches found for "${searchQuery}"` : 'Type to search notes, faculty, routes & clubs'}
)}
)}
{/* Right Header Status Bar */}
{/* Date Display Badge */}
{currentDate}
{/* Functional Notifications Dropdown */}
{/* Notifications Panel Dropdown */} {isNotifOpen && (
Notifications {unreadCount > 0 && ( {unreadCount} new )}
{unreadCount > 0 && ( )} {notifications.length > 0 && ( )}
{notifications.length > 0 ? ( notifications.map((n) => (
{n.title} {n.time}

{n.message}

)) ) : (
No new notifications
)}
)}
{/* User Auth Quick Badge (If Logged In) */} {isAuthenticated && user && (
{user.pictureUrl ? ( {user.name} ) : (
{user.name.charAt(0)}
)}
{user.name} {isVerifiedStudent ? 'Verified Student' : 'RIT Account'}
)}
); }