feat: initial Proof of Concept UI (#1)
* initial dashboard layout * add node status card * add accounting section, pull peer data * add file functionality with bee-js, first iteration of accounts page * Add balances and chequebook table * add blockie / identicon for addresses * add basic settlements table * implement theme overrides * cleanup logging * Add troubleshooting block * add initial dark theme support, add copy to clipboard, QR code support * show active element on sidebar * remove duplicate status page and make status page index * Update package.json Co-authored-by: Vojtech Simetka <vojtech@simetka.cz> * Update public/index.html Co-authored-by: Vojtech Simetka <vojtech@simetka.cz> * Update src/pages/accounting/AccountCard.tsx Co-authored-by: Vojtech Simetka <vojtech@simetka.cz> * change bee api client to use beeJS library * add initial setup workflow * breakout ethereum address component, define initial setup workflow * add types to responses, add additional node troubleshooting info to workflow * make setup steps nonlinear and interactive * make host endpoint dynamic on setup * split out api calls into custom hooks, add component loading indicators * add depost / withdrawl functionality, show transactions in BZZ * add multiOS code support troubleshooting, check for balance in chequebook on setup * add ability to change apis in settings page * show file loading status * Style active sidebar item * reload on theme change * modify troubleshooting verbage, add cashout functionality and details, * facilitate file upload with beeJS * update readme to show UI samples * remove nnPeersWatermark from peers page * split node steps into separate components, make status page visible at anytime * minor UI/UX enhancements * format accounting page * remove WIP wallet connection code * Update src/components/CashoutModal.tsx Co-authored-by: Vojtech Simetka <vojtech@simetka.cz> * use bigint for deposits/withdrawls * revise status card * clean up unused imports and variables * add api status to sidebar * obfuscate pages with troubleshooting component when apis not connected * add localhost OS detection for troubleshooting code * cleanup extra logos * monospace BZZ in tables * hide troubleshooting page while loading API status * Remove ability to remove peers * add null types to API responses Co-authored-by: Vojtech Simetka <vojtech@simetka.cz>
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
import React, { useEffect, useState } 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, Sync, ExpandLessSharp, ExpandMoreSharp } from '@material-ui/icons/';
|
||||
|
||||
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';
|
||||
|
||||
|
||||
const useStyles = makeStyles((theme: Theme) =>
|
||||
createStyles({
|
||||
root: {
|
||||
width: '100%',
|
||||
},
|
||||
button: {
|
||||
marginTop: theme.spacing(1),
|
||||
marginRight: theme.spacing(1),
|
||||
},
|
||||
actionsContainer: {
|
||||
margin: theme.spacing(2),
|
||||
},
|
||||
resetContainer: {
|
||||
padding: theme.spacing(5),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
function getSteps() {
|
||||
return [
|
||||
'Node Connection Check',
|
||||
'Version Check',
|
||||
'Connect to Ethereum Blockchain',
|
||||
'Deploy and Fund Chequebook',
|
||||
'Connect to Peers',
|
||||
];
|
||||
}
|
||||
|
||||
function getStepContent(step: number, props: any) {
|
||||
|
||||
switch (step) {
|
||||
case 0:
|
||||
return <NodeConnectionCheck {...props} />;
|
||||
case 1:
|
||||
return <VersionCheck {...props} />;
|
||||
case 2:
|
||||
return <EthereumConnectionCheck {...props} />;
|
||||
case 3:
|
||||
return <ChequebookDeployFund {...props} />;
|
||||
default:
|
||||
return <PeerConnection {...props} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default function NodeSetupWorkflow(props: any) {
|
||||
const classes = useStyles();
|
||||
const [activeStep, setActiveStep] = useState(0);
|
||||
const [completed, setCompleted] = useState<{ [k: number]: boolean }>({});
|
||||
const steps = getSteps();
|
||||
|
||||
const evaluateNodeStatus = () => {
|
||||
if (props.nodeHealth?.status === 'ok' && props.nodeApiHealth) {
|
||||
handleComplete(0)
|
||||
setActiveStep(1)
|
||||
}
|
||||
|
||||
if (props.beeRelease && props.beeRelease.name === `v${props.nodeHealth?.version?.split('-')[0]}`) {
|
||||
handleComplete(1)
|
||||
setActiveStep(2)
|
||||
}
|
||||
|
||||
if (props.nodeAddresses?.ethereum) {
|
||||
handleComplete(2)
|
||||
setActiveStep(3)
|
||||
}
|
||||
|
||||
if (props.chequebookAddress?.chequebookaddress && props.chequebookBalance.totalBalance > 0) {
|
||||
handleComplete(3)
|
||||
setActiveStep(4)
|
||||
}
|
||||
|
||||
if (props.nodeTopology.connected && props.nodeTopology.connected > 0) {
|
||||
handleComplete(4)
|
||||
setActiveStep(5)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
evaluateNodeStatus()
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
evaluateNodeStatus()
|
||||
}, [props])
|
||||
|
||||
const handleNext = () => {
|
||||
setActiveStep((prevActiveStep) => prevActiveStep + 1);
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
setActiveStep((prevActiveStep) => prevActiveStep - 1);
|
||||
};
|
||||
|
||||
const handleSetupComplete = () => {
|
||||
props.setStatusChecksVisible(false)
|
||||
};
|
||||
|
||||
const handleComplete = (index: number) => {
|
||||
const newCompleted = completed;
|
||||
newCompleted[index] = true;
|
||||
setCompleted(newCompleted);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classes.root}>
|
||||
<Typography variant="h4" gutterBottom>
|
||||
Node Setup
|
||||
<span style={{marginLeft:'25px'}}>
|
||||
<Button variant='outlined' size='small' onClick={() => window.location.reload()}><Sync/><span style={{marginLeft:'7px'}}>Refresh Checks</span></Button>
|
||||
</span>
|
||||
</Typography>
|
||||
<Stepper nonLinear activeStep={activeStep} orientation="vertical">
|
||||
{steps.map((label, index) => (
|
||||
<Step key={label}>
|
||||
<StepLabel
|
||||
onClick={() => setActiveStep(index === activeStep ? 5 : index)}
|
||||
StepIconComponent={() => {
|
||||
if(completed[index])
|
||||
return <CheckCircle style={{color:'#32c48d', height: '25px', cursor:'pointer'}} />
|
||||
else {
|
||||
return <Error style={{color:'#c9201f', height: '25px', cursor:'pointer'}} />
|
||||
}
|
||||
}}
|
||||
>
|
||||
<StepButton onClick={() => setActiveStep(index === activeStep ? 5 : index)} style={{justifyContent:'space-between'}}>
|
||||
<div style={{display:'flex'}}>
|
||||
<div style={{marginTop:'5px'}}>{label}</div>
|
||||
<div style={{marginLeft:'12px'}}>{index === activeStep ? <ExpandLessSharp /> : <ExpandMoreSharp />}</div>
|
||||
</div>
|
||||
</StepButton>
|
||||
</StepLabel>
|
||||
<StepContent>
|
||||
<Typography>{getStepContent(index, props)}</Typography>
|
||||
<div className={classes.actionsContainer}>
|
||||
<div>
|
||||
<Button
|
||||
disabled={activeStep === 0}
|
||||
onClick={handleBack}
|
||||
className={classes.button}
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={handleNext}
|
||||
className={classes.button}
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</StepContent>
|
||||
</Step>
|
||||
))}
|
||||
</Stepper>
|
||||
{Object.values(completed).filter(value => value).length === 5 ? (
|
||||
<Paper square elevation={0} className={classes.resetContainer}>
|
||||
<Typography>Bee setup complete! Welcome to the swarm and the internet of decentralized storage</Typography>
|
||||
<Button
|
||||
onClick={handleBack}
|
||||
className={classes.button}
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
<Button onClick={handleSetupComplete} variant="contained" color="primary" className={classes.button}>
|
||||
Complete
|
||||
</Button>
|
||||
</Paper>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user