Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add account tabs #378

Merged
merged 5 commits into from
Jun 17, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 11 additions & 46 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -1,63 +1,28 @@
@font-face {
font-family: 'Work Sans';
font-family: 'iAWriterQuattroV';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url(assets/fonts/WorkSans/WorkSans-Light.ttf) format('truetype');
}
@font-face {
font-family: 'Work Sans';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(assets/fonts/WorkSans/WorkSans-Regular.ttf) format('truetype');
}
@font-face {
font-family: 'Work Sans';
font-style: normal;
font-weight: 500;
font-display: swap;
src: url(assets/fonts/WorkSans/WorkSans-Medium.ttf) format('truetype');
src: url(assets/fonts/iAWriterQuattroV.ttf) format('truetype');
}

@font-face {
font-family: 'Work Sans';
font-family: 'iAWriterMonoV';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(assets/fonts/WorkSans/WorkSans-SemiBold.ttf) format('truetype');
}
@font-face {
font-family: 'IBMPlexMono500';
src: url(assets/fonts/IBMPlexMono500.ttf) format('truetype');
font-weight: 500;
}
@font-face {
font-family: 'IBMPlexMono600';
src: url(assets/fonts/IBMPlexMono600.ttf) format('truetype');
font-weight: 600;
}
@font-face {
font-family: 'IBMPlexMonoregular';
src: url(assets/fonts/IBMPlexMonoregular.ttf) format('truetype');
font-weight: 300;
}
@font-face {
font-family: 'WorkSans-Italic-VariableFont_wght';
src: url(assets/fonts/WorkSans-Italic-VariableFont_wght.ttf) format('truetype');
font-weight: 700;
}
@font-face {
font-family: 'WorkSans-VariableFont_wght';
src: url(assets/fonts/WorkSans-VariableFont_wght.ttf) format('truetype');
font-weight: 400;
font-display: swap;
src: url(assets/fonts/iAWriterMonoV.ttf) format('truetype');
}

.App {
font-family: 'Work Sans', 'Helvetica Neue', HelveticaNeue, Helvetica, Arial, sans-serif;
font-family: 'iAWriterQuattroV', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

a,
button {
font-family: 'IBMPlexMono500' !important;
font-family: 'iAWriterMonoV' !important;
color: #dd7700;
}
Binary file removed src/assets/fonts/IBMPlexMono500.ttf
Binary file not shown.
Binary file removed src/assets/fonts/IBMPlexMono500.woff
Binary file not shown.
Binary file removed src/assets/fonts/IBMPlexMono600.ttf
Binary file not shown.
Binary file removed src/assets/fonts/IBMPlexMono600.woff
Binary file not shown.
Binary file removed src/assets/fonts/IBMPlexMonoRegular.woff
Binary file not shown.
Binary file removed src/assets/fonts/IBMPlexMonoregular.ttf
Binary file not shown.
Binary file removed src/assets/fonts/SourceCodePro-Medium.ttf
Binary file not shown.
Binary file removed src/assets/fonts/SourceCodePro-Regular.ttf
Binary file not shown.
Binary file removed src/assets/fonts/SourceCodePro-SemiBold.ttf
Binary file not shown.
Binary file removed src/assets/fonts/SpaceMono-Bold.ttf
Binary file not shown.
Binary file removed src/assets/fonts/SpaceMono-Regular.ttf
Binary file not shown.
Binary file not shown.
Binary file removed src/assets/fonts/WorkSans-VariableFont_wght.ttf
Binary file not shown.
Binary file removed src/assets/fonts/WorkSans/WorkSans-Light.ttf
Binary file not shown.
Binary file removed src/assets/fonts/WorkSans/WorkSans-Medium.ttf
Binary file not shown.
Binary file removed src/assets/fonts/WorkSans/WorkSans-Regular.ttf
Binary file not shown.
Binary file removed src/assets/fonts/WorkSans/WorkSans-SemiBold.ttf
Binary file not shown.
Binary file removed src/assets/fonts/WorkSans500.woff
Binary file not shown.
Binary file removed src/assets/fonts/WorkSansRegular.woff
Binary file not shown.
Binary file added src/assets/fonts/iAWriterMonoV.ttf
Binary file not shown.
Binary file added src/assets/fonts/iAWriterQuattroV.ttf
Binary file not shown.
55 changes: 24 additions & 31 deletions src/components/SideBar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { BeeModes } from '@ethersphere/bee-js'
import { Divider, Drawer, Grid, Link as MUILink, List } from '@material-ui/core'
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
import { OpenInNewSharp } from '@material-ui/icons'
import type { ReactElement } from 'react'
import { Bookmark, BookOpen, Briefcase, DollarSign, FileText, Gift, Home, Layers, Settings } from 'react-feather'
import { ReactElement, useContext } from 'react'
import { BookOpen, Briefcase, DollarSign, FileText, Home, Settings } from 'react-feather'
import { Link } from 'react-router-dom'
import Logo from '../assets/logo.svg'
import { config } from '../config'
import { Context } from '../providers/Bee'
import { ROUTES } from '../routes'
import SideBarItem from './SideBarItem'
import SideBarStatus from './SideBarStatus'
Expand All @@ -21,35 +23,22 @@ const navBarItems = [
path: ROUTES.UPLOAD,
icon: FileText,
},
{
label: 'Feeds',
path: ROUTES.FEEDS,
icon: Bookmark,
},
{
label: 'Stamps',
path: ROUTES.STAMPS,
icon: Layers,
},
{
label: 'Accounting',
path: ROUTES.ACCOUNTING,
icon: DollarSign,
},
{
label: 'Settings',
path: ROUTES.SETTINGS,
icon: Settings,
},
{
label: 'Account',
path: ROUTES.WALLET,
path: ROUTES.ACCOUNT_WALLET,
icon: Briefcase,
pathMatcherSubstring: '/account/',
},
{
label: 'Gift Wallets',
path: ROUTES.GIFT_CODES,
icon: Gift,
label: 'Top Up',
path: ROUTES.WALLET,
icon: DollarSign,
requiresMode: BeeModes.ULTRA_LIGHT,
},
]

Expand Down Expand Up @@ -103,6 +92,7 @@ const useStyles = makeStyles((theme: Theme) =>

export default function SideBar(): ReactElement {
const classes = useStyles()
const { nodeInfo } = useContext(Context)

return (
<Drawer className={classes.drawer} variant="permanent" anchor="left" classes={{ paper: classes.drawerPaper }}>
Expand All @@ -114,16 +104,19 @@ export default function SideBar(): ReactElement {
</Grid>
<Grid>
<List>
{navBarItems.map(p => (
<Link to={p.path} key={p.path} className={classes.link}>
<SideBarItem
key={p.path}
iconStart={<p.icon className={classes.icon} />}
path={p.path}
label={p.label}
/>
</Link>
))}
{navBarItems
.filter(p => !p.requiresMode || nodeInfo?.beeMode === p.requiresMode)
.map(p => (
<Link to={p.path} key={p.path} className={classes.link}>
<SideBarItem
key={p.path}
iconStart={<p.icon className={classes.icon} />}
path={p.path}
pathMatcherSubstring={p.pathMatcherSubstring}
label={p.label}
/>
</Link>
))}
</List>
<Divider className={classes.divider} />
<List>
Expand Down
14 changes: 8 additions & 6 deletions src/components/SideBarItem.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { ListItem, ListItemIcon, ListItemText } from '@material-ui/core'
import { createStyles, makeStyles, Theme, withStyles } from '@material-ui/core/styles'
import type { ReactElement, ReactNode } from 'react'
import { useLocation, matchPath } from 'react-router-dom'

import { createStyles, Theme, makeStyles, withStyles } from '@material-ui/core/styles'
import { ListItemText, ListItemIcon, ListItem } from '@material-ui/core'
import { matchPath, useLocation } from 'react-router-dom'

const StyledListItem = withStyles((theme: Theme) => ({
root: {
Expand Down Expand Up @@ -45,12 +44,15 @@ interface Props {
iconEnd?: ReactNode
path?: string
label: ReactNode
pathMatcherSubstring?: string
}

export default function SideBarItem({ iconStart, iconEnd, path, label }: Props): ReactElement {
export default function SideBarItem({ iconStart, iconEnd, path, label, pathMatcherSubstring }: Props): ReactElement {
const classes = useStyles()
const location = useLocation()
const isSelected = Boolean(path && matchPath(location.pathname, path))
const isSelected = pathMatcherSubstring
? location.pathname.startsWith(pathMatcherSubstring)
: Boolean(path && matchPath(location.pathname, path))

return (
<StyledListItem button selected={isSelected} disableRipple>
Expand Down
8 changes: 3 additions & 5 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ body {
height: 100vh;
min-height: 100vh;
margin: 0;
font-family: 'Work Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
font-family: 'iAWriterQuattroV', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
Expand All @@ -16,6 +15,5 @@ body {
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
}
56 changes: 56 additions & 0 deletions src/pages/account/AccountNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { createStyles, makeStyles, Tab, Tabs, Theme } from '@material-ui/core'
import { ReactElement } from 'react'
import { useNavigate } from 'react-router-dom'

const tabMap = {
WALLET: 0,
CHEQUEBOOK: 1,
STAMPS: 2,
FEEDS: 3,
}

const tabMapReverse = ['/account/wallet', '/account/chequebook', '/account/stamps', '/account/feeds']

interface Props {
active: 'WALLET' | 'CHEQUEBOOK' | 'STAMPS' | 'FEEDS'
}

const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
flexGrow: 1,
marginBottom: theme.spacing(4),
textTransform: 'none',
},
leftTab: {
marginRight: theme.spacing(0.125),
},
centerTab: {
marginLeft: theme.spacing(0.125),
marginRight: theme.spacing(0.125),
},
rightTab: {
marginLeft: theme.spacing(0.125),
},
}),
)

export function AccountNavigation({ active }: Props): ReactElement {
const classes = useStyles()
const navigate = useNavigate()

function onChange(event: React.ChangeEvent<Record<string, never>>, newValue: number) {
navigate(tabMapReverse[newValue])
}

return (
<div className={classes.root}>
<Tabs value={tabMap[active]} onChange={onChange} variant="fullWidth">
<Tab className={classes.leftTab} key="WALLET" label="Wallet" />
<Tab className={classes.centerTab} key="CHEQUEBOOK" label="Chequebook" />
<Tab className={classes.centerTab} key="STAMPS" label="Stamps" />
<Tab className={classes.rightTab} key="FEEDS" label="Feeds" />
</Tabs>
</div>
)
}
10 changes: 10 additions & 0 deletions src/pages/account/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Box, Typography } from '@material-ui/core'
import { ReactElement } from 'react'

export function Header(): ReactElement {
return (
<Box mb={4}>
<Typography variant="h1">Account</Typography>
</Box>
)
}
60 changes: 60 additions & 0 deletions src/pages/account/chequebook/AccountChequebook.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { ReactElement, useContext } from 'react'
import ExpandableList from '../../../components/ExpandableList'
import ExpandableListItem from '../../../components/ExpandableListItem'
import ExpandableListItemActions from '../../../components/ExpandableListItemActions'
import ExpandableListItemKey from '../../../components/ExpandableListItemKey'
import TroubleshootConnectionCard from '../../../components/TroubleshootConnectionCard'
import DepositModal from '../../../containers/DepositModal'
import WithdrawModal from '../../../containers/WithdrawModal'
import { useAccounting } from '../../../hooks/accounting'
import { CheckState, Context as BeeContext } from '../../../providers/Bee'
import { Context as SettingsContext } from '../../../providers/Settings'
import PeerBalances from '../../accounting/PeerBalances'
import { AccountNavigation } from '../AccountNavigation'
import { Header } from '../Header'

export function AccountChequebook(): ReactElement {
const { status, nodeAddresses, chequebookAddress, chequebookBalance, settlements, peerBalances } =
useContext(BeeContext)
const { beeDebugApi } = useContext(SettingsContext)

const { accounting, totalUncashed, isLoadingUncashed } = useAccounting(beeDebugApi, settlements, peerBalances)

if (status.all === CheckState.ERROR) return <TroubleshootConnectionCard />

return (
<>
<Header />
<AccountNavigation active="CHEQUEBOOK" />
<div>
<ExpandableList label="Chequebook" defaultOpen>
<ExpandableListItem label="Total Balance" value={`${chequebookBalance?.totalBalance.toFixedDecimal()} BZZ`} />
<ExpandableListItem
label="Available Uncommitted Balance"
value={`${chequebookBalance?.availableBalance.toFixedDecimal()} BZZ`}
/>
<ExpandableListItem
label="Total Cheques Amount Sent"
value={`${settlements?.totalSent.toFixedDecimal()} BZZ`}
/>
<ExpandableListItem
label="Total Cheques Amount Received"
value={`${settlements?.totalReceived.toFixedDecimal()} BZZ`}
/>
<ExpandableListItemActions>
<WithdrawModal />
<DepositModal />
</ExpandableListItemActions>
</ExpandableList>
<ExpandableList label="Blockchain" defaultOpen>
<ExpandableListItemKey label="Ethereum address" value={nodeAddresses?.ethereum || ''} />
<ExpandableListItemKey
label="Chequebook contract address"
value={chequebookAddress?.chequebookAddress || ''}
/>
</ExpandableList>
<PeerBalances accounting={accounting} isLoadingUncashed={isLoadingUncashed} totalUncashed={totalUncashed} />
</div>
</>
)
}
Loading