Header.tsx

  1import React from 'react';
  2import { Link, useLocation } from 'react-router-dom';
  3
  4import AppBar from '@material-ui/core/AppBar';
  5import Tab, { TabProps } from '@material-ui/core/Tab';
  6import Tabs from '@material-ui/core/Tabs';
  7import Toolbar from '@material-ui/core/Toolbar';
  8import Tooltip from '@material-ui/core/Tooltip/Tooltip';
  9import { fade, makeStyles } from '@material-ui/core/styles';
 10
 11import CurrentIdentity from '../Identity/CurrentIdentity';
 12import { LightSwitch } from '../Themer';
 13
 14const useStyles = makeStyles((theme) => ({
 15  offset: {
 16    ...theme.mixins.toolbar,
 17  },
 18  filler: {
 19    flexGrow: 1,
 20  },
 21  appBar: {
 22    backgroundColor: theme.palette.primary.dark,
 23    color: theme.palette.primary.contrastText,
 24  },
 25  appTitle: {
 26    ...theme.typography.h6,
 27    color: theme.palette.primary.contrastText,
 28    textDecoration: 'none',
 29    display: 'flex',
 30    alignItems: 'center',
 31  },
 32  lightSwitch: {
 33    marginRight: '20px',
 34    color: fade(theme.palette.primary.contrastText, 0.5),
 35  },
 36  logo: {
 37    height: '42px',
 38    marginRight: theme.spacing(2),
 39  },
 40}));
 41
 42function a11yProps(index: any) {
 43  return {
 44    id: `nav-tab-${index}`,
 45    'aria-controls': `nav-tabpanel-${index}`,
 46  };
 47}
 48
 49const DisabledTabWithTooltip = (props: TabProps) => {
 50  /*The span elements around disabled tabs are needed, as the tooltip
 51   * won't be triggered by disabled elements.
 52   * See: https://material-ui.com/components/tooltips/#disabled-elements
 53   * This must be done in a wrapper component, otherwise the TabS component
 54   * cannot pass it styles down to the Tab component. Resulting in (console)
 55   * warnings. This wrapper acceps the passed down TabProps and pass it around
 56   * the span element to the Tab component.
 57   */
 58  const msg = `This feature doesn't exist yet. Come help us build it.`;
 59  return (
 60    <Tooltip title={msg}>
 61      <span>
 62        <Tab disabled {...props} />
 63      </span>
 64    </Tooltip>
 65  );
 66};
 67
 68function Header() {
 69  const classes = useStyles();
 70  const location = useLocation();
 71
 72  // Prevents error of invalid tab selection in <Tabs>
 73  // Will return a valid tab path or false if path is unkown.
 74  function highlightTab() {
 75    const validTabs = ['/', '/code', '/pulls', '/settings'];
 76    const tab = validTabs.find((tabPath) => tabPath === location.pathname);
 77    return tab === undefined ? false : tab;
 78  }
 79
 80  return (
 81    <>
 82      <AppBar position="fixed" className={classes.appBar}>
 83        <Toolbar>
 84          <Link to="/" className={classes.appTitle}>
 85            <img src="/logo.svg" className={classes.logo} alt="git-bug logo" />
 86            git-bug
 87          </Link>
 88          <div className={classes.filler} />
 89          <LightSwitch className={classes.lightSwitch} />
 90          <CurrentIdentity />
 91        </Toolbar>
 92      </AppBar>
 93      <div className={classes.offset} />
 94      <Tabs centered value={highlightTab()} aria-label="nav tabs">
 95        <DisabledTabWithTooltip label="Code" value="/code" {...a11yProps(1)} />
 96        <Tab label="Bugs" value="/" component={Link} to="/" {...a11yProps(2)} />
 97        <DisabledTabWithTooltip
 98          label="Pull Requests"
 99          value="/pulls"
100          {...a11yProps(3)}
101        />
102        <DisabledTabWithTooltip
103          label="Settings"
104          value="/settings"
105          {...a11yProps(4)}
106        />
107      </Tabs>
108    </>
109  );
110}
111
112export default Header;