sigit.io/src/components/AppBar/AppBar.tsx
SwiftHawk bd1e8417c1
All checks were successful
Release / build_and_release (push) Successful in 1m2s
feat: create signing request and send a DM to first signer with zip file url and encryption key
2024-04-08 17:45:51 +05:00

288 lines
8.1 KiB
TypeScript

import { Menu as MenuIcon } from '@mui/icons-material'
import {
AppBar as AppBarMui,
Box,
Button,
IconButton,
Menu,
MenuItem,
Tab,
Tabs,
Toolbar,
Typography
} from '@mui/material'
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'
import { Link, useLocation, useNavigate } from 'react-router-dom'
import nostrichAvatar from '../../assets/images/avatar.png'
import nostrichLogo from '../../assets/images/nostr-logo.jpg'
import { NostrController } from '../../controllers'
import {
appPrivateRoutes,
appPublicRoutes,
getProfileRoute
} from '../../routes'
import {
clearAuthToken,
saveNsecBunkerDelegatedKey,
shorten
} from '../../utils'
import styles from './style.module.scss'
const validTabs = [appPrivateRoutes.homePage, appPrivateRoutes.decryptZip]
export const AppBar = () => {
const navigate = useNavigate()
const { pathname } = useLocation()
const [tabValue, setTabValue] = useState(
validTabs.includes(pathname) ? pathname : '/'
)
const dispatch: Dispatch = useDispatch()
const [username, setUsername] = useState('')
const [userAvatar, setUserAvatar] = useState(nostrichAvatar)
const [anchorElUser, setAnchorElUser] = useState<null | HTMLElement>(null)
const [anchorElNav, setAnchorElNav] = useState<null | HTMLElement>(null)
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)
}
const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorElNav(event.currentTarget)
}
const handleCloseUserMenu = () => {
setAnchorElUser(null)
}
const handleCloseNavMenu = () => {
setAnchorElNav(null)
}
const handleProfile = () => {
const hexKey = authState?.usersPubkey
if (hexKey) navigate(getProfileRoute(hexKey))
setAnchorElUser(null)
}
const handleLogout = () => {
handleCloseUserMenu()
dispatch(
setAuthState({
loggedIn: false,
usersPubkey: undefined,
loginMethod: undefined,
nsecBunkerPubkey: undefined
})
)
// clear authToken saved in local storage
clearAuthToken()
// update nsecBunker delegated key after logout
const nostrController = NostrController.getInstance()
const newDelegatedKey = nostrController.generateDelegatedKey()
saveNsecBunkerDelegatedKey(newDelegatedKey)
navigate('/')
}
const isAuthenticated = authState?.loggedIn === true
return (
<AppBarMui position='fixed' className={styles.AppBar}>
<Toolbar className={styles.toolbar}>
<Box sx={{ display: { xs: 'none', md: 'flex' } }}>
<Box className={styles.logoWrapper}>
<img src={nostrichLogo} alt='Logo' onClick={() => navigate('/')} />
</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}
/>
</Tabs>
)}
</Box>
<Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}>
{!isAuthenticated && (
<Box className={styles.logoWrapper}>
<img
src={nostrichLogo}
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>
</Menu>
</>
)}
</Box>
<Box className={styles.rightSideBox}>
{!isAuthenticated && (
<Button
onClick={() => {
navigate(appPublicRoutes.login)
}}
variant='contained'
>
Sign in
</Button>
)}
{isAuthenticated && (
<>
<Username
username={username}
avatarContent={userAvatar}
handleClick={handleOpenUserMenu}
/>
<Menu
id='menu-appbar'
anchorEl={anchorElUser}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center'
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'center'
}}
open={!!anchorElUser}
onClose={handleCloseUserMenu}
>
<MenuItem
sx={{
justifyContent: 'center',
display: { md: 'none' }
}}
>
<Typography variant='h6'>{username}</Typography>
</MenuItem>
<MenuItem
onClick={handleProfile}
sx={{
justifyContent: 'center'
}}
>
Profile
</MenuItem>
<Link
to={appPublicRoutes.help}
target='_blank'
style={{ color: 'inherit', textDecoration: 'inherit' }}
>
<MenuItem
sx={{
justifyContent: 'center'
}}
>
Help
</MenuItem>
</Link>
<MenuItem
onClick={handleLogout}
sx={{
justifyContent: 'center'
}}
>
Logout
</MenuItem>
</Menu>
</>
)}
</Box>
</Toolbar>
</AppBarMui>
)
}