runtipi/src/app/(dashboard)/components/Header/Header.tsx
2023-11-26 09:13:06 +01:00

103 lines
4 KiB
TypeScript

'use client';
import React from 'react';
import { IconBrandGithub, IconHeart, IconLogin, IconLogout, IconMoon, IconSun } from '@tabler/icons-react';
import Image from 'next/image';
import clsx from 'clsx';
import Link from 'next/link';
import { Tooltip } from 'react-tooltip';
import { useTranslations } from 'next-intl';
import { useUIStore } from '@/client/state/uiStore';
import { useAction } from 'next-safe-action/hook';
import { logoutAction } from '@/actions/logout/logout-action';
import Script from 'next/script';
import { useRouter } from 'next/navigation';
import { getLogo } from '@/lib/themes';
import { NavBar } from '../NavBar';
interface IProps {
isUpdateAvailable?: boolean;
authenticated?: boolean;
autoTheme: boolean;
}
export const Header: React.FC<IProps> = ({ isUpdateAvailable, authenticated = true, autoTheme }) => {
const { setDarkMode } = useUIStore();
const t = useTranslations('header');
const router = useRouter();
const logoutMutation = useAction(logoutAction, {
onSuccess: () => {
router.push('/');
},
});
const logHandler = () => {
if (authenticated) {
logoutMutation.execute();
} else {
router.push('/login');
}
};
return (
<header className="text-white navbar navbar-expand-md navbar-dark navbar-overlap d-print-none" data-bs-theme="dark">
<Script src="https://cdn.jsdelivr.net/npm/@tabler/core@latest/dist/js/tabler.min.js" async />
<div className="container-xl">
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar-menu">
<span className="navbar-toggler-icon" />
</button>
<Link href="/" passHref>
<h1 className="navbar-brand d-none-navbar-horizontal pe-0 pe-md-3">
<Image
priority
alt="Tipi logo"
className={clsx('navbar-brand-image me-3')}
width={100}
height={100}
src={getLogo(autoTheme)}
style={{
width: '30px',
maxWidth: '30px',
height: 'auto',
}}
/>
Tipi
</h1>
</Link>
<div className="navbar-nav flex-row order-md-last">
<div className="nav-item d-none d-xl-flex me-3">
<div className="btn-list">
<a href="https://github.com/runtipi/runtipi" target="_blank" rel="noreferrer" className="btn btn-dark">
<IconBrandGithub data-testid="icon-github" className="me-1 icon" size={24} />
{t('source-code')}
</a>
<a href="https://github.com/runtipi/runtipi?sponsor=1" target="_blank" rel="noreferrer" className="btn btn-dark">
<IconHeart className="me-1 icon text-pink" size={24} />
{t('sponsor')}
</a>
</div>
</div>
<div style={{ zIndex: 1 }} className="d-flex">
<Tooltip anchorSelect=".darkMode">{t('dark-mode')}</Tooltip>
<div onClick={() => setDarkMode(true)} role="button" aria-hidden="true" className="darkMode nav-link px-0 hide-theme-dark cursor-pointer" data-testid="dark-mode-toggle">
<IconMoon data-testid="icon-moon" size={20} />
</div>
<Tooltip anchorSelect=".lightMode">{t('light-mode')}</Tooltip>
<div onClick={() => setDarkMode(false)} aria-hidden="true" className="lightMode nav-link px-0 hide-theme-light cursor-pointer" data-testid="light-mode-toggle">
<IconSun data-testid="icon-sun" size={20} />
</div>
<Tooltip anchorSelect=".logOut">{authenticated ? t('logout') : t('login')}</Tooltip>
<div onClick={() => logHandler()} tabIndex={0} onKeyPress={() => logHandler()} role="button" className="logOut nav-link px-0 cursor-pointer" data-testid="logout-button">
{authenticated ? <IconLogout size={20} /> : <IconLogin size={20} />}
</div>
</div>
</div>
<NavBar isUpdateAvailable={isUpdateAvailable} />
</div>
</header>
);
};