mirror of
https://github.com/RoboSats/robosats.git
synced 2025-02-26 07:09:01 +00:00
TopNavBar Added
This commit is contained in:
parent
6dd32780a7
commit
6729babdb5
@ -1,41 +1,44 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { MemoryRouter, BrowserRouter, Routes, Route } from 'react-router-dom';
|
||||
import { Box, Slide, Typography, styled } from '@mui/material';
|
||||
import { type UseAppStoreType, AppContext, closeAll } from '../contexts/AppContext';
|
||||
|
||||
import { RobotPage, MakerPage, BookPage, OrderPage, SettingsPage, NavBar, MainDialogs } from './';
|
||||
import RobotAvatar from '../components/RobotAvatar';
|
||||
import { Box, Slide, styled } from '@mui/material';
|
||||
import { type UseAppStoreType, AppContext } from '../contexts/AppContext';
|
||||
import {
|
||||
TopNavBar,
|
||||
NavBar,
|
||||
RobotPage,
|
||||
MakerPage,
|
||||
BookPage,
|
||||
OrderPage,
|
||||
SettingsPage,
|
||||
MainDialogs,
|
||||
} from './';
|
||||
import Notifications from '../components/Notifications';
|
||||
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { GarageContext, type UseGarageStoreType } from '../contexts/GarageContext';
|
||||
|
||||
const Router = window.NativeRobosats === undefined ? BrowserRouter : MemoryRouter;
|
||||
|
||||
const TestnetTypography = styled(Typography)({
|
||||
height: 0,
|
||||
});
|
||||
|
||||
interface MainBoxProps {
|
||||
navbarHeight: number;
|
||||
}
|
||||
|
||||
const MainBox = styled(Box)<MainBoxProps>((props) => ({
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: `translate(-50%, -50%) translate(0, -${props.navbarHeight / 2}em)`,
|
||||
const MainContent = styled(Box)(({ theme }) => ({
|
||||
marginTop: '100px',
|
||||
marginBottom: '80px',
|
||||
padding: theme.spacing(2),
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
height: 'calc(100vh - 180px)',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}));
|
||||
|
||||
const Main: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const { settings, page, slideDirection, setOpen, windowSize, navbarHeight } =
|
||||
const { settings, page, slideDirection, setOpen, windowSize } =
|
||||
useContext<UseAppStoreType>(AppContext);
|
||||
const { garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||
|
||||
return (
|
||||
<Router>
|
||||
<RobotAvatar style={{ display: 'none' }} hashId={garage.getSlot()?.hashId} />
|
||||
<TopNavBar />
|
||||
<Notifications
|
||||
page={page}
|
||||
openProfile={() => {
|
||||
@ -44,36 +47,25 @@ const Main: React.FC = () => {
|
||||
rewards={garage.getSlot()?.getRobot()?.earnedRewards}
|
||||
windowWidth={windowSize?.width}
|
||||
/>
|
||||
{settings.network === 'testnet' ? (
|
||||
<TestnetTypography color='secondary' align='center'>
|
||||
<i>{t('Using Testnet Bitcoin')}</i>
|
||||
</TestnetTypography>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
|
||||
<MainBox navbarHeight={navbarHeight}>
|
||||
<MainContent>
|
||||
<Routes>
|
||||
{['/robot/:token?', '/', ''].map((path, index) => {
|
||||
return (
|
||||
<Route
|
||||
path={path}
|
||||
element={
|
||||
<Slide
|
||||
direction={page === 'robot' ? slideDirection.in : slideDirection.out}
|
||||
in={page === 'robot'}
|
||||
appear={slideDirection.in !== undefined}
|
||||
>
|
||||
<div>
|
||||
<RobotPage />
|
||||
</div>
|
||||
</Slide>
|
||||
}
|
||||
key={index}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
||||
{['/robot/:token?', '/', ''].map((path, index) => (
|
||||
<Route
|
||||
path={path}
|
||||
element={
|
||||
<Slide
|
||||
direction={page === 'robot' ? slideDirection.in : slideDirection.out}
|
||||
in={page === 'robot'}
|
||||
appear={slideDirection.in !== undefined}
|
||||
>
|
||||
<div>
|
||||
<RobotPage />
|
||||
</div>
|
||||
</Slide>
|
||||
}
|
||||
key={index}
|
||||
/>
|
||||
))}
|
||||
<Route
|
||||
path={'/offers'}
|
||||
element={
|
||||
@ -88,7 +80,6 @@ const Main: React.FC = () => {
|
||||
</Slide>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path='/create'
|
||||
element={
|
||||
@ -103,7 +94,6 @@ const Main: React.FC = () => {
|
||||
</Slide>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path='/order/:shortAlias/:orderId'
|
||||
element={
|
||||
@ -118,7 +108,6 @@ const Main: React.FC = () => {
|
||||
</Slide>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path='/settings'
|
||||
element={
|
||||
@ -134,7 +123,7 @@ const Main: React.FC = () => {
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</MainBox>
|
||||
</MainContent>
|
||||
<NavBar />
|
||||
<MainDialogs />
|
||||
</Router>
|
||||
|
250
frontend/src/basic/TopNavBar/TopNavBar.tsx
Normal file
250
frontend/src/basic/TopNavBar/TopNavBar.tsx
Normal file
@ -0,0 +1,250 @@
|
||||
import React, { useContext, useState } from 'react';
|
||||
import {
|
||||
AppBar,
|
||||
Toolbar,
|
||||
Typography,
|
||||
IconButton,
|
||||
Box,
|
||||
useMediaQuery,
|
||||
styled,
|
||||
useTheme,
|
||||
Drawer,
|
||||
List,
|
||||
ListItem,
|
||||
ListItemText,
|
||||
Divider,
|
||||
} from '@mui/material';
|
||||
import MenuIcon from '@mui/icons-material/Menu';
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
|
||||
import { AppContext, type UseAppStoreType, closeAll } from '../../contexts/AppContext';
|
||||
import { GarageContext, type UseGarageStoreType } from '../../contexts/GarageContext';
|
||||
import RobotAvatar from '../../components/RobotAvatar';
|
||||
import { RoboSatsTextIcon } from '../../components/Icons';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const NAVBAR_HEIGHT = '64px';
|
||||
|
||||
const StyledAppBar = styled(AppBar)(({ theme, isMobile, drawerOpen }) => ({
|
||||
height: NAVBAR_HEIGHT,
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
boxShadow: isMobile ? 'none' : '8px 8px 0px 0px rgba(0,0,0,1)',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
borderBottom: isMobile ? `2px solid ${theme.palette.mode === 'dark' ? '#fff' : '#000'}` : '',
|
||||
border: !isMobile ? `2px solid ${theme.palette.mode === 'dark' ? '#fff' : '#000'}` : '',
|
||||
borderRadius: isMobile ? '0' : '1vw',
|
||||
padding: isMobile ? '0' : '1vh',
|
||||
top: isMobile ? 0 : theme.spacing(2),
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
width: isMobile ? '100%' : 'calc(100% - 64px)',
|
||||
position: 'fixed',
|
||||
zIndex: 1100,
|
||||
...(drawerOpen &&
|
||||
isMobile && {
|
||||
background: 'none',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
}),
|
||||
}));
|
||||
|
||||
const StyledToolbar = styled(Toolbar)(({ theme }) => ({
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
padding: '0 5vw',
|
||||
minHeight: NAVBAR_HEIGHT,
|
||||
}));
|
||||
|
||||
const CenterBox = styled(Box)({
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: '2vw',
|
||||
flexGrow: 1,
|
||||
});
|
||||
|
||||
const CenterButton = styled(Typography)(({ theme }) => ({
|
||||
cursor: 'pointer',
|
||||
color: theme.palette.mode === 'dark' ? '#fff' : '#000',
|
||||
'&:hover': {
|
||||
textDecoration: 'underline',
|
||||
},
|
||||
}));
|
||||
|
||||
const MobileToolbarContent = styled(Box)(({ theme }) => ({
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
width: '100%',
|
||||
marginLeft: theme.spacing(2),
|
||||
}));
|
||||
|
||||
const TopNavBar = (): JSX.Element => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const { setOpen, open } = useContext<UseAppStoreType>(AppContext);
|
||||
const { garage } = useContext<UseGarageStoreType>(GarageContext);
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||||
|
||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||
|
||||
const slot = garage.getSlot();
|
||||
|
||||
const navItems = [
|
||||
{ label: 'Robosats Info', key: 'info' },
|
||||
{ label: 'Learn Robosats', key: 'learn' },
|
||||
{ label: 'Community', key: 'community' },
|
||||
{ label: 'Exchange Summary', key: 'exchange' },
|
||||
];
|
||||
|
||||
const toggleDrawer = (open: boolean) => () => {
|
||||
setDrawerOpen(open);
|
||||
};
|
||||
|
||||
const handleLogoClick = () => {
|
||||
setOpen({ ...closeAll, client: !open.client });
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledAppBar
|
||||
position='fixed'
|
||||
elevation={drawerOpen ? 0 : 3}
|
||||
isMobile={isMobile}
|
||||
drawerOpen={drawerOpen}
|
||||
>
|
||||
<StyledToolbar>
|
||||
<svg width={0} height={0}>
|
||||
<linearGradient id='linearColors' x1={1} y1={0} x2={1} y2={1}>
|
||||
<stop offset={0} stopColor={theme.palette.primary.main} />
|
||||
<stop offset={1} stopColor={theme.palette.secondary.main} />
|
||||
</linearGradient>
|
||||
</svg>
|
||||
{isMobile ? (
|
||||
<>
|
||||
<IconButton edge='start' aria-label='menu' onClick={toggleDrawer(true)}>
|
||||
{drawerOpen ? (
|
||||
<CloseIcon style={{ color: theme.palette.mode === 'dark' ? '#fff' : '#000' }} />
|
||||
) : (
|
||||
<MenuIcon style={{ color: theme.palette.mode === 'dark' ? '#fff' : '#000' }} />
|
||||
)}
|
||||
</IconButton>
|
||||
<MobileToolbarContent>
|
||||
<IconButton
|
||||
edge='end'
|
||||
onClick={() => {
|
||||
setOpen({ ...closeAll, profile: !open.profile });
|
||||
}}
|
||||
style={{ visibility: slot?.hashId ? 'visible' : 'hidden' }}
|
||||
>
|
||||
{slot?.hashId ? (
|
||||
<RobotAvatar
|
||||
style={{ width: '2.5em', height: '2.5em' }}
|
||||
avatarClass={
|
||||
theme.palette.mode === 'dark' ? 'navBarAvatarDark' : 'navBarAvatar'
|
||||
}
|
||||
hashId={slot?.hashId}
|
||||
/>
|
||||
) : (
|
||||
<AccountCircleIcon style={{ fontSize: '1.5em' }} />
|
||||
)}
|
||||
</IconButton>
|
||||
</MobileToolbarContent>
|
||||
<Drawer
|
||||
anchor='left'
|
||||
open={drawerOpen}
|
||||
onClose={toggleDrawer(false)}
|
||||
BackdropProps={{ invisible: true }}
|
||||
PaperProps={{
|
||||
style: {
|
||||
marginTop: NAVBAR_HEIGHT,
|
||||
borderLeft: '2px solid black',
|
||||
borderRight: '2px solid black',
|
||||
borderBottom: '2px solid black',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<List>
|
||||
<ListItem
|
||||
button
|
||||
onClick={handleLogoClick}
|
||||
sx={{ borderBottom: '1px solid black' }}
|
||||
>
|
||||
<RoboSatsTextIcon
|
||||
sx={{
|
||||
height: '2em',
|
||||
width: 'auto',
|
||||
cursor: 'pointer',
|
||||
fill: 'url(#linearColors)',
|
||||
}}
|
||||
/>
|
||||
</ListItem>
|
||||
<Divider />
|
||||
{navItems.map((item) => (
|
||||
<ListItem
|
||||
button
|
||||
key={item.key}
|
||||
onClick={() => setOpen({ ...closeAll, [item.key]: !open[item.key] })}
|
||||
sx={{
|
||||
borderBottom: `1px solid ${theme.palette.divider}`,
|
||||
padding: theme.spacing(2),
|
||||
}}
|
||||
>
|
||||
<ListItemText primary={t(item.label)} />
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Drawer>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<RoboSatsTextIcon
|
||||
sx={{
|
||||
height: '1.5em',
|
||||
width: 'auto',
|
||||
cursor: 'pointer',
|
||||
marginLeft: -2,
|
||||
fill: 'url(#linearColors)',
|
||||
}}
|
||||
onClick={handleLogoClick}
|
||||
/>
|
||||
<CenterBox>
|
||||
{navItems.map((item) => (
|
||||
<CenterButton
|
||||
key={item.key}
|
||||
onClick={() => setOpen({ ...closeAll, [item.key]: !open[item.key] })}
|
||||
>
|
||||
{t(item.label)}
|
||||
</CenterButton>
|
||||
))}
|
||||
</CenterBox>
|
||||
<IconButton
|
||||
edge='end'
|
||||
onClick={() => {
|
||||
setOpen({ ...closeAll, profile: !open.profile });
|
||||
}}
|
||||
style={{ visibility: slot?.hashId ? 'visible' : 'hidden' }}
|
||||
>
|
||||
{slot?.hashId ? (
|
||||
<RobotAvatar
|
||||
style={{ width: '2.5em', height: '2.5em' }}
|
||||
avatarClass={
|
||||
theme.palette.mode === 'dark' ? 'navBarAvatarDark' : 'navBarAvatar'
|
||||
}
|
||||
hashId={slot?.hashId}
|
||||
/>
|
||||
) : (
|
||||
<AccountCircleIcon style={{ fontSize: '1.5em' }} />
|
||||
)}
|
||||
</IconButton>
|
||||
</>
|
||||
)}
|
||||
</StyledToolbar>
|
||||
</StyledAppBar>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default TopNavBar;
|
3
frontend/src/basic/TopNavBar/index.tsx
Normal file
3
frontend/src/basic/TopNavBar/index.tsx
Normal file
@ -0,0 +1,3 @@
|
||||
import TopNavBar from './TopNavBar';
|
||||
|
||||
export default TopNavBar;
|
@ -5,3 +5,4 @@ export { default as NavBar } from './NavBar';
|
||||
export { default as OrderPage } from './OrderPage';
|
||||
export { default as RobotPage } from './RobotPage';
|
||||
export { default as SettingsPage } from './SettingsPage';
|
||||
export { default as TopNavBar } from './TopNavBar';
|
||||
|
Loading…
Reference in New Issue
Block a user