WhiteNightsAdminPanel/src/components/header/index.tsx

227 lines
7.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import DarkModeOutlined from "@mui/icons-material/DarkModeOutlined";
import LightModeOutlined from "@mui/icons-material/LightModeOutlined";
import AppBar from "@mui/material/AppBar";
import Avatar from "@mui/material/Avatar";
import IconButton from "@mui/material/IconButton";
import Stack from "@mui/material/Stack";
import Toolbar from "@mui/material/Toolbar";
import Typography from "@mui/material/Typography";
import { languageStore } from "../../store/LanguageStore";
import {
useGetIdentity,
useList,
usePermissions,
useWarnAboutChange,
} from "@refinedev/core";
import { HamburgerMenu, RefineThemedLayoutV2HeaderProps } from "@refinedev/mui";
import React, { useContext, useEffect, useState } from "react";
import { ColorModeContext } from "../../contexts/color-mode";
import Cookies from "js-cookie";
import { useTranslation } from "react-i18next";
import {
Button,
Select,
MenuItem,
FormControl,
SelectChangeEvent,
} from "@mui/material";
import { useNavigate } from "react-router";
import { cityStore } from "../../store/CityStore";
import { observer } from "mobx-react-lite";
type IUser = {
id: number;
name: string;
avatar: string;
is_admin: boolean;
};
export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = observer(
({ sticky }) => {
const { city_id, setCityIdAction } = cityStore;
const { language } = languageStore;
const { data: cities } = useList({
resource: "city",
});
const { mode, setMode } = useContext(ColorModeContext);
const { data: user } = useGetIdentity<IUser>();
const { data: permissions } = usePermissions<string[]>();
const isAdmin = permissions?.includes("admin");
const { i18n } = useTranslation();
const { setWarnWhen, warnWhen } = useWarnAboutChange();
const navigate = useNavigate();
const handleChange = (event: SelectChangeEvent<string>) => {
setCityIdAction(event.target.value);
};
const handleLanguageChange = async (lang: string) => {
// console.log('Language change requested:', lang)
// console.log('Current warnWhen state:', warnWhen)
const form = document.querySelector("form");
const inputs = form?.querySelectorAll<
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
>("input, textarea, select");
const saveButton = document.querySelector(
".refine-save-button"
) as HTMLButtonElement;
// Сохраняем текущий URL перед любыми действиями
const currentLocation = window.location.pathname + window.location.search;
if (form && saveButton) {
const hasChanges = Array.from(inputs || []).some((input) => {
if (
input instanceof HTMLInputElement ||
input instanceof HTMLTextAreaElement
) {
return input.value !== input.defaultValue;
}
if (input instanceof HTMLSelectElement) {
return (
input.value !==
input.options[input.selectedIndex].defaultSelected.toString()
);
}
return false;
});
if (hasChanges || warnWhen) {
try {
// console.log('Attempting to save changes...')
setWarnWhen(false);
saveButton.click();
// console.log('Save button clicked')
await new Promise((resolve) => setTimeout(resolve, 1000));
// После сохранения меняем язык и возвращаемся на ту же страницу
Cookies.set("lang", lang);
i18n.changeLanguage(lang);
navigate(currentLocation);
return;
} catch (error) {
console.error("Failed to save form:", error);
setWarnWhen(true);
return;
}
}
}
// Если нет формы или изменений, просто меняем язык
// console.log('Setting language cookie:', lang)
Cookies.set("lang", lang);
// console.log('Changing i18n language')
i18n.changeLanguage(lang);
// Используем текущий URL для навигации
navigate(0);
};
useEffect(() => {
const savedLang = Cookies.get("lang") || "ru";
i18n.changeLanguage(savedLang);
}, [i18n]);
return (
<AppBar position={sticky ? "sticky" : "relative"}>
<Toolbar>
<Stack
direction="row"
width="100%"
justifyContent="flex-end"
alignItems="center"
>
<HamburgerMenu />
<Stack
direction="row"
width="100%"
justifyContent="flex-end"
alignItems="center"
spacing={2}
>
<FormControl variant="standard" sx={{ width: "min-content" }}>
{city_id && cities && (
<Select
defaultValue={city_id}
value={city_id}
onChange={handleChange}
>
<MenuItem value={String(0)} key={0}>
Все города
</MenuItem>
{cities.data?.map((city) => (
<MenuItem value={String(city.id)} key={city.id}>
{city.name}
</MenuItem>
))}
</Select>
)}
</FormControl>
<IconButton
color="inherit"
onClick={() => {
setMode();
}}
sx={{
marginRight: "2px",
}}
>
{mode === "dark" ? <LightModeOutlined /> : <DarkModeOutlined />}
</IconButton>
{(user?.avatar || user?.name) && (
<Stack
direction="row"
gap="16px"
alignItems="center"
justifyContent="center"
>
{user?.name && (
<Stack direction="column" alignItems="start" gap="0px">
<Typography
sx={{
display: {
xs: "none",
sm: "inline-block",
},
}}
variant="subtitle2"
>
{user?.name}
</Typography>
<Typography
sx={{
display: {
xs: "none",
sm: "inline-block",
},
backgroundColor: "primary.main",
color: "rgba(255, 255, 255, 0.7)",
padding: "1px 4px",
borderRadius: 1,
fontSize: "0.6rem",
}}
variant="subtitle2"
>
{isAdmin ? "Администратор" : "Пользователь"}
</Typography>
</Stack>
)}
<Avatar src={user?.avatar} alt={user?.name} />
</Stack>
)}
</Stack>
</Stack>
</Toolbar>
</AppBar>
);
}
);