ShiftSync/components/core/Shell/NavBar/NavBar.jsx

200 lines
No EOL
4.5 KiB
JavaScript

import React, { useEffect, useRef, useState } from 'react';
import styled from '@emotion/styled';
import {
useLocation,
useNavigate,
useParams
} from 'react-router';
import { Avatar, Stack } from '@mui/material';
import { useLocalStore } from '@components';
const NavBox = styled(Stack)`
width: 100%;
`;
const LeftContainer = styled(Stack)`
display: flex;
align-items: center;
flex-direction: row;
flex-flow: row wrap;
`;
const RightContainer = styled(Stack)`
display: flex;
flex-direction: row;
flex-flow: row wrap;
`;
const NavGroup = styled(Stack)`
display: flex;
background: #ffffff
width: 100%;
height: 60px;
padding: 4px;
justify-content: space-between !important
`;
const Title = styled('p')`
cursor: pointer;
`;
const Tab = styled('div')`
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
height: 100%;
padding: 6px 16px;
font-size: 20px;
font-weight: 800;
color: grey;
background: none;
border: none;
cursor: pointer;
font-family: "WDXL Lubrifont TC";
letter-spacing: .05em;
word-spacing: .2em;
`;
const SlidingIndicator = styled('div')`
position: absolute;
bottom: -6px;
height: 2px;
background-color: #4D79FF;
transition: left 0.3s ease, width 0.3s ease;
`;
const Border = styled('div')`
height: 2px;
width: 100%;
background-color: #A8A8A8;
`;
export const NavBar = ({ notifications, disableNav, settings }) => {
const { pathname } = useLocation();
const navigate = useNavigate();
const routeParams = useParams();
const { user } = useLocalStore();
const [indicatorStyle, setIndicatorStyle] = useState({ left: 0, width: 0 });
const tabRefs = useRef({});
const isAdmin = user?.isAdmin;
const navItems = [
{
name: 'Home',
id: 'home',
href: '/',
matches: ['', 'home']
},
{
name: 'Schedule',
id: 'schedule',
href: '/schedule',
matches: ['schedule']
},
{
name: 'Settings',
id: 'settings',
href: '/settings',
matches: ['settings', 'settings']
},
{
name: 'Administrator Panel',
id: 'admin',
href: '/admin',
matches: ['admin'],
hidden: !isAdmin
},
// Keep this Last (Replaced with the profile icon)
{
name: 'Profile',
id: 'profile',
href: '/profile',
matches: ['profile'],
hidden: true
}
];
let activeTab = navItems.find((tab) => {
return tab.matches.some((item) => {
return item === pathname?.split('/')[1];
});
});
const onShiftSyncClick = () => {
navigate('/');
}
const onNavButtonClick = (tab) => {
activeTab = tab;
navigate(tab.href);
};
const onUserIconClick = () => {
navigate('/profile');
};
useEffect(() => {
if (activeTab?.id && tabRefs.current[activeTab.id]) {
const el = tabRefs.current[activeTab.id];
const rect = el.getBoundingClientRect();
const containerRect = el.parentNode.getBoundingClientRect();
setIndicatorStyle({
left: rect.left - containerRect.left,
width: rect.width
});
}
}, [pathname, activeTab?.id]);
return (
<NavBox direction='column'>
<NavGroup direction='row'>
<LeftContainer>
<Title
style={{
color: 'darkgray',
fontWeight: '400',
fontSize: '40px',
fontFamily: "WDXL Lubrifont TC, sans-serif",
letterSpacing: '.08em'
}}
onClick={onShiftSyncClick}
>
ShiftSync
</Title>
</LeftContainer>
<RightContainer style={{ position: 'relative' }}>
{navItems?.map((item) => {
if (!item?.hidden) {
return (
<Tab
key={item?.id}
ref={(el) => { tabRefs.current[item.id] = el; }}
onClick={() => onNavButtonClick(item)}
>
{item?.name}
</Tab>
);
}
return null;
}).filter((item) => item !== null)}
<Tab
key='profile'
ref={(el) => { tabRefs.current['profile'] = el; }}
>
<Avatar
onClick={() => onUserIconClick()}
>
{`${user?.firstName[0]}${user?.lastName[0]}`}
</Avatar>
</Tab>
<SlidingIndicator style={indicatorStyle} />
</RightContainer>
</NavGroup>
<Border />
</NavBox>
)
}