diff --git a/src/components/SideBar.tsx b/src/components/SideBar.tsx index 3e4efa4..4300aab 100644 --- a/src/components/SideBar.tsx +++ b/src/components/SideBar.tsx @@ -4,19 +4,18 @@ import { Link, RouteComponentProps } from 'react-router-dom' import { createStyles, Theme, makeStyles } from '@material-ui/core/styles' import { ListItemText, ListItemIcon, ListItem, Divider, List, Drawer, Link as MUILink } from '@material-ui/core' import { OpenInNewSharp } from '@material-ui/icons' -import { Activity, FileText, DollarSign, Share2, Settings, Layers } from 'react-feather' +import { Home, FileText, DollarSign, Share2, Settings, Layers } from 'react-feather' import SwarmLogoOrange from '../assets/swarm-logo-orange.svg' -import { Health } from '@ethersphere/bee-js' const drawerWidth = 240 const navBarItems = [ { - label: 'Status', - id: 'status', + label: 'Info', + id: 'info', path: '/', - icon: Activity, + icon: Home, }, { label: 'Files', @@ -83,8 +82,7 @@ const useStyles = makeStyles((theme: Theme) => interface Props extends RouteComponentProps { themeMode: string - health: boolean - nodeHealth: Health | null + isOk: boolean } export default function SideBar(props: Props): ReactElement { @@ -139,11 +137,11 @@ export default function SideBar(props: Props): ReactElement {
- -
-
+ + - API -
-
-
- Debug API -
- + Node {props.isOk ? 'OK' : 'Error'} + +
diff --git a/src/components/TroubleshootConnectionCard.tsx b/src/components/TroubleshootConnectionCard.tsx index 43426cf..5053df2 100644 --- a/src/components/TroubleshootConnectionCard.tsx +++ b/src/components/TroubleshootConnectionCard.tsx @@ -26,7 +26,7 @@ export default function TroubleshootConnectionCard(): ReactElement {
- Click to run status checks on your nodes connection or check out the{' '} + Click to run status checks on your nodes connection or check out the{' '} Swarm Bee Docs diff --git a/src/layout/Dashboard.tsx b/src/layout/Dashboard.tsx index f410c49..79f9664 100644 --- a/src/layout/Dashboard.tsx +++ b/src/layout/Dashboard.tsx @@ -33,7 +33,7 @@ const Dashboard = (props: Props): ReactElement => { const [themeMode, toggleThemeMode] = useState('light') - const { isLoading, apiHealth, debugApiHealth } = useContext(Context) + const { isLoading, status } = useContext(Context) useEffect(() => { const theme = localStorage.getItem('theme') @@ -56,7 +56,7 @@ const Dashboard = (props: Props): ReactElement => { return (
- +
diff --git a/src/pages/info/StatusCard.tsx b/src/pages/info/StatusCard.tsx new file mode 100644 index 0000000..22579fe --- /dev/null +++ b/src/pages/info/StatusCard.tsx @@ -0,0 +1,112 @@ +import { ReactElement, useState } from 'react' +import { Link } from 'react-router-dom' + +import { createStyles, makeStyles } from '@material-ui/core/styles' +import { Card, CardContent, Typography, Chip, Button } from '@material-ui/core/' +import { ArrowRight, ArrowDropUp } from '@material-ui/icons/' +import { NodeAddresses, Topology } from '@ethersphere/bee-js' + +const useStyles = makeStyles(() => + createStyles({ + root: { + display: 'flex', + flex: '1 1 auto', + flexDirection: 'column', + }, + status: { + color: '#2145a0', + backgroundColor: '#e1effe', + }, + }), +) + +interface Props { + nodeAddresses: NodeAddresses | null + nodeTopology: Topology | null + userBeeVersion?: string + isLatestBeeVersion: boolean + isOk: boolean + latestUrl: string +} + +function StatusCard({ + userBeeVersion, + nodeAddresses, + nodeTopology, + isLatestBeeVersion, + latestUrl, +}: Props): ReactElement | null { + const classes = useStyles() + + const [underlayAddressesVisible, setUnderlayAddresessVisible] = useState(false) + + return ( + + + <> +
+ Discovered Nodes: {nodeTopology?.population} + + Connected Peers: + {nodeTopology?.connected} + +
+
+ + AGENT: + + Bee + {' '} + {userBeeVersion || '-'} + {isLatestBeeVersion ? ( + + ) : ( + + )} + + + PUBLIC KEY: + {nodeAddresses?.publicKey ? nodeAddresses.publicKey : '-'} + + + PSS PUBLIC KEY: + {nodeAddresses?.pssPublicKey ? nodeAddresses.pssPublicKey : '-'} + + + OVERLAY ADDRESS (PEER ID): + {nodeAddresses?.overlay ? nodeAddresses.overlay : '-'} + + + setUnderlayAddresessVisible(!underlayAddressesVisible)}> + + + {underlayAddressesVisible && ( +
+ {nodeAddresses?.underlay.map(item => ( +
  • {item}
  • + ))} +
    + )} +
    +
    + +
    +
    + ) +} + +export default StatusCard diff --git a/src/pages/info/index.tsx b/src/pages/info/index.tsx new file mode 100644 index 0000000..3e7d7ac --- /dev/null +++ b/src/pages/info/index.tsx @@ -0,0 +1,49 @@ +import { ReactElement, useContext } from 'react' +import { makeStyles, Theme, createStyles } from '@material-ui/core/styles' + +import StatusCard from './StatusCard' +import EthereumAddressCard from '../../components/EthereumAddressCard' +import TroubleshootConnectionCard from '../../components/TroubleshootConnectionCard' +import { Context as BeeContext } from '../../providers/Bee' + +const useStyles = makeStyles((theme: Theme) => + createStyles({ + root: { + width: '100%', + display: 'grid', + rowGap: theme.spacing(3), + }, + }), +) + +export default function Status(): ReactElement { + const classes = useStyles() + + const { + status, + latestUserVersion, + isLatestBeeVersion, + latestBeeVersionUrl, + topology, + nodeAddresses, + chequebookAddress, + } = useContext(BeeContext) + + if (!status.all) return + + return ( +
    + + {nodeAddresses && chequebookAddress && ( + + )} +
    + ) +} diff --git a/src/pages/status/NodeSetupWorkflow.tsx b/src/pages/status/NodeSetupWorkflow.tsx deleted file mode 100644 index d8274ee..0000000 --- a/src/pages/status/NodeSetupWorkflow.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import { ReactElement, useEffect, useState, useContext } from 'react' -import { makeStyles, Theme, createStyles } from '@material-ui/core/styles' -import { Typography, Paper, Button, Step, StepLabel, StepContent, Stepper, StepButton } from '@material-ui/core/' -import { CheckCircle, Error, ExpandLessSharp, ExpandMoreSharp, Autorenew } from '@material-ui/icons/' - -import DebugConnectionCheck from './SetupSteps/DebugConnectionCheck' -import NodeConnectionCheck from './SetupSteps/NodeConnectionCheck' -import VersionCheck from './SetupSteps/VersionCheck' -import EthereumConnectionCheck from './SetupSteps/EthereumConnectionCheck' -import ChequebookDeployFund from './SetupSteps/ChequebookDeployFund' -import PeerConnection from './SetupSteps/PeerConnection' -import { Context } from '../../providers/Bee' - -const useStyles = makeStyles((theme: Theme) => - createStyles({ - root: { - padding: theme.spacing(2), - width: '100%', - }, - button: { - marginTop: theme.spacing(1), - marginRight: theme.spacing(1), - }, - actionsContainer: { - margin: theme.spacing(2), - }, - }), -) - -interface Step { - label: string - isOk: boolean - component: ReactElement -} - -export default function NodeSetupWorkflow(): ReactElement { - const classes = useStyles() - const [activeStep, setActiveStep] = useState(-1) - - const { - status, - isLoading, - latestUserVersion, - latestPublishedVersion, - isLatestBeeVersion, - latestBeeVersionUrl, - topology, - nodeAddresses, - chequebookAddress, - } = useContext(Context) - - const steps: Step[] = [ - { - label: 'Connected to Node DebugAPI', - isOk: status.debugApiConnection, - component: , - }, - { - label: 'Running latest Bee version', - isOk: status.version, - component: ( - - ), - }, - { - label: 'Connected to xDai Blockchain', - isOk: status.blockchainConnection, - component: , - }, - { - label: 'Deployed and Funded Chequebook', - isOk: status.chequebook, - component: ( - - ), - }, - { - label: 'Connected to Node API', - isOk: status.apiConnection, - component: , - }, - { - label: 'Connected to Peers', - isOk: status.topology, - component: , - }, - ] - - useEffect(() => { - // If the user already changed the active step we don't want to overwrite it - if (activeStep >= 0 && activeStep < steps.length) return - - // If any step is not fully loaded yet return - if (!isLoading) return - - // Select first step that is not OK - // This is deliberately a for loop (and not forEach) so that we can terminate the useEffect from within the cycle - for (let i = 0; i < steps.length; ++i) { - if (!steps[i].isOk) { - setActiveStep(i) - - return - } - } - }, [steps]) - - const handleNext = () => { - setActiveStep(prevActiveStep => prevActiveStep + 1) - } - - const handleBack = () => { - setActiveStep(prevActiveStep => prevActiveStep - 1) - } - - return ( - - - Node Setup - - - {steps.map(({ label, isOk, component }, index) => ( - - setActiveStep(index === activeStep ? steps.length : index)} - StepIconComponent={() => { - if (isLoading) return - - if (isOk) return - - return - }} - > - setActiveStep(index === activeStep ? steps.length : index)} - style={{ justifyContent: 'space-between' }} - > -
    -
    {label}
    -
    - {index === activeStep ? : } -
    -
    -
    -
    - - {component} -
    -
    - - -
    -
    -
    -
    - ))} -
    -
    - ) -} diff --git a/src/pages/status/StatusCard.tsx b/src/pages/status/StatusCard.tsx deleted file mode 100644 index c9a8e1f..0000000 --- a/src/pages/status/StatusCard.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import { ReactElement, useState } from 'react' -import { Link } from 'react-router-dom' - -import { createStyles, makeStyles } from '@material-ui/core/styles' -import { Card, CardContent, Typography, Chip, Button } from '@material-ui/core/' -import { CheckCircle, Error, ArrowRight, ArrowDropUp } from '@material-ui/icons/' -import { NodeAddresses, Topology } from '@ethersphere/bee-js' - -const useStyles = makeStyles(() => - createStyles({ - root: { - display: 'flex', - flex: '1 1 auto', - flexDirection: 'column', - }, - status: { - color: '#2145a0', - backgroundColor: '#e1effe', - }, - }), -) - -interface Props { - nodeAddresses: NodeAddresses | null - nodeTopology: Topology | null - userBeeVersion?: string - isLatestBeeVersion: boolean - isOk: boolean - latestUrl: string -} - -function StatusCard({ - userBeeVersion, - nodeAddresses, - nodeTopology, - isOk, - isLatestBeeVersion, - latestUrl, -}: Props): ReactElement | null { - const classes = useStyles() - - const [underlayAddressesVisible, setUnderlayAddresessVisible] = useState(false) - - return ( - - - - {isOk && ( -
    - - Your Bee node is running as expected -
    - )} - {!isOk && ( -
    - - Could not connect to Bee Node -
    - )} -
    - {isOk && ( - <> -
    - Discovered Nodes: {nodeTopology?.population} - - Connected Peers: - {nodeTopology?.connected} - -
    -
    - - AGENT: - - Bee - {' '} - {userBeeVersion || '-'} - {isLatestBeeVersion ? ( - - ) : ( - - )} - - - PUBLIC KEY: - {nodeAddresses?.publicKey ? nodeAddresses.publicKey : '-'} - - - PSS PUBLIC KEY: - {nodeAddresses?.pssPublicKey ? nodeAddresses.pssPublicKey : '-'} - - - OVERLAY ADDRESS (PEER ID): - {nodeAddresses?.overlay ? nodeAddresses.overlay : '-'} - - - setUnderlayAddresessVisible(!underlayAddressesVisible)}> - - - {underlayAddressesVisible && ( -
    - {nodeAddresses?.underlay.map(item => ( -
  • {item}
  • - ))} -
    - )} -
    -
    - - )} -
    -
    - ) -} - -export default StatusCard diff --git a/src/pages/status/index.tsx b/src/pages/status/index.tsx index a65ba71..8386d4f 100644 --- a/src/pages/status/index.tsx +++ b/src/pages/status/index.tsx @@ -1,48 +1,152 @@ -import { ReactElement, useContext } from 'react' +import { ReactElement, useState, useContext } from 'react' import { makeStyles, Theme, createStyles } from '@material-ui/core/styles' +import { Typography, Paper, Button, Step, StepLabel, StepContent, Stepper, StepButton } from '@material-ui/core/' +import { CheckCircle, Error, ExpandLessSharp, ExpandMoreSharp, Autorenew } from '@material-ui/icons/' -import NodeSetupWorkflow from './NodeSetupWorkflow' -import StatusCard from './StatusCard' -import EthereumAddressCard from '../../components/EthereumAddressCard' -import { Context as BeeContext } from '../../providers/Bee' +import DebugConnectionCheck from './SetupSteps/DebugConnectionCheck' +import NodeConnectionCheck from './SetupSteps/NodeConnectionCheck' +import VersionCheck from './SetupSteps/VersionCheck' +import EthereumConnectionCheck from './SetupSteps/EthereumConnectionCheck' +import ChequebookDeployFund from './SetupSteps/ChequebookDeployFund' +import PeerConnection from './SetupSteps/PeerConnection' +import { Context } from '../../providers/Bee' const useStyles = makeStyles((theme: Theme) => createStyles({ root: { + padding: theme.spacing(2), width: '100%', - display: 'grid', - rowGap: theme.spacing(3), + }, + button: { + marginTop: theme.spacing(1), + marginRight: theme.spacing(1), + }, + actionsContainer: { + margin: theme.spacing(2), }, }), ) -export default function Status(): ReactElement { +interface Step { + label: string + isOk: boolean + component: ReactElement +} + +export default function NodeSetupWorkflow(): ReactElement { const classes = useStyles() + const [activeStep, setActiveStep] = useState(-1) const { status, + isLoading, latestUserVersion, + latestPublishedVersion, isLatestBeeVersion, latestBeeVersionUrl, topology, nodeAddresses, chequebookAddress, - } = useContext(BeeContext) + } = useContext(Context) + + const steps: Step[] = [ + { + label: 'Connected to Node DebugAPI', + isOk: status.debugApiConnection, + component: , + }, + { + label: 'Running latest Bee version', + isOk: status.version, + component: ( + + ), + }, + { + label: 'Connected to xDai Blockchain', + isOk: status.blockchainConnection, + component: , + }, + { + label: 'Deployed and Funded Chequebook', + isOk: status.chequebook, + component: ( + + ), + }, + { + label: 'Connected to Node API', + isOk: status.apiConnection, + component: , + }, + { + label: 'Connected to Peers', + isOk: status.topology, + component: , + }, + ] + + const handleNext = () => { + setActiveStep(prevActiveStep => prevActiveStep + 1) + } + + const handleBack = () => { + setActiveStep(prevActiveStep => prevActiveStep - 1) + } return ( -
    - - {nodeAddresses && chequebookAddress && ( - - )} - -
    + + + Node Setup + + + {steps.map(({ label, isOk, component }, index) => ( + + setActiveStep(index === activeStep ? steps.length : index)} + StepIconComponent={() => { + if (isLoading) return + + if (isOk) return + + return + }} + > + setActiveStep(index === activeStep ? steps.length : index)} + style={{ justifyContent: 'space-between' }} + > +
    +
    {label}
    +
    + {index === activeStep ? : } +
    +
    +
    +
    + + {component} +
    +
    + + +
    +
    +
    +
    + ))} +
    +
    ) } diff --git a/src/routes/routes.tsx b/src/routes/routes.tsx index 0a8e694..2571eb6 100644 --- a/src/routes/routes.tsx +++ b/src/routes/routes.tsx @@ -7,6 +7,7 @@ import AppRoute from './AppRoute' import Dashboard from '../layout/Dashboard' // pages +import Info from '../pages/info' import Status from '../pages/status' import Files from '../pages/files' import Peers from '../pages/peers' @@ -16,12 +17,13 @@ import Stamps from '../pages/stamps' const BaseRouter = (): ReactElement => ( - + + )