feat: troubleshooting component (#204)
* feat: troubleshooting component and general layout improvements * style: background color, links and button * chore: disable ripples and rounded corners on buttons * fix: spacing on the troubleshooting card
This commit is contained in:
@@ -44,6 +44,8 @@ const navBarItems = [
|
||||
},
|
||||
]
|
||||
|
||||
const drawerWidth = 300
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
@@ -52,6 +54,14 @@ const useStyles = makeStyles((theme: Theme) =>
|
||||
paddingTop: theme.spacing(8),
|
||||
paddingBottom: theme.spacing(8),
|
||||
},
|
||||
drawer: {
|
||||
width: drawerWidth,
|
||||
flexShrink: 0,
|
||||
},
|
||||
drawerPaper: {
|
||||
width: drawerWidth,
|
||||
backgroundColor: '#212121',
|
||||
},
|
||||
logo: {
|
||||
marginLeft: theme.spacing(8),
|
||||
marginRight: theme.spacing(8),
|
||||
@@ -86,7 +96,7 @@ export default function SideBar(): ReactElement {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<Drawer variant="permanent">
|
||||
<Drawer className={classes.drawer} variant="permanent" anchor="left" classes={{ paper: classes.drawerPaper }}>
|
||||
<Grid container direction="column" justifyContent="space-between" className={classes.root}>
|
||||
<Grid className={classes.logo}>
|
||||
<Link to={ROUTES.INFO}>
|
||||
|
||||
@@ -40,25 +40,23 @@ const Indicator = ({ thresholds }: Props): ReactElement => {
|
||||
}
|
||||
|
||||
const Metrics = ({ topology, thresholds }: Props): ReactElement => (
|
||||
<Grid style={{ marginBottom: '20px', flexGrow: 1 }}>
|
||||
<Grid container spacing={3}>
|
||||
<Grid key={1} item xs={12} sm={12} md={6} lg={4} xl={4}>
|
||||
<StatCard
|
||||
label="Connected Peers"
|
||||
statistic={topology?.connected.toString()}
|
||||
tooltip={thresholds.connectedPeers.explanation}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid key={2} item xs={12} sm={12} md={6} lg={4} xl={4}>
|
||||
<StatCard
|
||||
label="Population"
|
||||
statistic={topology?.population.toString()}
|
||||
tooltip={thresholds.population.explanation}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid key={3} item xs={12} sm={12} md={6} lg={4} xl={4}>
|
||||
<StatCard label="Depth" statistic={topology?.depth.toString()} tooltip={thresholds.depth.explanation} />
|
||||
</Grid>
|
||||
<Grid container spacing={3} style={{ marginBottom: '20px' }}>
|
||||
<Grid key={1} item xs={12} sm={12} md={6} lg={4} xl={4}>
|
||||
<StatCard
|
||||
label="Connected Peers"
|
||||
statistic={topology?.connected.toString()}
|
||||
tooltip={thresholds.connectedPeers.explanation}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid key={2} item xs={12} sm={12} md={6} lg={4} xl={4}>
|
||||
<StatCard
|
||||
label="Population"
|
||||
statistic={topology?.population.toString()}
|
||||
tooltip={thresholds.population.explanation}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid key={3} item xs={12} sm={12} md={6} lg={4} xl={4}>
|
||||
<StatCard label="Depth" statistic={topology?.depth.toString()} tooltip={thresholds.depth.explanation} />
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
|
||||
@@ -1,48 +1,65 @@
|
||||
import type { ReactElement } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import { Card, CardContent, Typography } from '@material-ui/core/'
|
||||
import { createStyles, makeStyles, Theme } from '@material-ui/core/styles'
|
||||
import { Button, Grid, Typography, Link as MuiLink } from '@material-ui/core/'
|
||||
import { ROUTES } from '../routes'
|
||||
import { Activity } from 'react-feather'
|
||||
|
||||
const useStyles = makeStyles({
|
||||
root: {
|
||||
flexGrow: 1,
|
||||
marginTop: '20px',
|
||||
},
|
||||
title: {
|
||||
textAlign: 'center',
|
||||
fontSize: 26,
|
||||
},
|
||||
})
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
height: '100%',
|
||||
},
|
||||
content: {
|
||||
maxWidth: 500,
|
||||
marginBottom: theme.spacing(4),
|
||||
'&:last-child': {
|
||||
marginBottom: 0,
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
height: '1rem',
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
export default function TroubleshootConnectionCard(): ReactElement {
|
||||
const classes = useStyles()
|
||||
|
||||
return (
|
||||
<Card className={classes.root}>
|
||||
<CardContent>
|
||||
<Typography className={classes.title} gutterBottom>
|
||||
Looks like your node is not connected
|
||||
<Grid container direction="column" justifyContent="center" alignItems="center" className={classes.root}>
|
||||
<Grid item className={classes.content}>
|
||||
<Typography variant="h1" align="center">
|
||||
Uh oh, it looks like your node is not connected.
|
||||
</Typography>
|
||||
<div style={{ marginBottom: '20px', textAlign: 'center' }}>
|
||||
<strong>
|
||||
<Link to={ROUTES.STATUS}>Click to run status checks</Link> on your nodes connection or check out the{' '}
|
||||
<a href={process.env.REACT_APP_BEE_DOCS_HOST} target="_blank" rel="noreferrer">
|
||||
Swarm Bee Docs
|
||||
</a>
|
||||
</strong>
|
||||
</div>
|
||||
|
||||
<div style={{ marginBottom: '20px', textAlign: 'center' }}>
|
||||
<p style={{ marginTop: '50px' }}>
|
||||
Still not working? Drop us a message on the Ethereum Swarm{' '}
|
||||
<a href={process.env.REACT_APP_BEE_DISCORD_HOST} target="_blank" rel="noreferrer">
|
||||
Discord
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item className={classes.content}>
|
||||
<Typography align="center">
|
||||
Please check your node status to fix the problem. You can also check out the{' '}
|
||||
<MuiLink href={process.env.REACT_APP_BEE_DOCS_HOST} target="_blank" rel="noreferrer">
|
||||
Swarm Bee Docs
|
||||
</MuiLink>{' '}
|
||||
or ask for support on the{' '}
|
||||
<MuiLink href={process.env.REACT_APP_BEE_DISCORD_HOST} target="_blank" rel="noreferrer">
|
||||
Ethereum Swarm Discord
|
||||
</MuiLink>
|
||||
.
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item className={classes.content}>
|
||||
<Typography align="center">
|
||||
<Button
|
||||
component={Link}
|
||||
variant="contained"
|
||||
size="large"
|
||||
startIcon={<Activity className={classes.icon} />}
|
||||
to={ROUTES.STATUS}
|
||||
>
|
||||
Check node status
|
||||
</Button>
|
||||
</Typography>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
+16
-17
@@ -12,11 +12,8 @@ import { Context } from '../providers/Bee'
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
content: {
|
||||
marginLeft: 300,
|
||||
flexGrow: 1,
|
||||
backgroundColor: theme.palette.background.default,
|
||||
padding: theme.spacing(3),
|
||||
paddingBottom: '65px',
|
||||
minHeight: '100vh',
|
||||
},
|
||||
}),
|
||||
)
|
||||
@@ -31,20 +28,22 @@ const Dashboard = (props: Props): ReactElement => {
|
||||
const { isLoading } = useContext(Context)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<SideBar />
|
||||
<ErrorBoundary>
|
||||
<main className={classes.content}>
|
||||
<AlertVersion />
|
||||
{isLoading ? (
|
||||
<Container style={{ textAlign: 'center', padding: '50px' }}>
|
||||
<CircularProgress />
|
||||
</Container>
|
||||
) : (
|
||||
props.children
|
||||
)}
|
||||
</main>
|
||||
</ErrorBoundary>
|
||||
<Container className={classes.content}>
|
||||
<ErrorBoundary>
|
||||
<>
|
||||
<AlertVersion />
|
||||
{isLoading ? (
|
||||
<div style={{ textAlign: 'center', width: '100%' }}>
|
||||
<CircularProgress />
|
||||
</div>
|
||||
) : (
|
||||
props.children
|
||||
)}
|
||||
</>
|
||||
</ErrorBoundary>
|
||||
</Container>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -59,36 +59,34 @@ function PeerTable(props: Props): ReactElement {
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<TableContainer component={Paper}>
|
||||
<Table className={classes.table}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Index</TableCell>
|
||||
<TableCell>Peer Id</TableCell>
|
||||
<TableCell align="right">Actions</TableCell>
|
||||
<TableContainer component={Paper}>
|
||||
<Table className={classes.table}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Index</TableCell>
|
||||
<TableCell>Peer Id</TableCell>
|
||||
<TableCell align="right">Actions</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{props.peers?.map((peer: Peer, idx: number) => (
|
||||
<TableRow key={peer.address}>
|
||||
<TableCell component="th" scope="row">
|
||||
{idx + 1}
|
||||
</TableCell>
|
||||
<TableCell>{peer.address}</TableCell>
|
||||
<TableCell align="right">
|
||||
<Tooltip title="Ping node">
|
||||
<Button color="primary" onClick={() => pingPeer(peer.address)}>
|
||||
{getPingState(peerLatency, peer)}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{props.peers?.map((peer: Peer, idx: number) => (
|
||||
<TableRow key={peer.address}>
|
||||
<TableCell component="th" scope="row">
|
||||
{idx + 1}
|
||||
</TableCell>
|
||||
<TableCell>{peer.address}</TableCell>
|
||||
<TableCell align="right">
|
||||
<Tooltip title="Ping node">
|
||||
<Button color="primary" onClick={() => pingPeer(peer.address)}>
|
||||
{getPingState(peerLatency, peer)}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</div>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { ReactElement, useState, useContext } from 'react'
|
||||
import { Paper, Container, TextField, Typography, Button } from '@material-ui/core'
|
||||
import { ReactElement, useState, useContext } from 'react'
|
||||
import { Paper, TextField, Typography, Button } from '@material-ui/core'
|
||||
import { Context as SettingsContext } from '../../providers/Settings'
|
||||
|
||||
export default function Settings(): ReactElement {
|
||||
@@ -16,55 +16,53 @@ export default function Settings(): ReactElement {
|
||||
const touched = host !== apiUrl || debugHost !== apiDebugUrl
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Container>
|
||||
<Typography variant="h4" gutterBottom>
|
||||
Settings
|
||||
</Typography>
|
||||
<Paper>
|
||||
<TextField
|
||||
label="API Endpoint"
|
||||
style={{ margin: 0 }}
|
||||
placeholder="ex: 127.0.0.0.1:1633"
|
||||
helperText="Enter node host override / port"
|
||||
fullWidth
|
||||
defaultValue={apiUrl}
|
||||
margin="normal"
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
onChange={e => {
|
||||
setHost(e.target.value)
|
||||
}}
|
||||
variant="filled"
|
||||
/>
|
||||
</Paper>
|
||||
<Paper style={{ marginTop: '20px' }}>
|
||||
<TextField
|
||||
label="Debug API Endpoint"
|
||||
style={{ margin: 0 }}
|
||||
placeholder="ex: 127.0.0.0.1:1635"
|
||||
helperText="Enter node debug host override / port"
|
||||
fullWidth
|
||||
defaultValue={apiDebugUrl}
|
||||
onChange={e => {
|
||||
setDebugHost(e.target.value)
|
||||
}}
|
||||
margin="normal"
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
variant="filled"
|
||||
/>
|
||||
</Paper>
|
||||
{touched ? (
|
||||
<div style={{ marginTop: '20px' }}>
|
||||
<Button variant="outlined" color="primary" onClick={submit}>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
) : null}
|
||||
</Container>
|
||||
</div>
|
||||
<>
|
||||
<Typography variant="h4" gutterBottom>
|
||||
Settings
|
||||
</Typography>
|
||||
<Paper>
|
||||
<TextField
|
||||
label="API Endpoint"
|
||||
style={{ margin: 0 }}
|
||||
placeholder="ex: 127.0.0.0.1:1633"
|
||||
helperText="Enter node host override / port"
|
||||
fullWidth
|
||||
defaultValue={apiUrl}
|
||||
margin="normal"
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
onChange={e => {
|
||||
setHost(e.target.value)
|
||||
}}
|
||||
variant="filled"
|
||||
/>
|
||||
</Paper>
|
||||
<Paper style={{ marginTop: '20px' }}>
|
||||
<TextField
|
||||
label="Debug API Endpoint"
|
||||
style={{ margin: 0 }}
|
||||
placeholder="ex: 127.0.0.0.1:1635"
|
||||
helperText="Enter node debug host override / port"
|
||||
fullWidth
|
||||
defaultValue={apiDebugUrl}
|
||||
onChange={e => {
|
||||
setDebugHost(e.target.value)
|
||||
}}
|
||||
margin="normal"
|
||||
InputLabelProps={{
|
||||
shrink: true,
|
||||
}}
|
||||
variant="filled"
|
||||
/>
|
||||
</Paper>
|
||||
{touched ? (
|
||||
<div style={{ marginTop: '20px' }}>
|
||||
<Button variant="outlined" color="primary" onClick={submit}>
|
||||
Save
|
||||
</Button>
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
+57
-5
@@ -9,10 +9,55 @@ declare module '@material-ui/core/styles/createPalette' {
|
||||
|
||||
// Overwriting default components styles
|
||||
const componentsOverrides = (theme: Theme) => ({
|
||||
MuiDrawer: {
|
||||
paper: {
|
||||
width: 300,
|
||||
backgroundColor: '#212121',
|
||||
MuiContainer: {
|
||||
root: { padding: theme.spacing(8) },
|
||||
maxWidthXs: { padding: theme.spacing(8) },
|
||||
maxWidthSm: { padding: theme.spacing(8) },
|
||||
maxWidthMd: { padding: theme.spacing(8) },
|
||||
maxWidthLg: { padding: theme.spacing(8) },
|
||||
maxWidthXl: { padding: theme.spacing(8) },
|
||||
},
|
||||
MuiButton: {
|
||||
textSizeLarge: {
|
||||
padding: theme.spacing(2),
|
||||
},
|
||||
containedSizeLarge: {
|
||||
padding: theme.spacing(2),
|
||||
boxShadow: 'none',
|
||||
borderRadius: 0,
|
||||
'&: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',
|
||||
},
|
||||
},
|
||||
},
|
||||
contained: {
|
||||
backgroundColor: 'white',
|
||||
boxShadow: 'none',
|
||||
'&:hover': {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
color: 'white',
|
||||
// https://github.com/mui-org/material-ui/issues/22543
|
||||
'@media (hover: none)': {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
color: 'white',
|
||||
boxShadow: 'none',
|
||||
},
|
||||
},
|
||||
'&:focus': {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
color: 'white',
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
color: 'white',
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiTab: {
|
||||
@@ -59,13 +104,16 @@ const propsOverrides = {
|
||||
MuiTab: {
|
||||
disableRipple: true,
|
||||
},
|
||||
MuiButtonBase: {
|
||||
disableRipple: true,
|
||||
},
|
||||
}
|
||||
|
||||
export const theme = createMuiTheme({
|
||||
palette: {
|
||||
type: 'light',
|
||||
background: {
|
||||
default: '#fafafa',
|
||||
default: '#efefef',
|
||||
},
|
||||
primary: {
|
||||
light: orange.A200,
|
||||
@@ -78,6 +126,10 @@ export const theme = createMuiTheme({
|
||||
},
|
||||
typography: {
|
||||
fontFamily: ['Work Sans', 'Montserrat', 'Nunito', 'Roboto', '"Helvetica Neue"', 'Arial', 'sans-serif'].join(','),
|
||||
h1: {
|
||||
fontSize: '1.3rem',
|
||||
fontWeight: 500,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user