Add sample mui stepper
This commit is contained in:
parent
80d5b181d9
commit
0104af35f7
8 changed files with 1111 additions and 11 deletions
924
frontend/package-lock.json
generated
924
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -3,6 +3,9 @@
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@emotion/react": "^11.4.1",
|
||||||
|
"@emotion/styled": "^11.3.0",
|
||||||
|
"@mui/material": "^5.0.2",
|
||||||
"@testing-library/jest-dom": "^5.14.1",
|
"@testing-library/jest-dom": "^5.14.1",
|
||||||
"@testing-library/react": "^11.2.7",
|
"@testing-library/react": "^11.2.7",
|
||||||
"@testing-library/user-event": "^12.8.3",
|
"@testing-library/user-event": "^12.8.3",
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
import SamplePage from './pages/SamplePage';
|
import SamplePage from './pages/SamplePage';
|
||||||
|
import { createTheme, ThemeProvider } from '@mui/material/styles';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
const darkTheme = createTheme({
|
||||||
|
palette: {
|
||||||
|
mode: 'dark',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
|
<ThemeProvider theme={darkTheme}>
|
||||||
<SamplePage />
|
<SamplePage />
|
||||||
|
</ThemeProvider>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
128
frontend/src/components/Stepper.js
Normal file
128
frontend/src/components/Stepper.js
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import Box from '@mui/material/Box';
|
||||||
|
import Stepper from '@mui/material/Stepper';
|
||||||
|
import Step from '@mui/material/Step';
|
||||||
|
import StepButton from '@mui/material/StepButton';
|
||||||
|
import Button from '@mui/material/Button';
|
||||||
|
import Typography from '@mui/material/Typography';
|
||||||
|
|
||||||
|
import LocationStep from './steps/Location'
|
||||||
|
import SoilStep from './steps/Soil'
|
||||||
|
import ResultsStep from './steps/Results'
|
||||||
|
|
||||||
|
export default function StepperWizard(props) {
|
||||||
|
const [activeStep, setActiveStep] = React.useState(0);
|
||||||
|
const [completed, setCompleted] = React.useState({});
|
||||||
|
|
||||||
|
const steps = [
|
||||||
|
{'label': 'Select location', 'component': LocationStep },
|
||||||
|
{'label': 'Choose soil', 'component': SoilStep },
|
||||||
|
{'label': 'Choose habitat', 'component': SoilStep },
|
||||||
|
{'label': 'Select zone', 'component': SoilStep },
|
||||||
|
{'label': 'Project specifics', 'component': SoilStep },
|
||||||
|
{'label': 'Summary', 'component': SoilStep }
|
||||||
|
];
|
||||||
|
|
||||||
|
const totalSteps = () => {
|
||||||
|
return steps.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
const completedSteps = () => {
|
||||||
|
return Object.keys(completed).length;
|
||||||
|
};
|
||||||
|
|
||||||
|
const isLastStep = () => {
|
||||||
|
return activeStep === totalSteps() - 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
const allStepsCompleted = () => {
|
||||||
|
return completedSteps() === totalSteps();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNext = () => {
|
||||||
|
const newActiveStep =
|
||||||
|
isLastStep() && !allStepsCompleted()
|
||||||
|
? // It's the last step, but not all steps have been completed,
|
||||||
|
// find the first step that has been completed
|
||||||
|
steps.findIndex((step, i) => !(i in completed))
|
||||||
|
: activeStep + 1;
|
||||||
|
setActiveStep(newActiveStep);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
setActiveStep((prevActiveStep) => prevActiveStep - 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleStep = (step) => () => {
|
||||||
|
setActiveStep(step);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleComplete = () => {
|
||||||
|
const newCompleted = completed;
|
||||||
|
newCompleted[activeStep] = true;
|
||||||
|
setCompleted(newCompleted);
|
||||||
|
handleNext();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleReset = () => {
|
||||||
|
setActiveStep(0);
|
||||||
|
setCompleted({});
|
||||||
|
};
|
||||||
|
|
||||||
|
let CurrentStep = activeStep > totalSteps() ? steps[activeStep].component : steps[totalSteps()-1].component;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box sx={{ width: '100%' }}>
|
||||||
|
<Stepper nonLinear activeStep={activeStep}>
|
||||||
|
{steps.map((step, index) => (
|
||||||
|
<Step key={step.label} completed={completed[index]}>
|
||||||
|
<StepButton color="inherit" onClick={handleStep(index)}>
|
||||||
|
{step.label}
|
||||||
|
</StepButton>
|
||||||
|
</Step>
|
||||||
|
))}
|
||||||
|
</Stepper>
|
||||||
|
<div>
|
||||||
|
{allStepsCompleted() ? (
|
||||||
|
<React.Fragment>
|
||||||
|
<ResultsStep {...props} />
|
||||||
|
<Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}>
|
||||||
|
<Box sx={{ flex: '1 1 auto' }} />
|
||||||
|
<Button onClick={handleReset}>Reset</Button>
|
||||||
|
</Box>
|
||||||
|
</React.Fragment>
|
||||||
|
) : (
|
||||||
|
<React.Fragment>
|
||||||
|
<CurrentStep {...props} />
|
||||||
|
<Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}>
|
||||||
|
<Button
|
||||||
|
color="inherit"
|
||||||
|
disabled={activeStep === 0}
|
||||||
|
onClick={handleBack}
|
||||||
|
sx={{ mr: 1 }}
|
||||||
|
>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
<Box sx={{ flex: '1 1 auto' }} />
|
||||||
|
<Button onClick={handleNext} sx={{ mr: 1 }}>
|
||||||
|
Next
|
||||||
|
</Button>
|
||||||
|
{activeStep !== steps.length &&
|
||||||
|
(completed[activeStep] ? (
|
||||||
|
<Typography variant="caption" sx={{ display: 'inline-block' }}>
|
||||||
|
Step {activeStep + 1} already completed
|
||||||
|
</Typography>
|
||||||
|
) : (
|
||||||
|
<Button onClick={handleComplete}>
|
||||||
|
{completedSteps() === totalSteps() - 1
|
||||||
|
? 'Finish'
|
||||||
|
: 'Complete Step'}
|
||||||
|
</Button>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</React.Fragment>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
13
frontend/src/components/steps/Location.js
Normal file
13
frontend/src/components/steps/Location.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { Container } from 'reactstrap';
|
||||||
|
|
||||||
|
|
||||||
|
export default class Step1 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Container className="pt-4">
|
||||||
|
<p>Please choose your location...</p>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
18
frontend/src/components/steps/Results.js
Normal file
18
frontend/src/components/steps/Results.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { Container, ListGroup, ListGroupItem } from 'reactstrap';
|
||||||
|
|
||||||
|
|
||||||
|
export default class Step3 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Container className="p-2">
|
||||||
|
<h5 className="pt-4">Plant List</h5>
|
||||||
|
<ListGroup>
|
||||||
|
{this.props.plants.map(function (plant, i) {
|
||||||
|
return <ListGroupItem key={i} >{plant.name}</ListGroupItem>;
|
||||||
|
})}
|
||||||
|
</ListGroup>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
13
frontend/src/components/steps/Soil.js
Normal file
13
frontend/src/components/steps/Soil.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { Container } from 'reactstrap';
|
||||||
|
|
||||||
|
|
||||||
|
export default class Step2 extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Container className="pt-4">
|
||||||
|
<p >Sample step</p>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Container, ListGroup, ListGroupItem } from 'reactstrap';
|
import { Container } from 'reactstrap';
|
||||||
|
import Stepper from '../components/Stepper'
|
||||||
|
|
||||||
import PlantRepsostory from '../repository/PlantRepository'
|
import PlantRepsostory from '../repository/PlantRepository'
|
||||||
|
|
||||||
|
@ -33,12 +34,9 @@ export default class SamplePage extends React.Component {
|
||||||
<h1>Right Tree</h1>
|
<h1>Right Tree</h1>
|
||||||
<h4>Right Plant Right Place Right Time</h4>
|
<h4>Right Plant Right Place Right Time</h4>
|
||||||
|
|
||||||
<h5 className="pt-4">Plant List</h5>
|
<div className="pt-4">
|
||||||
<ListGroup>
|
<Stepper plants={this.state.plants} />
|
||||||
{this.state.plants.map(function (plant, i) {
|
</div>
|
||||||
return <ListGroupItem key={i} >{plant.name}</ListGroupItem>;
|
|
||||||
})}
|
|
||||||
</ListGroup>
|
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue