Spaces:
Sleeping
Sleeping
Download src/components/Navbar.tsx from viraj-421/InterviewAI: direct link, hf CLI and curl.
- Browser
- Download file 5.86 kB
-
https://huggingface.co/spaces/viraj-421/InterviewAI/resolve/main/src/components/Navbar.tsx
- Command line
-
hf download hf://spaces/viraj-421/InterviewAI/src/components/Navbar.tsx
-
curl -L -o Navbar.tsx https://huggingface.co/spaces/viraj-421/InterviewAI/resolve/main/src/components/Navbar.tsx
5.86 kB
| 'use client'; | |
| import Link from 'next/link'; | |
| import { usePathname, useRouter } from 'next/navigation'; | |
| import { motion } from 'framer-motion'; | |
| import { useAuth } from '@/context/AuthContext'; | |
| import { Brain, Home, BarChart3, Settings, LogIn, LogOut, User, Award } from 'lucide-react'; | |
| export default function Navbar() { | |
| const pathname = usePathname(); | |
| const router = useRouter(); | |
| const { user, isAuthenticated, logout } = useAuth(); | |
| const isActive = (path: string) => pathname === path; | |
| const handleLogout = () => { | |
| logout(); | |
| router.push('/'); | |
| }; | |
| return ( | |
| <motion.nav | |
| initial={{ y: -20, opacity: 0 }} | |
| animate={{ y: 0, opacity: 1 }} | |
| transition={{ duration: 0.5 }} | |
| className="glass fixed top-0 left-0 right-0 z-50" | |
| style={{ borderBottom: '1px solid var(--border)' }} | |
| > | |
| <div className="max-w-7xl mx-auto px-6 h-16 flex items-center justify-between"> | |
| {/* Logo */} | |
| <Link href="/" className="flex items-center gap-3 group"> | |
| <div | |
| className="w-10 h-10 rounded-xl flex items-center justify-center glow-primary" | |
| style={{ background: 'var(--gradient-primary)' }} | |
| > | |
| <Brain className="w-5 h-5 text-white" /> | |
| </div> | |
| <span className="font-bold text-lg tracking-tight"> | |
| <span className="text-gradient">InterviewAI</span> | |
| </span> | |
| </Link> | |
| {/* Navigation */} | |
| <div className="flex items-center gap-1"> | |
| <NavLink href="/" active={isActive('/')}> | |
| <Home className="w-4 h-4" /> | |
| <span className="hidden sm:inline">Home</span> | |
| </NavLink> | |
| <NavLink href="/interview" active={isActive('/interview') || isActive('/interview/session')}> | |
| <Brain className="w-4 h-4" /> | |
| <span className="hidden sm:inline">Interview</span> | |
| </NavLink> | |
| <NavLink href="/dashboard" active={isActive('/dashboard')}> | |
| <BarChart3 className="w-4 h-4" /> | |
| <span className="hidden sm:inline">Dashboard</span> | |
| </NavLink> | |
| <NavLink href="/results" active={isActive('/results')}> | |
| <Award className="w-4 h-4" /> | |
| <span className="hidden sm:inline">Results</span> | |
| </NavLink> | |
| </div> | |
| {/* User Area */} | |
| <div className="flex items-center gap-2"> | |
| {isAuthenticated && user ? ( | |
| <div className="flex items-center gap-3"> | |
| {/* User Badge */} | |
| <div className="flex items-center gap-2 px-3 py-1.5 rounded-lg" | |
| style={{ background: 'rgba(108, 92, 231, 0.08)', border: '1px solid rgba(108, 92, 231, 0.15)' }} | |
| > | |
| <div className="w-6 h-6 rounded-full flex items-center justify-center text-xs font-bold" | |
| style={{ background: 'var(--gradient-primary)', color: 'white' }}> | |
| {user.displayName.charAt(0).toUpperCase()} | |
| </div> | |
| <span className="text-sm font-medium hidden sm:inline" style={{ color: 'var(--primary-light)' }}> | |
| {user.displayName.split(' ')[0]} | |
| </span> | |
| </div> | |
| {/* Settings */} | |
| <Link | |
| href="/settings" | |
| className="p-2 rounded-lg transition-all duration-300" | |
| style={{ color: 'var(--muted)' }} | |
| onMouseEnter={(e) => { e.currentTarget.style.color = 'var(--foreground)'; }} | |
| onMouseLeave={(e) => { e.currentTarget.style.color = 'var(--muted)'; }} | |
| > | |
| <Settings className="w-4 h-4" /> | |
| </Link> | |
| {/* Logout */} | |
| <button | |
| onClick={handleLogout} | |
| className="p-2 rounded-lg transition-all duration-300 cursor-pointer" | |
| style={{ color: 'var(--muted)' }} | |
| onMouseEnter={(e) => { e.currentTarget.style.color = 'var(--danger)'; }} | |
| onMouseLeave={(e) => { e.currentTarget.style.color = 'var(--muted)'; }} | |
| title="Logout" | |
| > | |
| <LogOut className="w-4 h-4" /> | |
| </button> | |
| </div> | |
| ) : ( | |
| <Link | |
| href="/login" | |
| className="flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-all duration-300" | |
| style={{ background: 'var(--gradient-primary)', color: 'white' }} | |
| > | |
| <LogIn className="w-4 h-4" /> | |
| <span className="hidden sm:inline">Sign In</span> | |
| </Link> | |
| )} | |
| </div> | |
| </div> | |
| </motion.nav> | |
| ); | |
| } | |
| function NavLink({ | |
| href, | |
| active, | |
| children, | |
| }: { | |
| href: string; | |
| active: boolean; | |
| children: React.ReactNode; | |
| }) { | |
| return ( | |
| <Link | |
| href={href} | |
| className="relative flex items-center gap-2 px-3 sm:px-4 py-2 rounded-lg text-sm font-medium transition-all duration-300" | |
| style={{ | |
| color: active ? 'var(--primary-light)' : 'var(--muted)', | |
| background: active ? 'rgba(108, 92, 231, 0.1)' : 'transparent', | |
| }} | |
| onMouseEnter={(e) => { | |
| if (!active) { | |
| e.currentTarget.style.color = 'var(--foreground)'; | |
| e.currentTarget.style.background = 'rgba(255,255,255,0.03)'; | |
| } | |
| }} | |
| onMouseLeave={(e) => { | |
| if (!active) { | |
| e.currentTarget.style.color = 'var(--muted)'; | |
| e.currentTarget.style.background = 'transparent'; | |
| } | |
| }} | |
| > | |
| {children} | |
| {active && ( | |
| <motion.div | |
| layoutId="navbar-indicator" | |
| className="absolute bottom-0 left-2 right-2 h-0.5 rounded-full" | |
| style={{ background: 'var(--gradient-primary)' }} | |
| transition={{ type: 'spring', stiffness: 400, damping: 30 }} | |
| /> | |
| )} | |
| </Link> | |
| ); | |
| } | |