263 lines
6.6 KiB
TypeScript
263 lines
6.6 KiB
TypeScript
import {
|
|
ClockCircleOutlined,
|
|
DesktopOutlined,
|
|
GlobalOutlined,
|
|
LogoutOutlined,
|
|
MenuOutlined,
|
|
MoonOutlined,
|
|
PicCenterOutlined,
|
|
SettingOutlined,
|
|
SunOutlined,
|
|
UserOutlined,
|
|
} from "@ant-design/icons";
|
|
import { Drawer, Layout, Menu, MenuProps, Switch } from "antd";
|
|
import React, { useEffect, useState } from "react";
|
|
import AuthModal from "./AuthModal";
|
|
import "./styles.css";
|
|
import {
|
|
StorePrototype,
|
|
logOut,
|
|
setLanguage,
|
|
setTheme,
|
|
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";
|
|
import { isMobile } from "react-device-detect";
|
|
|
|
const { Header } = Layout;
|
|
|
|
type NullableUser = { name: string | null; username: string } | null;
|
|
|
|
const HeaderComponent = () => {
|
|
const navigate = useNavigate();
|
|
|
|
const [authModalOpen, setAuthModalOpen] = useState(false);
|
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
// const [screenOrientation, setScreenOrientation] = useState<OrientationType>(
|
|
// window.screen.orientation.type
|
|
// );
|
|
|
|
// window.addEventListener("orientationchange", () =>
|
|
// setScreenOrientation(window.screen.orientation.type)
|
|
// );
|
|
|
|
const currentLanguage = useSelector(
|
|
(state: StorePrototype) => state.settings.language
|
|
);
|
|
|
|
const user: NullableUser = useSelector(
|
|
(state: StorePrototype) => state.auth.user
|
|
);
|
|
|
|
const currentTheme: string | undefined = useSelector(
|
|
(state: StorePrototype) => state.settings.theme
|
|
);
|
|
|
|
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
|
|
useEffect(() => {
|
|
const keys = [];
|
|
user && keys.push("login");
|
|
currentLanguage && keys.push(currentLanguage);
|
|
setSelectedKeys(keys);
|
|
}, [user, currentLanguage]);
|
|
|
|
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: <Link to="/parting">{tr("Current queues")}</Link>,
|
|
key: "parting",
|
|
icon: <ClockCircleOutlined />,
|
|
},
|
|
{
|
|
label: <Link to="/news">{tr("News")}</Link>,
|
|
key: "news",
|
|
icon: <PicCenterOutlined />,
|
|
},
|
|
{
|
|
label: tr("Language"),
|
|
key: "language",
|
|
icon: <GlobalOutlined />,
|
|
children: languageSelectItems,
|
|
style: { background: "#001529" },
|
|
},
|
|
{
|
|
label: (
|
|
<Switch
|
|
onChange={(v: boolean) =>
|
|
store.dispatch(setTheme(v ? "light" : "dark"))
|
|
}
|
|
defaultChecked={currentTheme === "light"}
|
|
/>
|
|
),
|
|
key: "theme",
|
|
icon: currentTheme === "dark" ? <MoonOutlined /> : <SunOutlined />,
|
|
},
|
|
{
|
|
label: user ? user.username : tr("Log in"),
|
|
key: "login",
|
|
icon: <UserOutlined />,
|
|
onClick: () => !user && setAuthModalOpen(true),
|
|
...(user ? { children: userMenuItems } : {}),
|
|
},
|
|
];
|
|
|
|
const mobileItems: MenuProps["items"] = [
|
|
{
|
|
label: (
|
|
<div className="header-logo">
|
|
<img className="logo" src={logo} alt="logo" />
|
|
</div>
|
|
),
|
|
key: "logo",
|
|
onClick: () => navigate("/"),
|
|
},
|
|
{
|
|
icon: <MenuOutlined />,
|
|
key: "drawer",
|
|
onClick: () => setDrawerOpen(true),
|
|
},
|
|
];
|
|
|
|
const drawerItems: MenuProps["items"] = [
|
|
{
|
|
label: <Link to={user ? "/dashboard" : "#"}>{tr("Dashboard")}</Link>,
|
|
key: "dashboard",
|
|
icon: <DesktopOutlined />,
|
|
disabled: !user,
|
|
onClick: () => setDrawerOpen(false),
|
|
},
|
|
{
|
|
label: <Link to="/parting">{tr("Current queues")}</Link>,
|
|
key: "parting",
|
|
icon: <ClockCircleOutlined />,
|
|
onClick: () => setDrawerOpen(false),
|
|
},
|
|
{
|
|
label: <Link to="/news">{tr("News")}</Link>,
|
|
key: "news",
|
|
icon: <PicCenterOutlined />,
|
|
onClick: () => setDrawerOpen(false),
|
|
},
|
|
{
|
|
label: tr("Language"),
|
|
key: "language",
|
|
icon: <GlobalOutlined />,
|
|
children: languageSelectItems,
|
|
style: { background: "#001529" },
|
|
},
|
|
{
|
|
label: user ? user.username : tr("Log in"),
|
|
key: "login",
|
|
icon: <UserOutlined />,
|
|
onClick: () => !user && setAuthModalOpen(true),
|
|
...(user ? { children: userMenuItems } : {}),
|
|
},
|
|
{
|
|
label: (
|
|
<Switch
|
|
onChange={(v: boolean) =>
|
|
store.dispatch(setTheme(v ? "light" : "dark"))
|
|
}
|
|
defaultChecked={currentTheme === "light"}
|
|
/>
|
|
),
|
|
key: "theme",
|
|
icon: currentTheme === "dark" ? <MoonOutlined /> : <SunOutlined />,
|
|
},
|
|
];
|
|
|
|
return (
|
|
<>
|
|
<AuthModal
|
|
open={authModalOpen}
|
|
setOpen={setAuthModalOpen}
|
|
setDrawerOpen={setDrawerOpen}
|
|
/>
|
|
<Header className="header">
|
|
<Menu
|
|
theme="dark"
|
|
mode="horizontal"
|
|
items={
|
|
isMobile && window.screen.orientation.type === "portrait-primary"
|
|
? mobileItems
|
|
: items
|
|
}
|
|
style={{ flex: 1, minWidth: 0 }}
|
|
selectedKeys={selectedKeys}
|
|
className="header-container"
|
|
triggerSubMenuAction="click"
|
|
defaultActiveFirst={false}
|
|
overflowedIndicator={<MenuOutlined />}
|
|
/>
|
|
</Header>
|
|
<Drawer
|
|
open={drawerOpen}
|
|
onClose={() => setDrawerOpen(false)}
|
|
style={{ marginLeft: "3rem", paddingRight: "3rem" }}
|
|
>
|
|
<Menu
|
|
theme="dark"
|
|
mode="inline"
|
|
items={drawerItems}
|
|
selectedKeys={selectedKeys}
|
|
triggerSubMenuAction="click"
|
|
defaultActiveFirst={false}
|
|
/>
|
|
</Drawer>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default HeaderComponent;
|