photum/frontend/components/Navbar.tsx
2025-12-03 09:44:21 -03:00

255 lines
9.4 KiB
TypeScript

import React, { useState, useEffect } from "react";
import { UserRole } from "../types";
import { useAuth } from "../contexts/AuthContext";
import { Menu, X, LogOut, User } from "lucide-react";
import { Button } from "./Button";
interface NavbarProps {
onNavigate: (page: string) => void;
currentPage: string;
}
export const Navbar: React.FC<NavbarProps> = ({ onNavigate, currentPage }) => {
const { user, logout } = useAuth();
const [isScrolled, setIsScrolled] = useState(false);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const [isAccountDropdownOpen, setIsAccountDropdownOpen] = useState(false);
useEffect(() => {
const handleScroll = () => {
setIsScrolled(window.scrollY > 20);
};
window.addEventListener("scroll", handleScroll);
return () => window.removeEventListener("scroll", handleScroll);
}, []);
const getLinks = () => {
if (!user) return [];
switch (user.role) {
case UserRole.SUPERADMIN:
case UserRole.BUSINESS_OWNER:
return [
{ name: "Gestão de Eventos", path: "dashboard" },
{ name: "Equipe & Fotógrafos", path: "team" },
{ name: "Financeiro", path: "finance" },
{ name: "Configurações", path: "settings" },
];
case UserRole.EVENT_OWNER:
return [
{ name: "Meus Eventos", path: "dashboard" },
{ name: "Solicitar Evento", path: "request-event" },
];
case UserRole.PHOTOGRAPHER:
return [
{ name: "Eventos Designados", path: "dashboard" },
{ name: "Agenda", path: "calendar" },
];
default:
return [];
}
};
const getRoleLabel = () => {
if (!user) return "";
if (user.role === UserRole.BUSINESS_OWNER) return "Empresa";
if (user.role === UserRole.EVENT_OWNER) return "Cliente";
if (user.role === UserRole.PHOTOGRAPHER) return "Fotógrafo";
if (user.role === UserRole.SUPERADMIN) return "Super Admin";
return "";
};
return (
<nav className="fixed w-full z-50 bg-white shadow-sm py-3">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between items-center h-16">
{/* Logo */}
<div
className="flex-shrink-0 flex items-center cursor-pointer"
onClick={() => onNavigate("home")}
>
<img
src="/logo.png"
alt="Photum Formaturas"
className="h-30 mb-6 w-auto object-contain"
/>
</div>
{/* Desktop Navigation */}
{user && (
<div className="hidden md:flex items-center space-x-6">
{getLinks().map((link) => (
<button
key={link.path}
onClick={() => onNavigate(link.path)}
className={`text-sm font-medium tracking-wide uppercase hover:text-brand-gold transition-colors pb-1 ${
currentPage === link.path
? "text-brand-gold border-b-2 border-brand-gold"
: "text-gray-600 border-b-2 border-transparent"
}`}
>
{link.name}
</button>
))}
</div>
)}
{/* Right Side Actions */}
<div className="hidden md:flex items-center space-x-4">
{user ? (
<div className="flex items-center space-x-4 pl-4 border-l border-gray-200">
<div className="flex flex-col items-end mr-2">
<span className="text-sm font-bold text-brand-black leading-tight">
{user.name}
</span>
<span className="text-[10px] uppercase tracking-wider text-brand-gold leading-tight">
{getRoleLabel()}
</span>
</div>
<div className="h-9 w-9 rounded-full bg-gray-100 overflow-hidden border border-gray-200 ring-2 ring-transparent hover:ring-brand-gold transition-all">
<img
src={user.avatar}
alt="Avatar"
className="w-full h-full object-cover"
/>
</div>
<button
onClick={logout}
className="text-gray-400 hover:text-red-500 transition-colors p-1"
title="Sair"
>
<LogOut size={18} />
</button>
</div>
) : (
<div className="relative">
<button
onClick={() =>
setIsAccountDropdownOpen(!isAccountDropdownOpen)
}
className="flex items-center gap-2 p-2 rounded-full hover:bg-gray-100 transition-colors"
>
<div className="w-10 h-10 rounded-full border-2 border-brand-gold flex items-center justify-center text-brand-gold hover:bg-brand-gold hover:text-white transition-colors">
<User size={24} />
</div>
<div className="text-left hidden lg:block">
<p className="text-xs text-gray-500">Olá, bem-vindo(a)</p>
<p className="text-sm font-medium text-brand-black">
Entrar / Cadastrar
</p>
</div>
</button>
{/* Dropdown Popup - Centralizado */}
{isAccountDropdownOpen && (
<div className="absolute left-1/2 -translate-x-1/2 top-full mt-2 w-64 bg-white rounded-xl shadow-xl border border-gray-200 overflow-hidden z-50 fade-in">
<div className="p-4 space-y-3">
<Button
onClick={() => {
onNavigate("login");
setIsAccountDropdownOpen(false);
}}
variant="secondary"
className="w-full rounded-xl"
>
ENTRAR
</Button>
<Button
onClick={() => {
onNavigate("register");
setIsAccountDropdownOpen(false);
}}
className="w-full bg-purple-600 text-white hover:bg-purple-700 focus:ring-purple-500 rounded-xl"
>
Cadastre-se agora
</Button>
</div>
</div>
)}
</div>
)}
</div>
{/* Mobile Button */}
<div className="md:hidden flex items-center">
<button
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
className="text-brand-black hover:text-brand-gold p-2"
>
{isMobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
</button>
</div>
</div>
</div>
{/* Mobile Menu */}
{isMobileMenuOpen && (
<div className="md:hidden absolute top-full left-0 w-full bg-white border-b border-gray-100 shadow-lg fade-in">
<div className="px-4 py-4 space-y-3">
{user &&
getLinks().map((link) => (
<button
key={link.path}
onClick={() => {
onNavigate(link.path);
setIsMobileMenuOpen(false);
}}
className="block w-full text-left text-base font-medium text-gray-700 hover:text-brand-gold py-2 border-b border-gray-50"
>
{link.name}
</button>
))}
<div className="pt-4">
{user ? (
<div className="flex items-center justify-between">
<div className="flex items-center">
<img
src={user.avatar}
className="w-8 h-8 rounded-full mr-2"
/>
<div>
<span className="font-bold text-sm block">
{user.name}
</span>
<span className="text-xs text-brand-gold">
{getRoleLabel()}
</span>
</div>
</div>
<Button variant="ghost" size="sm" onClick={logout}>
Sair
</Button>
</div>
) : (
<div className="flex flex-col gap-2">
<Button
className="w-full rounded-lg"
size="lg"
variant="secondary"
onClick={() => {
onNavigate("login");
setIsMobileMenuOpen(false);
}}
>
ENTRAR
</Button>
<Button
className="w-full bg-purple-600 text-white hover:bg-purple-700 focus:ring-purple-500 rounded-lg"
size="lg"
onClick={() => {
onNavigate("register");
setIsMobileMenuOpen(false);
}}
>
Cadastre-se agora
</Button>
</div>
)}
</div>
</div>
</div>
)}
</nav>
);
};