InterviewAI / src /components /Navbar.tsx
viraj-421's picture
Initial commit: AI-Powered Mock Interview Platform with Auth, Certificates, and Timer
a0da743
Raw History Blame Contribute Delete
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>
);
}