/* eslint-disable jsx-a11y/anchor-is-valid */ /* eslint-disable jsx-a11y/anchor-has-content */ import { useCallback, useEffect, useMemo, useRef, } from 'react'; import { useLocation, useNavigate, Link, generatePath, useMatch, } from 'react-router-dom'; import { Layout, Space, Button, Row, Col, Tooltip, Grid, Menu, Dropdown, Typography, Radio, } from 'antd'; import { UserOutlined, CloudUploadOutlined, CloudDownloadOutlined, SettingOutlined, LoginOutlined, LineChartOutlined, SlidersOutlined, FileZipOutlined, DesktopOutlined, DownOutlined, SearchOutlined, ToolOutlined, FundOutlined, UserAddOutlined, LogoutOutlined, InfoCircleOutlined, CarOutlined, FileTextOutlined, FileExcelOutlined, } from '@ant-design/icons'; import { useKBar } from 'kbar'; import store from '../store'; import { isMac } from '../utils/env'; import { isToggleSidebar } from '../utils/keyboard/shortcuts'; import { Routes } from '../routes'; import { useAuth } from '../contexts/AuthContext'; import { logOutSuccessful } from '../pages/auth/notifications'; import { TuneDataState } from '../types/state'; import { removeFilenameSuffix } from '../pocketbase'; import useServerStorage from '../hooks/useServerStorage'; const { Header } = Layout; const { useBreakpoint } = Grid; const logsExtensionsIcons: { [key: string]: any } = { 'mlg': , 'msl': , 'csv': , }; const TopBar = ({ tuneData, }: { tuneData: TuneDataState | null; }) => { const { xs, sm, lg } = useBreakpoint(); const { pathname } = useLocation(); const { currentUser, logout } = useAuth(); const navigate = useNavigate(); const { query } = useKBar(); const buildTuneUrl = useCallback((route: string) => tuneData?.tuneId ? generatePath(route, { tuneId: tuneData.tuneId }) : null, [tuneData?.tuneId]); const hubPathMatch = useMatch(Routes.HUB); const tuneRootMatch = useMatch(`${Routes.TUNE_ROOT}/*`); const tuneTuneMatch = useMatch(`${Routes.TUNE_TUNE}/*`); const tuneLogMatch = useMatch(`${Routes.TUNE_LOGS}/*`); const toothLogMatch = useMatch(`${Routes.TUNE_DIAGNOSE}/*`); const tabMatch = useMatch(`${Routes.TUNE_TAB}/*`); const uploadMatch = useMatch(Routes.UPLOAD); const hubMatch = useMatch(Routes.HUB); const { downloadFile } = useServerStorage(); const downloadAnchorRef = useRef(null); const logoutClick = useCallback(() => { logout(); logOutSuccessful(); navigate(Routes.HUB); }, [logout, navigate]); const toggleCommandPalette = useCallback(() => query.toggle(), [query]); const handleGlobalKeyboard = useCallback((e: KeyboardEvent) => { if (isToggleSidebar(e)) { e.preventDefault(); store.dispatch({ type: 'ui/toggleSidebar' }); } }, []); const downloadLogsItems = { label: 'Logs', icon: , key: 'logs', children: (tuneData?.logFiles || []).map((filename) => ({ key: filename, label: removeFilenameSuffix(filename), icon: logsExtensionsIcons[filename.slice(-3)], onClick: () => downloadFile(tuneData!.id, filename, downloadAnchorRef.current!), })), }; const downloadToothLogsItems = { label: 'Tooth logs', icon: , key: 'toothLogs', children: (tuneData?.toothLogFiles || []).map((filename) => ({ key: filename, label: removeFilenameSuffix(filename), icon: logsExtensionsIcons[filename.slice(-3)], onClick: () => downloadFile(tuneData!.id, filename, downloadAnchorRef.current!), })), }; const downloadItems = [ { label: 'Tune', icon: , key: 'tune', children: [ { label: 'Download', icon: , key: 'download', onClick: () => downloadFile(tuneData!.id, tuneData!.tuneFile, downloadAnchorRef.current!), }, { label: 'Open in app', icon: , key: 'open', disabled: true, onClick: () => window.open(`hypertuner://hypertuner.cloud/t/${tuneData!.tuneId}`, '_blank'), }, ], }, (tuneData?.logFiles || []).length > 0 ? { ...downloadLogsItems } : null, (tuneData?.toothLogFiles || []).length > 0 ? { ...downloadToothLogsItems } : null, ]; useEffect(() => { document.addEventListener('keydown', handleGlobalKeyboard); return () => document.removeEventListener('keydown', handleGlobalKeyboard); }, [currentUser, handleGlobalKeyboard]); const tabs = useMemo(() => ( navigate(e.target.value)} > {lg && 'Hub'} {lg && 'Info'} {lg && 'Tune'} {lg && 'Logs'} {lg && 'Diagnose'} ), [pathname, tuneLogMatch?.pathnameBase, toothLogMatch?.pathnameBase, tuneTuneMatch?.pathnameBase, tabMatch?.pathname, tuneRootMatch?.pathname, hubPathMatch?.pathname, buildTuneUrl, lg, tuneData?.logFiles, tuneData?.toothLogFiles, navigate]); const rightMenuColProps = tuneData?.tuneId ? { span: 8, md: 8, sm: 8, } : { span: 14, md: 10, sm: 8, }; const downloadButton = useMemo(() => { const list = []; if (lg) { list.push(Download); } if (sm) { list.push(); } return list.length ? list : null; }, [lg, sm]); const userAuthMenuItems = useMemo(() => currentUser ? [{ key: 'profile', icon: , label: 'Profile', onClick: () => navigate(Routes.PROFILE), }, { key: 'logout', icon: , label: 'Logout', onClick: logoutClick, }] : [{ key: 'login', icon: , label: 'Login', onClick: () => navigate(Routes.LOGIN), }, { key: 'sign-up', icon: , label: 'Sign Up', onClick: () => navigate(Routes.SIGN_UP), }], [currentUser, logoutClick, navigate]); const userMenuItems = [ ...userAuthMenuItems, { key: 'divider', type: 'divider', }, { key: 'about', icon: , label: 'About', onClick: () => navigate(Routes.ABOUT), }, ]; return (
{tuneData?.tuneId ? tabs : ( )} {sm && {isMac ? '⌘' : 'CTRL'} K }> {tuneData?.tuneId && } placement="bottom" trigger={['click']} > } } placement="bottomRight" trigger={['click']} > {/* dummy anchor for file download */}
); }; export default TopBar;