Add user status, signout button to app bar.

pull/31/head
Sander Vocke 5 years ago
parent 7144d07832
commit 2029b58466
  1. 82
      client/src/components/appbar/AppBar.tsx
  2. 50
      client/src/lib/useAuth.tsx

@ -1,10 +1,11 @@
import React from 'react';
import { AppBar as MuiAppBar, Box, Tab as MuiTab, Tabs, IconButton, Typography } from '@material-ui/core';
import { AppBar as MuiAppBar, Box, Tab as MuiTab, Tabs, IconButton, Typography, Menu, MenuItem } from '@material-ui/core';
import CloseIcon from '@material-ui/icons/Close';
import SearchIcon from '@material-ui/icons/Search';
import LocalOfferIcon from '@material-ui/icons/LocalOffer';
import { Link, useHistory } from 'react-router-dom';
import { WindowType } from '../windows/Windows';
import { useAuth } from '../../lib/useAuth';
export enum AppBarTab {
Query = 0,
@ -13,19 +14,58 @@ export enum AppBarTab {
export const appBarTabProps: Record<any, any> = {
[AppBarTab.Query]: {
label: <Box display="flex"><SearchIcon/><Typography variant="button">Query</Typography></Box>,
label: <Box display="flex"><SearchIcon /><Typography variant="button">Query</Typography></Box>,
path: "/query",
},
[AppBarTab.Tags]: {
label: <Box display="flex"><LocalOfferIcon/><Typography variant="button">Tags</Typography></Box>,
label: <Box display="flex"><LocalOfferIcon /><Typography variant="button">Tags</Typography></Box>,
path: "/tags",
},
}
export function UserMenu(props: {
position: null | number[],
open: boolean,
onLogout: () => void,
onClose: () => void,
}) {
let auth = useAuth();
const pos = props.open && props.position ?
{ left: props.position[0], top: props.position[1] }
: { left: 0, top: 0 }
return <Menu
open={props.open}
anchorReference="anchorPosition"
anchorPosition={pos}
keepMounted
onClose={props.onClose}
>
<Box p={2}>
{auth.user?.email || "Unknown user"}
<MenuItem
onClick={() => {
props.onClose();
props.onLogout();
}}
>Sign out</MenuItem>
</Box>
</Menu>
}
export default function AppBar(props: {
selectedTab: AppBarTab | null
}) {
const history = useHistory();
let history = useHistory();
let auth = useAuth();
const [userMenuPos, setUserMenuPos] = React.useState<null | number[]>(null);
const onOpenUserMenu = (e: any) => {
setUserMenuPos([e.clientX, e.clientY])
};
const onCloseUserMenu = () => {
setUserMenuPos(null);
};
return <>
<MuiAppBar position="static" style={{ background: 'grey' }}>
@ -35,18 +75,30 @@ export default function AppBar(props: {
<img height="30px" src={process.env.PUBLIC_URL + "/logo.svg"} alt="error"></img>
</Box>
</Link>
<Tabs
value={props.selectedTab}
onChange={(e: any, val: AppBarTab) => history.push(appBarTabProps[val].path)}
variant="scrollable"
scrollButtons="auto"
>
{Object.keys(appBarTabProps).map((tab: any, idx: number) => <MuiTab
label={appBarTabProps[tab].label}
value={idx}
/>)}
</Tabs>
<Box flexGrow={1}>
{auth.user && <Tabs
value={props.selectedTab}
onChange={(e: any, val: AppBarTab) => history.push(appBarTabProps[val].path)}
variant="scrollable"
scrollButtons="auto"
>
{Object.keys(appBarTabProps).map((tab: any, idx: number) => <MuiTab
label={appBarTabProps[tab].label}
value={idx}
/>)}
</Tabs>}
</Box>
{auth.user && <IconButton
color="primary"
onClick={(e: any) => { onOpenUserMenu(e) }}
>{auth.user.icon}</IconButton>}
</Box>
</MuiAppBar>
<UserMenu
position={userMenuPos}
open={userMenuPos !== null}
onClose={onCloseUserMenu}
onLogout={auth.signout}
/>
</>
}

@ -1,52 +1,14 @@
// Note: Based on https://usehooks.com/useAuth/
// import React from "react";
// import { ProvideAuth } from "./use-auth.js";
// function App(props) {
// return (
// <ProvideAuth>
// {/*
// Route components here, depending on how your app is structured.
// If using Next.js this would be /pages/_app.js
// */}
// </ProvideAuth>
// );
// }
// // Any component that wants auth state
// import React from "react";
// import { useAuth } from "./use-auth.js";
// function Navbar(props) {
// // Get auth state and re-render anytime it changes
// const auth = useAuth();
// return (
// <NavbarContainer>
// <Logo />
// <Menu>
// <Link to="/about">About</Link>
// <Link to="/contact">Contact</Link>
// {auth.user ? (
// <Fragment>
// <Link to="/account">Account ({auth.user.email})</Link>
// <Button onClick={() => auth.signout()}>Signout</Button>
// </Fragment>
// ) : (
// <Link to="/signin">Signin</Link>
// )}
// </Menu>
// </NavbarContainer>
// );
// }
// Hook (use-auth.js)
import React, { useState, useEffect, useContext, createContext } from "react";
import React, { useState, useContext, createContext, ReactFragment } from "react";
import PersonIcon from '@material-ui/icons/Person';
import * as serverApi from '../api';
export interface AuthUser {
id: number,
email: string,
icon: ReactFragment,
}
export interface Auth {
@ -92,7 +54,9 @@ function useProvideAuth() {
}
const user = {
id: json.userId
id: json.userId,
email: email,
icon: <PersonIcon/>,
}
setUser(user);
return user;

Loading…
Cancel
Save