feat: info page redesign (#390)

* feat: info page redesign

* feat: add chequebook card
This commit is contained in:
Vojtech Simetka
2022-06-18 17:09:13 +02:00
committed by GitHub
parent 41432bc346
commit caea5ae309
5 changed files with 214 additions and 50 deletions
+77
View File
@@ -0,0 +1,77 @@
import { createStyles, makeStyles, Theme, Typography } from '@material-ui/core'
import { ReactElement } from 'react'
import { AlertCircle, Check } from 'react-feather'
import { SwarmButton, SwarmButtonProps } from './SwarmButton'
interface Props {
icon: ReactElement
title: string
subtitle: string
buttonProps: SwarmButtonProps
status: 'ok' | 'error'
}
const useStyles = (backgroundColor: string) =>
makeStyles((theme: Theme) =>
createStyles({
root: {
flexGrow: 1,
flexBasis: '100px',
},
wrapper: {
backgroundColor,
padding: '16px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
textAlign: 'center',
},
iconWrapper: {
display: 'flex',
alignItems: 'flex-start',
marginBottom: '18px',
},
button: {
width: '100%',
marginTop: '2px',
backgroundColor,
'&:hover': {
backgroundColor: theme.palette.primary.main,
color: 'white',
boxShadow: 'none',
// https://github.com/mui-org/material-ui/issues/22543
'@media (hover: none)': {
backgroundColor: theme.palette.primary.main,
color: 'white',
boxShadow: 'none',
},
},
},
}),
)
export default function Card({ buttonProps, icon, title, subtitle, status }: Props): ReactElement {
const backgroundColor = status === 'error' ? 'white' : '#f3f3f3'
const { className, ...rest } = buttonProps
const classes = useStyles(backgroundColor)()
return (
<div className={classes.root}>
<div className={classes.wrapper}>
<div className={classes.iconWrapper}>
{icon}
{status === 'ok' ? (
<Check size="13" stroke="#09ca6c" />
) : (
<AlertCircle size="13" fill="#f44336" stroke="white" />
)}
</div>
<Typography variant="h2" style={{ marginBottom: '8px' }}>
{title}
</Typography>
<Typography variant="caption">{subtitle}</Typography>
</div>
<SwarmButton className={[classes.button, className].join(' ')} {...rest} />
</div>
)
}
+9
View File
@@ -0,0 +1,9 @@
import { ReactElement, CSSProperties } from 'react'
interface Props {
style?: CSSProperties
}
export default function Card({ style }: Props): ReactElement {
return <div style={Object.assign({}, style, { width: '100%', height: '380px', backgroundColor: '#f3f3f3' })}></div>
}
+11 -9
View File
@@ -1,13 +1,9 @@
import { Button, CircularProgress, createStyles, makeStyles } from '@material-ui/core' import { Button, ButtonProps, CircularProgress, createStyles, makeStyles } from '@material-ui/core'
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import { IconProps } from 'react-feather' import { IconProps } from 'react-feather'
interface Props { export interface SwarmButtonProps extends ButtonProps {
onClick: () => void
iconType: React.ComponentType<IconProps> iconType: React.ComponentType<IconProps>
children: string
className?: string
disabled?: boolean
loading?: boolean loading?: boolean
cancel?: boolean cancel?: boolean
variant?: 'text' | 'contained' | 'outlined' variant?: 'text' | 'contained' | 'outlined'
@@ -51,7 +47,9 @@ export function SwarmButton({
loading, loading,
cancel, cancel,
variant = 'contained', variant = 'contained',
}: Props): ReactElement { style,
...other
}: SwarmButtonProps): ReactElement {
const classes = useStyles() const classes = useStyles()
function getIconColor() { function getIconColor() {
@@ -73,14 +71,18 @@ export function SwarmButton({
return ( return (
<Button <Button
style={style}
className={getButtonClassName()} className={getButtonClassName()}
onClick={(event: React.MouseEvent<HTMLButtonElement>) => { onClick={(event: React.MouseEvent<HTMLButtonElement>) => {
onClick() if (onClick) {
event.currentTarget.blur() onClick(event)
event.currentTarget.blur()
}
}} }}
variant={variant} variant={variant}
startIcon={icon} startIcon={icon}
disabled={disabled} disabled={disabled}
{...other}
> >
{children} {children}
{loading && ( {loading && (
+116 -40
View File
@@ -1,12 +1,13 @@
import { ReactElement, useContext } from 'react' import { ReactElement, useContext } from 'react'
import { Button } from '@material-ui/core' import { Button } from '@material-ui/core'
import { Globe, Briefcase, Search, Settings, ArrowUp, RefreshCcw } from 'react-feather'
import TroubleshootConnectionCard from '../../components/TroubleshootConnectionCard' import { Context as BeeContext } from '../../providers/Bee'
import { CheckState, Context as BeeContext } from '../../providers/Bee' import Card from '../../components/Card'
import ExpandableList from '../../components/ExpandableList' import Map from '../../components/Map'
import ExpandableListItem from '../../components/ExpandableListItem' import ExpandableListItem from '../../components/ExpandableListItem'
import ExpandableListItemKey from '../../components/ExpandableListItemKey' import { useNavigate } from 'react-router'
import TopologyStats from '../../components/TopologyStats' import { ROUTES } from '../../routes'
export default function Status(): ReactElement { export default function Status(): ReactElement {
const { const {
@@ -15,48 +16,123 @@ export default function Status(): ReactElement {
isLatestBeeVersion, isLatestBeeVersion,
latestBeeVersionUrl, latestBeeVersionUrl,
topology, topology,
nodeAddresses,
chequebookAddress,
nodeInfo, nodeInfo,
balance,
chequebookBalance,
} = useContext(BeeContext) } = useContext(BeeContext)
const navigate = useNavigate()
if (status.all === CheckState.ERROR) return <TroubleshootConnectionCard />
return ( return (
<div> <div>
<ExpandableList label="Bee Node" defaultOpen> <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'stretch', alignContent: 'stretch' }}>
<ExpandableListItem label="Mode" value={nodeInfo?.beeMode} /> {status.all ? (
<ExpandableListItem <Card
label="Agent" buttonProps={{ iconType: Search, children: 'Access Content', onClick: () => navigate(ROUTES.DOWNLOAD) }}
value={ icon={<Globe />}
<div> title="Your node is connected."
<a href="https://github.com/ethersphere/bee" rel="noreferrer" target="_blank"> subtitle="You can now access content hosted on Swarm."
Bee status="ok"
</a> />
{` ${latestUserVersion || '-'} `} ) : (
<Button size="small" variant="outlined" href={latestBeeVersionUrl} target="_blank"> <Card
buttonProps={{ iconType: Settings, children: 'Open node setup', onClick: () => navigate(ROUTES.STATUS) }}
icon={<Globe />}
title="Your node is not connected…"
subtitle="Youre not connected to Swarm."
status="error"
/>
)}
<div style={{ width: '8px' }}></div>
{nodeInfo?.beeMode && ['light', 'full', 'dev'].includes(nodeInfo.beeMode) ? (
<Card
buttonProps={{
iconType: Briefcase,
children: 'Manage your wallet',
onClick: () => navigate(ROUTES.ACCOUNT_WALLET),
}}
icon={<Briefcase />}
title={`${balance?.bzz.toSignificantDigits(4)} xBZZ | ${balance?.dai.toSignificantDigits(4)} xDAI`}
subtitle="Current wallet balance."
status="ok"
/>
) : (
<Card
buttonProps={{
iconType: Settings,
children: 'Setup wallet',
onClick: () => navigate(ROUTES.WALLET),
}}
icon={<ArrowUp />}
title="Your wallet is not setup."
subtitle="To share content on Swarm, please setup your wallet."
status="error"
/>
)}
{nodeInfo?.beeMode && ['light', 'full', 'dev'].includes(nodeInfo.beeMode) && (
<>
<div style={{ width: '8px' }} />
{chequebookBalance?.availableBalance !== undefined &&
chequebookBalance?.availableBalance.toBigNumber.isGreaterThan(0) ? (
<Card
buttonProps={{
iconType: RefreshCcw,
children: 'View chequebook',
onClick: () => navigate(ROUTES.ACCOUNT_CHEQUEBOOK),
}}
icon={<RefreshCcw />}
title={`${chequebookBalance?.availableBalance.toSignificantDigits(4)} xBZZ`}
subtitle="Your chequebook is setup and has balance"
status="ok"
/>
) : (
<Card
buttonProps={{
iconType: RefreshCcw,
children: 'View chequebook',
onClick: () => navigate(ROUTES.ACCOUNT_CHEQUEBOOK),
}}
icon={<RefreshCcw />}
title={
chequebookBalance?.availableBalance
? `${chequebookBalance.availableBalance.toFixedDecimal(4)} xBZZ`
: 'No available balance'
}
subtitle="Your chequebook is not setup or has no balance."
status="error"
/>
)}
</>
)}
</div>
<div style={{ height: '16px' }} />
<Map />
<div style={{ height: '2px' }} />
<ExpandableListItem label="Connected peers" value={topology?.connected ?? '-'} />
<ExpandableListItem label="Depth" value={topology?.depth ?? '-'} />
<div style={{ height: '16px' }} />
<ExpandableListItem
label="Bee version"
value={
<div>
<a href="https://github.com/ethersphere/bee" rel="noreferrer" target="_blank">
Bee
</a>
{` ${latestUserVersion ?? '-'} `}
{latestUserVersion && (
<Button
size="small"
variant="outlined"
href={latestBeeVersionUrl}
target="_blank"
style={{ height: '26px' }}
>
{isLatestBeeVersion ? 'latest' : 'update'} {isLatestBeeVersion ? 'latest' : 'update'}
</Button> </Button>
</div> )}
} </div>
/> }
<ExpandableListItemKey label="Public key" value={nodeAddresses?.publicKey || ''} /> />
<ExpandableListItemKey label="PSS public key" value={nodeAddresses?.pssPublicKey || ''} /> <ExpandableListItem label="Mode" value={nodeInfo?.beeMode} />
<ExpandableListItemKey label="Overlay address (Peer ID)" value={nodeAddresses?.overlay || ''} />
<ExpandableList level={1} label="Underlay addresses">
{nodeAddresses?.underlay.map(addr => (
<ExpandableListItem key={addr} value={addr} />
))}
</ExpandableList>
</ExpandableList>
<ExpandableList label="Blockchain" defaultOpen>
<ExpandableListItemKey label="Ethereum address" value={nodeAddresses?.ethereum || ''} />
<ExpandableListItemKey label="Chequebook contract address" value={chequebookAddress?.chequebookAddress || ''} />
</ExpandableList>
<ExpandableList label="Connectivity" defaultOpen>
<TopologyStats topology={topology} />
</ExpandableList>
</div> </div>
) )
} }
+1 -1
View File
@@ -174,7 +174,7 @@ export const theme = createTheme({
palette: { palette: {
type: 'light', type: 'light',
background: { background: {
default: '#efefef', default: '#ededed',
}, },
primary: { primary: {
light: '#fcf2e8', light: '#fcf2e8',