2024-04-08 12:45:51 +00:00
|
|
|
import { Menu as MenuIcon } from '@mui/icons-material'
|
2024-02-28 16:49:44 +00:00
|
|
|
import {
|
|
|
|
AppBar as AppBarMui,
|
|
|
|
Box,
|
|
|
|
Button,
|
2024-04-08 12:45:51 +00:00
|
|
|
IconButton,
|
2024-02-28 16:49:44 +00:00
|
|
|
Menu,
|
|
|
|
MenuItem,
|
2024-04-08 12:45:51 +00:00
|
|
|
Tab,
|
|
|
|
Tabs,
|
2024-02-28 16:49:44 +00:00
|
|
|
Toolbar,
|
|
|
|
Typography
|
|
|
|
} from '@mui/material'
|
2024-04-08 12:45:51 +00:00
|
|
|
|
2024-02-28 16:49:44 +00:00
|
|
|
import { useEffect, useState } from 'react'
|
|
|
|
import { useDispatch, useSelector } from 'react-redux'
|
|
|
|
import { setAuthState } from '../../store/actions'
|
|
|
|
import { State } from '../../store/rootReducer'
|
|
|
|
import { Dispatch } from '../../store/store'
|
|
|
|
import Username from '../username'
|
|
|
|
|
2024-04-08 12:45:51 +00:00
|
|
|
import { Link, useLocation, useNavigate } from 'react-router-dom'
|
2024-02-28 16:49:44 +00:00
|
|
|
import nostrichAvatar from '../../assets/images/avatar.png'
|
2024-03-25 05:30:01 +00:00
|
|
|
import { NostrController } from '../../controllers'
|
2024-04-08 12:45:51 +00:00
|
|
|
import {
|
|
|
|
appPrivateRoutes,
|
|
|
|
appPublicRoutes,
|
|
|
|
getProfileRoute
|
|
|
|
} from '../../routes'
|
2024-03-19 10:27:18 +00:00
|
|
|
import {
|
|
|
|
clearAuthToken,
|
|
|
|
saveNsecBunkerDelegatedKey,
|
|
|
|
shorten
|
|
|
|
} from '../../utils'
|
2024-02-28 16:49:44 +00:00
|
|
|
import styles from './style.module.scss'
|
|
|
|
|
2024-04-08 12:45:51 +00:00
|
|
|
const validTabs = [appPrivateRoutes.homePage, appPrivateRoutes.decryptZip]
|
|
|
|
|
2024-02-28 16:49:44 +00:00
|
|
|
export const AppBar = () => {
|
|
|
|
const navigate = useNavigate()
|
2024-04-08 12:45:51 +00:00
|
|
|
const { pathname } = useLocation()
|
|
|
|
const [tabValue, setTabValue] = useState(
|
|
|
|
validTabs.includes(pathname) ? pathname : '/'
|
|
|
|
)
|
2024-02-28 16:49:44 +00:00
|
|
|
const dispatch: Dispatch = useDispatch()
|
|
|
|
|
|
|
|
const [username, setUsername] = useState('')
|
|
|
|
const [userAvatar, setUserAvatar] = useState(nostrichAvatar)
|
|
|
|
const [anchorElUser, setAnchorElUser] = useState<null | HTMLElement>(null)
|
2024-04-08 12:45:51 +00:00
|
|
|
const [anchorElNav, setAnchorElNav] = useState<null | HTMLElement>(null)
|
2024-02-28 16:49:44 +00:00
|
|
|
|
|
|
|
const authState = useSelector((state: State) => state.auth)
|
|
|
|
const metadataState = useSelector((state: State) => state.metadata)
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (metadataState && metadataState.content) {
|
|
|
|
const { picture, display_name, name } = JSON.parse(metadataState.content)
|
|
|
|
|
|
|
|
if (picture) setUserAvatar(picture)
|
|
|
|
|
|
|
|
setUsername(shorten(display_name || name || '', 7))
|
|
|
|
}
|
|
|
|
}, [metadataState])
|
|
|
|
|
|
|
|
const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement>) => {
|
|
|
|
setAnchorElUser(event.currentTarget)
|
|
|
|
}
|
|
|
|
|
2024-04-08 12:45:51 +00:00
|
|
|
const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => {
|
|
|
|
setAnchorElNav(event.currentTarget)
|
|
|
|
}
|
|
|
|
|
2024-02-28 16:49:44 +00:00
|
|
|
const handleCloseUserMenu = () => {
|
|
|
|
setAnchorElUser(null)
|
|
|
|
}
|
|
|
|
|
2024-04-08 12:45:51 +00:00
|
|
|
const handleCloseNavMenu = () => {
|
|
|
|
setAnchorElNav(null)
|
|
|
|
}
|
|
|
|
|
2024-03-01 10:16:35 +00:00
|
|
|
const handleProfile = () => {
|
|
|
|
const hexKey = authState?.usersPubkey
|
|
|
|
if (hexKey) navigate(getProfileRoute(hexKey))
|
|
|
|
|
|
|
|
setAnchorElUser(null)
|
|
|
|
}
|
|
|
|
|
2024-02-28 16:49:44 +00:00
|
|
|
const handleLogout = () => {
|
2024-04-08 12:45:51 +00:00
|
|
|
handleCloseUserMenu()
|
2024-02-28 16:49:44 +00:00
|
|
|
dispatch(
|
|
|
|
setAuthState({
|
|
|
|
loggedIn: false,
|
2024-03-01 10:16:35 +00:00
|
|
|
usersPubkey: undefined,
|
2024-03-22 07:29:23 +00:00
|
|
|
loginMethod: undefined,
|
2024-03-25 05:30:01 +00:00
|
|
|
nsecBunkerPubkey: undefined
|
2024-02-28 16:49:44 +00:00
|
|
|
})
|
|
|
|
)
|
|
|
|
|
2024-03-19 10:27:18 +00:00
|
|
|
// clear authToken saved in local storage
|
|
|
|
clearAuthToken()
|
|
|
|
|
2024-03-19 07:29:24 +00:00
|
|
|
// update nsecBunker delegated key after logout
|
|
|
|
const nostrController = NostrController.getInstance()
|
|
|
|
const newDelegatedKey = nostrController.generateDelegatedKey()
|
|
|
|
saveNsecBunkerDelegatedKey(newDelegatedKey)
|
|
|
|
|
2024-02-28 16:49:44 +00:00
|
|
|
navigate('/')
|
|
|
|
}
|
|
|
|
const isAuthenticated = authState?.loggedIn === true
|
|
|
|
|
|
|
|
return (
|
|
|
|
<AppBarMui position='fixed' className={styles.AppBar}>
|
2024-02-29 07:05:05 +00:00
|
|
|
<Toolbar className={styles.toolbar}>
|
2024-04-08 12:45:51 +00:00
|
|
|
<Box sx={{ display: { xs: 'none', md: 'flex' } }}>
|
|
|
|
<Box className={styles.logoWrapper}>
|
2024-05-09 08:43:54 +00:00
|
|
|
<img src="/logo.png" alt='Logo' onClick={() => navigate('/')} />
|
2024-04-08 12:45:51 +00:00
|
|
|
</Box>
|
|
|
|
|
|
|
|
{isAuthenticated && (
|
|
|
|
<Tabs
|
|
|
|
indicatorColor='secondary'
|
|
|
|
value={tabValue}
|
|
|
|
onChange={(_, value) => setTabValue(value)}
|
|
|
|
>
|
|
|
|
<Tab
|
|
|
|
label='Home'
|
|
|
|
value={appPrivateRoutes.homePage}
|
|
|
|
to={appPrivateRoutes.homePage}
|
|
|
|
component={Link}
|
|
|
|
/>
|
|
|
|
<Tab
|
|
|
|
label='Decrypt Zip'
|
|
|
|
value={appPrivateRoutes.decryptZip}
|
|
|
|
to={appPrivateRoutes.decryptZip}
|
|
|
|
component={Link}
|
|
|
|
/>
|
2024-04-18 11:12:11 +00:00
|
|
|
<Tab
|
|
|
|
label='Sign Document'
|
|
|
|
value={appPrivateRoutes.sign}
|
|
|
|
to={appPrivateRoutes.sign}
|
|
|
|
component={Link}
|
|
|
|
/>
|
2024-04-08 12:45:51 +00:00
|
|
|
</Tabs>
|
|
|
|
)}
|
|
|
|
</Box>
|
|
|
|
|
|
|
|
<Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}>
|
|
|
|
{!isAuthenticated && (
|
|
|
|
<Box className={styles.logoWrapper}>
|
|
|
|
<img
|
2024-05-09 08:43:54 +00:00
|
|
|
src="/logo.png"
|
2024-04-08 12:45:51 +00:00
|
|
|
alt='Logo'
|
|
|
|
onClick={() => navigate('/')}
|
|
|
|
/>
|
|
|
|
</Box>
|
|
|
|
)}
|
|
|
|
|
|
|
|
{isAuthenticated && (
|
|
|
|
<>
|
|
|
|
<IconButton
|
|
|
|
size='large'
|
|
|
|
onClick={handleOpenNavMenu}
|
|
|
|
color='primary'
|
|
|
|
>
|
|
|
|
<MenuIcon />
|
|
|
|
</IconButton>
|
|
|
|
|
|
|
|
<Menu
|
|
|
|
id='menu-appbar'
|
|
|
|
anchorEl={anchorElNav}
|
|
|
|
anchorOrigin={{
|
|
|
|
vertical: 'bottom',
|
|
|
|
horizontal: 'left'
|
|
|
|
}}
|
|
|
|
keepMounted
|
|
|
|
transformOrigin={{
|
|
|
|
vertical: 'top',
|
|
|
|
horizontal: 'left'
|
|
|
|
}}
|
|
|
|
open={!!anchorElNav}
|
|
|
|
onClose={handleCloseNavMenu}
|
|
|
|
sx={{
|
|
|
|
display: { xs: 'block', md: 'none' }
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
<MenuItem sx={{ justifyContent: 'center' }}>
|
|
|
|
<Button
|
|
|
|
component={Link}
|
|
|
|
to={appPrivateRoutes.homePage}
|
|
|
|
onClick={handleCloseNavMenu}
|
|
|
|
variant='contained'
|
|
|
|
color='primary'
|
|
|
|
>
|
|
|
|
Home
|
|
|
|
</Button>
|
|
|
|
</MenuItem>
|
|
|
|
|
|
|
|
<MenuItem sx={{ justifyContent: 'center' }}>
|
|
|
|
<Button
|
|
|
|
component={Link}
|
|
|
|
to={appPrivateRoutes.decryptZip}
|
|
|
|
onClick={handleCloseNavMenu}
|
|
|
|
variant='contained'
|
|
|
|
color='primary'
|
|
|
|
>
|
|
|
|
Decrypt Zip
|
|
|
|
</Button>
|
|
|
|
</MenuItem>
|
2024-04-18 11:12:11 +00:00
|
|
|
|
|
|
|
<MenuItem sx={{ justifyContent: 'center' }}>
|
|
|
|
<Button
|
|
|
|
component={Link}
|
|
|
|
to={appPrivateRoutes.sign}
|
|
|
|
onClick={handleCloseNavMenu}
|
|
|
|
variant='contained'
|
|
|
|
color='primary'
|
|
|
|
>
|
|
|
|
Sign Document
|
|
|
|
</Button>
|
|
|
|
</MenuItem>
|
2024-04-08 12:45:51 +00:00
|
|
|
</Menu>
|
|
|
|
</>
|
|
|
|
)}
|
2024-02-28 16:49:44 +00:00
|
|
|
</Box>
|
|
|
|
|
2024-02-29 07:05:05 +00:00
|
|
|
<Box className={styles.rightSideBox}>
|
|
|
|
{!isAuthenticated && (
|
|
|
|
<Button
|
|
|
|
onClick={() => {
|
|
|
|
navigate(appPublicRoutes.login)
|
2024-02-28 16:49:44 +00:00
|
|
|
}}
|
2024-02-29 07:05:05 +00:00
|
|
|
variant='contained'
|
2024-02-28 16:49:44 +00:00
|
|
|
>
|
2024-02-29 07:05:05 +00:00
|
|
|
Sign in
|
|
|
|
</Button>
|
|
|
|
)}
|
|
|
|
|
|
|
|
{isAuthenticated && (
|
|
|
|
<>
|
|
|
|
<Username
|
|
|
|
username={username}
|
|
|
|
avatarContent={userAvatar}
|
|
|
|
handleClick={handleOpenUserMenu}
|
|
|
|
/>
|
|
|
|
<Menu
|
|
|
|
id='menu-appbar'
|
|
|
|
anchorEl={anchorElUser}
|
|
|
|
anchorOrigin={{
|
|
|
|
vertical: 'bottom',
|
|
|
|
horizontal: 'center'
|
2024-02-28 16:49:44 +00:00
|
|
|
}}
|
2024-02-29 07:05:05 +00:00
|
|
|
keepMounted
|
|
|
|
transformOrigin={{
|
|
|
|
vertical: 'top',
|
|
|
|
horizontal: 'center'
|
|
|
|
}}
|
|
|
|
open={!!anchorElUser}
|
|
|
|
onClose={handleCloseUserMenu}
|
2024-02-28 16:49:44 +00:00
|
|
|
>
|
|
|
|
<MenuItem
|
2024-02-29 07:05:05 +00:00
|
|
|
sx={{
|
|
|
|
justifyContent: 'center',
|
2024-03-05 09:08:18 +00:00
|
|
|
display: { md: 'none' }
|
2024-02-29 07:05:05 +00:00
|
|
|
}}
|
|
|
|
>
|
2024-03-05 09:08:18 +00:00
|
|
|
<Typography variant='h6'>{username}</Typography>
|
|
|
|
</MenuItem>
|
|
|
|
<MenuItem
|
|
|
|
onClick={handleProfile}
|
|
|
|
sx={{
|
|
|
|
justifyContent: 'center'
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
Profile
|
2024-02-29 07:05:05 +00:00
|
|
|
</MenuItem>
|
|
|
|
<Link
|
|
|
|
to={appPublicRoutes.help}
|
|
|
|
target='_blank'
|
|
|
|
style={{ color: 'inherit', textDecoration: 'inherit' }}
|
|
|
|
>
|
|
|
|
<MenuItem
|
|
|
|
sx={{
|
2024-03-05 09:08:18 +00:00
|
|
|
justifyContent: 'center'
|
2024-02-29 07:05:05 +00:00
|
|
|
}}
|
|
|
|
>
|
|
|
|
Help
|
|
|
|
</MenuItem>
|
|
|
|
</Link>
|
|
|
|
<MenuItem
|
|
|
|
onClick={handleLogout}
|
2024-02-28 16:49:44 +00:00
|
|
|
sx={{
|
2024-03-05 09:08:18 +00:00
|
|
|
justifyContent: 'center'
|
2024-02-28 16:49:44 +00:00
|
|
|
}}
|
|
|
|
>
|
2024-02-29 07:05:05 +00:00
|
|
|
Logout
|
2024-02-28 16:49:44 +00:00
|
|
|
</MenuItem>
|
2024-02-29 07:05:05 +00:00
|
|
|
</Menu>
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
</Box>
|
2024-02-28 16:49:44 +00:00
|
|
|
</Toolbar>
|
|
|
|
</AppBarMui>
|
|
|
|
)
|
|
|
|
}
|