feat: info page redesign (#390)
* feat: info page redesign * feat: add chequebook card
This commit is contained in:
@@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
|
}
|
||||||
@@ -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
@@ -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="You’re 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
@@ -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',
|
||||||
|
|||||||
Reference in New Issue
Block a user