34d2dfda5a
* 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>
185 lines
5.7 KiB
TypeScript
185 lines
5.7 KiB
TypeScript
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>
|
|
);
|
|
} |