Files
vkv/resources/js/Header.tsx
Zdeněk Burda 41e3ce6f25 Initial commit
2026-01-09 21:26:40 +01:00

83 lines
2.3 KiB
TypeScript

'use client'
import {MouseEvent} from 'react'
import {Link} from 'react-router-dom'
import axios from 'axios'
import ThemeSwitch from '@/components/ThemeSwitch'
import { useTranslation } from 'react-i18next';
import LanguageSwitcher from '@/components/LanguageSwitcher';
import { useUserStore } from '@/stores/userStore'
// https://reactrouter.com/start/declarative/navigating
export default function Header() {
const { t } = useTranslation('common')
const user = useUserStore((s) => s.user);
const clearUser = useUserStore((s) => s.clearUser);
const isAuthenticated = Boolean(user);
const isAdmin = Boolean(user?.is_admin);
const handleLogout = async (event: MouseEvent<HTMLAnchorElement>) => {
event.preventDefault()
try {
await axios.post(
'/logout',
{},
{
withCredentials: true,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
},
)
clearUser()
window.location.href = '/'
} catch (error) {
console.error(t("logout_failed"), error)
}
}
return (
<header className="border-b border-gray-200 px-4 py-2 shadow-sm">
<nav className="mx-auto flex max-w-7xl items-center justify-between">
<span className="text-xl font-semibold">VKV</span>
<div className="flex gap-4 text-sm font-medium">
<Link to="/contests">
{t("contests_link")}
</Link>
{isAdmin && (
<>
<Link to="/admin/contests">
{t("admin_contests_link")}
</Link>
<Link to="/admin/news">
{t("admin_news_link")}
</Link>
<Link to="/admin/evaluation-rule-sets">
{t("admin_rulesets_link")}
</Link>
<Link to="/admin/users">
{t("admin_users_link") ?? "Uživatelé"}
</Link>
</>
)}
{isAuthenticated ? (
<Link to="/logout" onClick={handleLogout}>
{t("logout_link")}
</Link>
) : (
<Link to="/login">
{t("login_link")}
</Link>
)}
<LanguageSwitcher />
<ThemeSwitch />
</div>
</nav>
</header>
)
}