123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- import { Menubar } from 'primereact/menubar';
- import React, { useContext, useEffect, useRef, useState } from 'react';
- import { useNavigate } from 'react-router-dom';
- import { AuthContext, TimeContext } from '../contexts';
- import { Configuration } from '../services';
- import { Airport } from '../services';
- import { AirportOverview, BackendReturnStatus, IAuthState } from '../types';
- export const NavBar: React.FC = () => {
- const [timestamp, setTimestamp] = useState<string>('');
- const [fullName, setFullName] = useState<string>('');
- const [menuTree, setMenuTree] = useState<any>(undefined);
- const authContext = useContext(AuthContext);
- const timeContext = useContext(TimeContext);
- const currentAuth = useRef<IAuthState>();
- const navigate = useNavigate();
- currentAuth.current = authContext.auth;
- const firBasedSubMenu = (airports: AirportOverview[], endpoint: string): any[] => {
- if (airports.length === 0) {
- return [{
- label: 'No airport available',
- disabled: true,
- }];
- }
- const firAirports: [string, AirportOverview[]][] = [];
- // cluster airports based on FIRs
- airports.forEach((airport) => {
- const idx = firAirports.findIndex((value) => value[0] === airport.flightInformationRegion);
- if (idx !== -1) {
- firAirports[idx][1].push(airport);
- } else {
- firAirports.push([airport.flightInformationRegion, [airport]]);
- }
- });
- // create the submenu for every FIR
- const retval: any[] = [];
- firAirports.forEach((fir) => {
- retval.push({
- label: fir[0],
- items: [],
- });
- // sort airports alphabetically
- fir[1].sort();
- // create the airport with the link
- fir[1].forEach((airport) => {
- retval[retval.length - 1].push({
- label: `${airport.icao} - ${airport.name}`,
- command: () => navigate(`${endpoint}?icao=${airport.icao}`),
- });
- });
- });
- return retval;
- }
- const updateMenuItems = async () => {
- if (currentAuth.current === undefined || !currentAuth.current.valid) return [];
- Airport.all().then((response) => {
- if (response.status !== BackendReturnStatus.Ok) return [];
- const newMenuTree: { label: string; items?: any[]; command?: () => void }[] = [
- {
- label: 'Airports',
- items: [] as any[],
- }
- ];
- // create the airports subtree
- const airportSubtree = firBasedSubMenu(response.airports, '/sequence');
- newMenuTree[0].items = airportSubtree;
- // collect all configuration airports
- const configurationAirports: AirportOverview[] = [];
- response.airports.forEach((airport) => {
- const idx = currentAuth.current?.user.airportConfigurationAccess.findIndex((value) => airport.icao === value);
- if (idx !== -1) configurationAirports.push(airport);
- });
- // create the configuration subtree
- if (configurationAirports.length !== 0) {
- const configurationSubtree = firBasedSubMenu(configurationAirports, '/configure/airport');
- newMenuTree[1].items = configurationSubtree;
- }
- if (currentAuth.current?.user.administrator) {
- newMenuTree.push({
- label: 'Administration',
- items: [
- {
- label: 'Users',
- command: () => navigate('/admin/users'),
- },
- {
- label: 'Airports',
- command: () => navigate('/admin/airports'),
- },
- ],
- });
- }
- newMenuTree.push({
- label: 'Logout',
- command: () => navigate('/logout'),
- });
- setMenuTree(newMenuTree);
- });
- }
- useEffect(() => {
- const event = new EventSource(`${Configuration.resourceServer}/airport/renew`);
- event.onmessage = () => {
- updateMenuItems();
- }
- const timeInterval = setInterval(() => {
- const serverUtcTime = new Date(new Date().getTime() + timeContext.offset);
- const hours = String(serverUtcTime.getUTCHours()).padStart(2, '0');
- const minutes = String(serverUtcTime.getUTCMinutes()).padStart(2, '0');
- const seconds = String(serverUtcTime.getUTCSeconds()).padStart(2, '0');
- if (currentAuth.current?.valid) {
- setTimestamp(`${hours}:${minutes}:${seconds}`);
- }
- }, 1000);
- return () => {
- clearInterval(timeInterval);
- event.close();
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
- useEffect(() => {
- if (currentAuth.current?.valid) {
- if (currentAuth.current.user.fullName !== '') {
- setFullName(currentAuth.current.user.fullName);
- } else {
- setFullName(currentAuth.current.user.vatsimId);
- }
- updateMenuItems();
- } else {
- setFullName('');
- setMenuTree([]);
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [authContext]);
- if (menuTree === undefined || !currentAuth.current.valid) return <></>;
- const rightSideInfo = (
- <div>{fullName} | {timestamp}</div>
- );
- return (menuTree.length !== 0 ? <Menubar model={menuTree} end={rightSideInfo} /> : <></>);
- };
|