prvi kod za live uporabu
Some checks failed
ERP CI Pipeline / test (push) Has been cancelled

This commit is contained in:
mariomitte
2026-07-09 21:21:17 +02:00
parent 857bb65d52
commit 5d39e048ba
239 changed files with 25151 additions and 0 deletions

View File

@@ -0,0 +1,100 @@
import NotificationBell from './NotificationBell';
import ThemeToggle from './ui/ThemeToggle';
import AuthWidget from './AuthWidget';
import UserDisplay from './ui/UserDisplay';
import { useEffect, useMemo, useState } from 'preact/hooks';
import { hydrateAuthFromStorage } from '../stores/authStore';
const ITEMS = [
{ id: 'dashboard', label: 'Dashboard', href: '/' },
{ id: 'work-orders', label: 'Putni nalozi', href: '/putni-nalozi' },
{ id: 'service-records', label: 'Servisni zapisi', href: '/servisni-zapisi' },
{ id: 'vehicles', label: 'Vozila', href: '/vehicles' },
{ id: 'clients', label: 'Klijenti', href: '/clients' },
];
export default function Navbar({ minimal = false }) {
const [pathname, setPathname] = useState('/');
const normalizedPath = useMemo(() => {
const value = String(pathname || '/');
if (value.length > 1 && value.endsWith('/')) return value.slice(0, -1);
return value;
}, [pathname]);
useEffect(() => {
const updatePath = () => setPathname(window.location.pathname || '/');
updatePath();
window.addEventListener('astro:page-load', updatePath);
// Hidratira auth iz storage pri prvi puta učitavanja Navbar-a
hydrateAuthFromStorage();
return () => window.removeEventListener('astro:page-load', updatePath);
}, []);
const currentItem = useMemo(
() => ITEMS.find((item) => item.href === normalizedPath) || ITEMS[0],
[normalizedPath]
);
return (
<nav className="sticky top-0 z-30 mb-4 rounded-lg border border-border-hairline bg-canvas-elevated/95 px-4 py-3 backdrop-blur">
<div className="flex flex-wrap items-center justify-between gap-2">
{/* Logo + korisnik */}
<a href="/" className="flex flex-col hover:opacity-80">
<span className="text-base font-bold tracking-tight text-text-main">ERP</span>
{!minimal && <UserDisplay field="ime_prezime" className="text-xs text-text-muted" />}
</a>
{/* Navigacijski linkovi */}
<ul className="hidden items-center gap-1 text-sm sm:flex">
{ITEMS.map((item) => (
<li key={item.id}>
<a
href={item.href}
className={
normalizedPath === item.href
? 'rounded-lg bg-indigo-50 px-3 py-2 font-medium text-indigo-700'
: 'rounded-lg px-3 py-2 text-text-main hover:bg-canvas-deep'
}
>
{item.label}
</a>
</li>
))}
</ul>
{/* Desna strana */}
<div className="flex items-center gap-2">
<details className="relative sm:hidden">
<summary className="list-none cursor-pointer rounded-lg border border-border-hairline px-2 py-1 text-xs text-text-main hover:bg-canvas-deep">
{currentItem?.label || 'Izbornik'}
</summary>
<div className="absolute right-0 mt-2 min-w-44 rounded-lg border border-border-hairline bg-canvas-elevated shadow-lg">
<div className="border-b border-border-hairline px-3 py-2 text-[11px] uppercase tracking-wide text-text-muted">
Navigacija
</div>
<ul className="py-1">
{ITEMS.map((item) => (
<li key={`mobile-${item.id}`}>
<a
href={item.href}
className={
normalizedPath === item.href
? 'block bg-indigo-50 px-3 py-2 text-sm font-medium text-indigo-700'
: 'block px-3 py-2 text-sm text-text-main hover:bg-canvas-deep'
}
>
{item.label}
</a>
</li>
))}
</ul>
</div>
</details>
<ThemeToggle />
<NotificationBell />
<AuthWidget />
</div>
</div>
</nav>
);
}