I want to save the progress state of Mobile Stepper, so that when user logged out, the user can resume from the place where he left. If progress bar is filled 2% then when next time the user login he should resume from 2% not from 0.
Here is the code:
import React, { useState, useReducer, useEffect } from "react"; import { Button, Typography, Grid, CircularProgress, Paper } from '@mui/material/'; import guardianOptions from '../../../constants/guardianOptions.js'; import studentClasses from '../../../constants/studentClasses.js'; import Stepper from '@mui/material/Stepper'; import Step from '@mui/material/Step'; import StepLabel from '@mui/material/StepLabel'; import MobileStepper from '@mui/material/MobileStepper'; import StepContent from '@mui/material/StepContent'; import { makeStyles, withStyles, createStyles } from '@mui/styles'; import { purple } from '@mui/material/colors'; import TextField from '@mui/material/TextField'; import useStyles from './styles'; import InputLabel from '@mui/material/InputLabel'; import MenuItem from '@mui/material/MenuItem'; import FormHelperText from '@mui/material/FormHelperText'; import FormControl from '@mui/material/FormControl'; import Select from '@mui/material/Select'; const User= (props) => { const { activeStep: lastActiveStep, userId } = props; const classes = useStyles(); const [guardianType, setGuardianType] = useState(0); const [activeStep, setActiveStep] = useState(lastActiveStep || 0); const [guardianRelationOptions, setGuardianRelationOptions] = useState(0); const [guardianDetailsForm, setGuardianDetailsForm] = useReducer( (state, newState) => ({ ...state, ...newState }), {} ); const [studentDetailsForm, setStudentDetailsForm] = useReducer( (state, newState) => ({ ...state, ...newState }), { s_firstName: '', s_lastName: '', s_age: '', s_class: '' } ); React.useEffect(() => { async function updateActiveStep() { // this is just pseudo code - whatever your endpoint looks like await window.fetch('http://localhost:8080/api/user/:userId', { method: 'PUT', body: JSON.stringify({activeStep}) }) } updateActiveStep() }, [activeStep]); function getSteps(){ return [<b style={{color:'purple'}}>'Personal Details'</b>, <b style={{color:'purple'}}>'Relation'</b>, <b style={{color:'purple'}}>'Guardian Details'</b>]; } const steps = getSteps(); function onGuardianTypeChangeChange(event) { // setAge(event.target.value); setGuardianType(event.target.value); let _guardianRelationOptions = guardianOptions.find(options => options.value === event.target.value); setGuardianRelationOptions(_guardianRelationOptions.relationships); } const handleGuardianDeatilsInput = evt => { const name = evt.target.name; const newValue = evt.target.value; setGuardianDetailsForm({ [name]: newValue }); }; const handleGuardianDetailsSubmit = evt => { evt.preventDefault(); let data = { guardianDetailsForm }; props.onGuardianDetails(guardianDetailsForm) console.log(data + "new user"); // console.log( props.onGuardianDetails(guardianDetailsForm) + "gana bajao"); setActiveStep((prevActiveStep) => prevActiveStep+1); setGuardianDetailsForm(); } function getStepContent(step) { switch (step) { case 0: if (!props.user.s_firstName) { return (<div> <form id ="form-step0" className={classes.root} onSubmit={handleGuardianDetailsSubmit} noValidate autoComplete="off"> <TextField id="outlined-basic" name="s_firstName" label="First Name" variant="outlined" defaultValue={guardianDetailsForm.s_firstName} onChange={handleGuardianDeatilsInput} /> <TextField id="outlined-basic" name="s_lastName" label="Last Name" variant="outlined" defaultValue={guardianDetailsForm.s_lastName} onChange={handleGuardianDeatilsInput} /> <TextField id="outlined-number" label="Age" name="s_age" defaultValue={guardianDetailsForm.s_age} type="number" InputLabelProps={{ shrink: true, }} onChange={handleGuardianDeatilsInput} variant="outlined" /> <FormControl variant="outlined" className={classes.formControl} sx={{ m: 1, minWidth: 120 }}> <InputLabel id="demo-simple-select-outlined-label">Class</InputLabel> <Select labelId="demo-simple-select-outlined-label" id="demo-simple-select-outlined" value={guardianDetailsForm.s_class} onChange={handleGuardianDeatilsInput} label="Class" name="s_class" > {studentClasses.map(c => <MenuItem key={c.value} value={c.value}>{c.name}</MenuItem> )} </Select> {/* <Button variant="contained" type="submit" color="primary" >NEXT</Button> */} </FormControl> </form> </div> )} ; case 1: if (!props.user.g_relationship) { return ( <div> <form id="form-step1" className={classes.root} onSubmit={handleGuardianDetailsSubmit} noValidate autoComplete="off"> <FormControl variant="outlined" className={classes.formControl} sx={{ m: 1, minWidth: 120 }}> <InputLabel id="demo-simple-select-outlined-label">Relationship</InputLabel> <Select labelId="demo-simple-select-outlined-label" id="demo-simple-select-outlined" onChange={onGuardianTypeChangeChange} label="Relationship" > {guardianOptions.map(type => <MenuItem key={type.value} value={type.value}>{type.name}</MenuItem> )} </Select> </FormControl> {guardianRelationOptions ? <FormControl variant="outlined" className={classes.formControl} sx={{ m: 1, minWidth: 120 }}> <InputLabel id="demo-simple-select-outlined-label">Relation</InputLabel> <Select labelId="demo-simple-select-outlined-label" id="demo-simple-select-outlined" // value={age} name="g_relationship" value={guardianDetailsForm.g_relationship} onChange={handleGuardianDeatilsInput} label="Relation" > {guardianRelationOptions.map(type => <MenuItem key={type.value} value={type.value}>{type.name}</MenuItem> )} </Select> </FormControl> : null } {!g_relationship} onClick={() => props.onGuardianDetails({g_relationship})}>NEXT</Button> */} {/* <Button variant="contained" color="primary" type="submit">NEXT</Button> */} </form> </div> )} ; case 2: return ( <div> <form id="form-step2" className={classes.root} onSubmit={handleGuardianDetailsSubmit} noValidate autoComplete="off"> <TextField id="outlined-basic" name="g_firstName" label="First Name" variant="outlined" defaultValue={guardianDetailsForm.g_firstName} onChange={handleGuardianDeatilsInput} /> <TextField id="outlined-basic" name="g_lastName" label="Last Name" variant="outlined" defaultValue={guardianDetailsForm.g_lastName} onChange={handleGuardianDeatilsInput} /> <TextField id="outlined-number" label="Age" name="g_age" defaultValue={guardianDetailsForm.g_age} type="number" InputLabelProps={{ shrink: true, }} onChange={handleGuardianDeatilsInput} variant="outlined" /> </form> </div>) ; default: return 'welcome lets fill the progress.' ; } } return ( <div className={classes.root} align="center"> <div className = {classes.actionsContainer}> <Paper square elevation={0}> <Typography>{getStepContent(activeStep)}</Typography> </Paper> <MobileStepper variant="progress" steps= {4} position="bottom" activeStep={activeStep} sx={{ minWidth: 400, flexGrow: 1 }} nextButton={ <> <Button size="small" onClick={handleGuardianDetailsSubmit} type="submit" form={`form-step${activeStep}`}> {activeStep === steps.length-1? 'Finish' : 'Next'} </Button> </> } /> </div> </div> ); } export default User;
If user refreshes or reload the page, he should see the progress from where he has left.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
@Tanya
So you are saying that your user can authorize. When this happens do you receive any data about the user? Can you update the user data via POST or PUT request? If so, I’d store the active step with this data.
Assuming you have some user data that you receive when the user signs in:
// user - user data export default function BuildAdStepper({user}) { const { activeStep: lastActiveStep, userId } = user const classes = useStyles(); const theme = useTheme(); const [activeStep, setActiveStep] = React.useState(lastActiveStep || 0); React.useEffect(() => { async function updateActiveStep() { // this is just pseudo code - whatever your endpoint looks like await window.fetch('/yourEndpoint/:userId', { method: 'PUT', body: JSON.stringify({activeStep}) }) } updateActiveStep() }, [activeStep]) /* ... rest of your component * / }
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0