227 lines
7.4 KiB
TypeScript
227 lines
7.4 KiB
TypeScript
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>
|
||
);
|
||
}
|
||
);
|