145 lines
3.6 KiB
TypeScript
145 lines
3.6 KiB
TypeScript
import {
|
|
DesktopOutlined,
|
|
GlobalOutlined,
|
|
LogoutOutlined,
|
|
SettingOutlined,
|
|
UserOutlined,
|
|
} from "@ant-design/icons";
|
|
import { Layout, Menu, MenuProps, Popover } from "antd";
|
|
import React, { useState } from "react";
|
|
import AuthModal from "./AuthModal";
|
|
import "./styles.css";
|
|
import { StorePrototype, logOut, setLanguage, store } from "../config/store";
|
|
import { useSelector } from "react-redux";
|
|
import tr from "../config/translation";
|
|
import { Link, useNavigate } from "react-router-dom";
|
|
import logo from "../../static/android-chrome-192x192.png";
|
|
|
|
const { Header } = Layout;
|
|
|
|
type NullableUser = { name: string | null; username: string } | null;
|
|
|
|
const HeaderComponent = () => {
|
|
const navigate = useNavigate();
|
|
|
|
const [authModalOpen, setAuthModalOpen] = useState(false);
|
|
const [userMenuOpen, setUserMenuOpen] = useState(false);
|
|
const [languageSelectOpen, setLanguageSelectOpen] = useState(false);
|
|
const currentLanguage = useSelector(
|
|
(state: StorePrototype) => state.settings.language
|
|
);
|
|
|
|
const user: NullableUser = useSelector(
|
|
(state: StorePrototype) => state.auth.user
|
|
);
|
|
|
|
const languageSelectItems: MenuProps["items"] = [
|
|
{
|
|
label: "English",
|
|
key: "en",
|
|
onClick: () => {
|
|
store.dispatch(setLanguage("en"));
|
|
window.location.reload();
|
|
},
|
|
},
|
|
{
|
|
label: "Русский",
|
|
key: "ru",
|
|
onClick: () => {
|
|
store.dispatch(setLanguage("ru"));
|
|
window.location.reload();
|
|
},
|
|
},
|
|
];
|
|
|
|
const userMenuItems: MenuProps["items"] = [
|
|
{
|
|
label: <Link to="/settings">{tr("Settings")}</Link>,
|
|
key: "settings",
|
|
icon: <SettingOutlined />,
|
|
},
|
|
{
|
|
label: tr("Log out"),
|
|
key: "logout",
|
|
icon: <LogoutOutlined />,
|
|
danger: true,
|
|
onClick: () => store.dispatch(logOut()) && navigate("/"),
|
|
},
|
|
];
|
|
|
|
const items: MenuProps["items"] = [
|
|
{
|
|
label: (
|
|
<div className="header-logo">
|
|
<img className="logo" src={logo} alt="logo" />
|
|
</div>
|
|
),
|
|
key: "logo",
|
|
onClick: () => navigate("/"),
|
|
},
|
|
{
|
|
label: <Link to={user ? "/dashboard" : "#"}>{tr("Dashboard")}</Link>,
|
|
key: "dashboard",
|
|
icon: <DesktopOutlined />,
|
|
disabled: !user,
|
|
},
|
|
{
|
|
label: (
|
|
<Popover
|
|
trigger="click"
|
|
open={languageSelectOpen}
|
|
onOpenChange={(isOpen) => setLanguageSelectOpen(isOpen)}
|
|
content={
|
|
<Menu
|
|
theme="dark"
|
|
mode="vertical"
|
|
items={languageSelectItems}
|
|
selectedKeys={currentLanguage ? [currentLanguage] : undefined}
|
|
/>
|
|
}
|
|
>
|
|
{tr("Language")}
|
|
</Popover>
|
|
),
|
|
key: "language",
|
|
icon: <GlobalOutlined />,
|
|
onClick: () => setLanguageSelectOpen(true),
|
|
},
|
|
{
|
|
label: user ? (
|
|
<Popover
|
|
trigger="click"
|
|
open={userMenuOpen}
|
|
onOpenChange={(isOpen) => setUserMenuOpen(isOpen)}
|
|
content={<Menu theme="dark" mode="vertical" items={userMenuItems} />}
|
|
>
|
|
{user.username}
|
|
</Popover>
|
|
) : (
|
|
tr("Log in")
|
|
),
|
|
key: "login",
|
|
icon: <UserOutlined />,
|
|
onClick: () => (user ? setUserMenuOpen(true) : setAuthModalOpen(true)),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<>
|
|
<AuthModal open={authModalOpen} setOpen={setAuthModalOpen} />
|
|
<Header className="header">
|
|
<Menu
|
|
theme="dark"
|
|
mode="horizontal"
|
|
items={items}
|
|
style={{ flex: 1, minWidth: 0 }}
|
|
selectedKeys={[]}
|
|
className="header-container"
|
|
/>
|
|
</Header>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default HeaderComponent;
|