sight edit update
This commit is contained in:
@ -1,181 +1,246 @@
|
||||
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 {useGetIdentity, usePermissions, useWarnAboutChange} from '@refinedev/core'
|
||||
import {HamburgerMenu, RefineThemedLayoutV2HeaderProps} from '@refinedev/mui'
|
||||
import React, {useContext, useEffect} from 'react'
|
||||
import {ColorModeContext} from '../../contexts/color-mode'
|
||||
import Cookies from 'js-cookie'
|
||||
import {useTranslation} from 'react-i18next'
|
||||
import {Button} from '@mui/material'
|
||||
import {useNavigate} from 'react-router'
|
||||
|
||||
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 {
|
||||
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,
|
||||
InputLabel,
|
||||
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
|
||||
}
|
||||
id: number;
|
||||
name: string;
|
||||
avatar: string;
|
||||
is_admin: boolean;
|
||||
};
|
||||
|
||||
export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = ({sticky = true}) => {
|
||||
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()
|
||||
export const Header: React.FC<RefineThemedLayoutV2HeaderProps> = observer(
|
||||
({ sticky }) => {
|
||||
const { city_id, setCityIdAction } = cityStore;
|
||||
const { data: cities } = useList({
|
||||
resource: "city",
|
||||
});
|
||||
|
||||
const navigate = useNavigate()
|
||||
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 handleLanguageChange = async (lang: string) => {
|
||||
// console.log('Language change requested:', lang)
|
||||
// console.log('Current warnWhen state:', warnWhen)
|
||||
const handleChange = (event: SelectChangeEvent<string>) => {
|
||||
setCityIdAction(event.target.value);
|
||||
};
|
||||
|
||||
const form = document.querySelector('form')
|
||||
const inputs = form?.querySelectorAll<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>('input, textarea, select')
|
||||
const saveButton = document.querySelector('.refine-save-button') as HTMLButtonElement
|
||||
const handleLanguageChange = async (lang: string) => {
|
||||
// console.log('Language change requested:', lang)
|
||||
// console.log('Current warnWhen state:', warnWhen)
|
||||
|
||||
// Сохраняем текущий URL перед любыми действиями
|
||||
const currentLocation = window.location.pathname + window.location.search
|
||||
const form = document.querySelector("form");
|
||||
const inputs = form?.querySelectorAll<
|
||||
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
|
||||
>("input, textarea, select");
|
||||
const saveButton = document.querySelector(
|
||||
".refine-save-button"
|
||||
) as HTMLButtonElement;
|
||||
|
||||
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
|
||||
})
|
||||
// Сохраняем текущий URL перед любыми действиями
|
||||
const currentLocation = window.location.pathname + window.location.search;
|
||||
|
||||
if (hasChanges || warnWhen) {
|
||||
try {
|
||||
// console.log('Attempting to save changes...')
|
||||
setWarnWhen(false)
|
||||
saveButton.click()
|
||||
// console.log('Save button clicked')
|
||||
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;
|
||||
});
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||
if (hasChanges || warnWhen) {
|
||||
try {
|
||||
// console.log('Attempting to save changes...')
|
||||
setWarnWhen(false);
|
||||
saveButton.click();
|
||||
// console.log('Save button clicked')
|
||||
|
||||
// После сохранения меняем язык и возвращаемся на ту же страницу
|
||||
Cookies.set('lang', lang)
|
||||
i18n.changeLanguage(lang)
|
||||
navigate(currentLocation)
|
||||
return
|
||||
} catch (error) {
|
||||
console.error('Failed to save form:', error)
|
||||
setWarnWhen(true)
|
||||
return
|
||||
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('Setting language cookie:', lang)
|
||||
Cookies.set("lang", lang);
|
||||
|
||||
// console.log('Changing i18n language')
|
||||
i18n.changeLanguage(lang)
|
||||
// console.log('Changing i18n language')
|
||||
i18n.changeLanguage(lang);
|
||||
|
||||
// Используем текущий URL для навигации
|
||||
navigate(0)
|
||||
}
|
||||
// Используем текущий URL для навигации
|
||||
navigate(0);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const savedLang = Cookies.get('lang') || 'ru'
|
||||
i18n.changeLanguage(savedLang)
|
||||
}, [i18n])
|
||||
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 />
|
||||
|
||||
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}>
|
||||
<Stack
|
||||
direction="row"
|
||||
spacing={1}
|
||||
sx={{
|
||||
backgroundColor: 'background.paper',
|
||||
padding: '4px',
|
||||
borderRadius: '4px',
|
||||
}}
|
||||
width="100%"
|
||||
justifyContent="flex-end"
|
||||
alignItems="center"
|
||||
spacing={2}
|
||||
>
|
||||
{['ru', 'en', 'zh'].map((lang) => (
|
||||
<Button
|
||||
key={lang}
|
||||
onClick={() => handleLanguageChange(lang)}
|
||||
variant={i18n.language === lang ? 'contained' : 'outlined'}
|
||||
size="small"
|
||||
sx={{
|
||||
minWidth: '30px',
|
||||
padding: '2px 0px',
|
||||
textTransform: 'uppercase',
|
||||
}}
|
||||
>
|
||||
{lang}
|
||||
</Button>
|
||||
))}
|
||||
</Stack>
|
||||
|
||||
<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>
|
||||
<FormControl variant="standard" sx={{ width: "min-content" }}>
|
||||
{city_id && cities && (
|
||||
<Select
|
||||
defaultValue={city_id}
|
||||
value={city_id}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{cities.data?.map((city) => (
|
||||
<MenuItem value={String(city.id)} key={city.id}>
|
||||
{city.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
)}
|
||||
<Avatar src={user?.avatar} alt={user?.name} />
|
||||
</FormControl>
|
||||
<Stack
|
||||
direction="row"
|
||||
spacing={1}
|
||||
sx={{
|
||||
backgroundColor: "background.paper",
|
||||
padding: "4px",
|
||||
borderRadius: "4px",
|
||||
}}
|
||||
>
|
||||
{["ru", "en", "zh"].map((lang) => (
|
||||
<Button
|
||||
key={lang}
|
||||
onClick={() => handleLanguageChange(lang)}
|
||||
variant={i18n.language === lang ? "contained" : "outlined"}
|
||||
size="small"
|
||||
sx={{
|
||||
minWidth: "30px",
|
||||
padding: "2px 0px",
|
||||
textTransform: "uppercase",
|
||||
}}
|
||||
>
|
||||
{lang}
|
||||
</Button>
|
||||
))}
|
||||
</Stack>
|
||||
)}
|
||||
|
||||
<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>
|
||||
</Stack>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
)
|
||||
}
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
Reference in New Issue
Block a user