How to save the Mobile Stepper progress on click of next button

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

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x