如何在单击下一步按钮时保存 Mobile Stepper 进度

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

我想保存 Mobile Stepper 的进度状态,这样当用户注销时,用户可以从他离开的地方继续。如果进度条填充了 2%,那么下次用户登录时,他应该从 2% 恢复,而不是从 0 恢复。 这是代码:

    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;

如果用户刷新或重新加载页面,他应该从他离开的地方看到进度。

@Tanya

所以你是说你的用户可以授权。发生这种情况时,您会收到有关用户的任何数据吗?您可以通过 POST 或 PUT 请求更新用户数据吗?如果是这样,我将使用此数据存储活动步骤。

假设您有一些在用户登录时收到的用户数据:

// 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 * /
}