143 lines
7.2 KiB
TypeScript
143 lines
7.2 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { User as UserIcon, LogOut, Search, Folder, BookOpenCheck, ChevronDown, ShieldCheck, Settings } from 'lucide-react';
|
|
import { useAuth } from '../context/AuthContext';
|
|
import { LoginModal } from './LoginModal';
|
|
import { SearchModal } from './SearchModal';
|
|
import { useNavigate, useLocation } from 'react-router-dom';
|
|
import { Course } from '../types';
|
|
import { Logo } from './Logo';
|
|
|
|
interface NavbarProps {
|
|
onPlay: (course: Course) => void;
|
|
}
|
|
|
|
export const Navbar: React.FC<NavbarProps> = ({ onPlay }) => {
|
|
const [scrolled, setScrolled] = useState(false);
|
|
const [showLoginModal, setShowLoginModal] = useState(false);
|
|
const [showSearchModal, setShowSearchModal] = useState(false);
|
|
const [showAccountMenu, setShowAccountMenu] = useState(false);
|
|
const { user, logout } = useAuth();
|
|
const navigate = useNavigate();
|
|
const location = useLocation();
|
|
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
setScrolled(window.scrollY > 20);
|
|
};
|
|
window.addEventListener('scroll', handleScroll);
|
|
return () => window.removeEventListener('scroll', handleScroll);
|
|
}, []);
|
|
|
|
const handleLogout = () => {
|
|
logout();
|
|
navigate('/');
|
|
};
|
|
|
|
const isMaterialsPage = location.pathname === '/materiais';
|
|
const isHomePage = location.pathname === '/';
|
|
const goTo = (path: string) => {
|
|
setShowAccountMenu(false);
|
|
navigate(path);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<nav
|
|
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-500 ease-in-out px-6 md:px-12 py-4 ${
|
|
scrolled || location.pathname !== '/'
|
|
? 'bg-[#09090b]/95 backdrop-blur-xl shadow-2xl shadow-black/80'
|
|
: 'bg-transparent bg-gradient-to-b from-black/90 via-black/40 to-transparent'
|
|
}`}
|
|
>
|
|
<div className="max-w-[1440px] mx-auto flex items-center justify-between gap-4">
|
|
<div className="flex items-center gap-6 md:gap-8">
|
|
<div
|
|
className="flex items-center gap-2 group cursor-pointer"
|
|
onClick={() => navigate('/')}
|
|
>
|
|
<Logo variant="dark" size="lg" />
|
|
</div>
|
|
|
|
{/* Quick Navigation Links */}
|
|
<div className="hidden md:flex items-center gap-2 text-sm font-medium">
|
|
<button
|
|
onClick={() => navigate('/')}
|
|
className={`px-4 py-2 rounded-[980px] transition-colors ${
|
|
isHomePage
|
|
? 'text-white bg-white/10 font-semibold'
|
|
: 'text-gray-400 hover:text-white hover:bg-white/5'
|
|
}`}
|
|
>
|
|
Cursos
|
|
</button>
|
|
<button
|
|
onClick={() => navigate('/materiais')}
|
|
className={`px-4 py-2 rounded-[980px] transition-colors flex items-center gap-2 ${
|
|
isMaterialsPage
|
|
? 'text-orange-400 bg-orange-500/15 font-semibold border border-orange-500/30'
|
|
: 'text-gray-400 hover:text-orange-400 hover:bg-white/5'
|
|
}`}
|
|
>
|
|
<Folder className="w-4 h-4 text-orange-400" />
|
|
<span>Biblioteca de Materiais</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-3 sm:gap-4">
|
|
|
|
{/* Search */}
|
|
<button
|
|
onClick={() => setShowSearchModal(true)}
|
|
className="text-gray-300 hover:text-white text-sm font-medium transition-colors flex items-center gap-2 px-3.5 py-2.5 rounded-[980px] hover:bg-white/10 border border-transparent hover:border-white/10"
|
|
>
|
|
<Search className="w-4 h-4" />
|
|
<span className="hidden lg:inline">Buscar</span>
|
|
</button>
|
|
|
|
{!user ? (
|
|
<button
|
|
onClick={() => setShowLoginModal(true)}
|
|
className="flex items-center gap-2.5 bg-orange-500 hover:bg-orange-600 active:scale-95 transition-all duration-300 px-6 py-2.5 rounded-[980px] text-sm font-bold text-white shadow-xl shadow-orange-500/25 shrink-0"
|
|
>
|
|
<UserIcon className="w-4 h-4 text-white" />
|
|
<span>Entrar</span>
|
|
</button>
|
|
) : (
|
|
<div className="flex items-center gap-3">
|
|
<div className="relative">
|
|
<button onClick={() => setShowAccountMenu((current) => !current)} className="flex items-center gap-2 rounded-[980px] px-3 py-2 text-sm text-gray-300 hover:bg-white/10 hover:text-white transition-colors" aria-expanded={showAccountMenu} aria-haspopup="menu">
|
|
<span className="hidden md:block">Olá, <strong className="font-semibold text-white">{user.name.split(' ')[0]}</strong></span>
|
|
<ChevronDown className={`h-4 w-4 transition-transform ${showAccountMenu ? 'rotate-180' : ''}`} />
|
|
</button>
|
|
{showAccountMenu && <div role="menu" className="absolute right-0 top-full mt-2 w-56 overflow-hidden rounded-xl border border-white/10 bg-zinc-950 p-1.5 shadow-2xl shadow-black/60">
|
|
{user.role === 'student' && <button role="menuitem" onClick={() => goTo('/meu-aprendizado')} className="flex w-full items-center gap-2.5 rounded-lg px-3 py-2.5 text-left text-sm text-gray-200 hover:bg-white/10"><BookOpenCheck className="h-4 w-4 text-orange-400" /> Meu aprendizado</button>}
|
|
{user.role === 'professor' && <button role="menuitem" onClick={() => goTo('/gerenciar')} className="flex w-full items-center gap-2.5 rounded-lg px-3 py-2.5 text-left text-sm text-gray-200 hover:bg-white/10"><Settings className="h-4 w-4 text-orange-400" /> Painel do instrutor</button>}
|
|
{user.role === 'superadmin' && <><button role="menuitem" onClick={() => goTo('/admin')} className="flex w-full items-center gap-2.5 rounded-lg px-3 py-2.5 text-left text-sm text-gray-200 hover:bg-white/10"><ShieldCheck className="h-4 w-4 text-orange-400" /> Painel administrativo</button><button role="menuitem" onClick={() => goTo('/gerenciar')} className="flex w-full items-center gap-2.5 rounded-lg px-3 py-2.5 text-left text-sm text-gray-200 hover:bg-white/10"><Settings className="h-4 w-4 text-orange-400" /> Gerenciar cursos</button></>}
|
|
</div>}
|
|
</div>
|
|
|
|
<div className="h-4 w-[1px] bg-white/20 hidden sm:block"></div>
|
|
|
|
<div className="flex items-center gap-2.5">
|
|
<button
|
|
onClick={handleLogout}
|
|
className="flex items-center gap-2 bg-red-500/10 hover:bg-red-500/20 active:scale-95 transition-all duration-300 px-4 py-2 rounded-[980px] border border-red-500/20 group text-xs font-semibold text-red-400"
|
|
title="Encerrar Sessão"
|
|
>
|
|
<LogOut className="w-3.5 h-3.5" />
|
|
<span className="hidden sm:inline">Sair</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<LoginModal isOpen={showLoginModal} onClose={() => setShowLoginModal(false)} />
|
|
<SearchModal isOpen={showSearchModal} onClose={() => setShowSearchModal(false)} onPlay={onPlay} />
|
|
</>
|
|
);
|
|
};
|