Skip to content

Commit

Permalink
split out AccountMenu from AppHeader (#409)
Browse files Browse the repository at this point in the history
  • Loading branch information
incognitojam authored Jul 25, 2023
1 parent 06e9549 commit 61c57a0
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 153 deletions.
71 changes: 71 additions & 0 deletions src/components/AppHeader/AccountMenu.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React, { useCallback, useEffect, useState } from 'react';
import dayjs from 'dayjs';

import {
Divider,
ListItem,
Menu,
MenuItem,
} from '@material-ui/core';

import MyCommaAuth from '@commaai/my-comma-auth';

const logOut = async () => {
await MyCommaAuth.logOut();
if (window.location) {
window.location = window.location.origin;
}
};

const AccountMenu = ({ profile, open, anchorEl, onClose, ...rest }) => {
const [buildTimestamp, setBuildTimestamp] = useState('');
const [version, setVersion] = useState('');

useEffect(() => {
setVersion(import.meta.env.VITE_APP_GIT_SHA?.substring(0, 7) || 'dev');

const buildDate = import.meta.env.VITE_APP_BUILD_TIMESTAMP;
if (buildDate) {
setBuildTimestamp(`, ${dayjs(buildDate).fromNow()}`);
}
}, []);

const onLogOut = useCallback(() => {
onClose();
logOut();
}, [onClose]);

return (
<Menu
open={open}
onClose={onClose}
anchorEl={anchorEl}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
{...rest}
>
<ListItem className="text-white py-3 px-4 flex-col items-start">
<span className="font-bold">{profile.email}</span>
<span className="text-xs text-[#ffffff66] pt-2">{ profile.user_id }</span>
<span className="text-xs text-[#ffffff66] pt-2">{`Version: ${version}${buildTimestamp}`}</span>
</ListItem>
<Divider />
<MenuItem
className="py-3 px-4"
component="a"
href="https://useradmin.comma.ai/"
target="_blank"
>
Manage Account
</MenuItem>
<MenuItem
className="py-3 px-4"
onClick={onLogOut}
>
Log out
</MenuItem>
</Menu>
);
};

export default AccountMenu;
234 changes: 83 additions & 151 deletions src/components/AppHeader/index.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import React, { Component } from 'react';
import React, { useCallback, useState } from 'react';
import { connect } from 'react-redux';
import Obstruction from 'obstruction';
import dayjs from 'dayjs';

import { withStyles } from '@material-ui/core/styles';
import { Divider, Typography, Menu, MenuItem, ListItem, IconButton, Icon, AppBar } from '@material-ui/core';
import { Typography, IconButton, Icon, AppBar } from '@material-ui/core';

import MyCommaAuth from '@commaai/my-comma-auth';

import { selectDevice } from '../../actions';
import TimeFilter from './TimeFilter';
import { AccountIcon } from '../../icons';
import Colors from '../../colors';
import ResizeHandler from '../ResizeHandler';
import { filterRegularClick } from '../../utils';

import AccountMenu from './AccountMenu';
import TimeFilter from './TimeFilter';

const styles = () => ({
header: {
backgroundColor: '#1D2225',
Expand All @@ -31,9 +32,6 @@ const styles = () => ({
alignItems: 'center',
flexWrap: 'nowrap',
},
hamburger: {
marginRight: 10,
},
logo: {
alignItems: 'center',
display: 'flex',
Expand All @@ -57,169 +55,103 @@ const styles = () => ({
height: 34,
width: 34,
},
accountListItem: {
color: Colors.white,
padding: '12px 16px',
},
accountListEmail: {
flexDirection: 'column',
alignItems: 'flex-start',
'& :first-child': {
fontWeight: 'bold',
},
'& :not(:first-child)': {
fontSize: '0.75em',
color: Colors.white40,
paddingTop: 8,
},
},
accountMenuItem: {
padding: '12px 16px',
},
});

class AppHeader extends Component {
constructor(props) {
super(props);

this.handleClickedAccount = this.handleClickedAccount.bind(this);
this.handleClose = this.handleClose.bind(this);
this.handleLogOut = this.handleLogOut.bind(this);
this.toggleDrawer = this.toggleDrawer.bind(this);
this.onResize = this.onResize.bind(this);
const AppHeader = ({
profile, classes, dispatch, drawerIsOpen, annotating, showDrawerButton,
forwardRef, clips, handleDrawerStateChanged, primeNav, dongleId,
}) => {
const [anchorEl, setAnchorEl] = useState(null);
const [windowWidth, setWindowWidth] = useState(window.innerWidth);

this.state = {
anchorEl: null,
windowWidth: window.innerWidth,
};
}

toggleDrawer() {
this.props.handleDrawerStateChanged(!this.props.drawerIsOpen);
}

handleClickedAccount(event) {
const handleClickedAccount = useCallback((event) => {
if (MyCommaAuth.isAuthenticated()) {
this.setState({ anchorEl: event.currentTarget });
setAnchorEl(event.currentTarget);
} else if (window.location) {
window.location = window.location.origin;
}
}
}, []);

handleClose() {
this.setState({ anchorEl: null });
}
const handleClose = useCallback(() => {
setAnchorEl(null);
}, []);

async handleLogOut() {
this.handleClose();
await MyCommaAuth.logOut();
const toggleDrawer = useCallback(() => {
dispatch(handleDrawerStateChanged(!drawerIsOpen));
}, [dispatch, drawerIsOpen, handleDrawerStateChanged]);

if (window.location) {
window.location = window.location.origin;
}
}
const onResize = useCallback((width) => {
setWindowWidth(width);
}, []);

onResize(windowWidth) {
this.setState({ windowWidth });
}
const open = Boolean(anchorEl);

render() {
const { profile, classes, dispatch, annotating, forwardRef, showDrawerButton, primeNav, clips, dongleId } = this.props;
const { anchorEl, windowWidth } = this.state;
const open = Boolean(anchorEl);

let reorderWideStyle = {};
if (windowWidth < 640) {
reorderWideStyle = {
order: 4,
width: '100%',
display: 'flex',
justifyContent: 'center',
};
}
let reorderWideStyle = {};
if (windowWidth < 640) {
reorderWideStyle = {
order: 4,
width: '100%',
display: 'flex',
justifyContent: 'center',
};
}

const version = import.meta.env.VITE_APP_GIT_SHA?.substring(0, 7) || 'dev';
const buildDate = import.meta.env.VITE_APP_BUILD_TIMESTAMP;
let buildTimestamp = ''
if (buildDate) {
buildTimestamp = `, ${dayjs(buildDate).fromNow()}`;
}
return (
<>
<ResizeHandler onResize={ this.onResize } />
<AppBar position="sticky" elevation={ 1 }>
<div ref={ forwardRef } className={ classes.header }>
<div className={classes.titleContainer}>
{ showDrawerButton ? (
<IconButton aria-label="menu" className={classes.hamburger} onClick={this.toggleDrawer}>
<Icon>menu</Icon>
</IconButton>
)
: (
<a
href={ `/${dongleId}` }
className={ classes.logoImgLink }
onClick={ filterRegularClick(() => dispatch(selectDevice(dongleId))) }
>
<img alt="comma" src="/images/comma-white.png" className={classes.logoImg} />
</a>
)}
<a
href={ `/${dongleId}` }
className={classes.logo}
onClick={ filterRegularClick(() => dispatch(selectDevice(dongleId))) }
return (
<>
<ResizeHandler onResize={onResize} />
<AppBar position="sticky" elevation={1}>
<div ref={forwardRef} className={classes.header}>
<div className={classes.titleContainer}>
{showDrawerButton ? (
<IconButton
aria-label="menu"
className="mr-3"
onClick={toggleDrawer}
>
<Typography className={classes.logoText}>connect</Typography>
</a>
</div>
<div className={ classes.headerWideItem } style={ reorderWideStyle }>
{ Boolean(!primeNav && !clips && !annotating && dongleId) && <TimeFilter /> }
</div>
<IconButton
aria-owns={open ? 'menu-appbar' : null}
aria-haspopup="true"
onClick={this.handleClickedAccount}
aria-label="account menu"
<Icon>menu</Icon>
</IconButton>
)
: (
<a
href={`/${dongleId}`}
className={classes.logoImgLink}
onClick={filterRegularClick(() => dispatch(selectDevice(dongleId)))}
>
<img alt="comma" src="/images/comma-white.png" className={classes.logoImg} />
</a>
)}
<a
href={`/${dongleId}`}
onClick={filterRegularClick(() => dispatch(selectDevice(dongleId)))}
>
<AccountIcon className={classes.accountIcon} />
</IconButton>
<Typography className={classes.logoText}>connect</Typography>
</a>
</div>
</AppBar>
{ Boolean(MyCommaAuth.isAuthenticated() && profile) && (
<Menu
<div className={classes.headerWideItem} style={reorderWideStyle}>
{Boolean(!primeNav && !clips && !annotating && dongleId) && <TimeFilter />}
</div>
<IconButton
aria-owns={open ? 'menu-appbar' : null}
aria-haspopup="true"
onClick={handleClickedAccount}
aria-label="account menu"
>
<AccountIcon className={classes.accountIcon} />
</IconButton>
</div>
</AppBar>
{Boolean(MyCommaAuth.isAuthenticated() && profile) && (
<AccountMenu
id="menu-appbar"
open={open}
onClose={this.handleClose}
anchorEl={anchorEl}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
>
<ListItem className={ `${classes.accountListItem} ${classes.accountListEmail}` }>
<span>{ profile.email }</span>
<span>{ profile.user_id }</span>
<span>{`Version: ${version}${buildTimestamp}`}</span>
</ListItem>
<Divider />
<MenuItem
className={ classes.accountMenuItem }
component="a"
href="https://useradmin.comma.ai/"
target="_blank"
>
Manage Account
</MenuItem>
<MenuItem
className={ classes.accountMenuItem }
onClick={this.handleLogOut}
>
Log out
</MenuItem>
</Menu>
) }
</>
);
}
}
onClose={handleClose}
profile={profile}
/>
)}
</>
);
};

const stateToProps = Obstruction({
dongleId: 'dongleId',
Expand Down
4 changes: 2 additions & 2 deletions src/components/explorer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { connect } from 'react-redux';
import Obstruction from 'obstruction';
import localforage from 'localforage';
import { replace } from 'connected-react-router';
import * as Sentry from '@sentry/react';

import { withStyles, Button, CircularProgress, Divider, Grid, Modal, Paper, Typography } from '@material-ui/core';
import 'mapbox-gl/src/css/mapbox-gl.css';
Expand All @@ -19,8 +18,9 @@ import PullDownReload from './utils/PullDownReload';
import { analyticsEvent, selectDevice, updateDevice } from '../actions';
import init from '../actions/startup';
import Colors from '../colors';
import { verifyPairToken, pairErrorToMessage } from '../utils';
import { play, pause } from '../timeline/playback';
import { verifyPairToken, pairErrorToMessage } from '../utils';

import ResizeHandler from './ResizeHandler';

const ClipView = lazy(() => import('./ClipView'));
Expand Down
1 change: 1 addition & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
important: true,
content: [
'./index.html',
'./src/**/*.{js,ts,jsx,tsx}',
Expand Down

0 comments on commit 61c57a0

Please sign in to comment.