211 lines
7.6 KiB
JavaScript
211 lines
7.6 KiB
JavaScript
import { useState } from "react";
|
||
import { Dialog } from "@headlessui/react";
|
||
import { Bars3Icon, XMarkIcon } from "@heroicons/react/24/outline";
|
||
import { NavLink, Link, useNavigate } from "react-router-dom";
|
||
import { Button } from "../UI";
|
||
import { useAuth } from "../../hooks/useAuth";
|
||
|
||
const publicNavigation = [
|
||
{ name: "Дома", href: "/" },
|
||
{ name: "За нас", href: "/about" },
|
||
{ name: "Галерија", href: "/gallery" },
|
||
{ name: "Контакт", href: "/contact" },
|
||
{ name: "Логин", href: "/login" },
|
||
];
|
||
|
||
const basePrivateNavigation = [
|
||
{ name: "Дома", href: "/" },
|
||
{ name: "За нас", href: "/about" },
|
||
{ name: "Галерија", href: "/gallery" },
|
||
{ name: "Контакт", href: "/contact" },
|
||
];
|
||
|
||
export default function Navbar() {
|
||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||
const { user, logout } = useAuth();
|
||
const navigate = useNavigate();
|
||
|
||
const getNavigation = () => {
|
||
if (!user) return publicNavigation;
|
||
|
||
// Add appropriate dashboard link based on user role
|
||
const privateNavigation = [...basePrivateNavigation];
|
||
if (user.isAdmin) {
|
||
privateNavigation.push({ name: "Админ Панел", href: "/admin" });
|
||
} else {
|
||
privateNavigation.push({ name: "Клиент Зона", href: "/dashboard" });
|
||
}
|
||
return privateNavigation;
|
||
};
|
||
|
||
const navigation = getNavigation();
|
||
const handleLogout = async () => {
|
||
try {
|
||
await logout();
|
||
navigate("/");
|
||
} catch (error) {
|
||
console.error("Logout failed:", error);
|
||
}
|
||
};
|
||
return (
|
||
<div className="w-full bg-gradient-to-b from-primary-900 to-primary-800 border-b border-primary-700/50">
|
||
<header className="relative">
|
||
<nav className="container-base py-4" aria-label="Global">
|
||
<div className="flex items-center justify-between">
|
||
{/* Left Logo */}
|
||
<div className="flex-shrink-0">
|
||
<Link to="/" className="p-2 hover:bg-white/20 transition-colors">
|
||
<img
|
||
className="h-10 w-auto transition-transform duration-300 hover:scale-105"
|
||
src="/imklogorgb.png"
|
||
alt="IMK logo"
|
||
/>
|
||
</Link>
|
||
</div>
|
||
|
||
{/* Centered Desktop Navigation */}
|
||
<div className="hidden lg:flex flex-grow justify-center">
|
||
<div className="flex items-center gap-x-1">
|
||
{navigation.map((item) => (
|
||
<NavLink
|
||
key={item.name}
|
||
to={item.href}
|
||
className={({ isActive }) =>
|
||
`px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200
|
||
${
|
||
isActive
|
||
? "bg-primary-700 text-white shadow-lg"
|
||
: "text-neutral-200 hover:bg-primary-700/50 hover:text-white"
|
||
}`
|
||
}
|
||
>
|
||
{item.name}
|
||
</NavLink>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Right Side Content */}
|
||
<div className="flex items-center gap-x-4">
|
||
{/* User Menu & Logout */}
|
||
{user && (
|
||
<div className="hidden lg:flex items-center gap-x-4">
|
||
<span className="text-white text-sm">
|
||
{user.name || user.email}
|
||
</span>
|
||
<Button
|
||
variant="ghost"
|
||
onClick={handleLogout}
|
||
className="text-white hover:bg-primary-700/50 px-4 py-2 text-sm"
|
||
>
|
||
Одјави се
|
||
</Button>
|
||
</div>
|
||
)}
|
||
|
||
{/* TUF Logo */}
|
||
<div className="hidden lg:block">
|
||
<a href="/" className="p-2 hover:bg-white/20 transition-colors">
|
||
<img
|
||
className="h-10 w-auto transition-transform duration-300 hover:scale-105"
|
||
src="/tuf.png"
|
||
alt="TUF logo"
|
||
/>
|
||
</a>
|
||
</div>
|
||
|
||
{/* Mobile Menu Button */}
|
||
<Button
|
||
variant="ghost"
|
||
className="lg:hidden text-white hover:bg-primary-700/50"
|
||
onClick={() => setMobileMenuOpen(true)}
|
||
>
|
||
<span className="sr-only">Open main menu</span>
|
||
<Bars3Icon className="h-6 w-6" aria-hidden="true" />
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
{/* Mobile Menu */}
|
||
<Dialog
|
||
as="div"
|
||
className="lg:hidden"
|
||
open={mobileMenuOpen}
|
||
onClose={setMobileMenuOpen}
|
||
>
|
||
<div className="fixed inset-0 z-50 bg-neutral-900/50 backdrop-blur-sm" />
|
||
<Dialog.Panel className="fixed inset-y-0 right-0 z-50 w-full overflow-y-auto bg-primary-900 px-6 py-6 sm:max-w-sm">
|
||
<div className="flex items-center justify-between">
|
||
<Link to="/" className="bg-white/10 rounded-lg p-2">
|
||
<img
|
||
className="h-8 w-auto"
|
||
src="/imklogorgb.png"
|
||
alt="IMK logo"
|
||
/>
|
||
</Link>
|
||
<Button
|
||
variant="ghost"
|
||
onClick={() => setMobileMenuOpen(false)}
|
||
className="text-white hover:bg-primary-700/50"
|
||
>
|
||
<span className="sr-only">Close menu</span>
|
||
<XMarkIcon className="h-6 w-6" aria-hidden="true" />
|
||
</Button>
|
||
</div>
|
||
|
||
<div className="mt-6 flow-root">
|
||
<div className="space-y-1 py-6">
|
||
{/* User Info in Mobile Menu */}
|
||
{user && (
|
||
<div className="px-3 py-2 text-white border-b border-primary-700/50 mb-4">
|
||
<span className="block text-sm font-medium">
|
||
{user.name || user.email}
|
||
</span>
|
||
<span className="block text-sm text-primary-400">
|
||
{user.isAdmin ? "Администратор" : "Корисник"}
|
||
</span>
|
||
</div>
|
||
)}
|
||
|
||
{/* Navigation Items */}
|
||
{navigation.map((item) => (
|
||
<NavLink
|
||
key={item.name}
|
||
to={item.href}
|
||
className={({ isActive }) =>
|
||
`block px-3 py-2 text-base font-medium rounded-lg transition-colors
|
||
${
|
||
isActive
|
||
? "bg-primary-700 text-white"
|
||
: "text-neutral-200 hover:bg-primary-700/50 hover:text-white"
|
||
}`
|
||
}
|
||
onClick={() => setMobileMenuOpen(false)}
|
||
>
|
||
{item.name}
|
||
</NavLink>
|
||
))}
|
||
|
||
{/* Logout in Mobile Menu */}
|
||
{user && (
|
||
<Button
|
||
variant="ghost"
|
||
onClick={() => {
|
||
handleLogout();
|
||
setMobileMenuOpen(false);
|
||
}}
|
||
className="block w-full text-left px-3 py-2 text-base font-medium text-neutral-200 hover:bg-primary-700/50 hover:text-white rounded-lg mt-4"
|
||
>
|
||
Одјави се
|
||
</Button>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</Dialog.Panel>
|
||
</Dialog>
|
||
</header>
|
||
</div>
|
||
);
|
||
}
|