181 lines
3.9 KiB
React
181 lines
3.9 KiB
React
|
|
import React, { useEffect, useRef, useState } from 'react';
|
||
|
|
import styled from '@emotion/styled';
|
||
|
|
import {
|
||
|
|
useLocation,
|
||
|
|
useNavigate,
|
||
|
|
useParams
|
||
|
|
} from 'react-router';
|
||
|
|
import { Stack } from '@mui/material';
|
||
|
|
|
||
|
|
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')`
|
||
|
|
&:hover {
|
||
|
|
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: red;
|
||
|
|
transition: left 0.3s ease, width 0.3s ease;
|
||
|
|
`;
|
||
|
|
|
||
|
|
const UserButton = styled(Stack)`
|
||
|
|
width: 100%;
|
||
|
|
`;
|
||
|
|
|
||
|
|
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 [indicatorStyle, setIndicatorStyle] = useState({ left: 0, width: 0 });
|
||
|
|
const tabRefs = useRef({});
|
||
|
|
|
||
|
|
const isAdmin = true; // to be changed to check
|
||
|
|
|
||
|
|
const navItems = [
|
||
|
|
{
|
||
|
|
name: 'Home',
|
||
|
|
id: 'home',
|
||
|
|
href: '/',
|
||
|
|
matches: ['', 'home']
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: 'About Us',
|
||
|
|
id: 'about',
|
||
|
|
href: '/about',
|
||
|
|
matches: ['about', 'aboutus']
|
||
|
|
},
|
||
|
|
{
|
||
|
|
name: 'Administrator Panel',
|
||
|
|
id: 'admin',
|
||
|
|
href: '/admin',
|
||
|
|
matches: ['admin'],
|
||
|
|
hidden: !isAdmin
|
||
|
|
}
|
||
|
|
];
|
||
|
|
|
||
|
|
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('/settings');
|
||
|
|
};
|
||
|
|
|
||
|
|
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>
|
||
|
|
{/* <Icon /> */}
|
||
|
|
<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)}
|
||
|
|
<SlidingIndicator style={indicatorStyle} />
|
||
|
|
</RightContainer>
|
||
|
|
</NavGroup>
|
||
|
|
<Border />
|
||
|
|
</NavBox>
|
||
|
|
)
|
||
|
|
}
|