import React from "react"; import { Box, Button, HStack, IconButton, Menu, MenuButton, MenuList, MenuItem, useBreakpointValue, } from "@chakra-ui/core"; import { HamburgerIcon } from "@chakra-ui/icons"; import { Link, useLocation } from "react-router-dom"; import { useAuth0 } from "@auth0/auth0-react"; import { ChevronLeftIcon } from "@chakra-ui/icons"; import useCurrentUser from "./components/useCurrentUser"; import HomeLinkIcon from "../images/home-link-icon.png"; import HomeLinkIcon2x from "../images/home-link-icon@2x.png"; function GlobalHeader() { return ( <Box display="flex" alignItems="center" flexWrap="wrap"> <HomeLink marginRight="2" /> <Box marginLeft="auto"> <UserNavBarSection /> </Box> </Box> ); } function HomeLink(props) { const { pathname } = useLocation(); const isHomePage = pathname === "/"; return ( <Box as={Link} to="/" display="flex" alignItems="center" role="group" // HACK: When we're on the homepage, I want the title "Dress to Impress" // to stay visible for transition, but I don't want it to be a // click target. To do this, I constrain the size of the container, // and also remove pointer events from the overflowing children. maxWidth={isHomePage ? "32px" : "none"} {...props} > <Box flex="0 0 auto" display="flex" alignItems="center" marginRight="2" position="relative" transition="all 0.2s" opacity="0.8" _groupHover={{ transform: "scale(1.1)", opacity: "1" }} _groupFocus={{ transform: "scale(1.1)", opacity: "1" }} > <Box position="absolute" right="100%" opacity={isHomePage ? "0" : "1"} pointerEvents={isHomePage ? "none" : "all"} transform={isHomePage ? "translateX(3px)" : "none"} transition="all 0.2s" > <ChevronLeftIcon /> </Box> <Box as="img" src={HomeLinkIcon} srcSet={`${HomeLinkIcon} 1x, ${HomeLinkIcon2x} 2x`} alt="" height="2em" width="2em" borderRadius="lg" boxShadow="md" /> <Box height="2em" width="2em" position="absolute" top="0" left="0" right="0" bottom="0" borderRadius="lg" transition="border 0.2s" /> </Box> <Box flex="0 0 auto" fontFamily="Delicious" fontWeight="600" fontSize="2xl" display={{ base: "none", sm: "block" }} opacity={isHomePage ? "0" : "1"} transition="all 0.2s" marginRight="2" pointerEvents={isHomePage ? "none" : "all"} _groupHover={{ fontWeight: "900" }} _groupFocus={{ fontWeight: "900" }} > Dress to Impress </Box> </Box> ); } function UserNavBarSection() { const { isLoading, isAuthenticated, loginWithRedirect, logout } = useAuth0(); const { id, username } = useCurrentUser(); if (isLoading) { return null; } if (isAuthenticated) { return ( <HStack align="center" spacing="2"> {username && ( <Box fontSize="sm" textAlign="right"> Hi, {username}! </Box> )} <NavLinksList> {id && ( <NavLinkItem as={Link} to={`/user/${id}/items`}> Items </NavLinkItem> )} <NavLinkItem as={Link} to="/modeling"> Modeling </NavLinkItem> </NavLinksList> <NavButton onClick={() => logout({ returnTo: window.location.origin })}> Log out </NavButton> </HStack> ); } else { return ( <HStack align="center" spacing="2"> <NavButton as={Link} to="/modeling"> Modeling </NavButton> <NavButton onClick={() => loginWithRedirect()}>Log in</NavButton> </HStack> ); } } function NavLinksList({ children }) { const navStyle = useBreakpointValue({ base: "menu", md: "buttons" }); if (navStyle === "menu") { return ( <Menu> <MenuButton> <NavButton icon={<HamburgerIcon />} /> </MenuButton> <MenuList>{children}</MenuList> </Menu> ); } else { return children; } } function NavLinkItem(props) { const navStyle = useBreakpointValue({ base: "menu", md: "buttons" }); if (navStyle === "menu") { return <MenuItem {...props} />; } else { return <NavButton {...props} />; } } const NavButton = React.forwardRef(({ icon, ...props }, ref) => { const Component = icon ? IconButton : Button; // Opacity is in a separate Box, to avoid overriding the built-in Button // hover/focus states. return ( <Box opacity="0.8" _hover={{ opacity: "1" }} _focusWithin={{ opacity: "1" }} > <Component size="sm" variant="outline" icon={icon} ref={ref} {...props} /> </Box> ); }); export default GlobalHeader;