202 lines
4.8 KiB
JavaScript
202 lines
4.8 KiB
JavaScript
import { useNavigate } from 'react-router-dom';
|
||
import { useAuth } from '../../app/context/AuthProvider';
|
||
import { useCallback, useState, useRef, useEffect } from 'react';
|
||
import styled from '@emotion/styled';
|
||
import { isTestMode } from '../../conf/config';
|
||
|
||
export function HeaderMenu() {
|
||
const { user, logout } = useAuth();
|
||
const navigate = useNavigate();
|
||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||
const menuRef = useRef(null);
|
||
|
||
const handleLogout = useCallback(async () => {
|
||
await logout();
|
||
navigate('/login');
|
||
setIsMenuOpen(false);
|
||
}, [logout, navigate]);
|
||
|
||
const getInitials = useCallback(() => {
|
||
if (user) {
|
||
const names = user.username.split(' ');
|
||
return names
|
||
.map((name) => name[0])
|
||
.join('')
|
||
.toUpperCase();
|
||
}
|
||
}, [user]);
|
||
|
||
const toggleMenu = useCallback(() => {
|
||
setIsMenuOpen((prev) => !prev);
|
||
}, []);
|
||
|
||
// Закрытие меню при клике вне его области
|
||
useEffect(() => {
|
||
const handleClickOutside = (event) => {
|
||
if (menuRef.current && !menuRef.current.contains(event.target)) {
|
||
setIsMenuOpen(false);
|
||
}
|
||
};
|
||
|
||
document.addEventListener('mousedown', handleClickOutside);
|
||
return () => {
|
||
document.removeEventListener('mousedown', handleClickOutside);
|
||
};
|
||
}, []);
|
||
|
||
return (
|
||
<HeaderMenuTag>
|
||
<Logo />
|
||
<TableInfo id="TableInfo" />
|
||
<UserInfo ref={menuRef}>
|
||
<UserAvatar>
|
||
<UserInitials>{user ? getInitials() : ''}</UserInitials>
|
||
</UserAvatar>
|
||
<UserNameAndRole>
|
||
<div className="username">{user?.full_name}</div>
|
||
<div className="role">{user?.role}</div>
|
||
</UserNameAndRole>
|
||
|
||
{/* на стенде прода не показываем кнопку выхода */}
|
||
{isTestMode && <DownButton onClick={toggleMenu} isOpen={isMenuOpen} />}
|
||
{(isTestMode && isMenuOpen) && (
|
||
<DropdownMenu>
|
||
<LogoutButton onClick={handleLogout}>Выйти</LogoutButton>
|
||
</DropdownMenu>
|
||
)}
|
||
</UserInfo>
|
||
</HeaderMenuTag>
|
||
);
|
||
}
|
||
|
||
const HeaderMenuTag = styled.div`
|
||
height: 3.75rem;
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
align-items: flex-start;
|
||
padding: 0.75rem 1.5rem 0.75rem 1.5rem;
|
||
width: 100%;
|
||
box-sizing: border-box;
|
||
border-bottom: 0.0625rem solid var(--Stroke, rgba(0, 0, 0, 0.1));
|
||
background: rgba(255, 255, 255, 1);
|
||
position: relative;
|
||
`;
|
||
|
||
const Logo = styled.div`
|
||
width: 7rem;
|
||
height: 2rem;
|
||
display: flex;
|
||
align-items: center;
|
||
background-image: url('images/logo.svg');
|
||
background-repeat: no-repeat;
|
||
background-size: contain;
|
||
z-index: 1;
|
||
`;
|
||
|
||
const TableInfo = styled.div`
|
||
display: flex;
|
||
padding-left: 1.5rem;
|
||
flex: 1;
|
||
height: 100%;
|
||
`;
|
||
|
||
const UserInfo = styled.div`
|
||
width: 12.23rem;
|
||
height: 2.25rem;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
gap: 0.75rem;
|
||
position: relative;
|
||
`;
|
||
|
||
const UserAvatar = styled.div`
|
||
width: 2rem;
|
||
height: 2rem;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
align-items: center;
|
||
border-radius: 33554400rem;
|
||
background: var(--PrimaryLight, rgba(237, 248, 240, 1));
|
||
`;
|
||
|
||
const UserInitials = styled.div`
|
||
color: var(--Primary, rgba(37, 129, 65, 1));
|
||
font-family: Arial;
|
||
font-size: 0.88rem;
|
||
font-weight: 400;
|
||
line-height: 1.25rem;
|
||
letter-spacing: 0rem;
|
||
text-align: left;
|
||
`;
|
||
|
||
const UserNameAndRole = styled.div`
|
||
display: flex;
|
||
flex-direction: column;
|
||
.username {
|
||
color: var(--Black, rgba(31, 31, 31, 1));
|
||
font-size: 0.88rem;
|
||
font-weight: 400;
|
||
line-height: 1.25rem;
|
||
letter-spacing: 0rem;
|
||
text-align: left;
|
||
}
|
||
.role {
|
||
color: var(--GreyDark, rgba(74, 85, 101, 1));
|
||
font-size: 0.75rem;
|
||
font-weight: 400;
|
||
line-height: 1rem;
|
||
letter-spacing: 0rem;
|
||
text-align: left;
|
||
}
|
||
`;
|
||
|
||
const DownButton = styled.button`
|
||
background-image: url('images/Down.svg');
|
||
width: 1rem;
|
||
height: 1rem;
|
||
background-repeat: no-repeat;
|
||
background-size: cover;
|
||
border: none;
|
||
cursor: pointer;
|
||
transition: transform 0.2s ease;
|
||
transform: ${(props) => (props.$isOpen ? 'rotate(180deg)' : 'rotate(0deg)')};
|
||
|
||
&:hover {
|
||
opacity: 0.7;
|
||
}
|
||
`;
|
||
|
||
const DropdownMenu = styled.div`
|
||
position: absolute;
|
||
top: 100%;
|
||
right: 0;
|
||
margin-top: 0.5rem;
|
||
background: rgba(255, 255, 255, 1);
|
||
border: 0.0625rem solid var(--Stroke, rgba(0, 0, 0, 0.1));
|
||
border-radius: 0.5rem;
|
||
box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);
|
||
z-index: 1000;
|
||
min-width: 8rem;
|
||
overflow: hidden;
|
||
`;
|
||
|
||
const LogoutButton = styled.button`
|
||
width: 100%;
|
||
padding: 0.75rem 1rem;
|
||
border: none;
|
||
background: transparent;
|
||
color: var(--Black, rgba(31, 31, 31, 1));
|
||
font-size: 0.88rem;
|
||
font-weight: 400;
|
||
text-align: left;
|
||
cursor: pointer;
|
||
|
||
&:hover {
|
||
background: var(--PrimaryLight, #f8eded);
|
||
color: var(--Primary, #812525);
|
||
}
|
||
`;
|