25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

269 lines
8.8 KiB

  1. // import { Link } from 'react-router-dom';
  2. import React, {
  3. useState,
  4. useRef,
  5. } from 'react';
  6. // material-ui
  7. import {
  8. Stepper,
  9. Step,
  10. StepButton,
  11. // Grid,
  12. Stack,
  13. Typography,
  14. Button, StepLabel,
  15. CircularProgress,
  16. } from '@mui/material';
  17. import { POST_USERNAME, POST_VERIFY_CAPTCHA } from "utils/ApiPathConst";
  18. import RegisterStepIcon, { registerStepStyle } from 'components/RegisterStepIcon';
  19. // project import
  20. import Loadable from 'components/Loadable';
  21. import { lazy } from 'react';
  22. import { notifyActionError } from 'utils/CommonFunction';
  23. import axios from "axios";
  24. import {FormattedMessage, useIntl} from "react-intl";
  25. import usePageTitle from "components/usePageTitle";
  26. import { PRIMARY_CONTAINED_BUTTON_SX } from "themes/colorConst";
  27. const CustomFormWizard = Loadable(lazy(() => import('./auth-forms/CustomFormWizard')));
  28. const AuthWrapper = Loadable(lazy(() => import('./AuthWrapperCustom')));
  29. // ================================|| REGISTER ||================================ //
  30. const Register = () => {
  31. const [activeStep, setActiveStep] = useState(0);
  32. const [completed, setCompleted] = useState([false]);
  33. const [updateValid, setUpdateValid] = useState(false);
  34. const step0GuardRef = useRef(null);
  35. const [username, setUsername] = useState("");
  36. const [base64Url, setBase64Url] = useState("")
  37. const [checkCode, setCheckCode] = useState("")
  38. const [isNextBusy, setIsNextBusy] = useState(false);
  39. const [registrationComplete, setRegistrationComplete] = useState(false);
  40. const nextBusyRef = useRef(false);
  41. const intl = useIntl();
  42. // Localized document title/meta for register flow
  43. usePageTitle("register");
  44. const steps = [
  45. intl.formatMessage({id: 'personalInformation'}),
  46. intl.formatMessage({id: 'preview'}),
  47. intl.formatMessage({id: 'finishSubmission'})
  48. ];
  49. const totalSteps = () => {
  50. return steps.length;
  51. };
  52. const completedSteps = () => {
  53. return Object.keys(completed).length;
  54. };
  55. const isLastStep = () => {
  56. return activeStep === totalSteps() - 1;
  57. };
  58. const allStepsCompleted = () => {
  59. return completedSteps() === totalSteps();
  60. };
  61. const handleCheckUsername = async () => {
  62. const response = await axios.post(`${POST_USERNAME}`, {
  63. u1: username,
  64. })
  65. return Number(response.data[0]) > 0
  66. }
  67. const handleCaptcha = async () => {
  68. const response = await axios.post(`${POST_VERIFY_CAPTCHA}`, {
  69. captcha: base64Url,
  70. checkCode: checkCode,
  71. })
  72. return Boolean(response.data["success"]);
  73. }
  74. const handleNext = async () => {
  75. if (nextBusyRef.current) return;
  76. nextBusyRef.current = true;
  77. setIsNextBusy(true);
  78. try {
  79. if (activeStep === 0 && step0GuardRef.current) {
  80. const step0Ok = await Promise.resolve(step0GuardRef.current());
  81. if (!step0Ok) {
  82. return;
  83. }
  84. }
  85. const captchaTest = await handleCaptcha();
  86. if (!captchaTest) {
  87. notifyActionError(intl.formatMessage({id: 'validVerify'}))
  88. return;
  89. }
  90. const test = await handleCheckUsername()
  91. if (test) {
  92. notifyActionError(intl.formatMessage({id: 'usernameTaken'}))
  93. } else {
  94. const newActiveStep =
  95. isLastStep() && !allStepsCompleted()
  96. ? // It's the last step, but not all steps have been completed,
  97. // find the first step that has been completed
  98. steps.findIndex((step, i) => !(i in completed))
  99. : activeStep + 1;
  100. setActiveStep(newActiveStep);
  101. scrollToTop();
  102. }
  103. } finally {
  104. nextBusyRef.current = false;
  105. setIsNextBusy(false);
  106. }
  107. };
  108. const handleBack = () => {
  109. scrollToTop();
  110. setActiveStep((prevActiveStep) => prevActiveStep - 1);
  111. };
  112. const scrollToTop = () => {
  113. window.scrollTo(0, 0);
  114. };
  115. const handleReset = () => {
  116. setActiveStep(0);
  117. setCompleted({});
  118. setRegistrationComplete(false);
  119. };
  120. const isStepCompleted = (index) => index < activeStep || registrationComplete;
  121. return (
  122. // <AuthWrapper>
  123. <Stack sx={{ width: '100%', fontSize: '2rem', paddingTop: '35px', bgcolor: 'backgroundColor.default' }} alignItems="center">
  124. <Stepper activeStep={activeStep} sx={registerStepStyle}>
  125. {steps.map((label, index) => (
  126. <Step key={label} completed={isStepCompleted(index)} readOnly={true}>
  127. <StepButton
  128. aria-current={activeStep === index ? 'step' : undefined}
  129. >
  130. <StepLabel
  131. StepIconComponent={RegisterStepIcon}
  132. sx={{
  133. flexDirection: 'column',
  134. "& .MuiStepLabel-iconContainer": { paddingRight: 0 }
  135. }}
  136. >
  137. <Typography variant="step1">{label}</Typography>
  138. </StepLabel>
  139. </StepButton>
  140. </Step>
  141. ))}
  142. </Stepper>
  143. {allStepsCompleted() ? (
  144. <React.Fragment>
  145. <Typography variant="h4" sx={{ mt: 2, mb: 1 }}>
  146. All steps completed - you&apos;re finished
  147. </Typography>
  148. <Stack direction="row" sx={{ pt: 2 }}>
  149. <Stack sx={{ flex: '1 1 auto' }} />
  150. <Button onClick={handleReset}><Typography variant="h5">Reset</Typography></Button>
  151. </Stack>
  152. </React.Fragment>
  153. ) : (
  154. <React.Fragment>
  155. <AuthWrapper>
  156. <CustomFormWizard
  157. setUpdateValid={setUpdateValid}
  158. step0GuardRef={step0GuardRef}
  159. step={activeStep}
  160. setUsername={setUsername}
  161. setBase64Url={setBase64Url}
  162. setCheckCode={setCheckCode}
  163. onRegistrationComplete={() => setRegistrationComplete(true)}
  164. />
  165. {/* <CustomFormWizard step={activeStep} /> */}
  166. </AuthWrapper>
  167. <Stack direction="row" sx={{ pb: 2, mt:-4, mb:2 }}>
  168. {activeStep === 2 || activeStep === 0 ? (
  169. <Button
  170. color="inherit"
  171. disabled={true}
  172. onClick={handleBack}
  173. sx={{ mr: 1 }}
  174. variant="h5"
  175. >
  176. <Typography variant="h5">
  177. <FormattedMessage id="back"/>
  178. </Typography>
  179. </Button>
  180. ) : (
  181. <Button
  182. color="inherit"
  183. disabled={activeStep === 0 || isNextBusy}
  184. onClick={handleBack}
  185. sx={{ mr: 1 }}
  186. variant="h5"
  187. >
  188. <Typography variant="h5">
  189. <FormattedMessage id="back"/>
  190. </Typography>
  191. </Button>
  192. )
  193. }
  194. <Stack sx={{ flex: '1 1 auto' }} />
  195. {activeStep === totalSteps() - 2 ?
  196. (
  197. <Button
  198. variant="contained"
  199. disabled={isNextBusy}
  200. onClick={handleNext}
  201. aria-busy={isNextBusy}
  202. sx={{ mr: 1, minWidth: 120, ...PRIMARY_CONTAINED_BUTTON_SX }}
  203. >
  204. {isNextBusy ? (
  205. <CircularProgress size={22} color="inherit" aria-hidden />
  206. ) : (
  207. <Typography variant="h5" sx={{ color: 'inherit' }}>
  208. <FormattedMessage id="submit"/>
  209. </Typography>
  210. )}
  211. </Button>
  212. ) : (activeStep === totalSteps() - 1 ?
  213. (
  214. <Button variant="contained" color="inherit"
  215. disabled={true} sx={{ mr: 1, ...PRIMARY_CONTAINED_BUTTON_SX }}>
  216. <Typography variant="h5" sx={{ color: 'inherit' }}>
  217. <FormattedMessage id="submit"/>
  218. </Typography>
  219. </Button>
  220. ) :
  221. (
  222. // <Button disabled={updateValid} variant="outlined" onClick={handleNext} sx={{ mr: 1 }}>
  223. <Button disabled={!updateValid || isNextBusy} variant="contained" onClick={handleNext} sx={{ mr: 1, ...PRIMARY_CONTAINED_BUTTON_SX }}>
  224. <Typography variant="h5" sx={{ color: 'inherit' }}>
  225. <FormattedMessage id="continue"/>
  226. </Typography>
  227. </Button>
  228. )
  229. )}
  230. {/* {activeStep !== steps.length &&
  231. (completed[activeStep] ? (
  232. <Typography variant="caption" sx={{ display: 'inline-block' }}>
  233. Step {activeStep + 1} already completed
  234. </Typography>
  235. ) : (
  236. <Button onClick={handleComplete}>
  237. {completedSteps() === totalSteps() - 1
  238. ? 'Finish'
  239. : 'Complete Step'}
  240. </Button>
  241. ))} */}
  242. </Stack>
  243. </React.Fragment>
  244. )}
  245. </Stack >
  246. // </AuthWrapper>
  247. );
  248. };
  249. export default Register;