AppHeaderLayout

Since I really new from the frontend and I really need help for this… I try to use element ui appbar for my header, quite similar to this

like when user login:

Also with the icon

and if they logout
It looks something like this


(Also have the sign up) in there

I can’t find any good resources to design that… I try to modify that but looks like not the same…

After login…

and Logout

and here is my AppHeaderLayout.js currently have…

import * as React from 'react'

import AccountCircle from '@mui/icons-material/AccountCircle'
import Container from '@mui/material/Container';
import MenuIcon from '@mui/icons-material/Menu'
import { Button } from '@mui/material'
import AppBar from '@mui/material/AppBar'
import Box from '@mui/material/Box'
import FormControlLabel from '@mui/material/FormControlLabel'
import FormGroup from '@mui/material/FormGroup'
import IconButton from '@mui/material/IconButton'
import Menu from '@mui/material/Menu'
import MenuItem from '@mui/material/MenuItem'
import Switch from '@mui/material/Switch'
import Toolbar from '@mui/material/Toolbar'
import Typography from '@mui/material/Typography'

import { Link, routes } from '@redwoodjs/router'

import { useAuth } from 'src/auth'

const AppHeaderLayout = ({ children }) => {
  const { logOut, isAuthenticated, currentUser } = useAuth()
  const [anchorElUser, setAnchorElUser] = React.useState(null)

  const handleOpenUserMenu = (event) => {
    setAnchorElUser(event.currentTarget)
  }

  const handleCloseUserMenu = () => {
    setAnchorElUser(null)
  }

  let userMenu = ['Profile', 'Account', 'Dashboard', 'Logout']

  return (
    <>
      <AppBar position="static">
        <Container maxWidth="x1">
          <Toolbar disableGutters>
            <IconButton
              size="large"
              edge="start"
              color="inherit"
              aria-label="menu"
              sx={{ mr: 2 }}
            >
              <MenuIcon />
            </IconButton>
            <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
              My App
            </Typography>
            <Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}>
              {isAuthenticated ? (
                <Button
                  onClick={logOut}
                  sx={{ my: 2, color: 'white', display: 'block' }}
                >
                  Sign Out
                </Button>
              ) : (
                <Button sx={{ my: 2, color: 'white', display: 'block' }}>
                  <Link to={routes.signup()}>Sign Up</Link>
                </Button>
              )}
              {isAuthenticated ? (
                <Button sx={{ my: 2, color: 'white', display: 'block' }}>
                  Login as {currentUser.firstName}
                </Button>
              ) : (
                <Button sx={{ my: 2, color: 'white', display: 'block' }}>
                  <Link to={routes.login()}>Login</Link>
                </Button>
              )}
            </Box>
          </Toolbar>
        </Container>
      </AppBar>

      {children}
    </>
  )
}

export default AppHeaderLayout

I don’t know what else I need to change now…

OK… Update version code first…

import * as React from 'react'

import AccountCircle from '@mui/icons-material/AccountCircle';
import MenuIcon from '@mui/icons-material/Menu'
import { Button } from '@mui/material'
import AppBar from '@mui/material/AppBar'
import Box from '@mui/material/Box'
import Container from '@mui/material/Container'
import IconButton from '@mui/material/IconButton'
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import Toolbar from '@mui/material/Toolbar'
import Typography from '@mui/material/Typography'

import { Link, routes } from '@redwoodjs/router'

import { useAuth } from 'src/auth'

const AppHeaderLayout = ({ children }) => {
  const { logOut, isAuthenticated, currentUser } = useAuth()
  const [anchorEl, setAnchorEl] = React.useState(null)
  const handleMenu = (event) => {
    setAnchorEl(event.currentTarget)
  }

  const handleClose = () => {
    setAnchorEl(null)
  }


  return (
    <>
      <Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}>
        <AppBar position="static">
          <Container maxWidth="x1">
            <Toolbar disableGutters>
              <IconButton
                size="large"
                edge="start"
                color="inherit"
                aria-label="menu"
                sx={{ mr: 2 }}
              >
                <MenuIcon />
              </IconButton>
              <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
                My App
              </Typography>

              {!isAuthenticated && (
                <Button sx={{ my: 2, color: 'white', display: 'block' }}>
                  <Link to={routes.signup()}>Sign Up</Link>
                </Button>
              )}

              {isAuthenticated ? (
                <Button sx={{ my: 2, color: 'white', display: 'block' }}>
                  Login as {currentUser.firstName}
                </Button>
              ) : (
                <Button sx={{ my: 2, color: 'white', display: 'block' }}>
                  <Link to={routes.login()}>Login</Link>
                </Button>
              )}

              {isAuthenticated && (
                <div>
                  <IconButton
                    size="large"
                    aria-label="account of current user"
                    aria-controls="menu-appbar"
                    aria-haspopup="true"
                    onClick={handleMenu}
                    color="inherit"
                  >
                    <AccountCircle />
                  </IconButton>
                  <Menu
                    id="menu-appbar"
                    anchorEl={anchorEl}
                    anchorOrigin={{
                      vertical: 'top',
                      horizontal: 'right',
                    }}
                    transformOrigin={{
                      vertical: 'top',
                      horizontal: 'right',
                    }}
                    open={Boolean(anchorEl)}
                    onClose={handleClose}
                  >
                    <MenuItem onClick={handleClose}>My Profile</MenuItem>
                    <MenuItem onClick={logOut}>Sign Out</MenuItem>
                  </Menu>
                </div>
              )}
            </Toolbar>
          </Container>
        </AppBar>
      </Box>
      {children}
    </>
  )
}

export default AppHeaderLayout

That works as my expected… but somehow… if I logout and log back in… It will looks like this…

What I need to change so when I log back in, the menu should not pop up automatically?

use an useEffect without a 2nd param

in the first you want to set setAnchorEl(null)

in general, from the snippet I wouldn’t do it like that. your anchorEl should always be set.

You really want a boolean to toggle it.

const [isUserMenuOpen, setIsUserMenuOpen] = React.useState<boolean>(false)
1 Like

For new version code

import * as React from 'react'

import AccountCircle from '@mui/icons-material/AccountCircle'
import MenuIcon from '@mui/icons-material/Menu'
import { Button } from '@mui/material'
import AppBar from '@mui/material/AppBar'
import Box from '@mui/material/Box'
import Container from '@mui/material/Container'
import IconButton from '@mui/material/IconButton'
import Menu from '@mui/material/Menu'
import MenuItem from '@mui/material/MenuItem'
import Toolbar from '@mui/material/Toolbar'
import Typography from '@mui/material/Typography'

import { Link, routes } from '@redwoodjs/router'

import { useAuth } from 'src/auth'

const AppHeaderLayout = ({ children }) => {
  const { logOut, isAuthenticated, currentUser } = useAuth()
  const [anchorEl, setAnchorEl, openedItem, setOpenedItem] =
    React.useState(null)
  const menus = ['main-menu-appbar', 'account-menu-appbar']

  const handleMenuItemOpen = (itemId) => {
    setOpenedItem(itemId)
  }

  const handleMenu = (event) => {
    setAnchorEl(event.currentTarget)
  }

  const handleMainMenu = (event) => {
    setAnchorEl(event.currentTarget)
  }

  const handleClose = () => {
    setAnchorEl(null)
  }

  return (
    <>
      <Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' } }}>
        <AppBar position="static">
          <Container maxWidth="x1">
            <Toolbar disableGutters>
              <div>
                <IconButton
                  size="large"
                  edge="start"
                  aria-controls="main-menu-appbar"
                  color="inherit"
                  onClick={handleMainMenu}
                  sx={{ mr: 2 }}
                >
                  <MenuIcon />
                  <Menu
                    id="main-menu-appbar"
                    anchorEl={anchorEl}
                    anchorOrigin={{
                      vertical: 'bottom',
                      horizontal: 'center',
                    }}
                    transformOrigin={{
                      vertical: 'top',
                      horizontal: 'center',
                    }}
                    open={Boolean(anchorEl)}
                    onClose={handleClose}
                  >
                    <MenuItem onClick={handleClose}>Home</MenuItem>
                    <MenuItem onClick={handleClose}>News</MenuItem>
                    <MenuItem onClick={handleClose}>Games</MenuItem>
                    <MenuItem onClick={handleClose}>About</MenuItem>
                  </Menu>
                </IconButton>
              </div>
              <Typography variant="h6" component="div" sx={{ flexGrow: 1 }}>
                Toronto Riichi Mahjong League
              </Typography>

              {!isAuthenticated && (
                <Button sx={{ my: 2, color: 'white', display: 'block' }}>
                  <Link to={routes.signup()}>Sign Up</Link>
                </Button>
              )}

              {isAuthenticated ? (
                <Button sx={{ my: 2, color: 'white', display: 'block' }}>
                  Login as {currentUser.firstName}
                </Button>
              ) : (
                <Button sx={{ my: 2, color: 'white', display: 'block' }}>
                  <Link to={routes.login()}>Login</Link>
                </Button>
              )}

              {isAuthenticated && (
                <div>
                  <IconButton
                    size="large"
                    aria-label="account of current user"
                    aria-controls="menu-appbar"
                    aria-haspopup="false"
                    onClick={handleMenu}
                    color="inherit"
                  >
                    <AccountCircle />
                  </IconButton>
                  <Menu
                    id="account-menu-appbar"
                    anchorEl={anchorEl}
                    anchorOrigin={{
                      vertical: 'bottom',
                      horizontal: 'center',
                    }}
                    transformOrigin={{
                      vertical: 'top',
                      horizontal: 'center',
                    }}
                    open={Boolean(anchorEl)}
                    onClose={handleClose}
                  >
                    <MenuItem onClick={handleClose}>My Profile</MenuItem>
                    <MenuItem onClick={logOut}>Sign Out</MenuItem>
                  </Menu>
                </div>
              )}
            </Toolbar>
          </Container>
        </AppBar>
      </Box>
      {children}
    </>
  )
}

export default AppHeaderLayout

Now the problem become like this and I really don’t know how to apply the change in now…

I think I solve the menu problem but right now overlapped… and also if I am logout it looks like the menu got stuck…

OK… take a while to resolve all…
I need to set one more anchor only for the user part…
const [anchorElUser, setAnchorElUser] = React.useState(null)
and in the accountIcon one just use the anchorElUser to do the determination. That will solve the overlapped issue…