| @@ -165,15 +165,25 @@ const BusCustomFormWizard = (props) => { | |||
| } | |||
| } | |||
| /** POST /user/checkE1 — returns true if email is already registered */ | |||
| const checkEmailRegistered = async (emailStr) => { | |||
| const em = emailStr?.trim(); | |||
| if (!em) return false; | |||
| const response = await axios.post(`${POST_USER_EMAIL}`, { e1: em }); | |||
| return Number(response.data[0]) > 0; | |||
| }; | |||
| const handleCheckEmail = async () => { | |||
| if (values?.email) { | |||
| const response = await axios.post(`${POST_USER_EMAIL}`, { | |||
| e1: values.email, | |||
| }) | |||
| setCheckEmail((Number(response.data[0]) > 0)) | |||
| return Number(response.data[0]) > 0 | |||
| if (!values?.email) return false; | |||
| try { | |||
| const taken = await checkEmailRegistered(values.email); | |||
| setCheckEmail(taken); | |||
| return taken; | |||
| } catch (error) { | |||
| notifyActionError(intl.formatMessage({ id: 'connectionError' })); | |||
| return false; | |||
| } | |||
| } | |||
| }; | |||
| useEffect(() => { | |||
| if (username) { | |||
| @@ -266,7 +276,8 @@ const BusCustomFormWizard = (props) => { | |||
| }); | |||
| } | |||
| const computeStep0Valid = (data) => ( | |||
| /** Step-0 validity excluding duplicate-email result from /checkE1 (see checkEmail state). */ | |||
| const computeStep0ValidSync = (data) => ( | |||
| handleCaptcha(data.captchaField) && | |||
| data.username !== "" && | |||
| data.password !== "" && | |||
| @@ -291,10 +302,11 @@ const BusCustomFormWizard = (props) => { | |||
| handleUserName(data.username) && | |||
| handleBrNo(data.brNo) && | |||
| isDistrictSelectionValid() && | |||
| !checkUsername&& | |||
| !checkEmail | |||
| !checkUsername | |||
| ); | |||
| const computeStep0Valid = (data) => computeStep0ValidSync(data) && !checkEmail; | |||
| const checkDataField = (data) => { | |||
| const can = computeStep0Valid(data); | |||
| setisValid(can); | |||
| @@ -653,15 +665,31 @@ const BusCustomFormWizard = (props) => { | |||
| useEffect(() => { | |||
| if (!props.step0GuardRef) return; | |||
| props.step0GuardRef.current = () => { | |||
| const can = computeStep0Valid(values); | |||
| setisValid(can); | |||
| if (!can && !isDistrictSelectionValid()) { | |||
| setDistrictErrStr(getRequiredErrStr("district")); | |||
| setCheckDistrict(true); | |||
| notifyActionError(intl.formatMessage({ id: 'require' }, { fieldname: intl.formatMessage({ id: 'district' }) })); | |||
| props.step0GuardRef.current = async () => { | |||
| const syncOk = computeStep0ValidSync(values); | |||
| if (!syncOk) { | |||
| setisValid(false); | |||
| if (!isDistrictSelectionValid()) { | |||
| setDistrictErrStr(getRequiredErrStr("district")); | |||
| setCheckDistrict(true); | |||
| notifyActionError(intl.formatMessage({ id: 'require' }, { fieldname: intl.formatMessage({ id: 'district' }) })); | |||
| } | |||
| return false; | |||
| } | |||
| return can; | |||
| try { | |||
| const taken = await checkEmailRegistered(values.email); | |||
| setCheckEmail(taken); | |||
| if (taken) { | |||
| setisValid(false); | |||
| notifyActionError(intl.formatMessage({ id: 'emailUsed' })); | |||
| return false; | |||
| } | |||
| } catch (error) { | |||
| notifyActionError(intl.formatMessage({ id: 'connectionError' })); | |||
| return false; | |||
| } | |||
| setisValid(true); | |||
| return true; | |||
| }; | |||
| }, [values, selectedAddress4, selectedAddress5, termsAndConAccept, fileList, checkUsername, checkEmail]); | |||
| @@ -1262,7 +1290,7 @@ const BusCustomFormWizard = (props) => { | |||
| <Grid container> | |||
| <Grid item xs={12} md={6}> | |||
| <Stack spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}> | |||
| <InputLabel htmlFor="email-signup"> | |||
| <InputLabel htmlFor="email-login"> | |||
| <Typography variant="pnspsFormHeader"> | |||
| <FormattedMessage id="userContactEmail"/> | |||
| <span style={{ color: '#B00020' }}>*</span> | |||
| @@ -1271,7 +1299,7 @@ const BusCustomFormWizard = (props) => { | |||
| <OutlinedInput | |||
| fullWidth | |||
| error={Boolean((formik.touched.email && formik.errors.email) || checkEmail)} | |||
| id="email-signup" | |||
| id="email-login" | |||
| type="email" | |||
| value={formik.values.email.trim()} | |||
| name="email" | |||
| @@ -1302,7 +1330,7 @@ const BusCustomFormWizard = (props) => { | |||
| </Grid> | |||
| <Grid item xs={12} md={6}> | |||
| <Stack spacing={1} > | |||
| <InputLabel htmlFor="emailConfirm-signup"> | |||
| <InputLabel htmlFor="emailConfirm-login"> | |||
| <Typography variant="pnspsFormHeader"> | |||
| <FormattedMessage id="confirmEmail"/> | |||
| <span style={{ color: '#B00020' }}>*</span> | |||
| @@ -1311,7 +1339,7 @@ const BusCustomFormWizard = (props) => { | |||
| <OutlinedInput | |||
| fullWidth | |||
| error={Boolean(formik.touched.emailConfirm && formik.errors.emailConfirm)} | |||
| id="emailConfirm-signup" | |||
| id="emailConfirm-login" | |||
| type="email" | |||
| value={formik.values.emailConfirm.trim()} | |||
| name="emailConfirm" | |||
| @@ -218,17 +218,26 @@ const CustomFormWizard = (props) => { | |||
| } | |||
| } | |||
| /** POST /user/checkE1 — returns true if email is already registered */ | |||
| const checkEmailRegistered = async (emailStr) => { | |||
| const em = emailStr?.trim(); | |||
| if (!em) return false; | |||
| const response = await axios.post(`${POST_USER_EMAIL}`, { e1: em }); | |||
| return Number(response.data[0]) > 0; | |||
| }; | |||
| const handleCheckEmail = async () => { | |||
| if (values?.email) { | |||
| if(handleEmail(values.email)){ | |||
| const response = await axios.post(`${POST_USER_EMAIL}`, { | |||
| e1: values.email, | |||
| }) | |||
| setCheckEmail((Number(response.data[0]) > 0)) | |||
| return Number(response.data[0]) > 0 | |||
| } | |||
| if (!values?.email) return false; | |||
| if (!handleEmail(values.email)) return false; | |||
| try { | |||
| const taken = await checkEmailRegistered(values.email); | |||
| setCheckEmail(taken); | |||
| return taken; | |||
| } catch (error) { | |||
| notifyActionError(intl.formatMessage({ id: 'connectionError' })); | |||
| return false; | |||
| } | |||
| } | |||
| }; | |||
| const isDistrictSelectionValid = () => { | |||
| if (selectedAddress5?.type !== "hongKong") { | |||
| @@ -358,7 +367,8 @@ const CustomFormWizard = (props) => { | |||
| }); | |||
| } | |||
| const computeStep0Valid = (data) => ( | |||
| /** Step-0 validity excluding duplicate-email result from /checkE1 (see checkEmail state). */ | |||
| const computeStep0ValidSync = (data) => ( | |||
| handleCaptcha(data.captchaField) && | |||
| data.username !== "" && | |||
| data.password !== "" && | |||
| @@ -382,10 +392,11 @@ const CustomFormWizard = (props) => { | |||
| handleUsername(data.username) && | |||
| isDistrictSelectionValid() && | |||
| !checkUsername && | |||
| !checkEmail && | |||
| !checkIdDocNumber | |||
| ); | |||
| const computeStep0Valid = (data) => computeStep0ValidSync(data) && !checkEmail; | |||
| const checkDataField = (data) => { | |||
| const can = computeStep0Valid(data); | |||
| setisValid(can); | |||
| @@ -875,15 +886,31 @@ const CustomFormWizard = (props) => { | |||
| useEffect(() => { | |||
| if (!props.step0GuardRef) return; | |||
| props.step0GuardRef.current = () => { | |||
| const can = computeStep0Valid(values); | |||
| setisValid(can); | |||
| if (!can && !isDistrictSelectionValid()) { | |||
| setDistrictErrStr(getRequiredErrStr("district")); | |||
| setCheckDistrict(true); | |||
| notifyActionError(intl.formatMessage({ id: 'require' }, { fieldname: intl.formatMessage({ id: 'district' }) })); | |||
| props.step0GuardRef.current = async () => { | |||
| const syncOk = computeStep0ValidSync(values); | |||
| if (!syncOk) { | |||
| setisValid(false); | |||
| if (!isDistrictSelectionValid()) { | |||
| setDistrictErrStr(getRequiredErrStr("district")); | |||
| setCheckDistrict(true); | |||
| notifyActionError(intl.formatMessage({ id: 'require' }, { fieldname: intl.formatMessage({ id: 'district' }) })); | |||
| } | |||
| return false; | |||
| } | |||
| return can; | |||
| try { | |||
| const taken = await checkEmailRegistered(values.email); | |||
| setCheckEmail(taken); | |||
| if (taken) { | |||
| setisValid(false); | |||
| notifyActionError(intl.formatMessage({ id: 'emailUsed' })); | |||
| return false; | |||
| } | |||
| } catch (error) { | |||
| notifyActionError(intl.formatMessage({ id: 'connectionError' })); | |||
| return false; | |||
| } | |||
| setisValid(true); | |||
| return true; | |||
| }; | |||
| }, [values, selectedAddress4, selectedAddress5, termsAndConAccept, fileList, checkUsername, checkEmail, checkIdDocNumber, selectedIdDocType]); | |||
| @@ -1589,7 +1616,7 @@ const CustomFormWizard = (props) => { | |||
| <Grid container> | |||
| <Grid item xs={12} md={6}> | |||
| <Stack spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}> | |||
| <InputLabel htmlFor="email-signup"> | |||
| <InputLabel htmlFor="email-login"> | |||
| <Typography variant="pnspsFormHeader"> | |||
| <FormattedMessage id="userContactEmail" /> | |||
| <span style={{ color: '#B00020' }}>*</span> | |||
| @@ -1598,7 +1625,7 @@ const CustomFormWizard = (props) => { | |||
| <OutlinedInput | |||
| fullWidth | |||
| error={Boolean((formik.touched.email && formik.errors.email) || checkEmail)} | |||
| id="email-signup" | |||
| id="email-login" | |||
| type="email" | |||
| value={formik.values.email.trim()} | |||
| name="email" | |||
| @@ -1629,7 +1656,7 @@ const CustomFormWizard = (props) => { | |||
| </Grid> | |||
| <Grid item xs={12} md={6}> | |||
| <Stack spacing={1} > | |||
| <InputLabel htmlFor="emailConfirm-signup"> | |||
| <InputLabel htmlFor="emailConfirm-login"> | |||
| <Typography variant="pnspsFormHeader"> | |||
| <FormattedMessage id="confirmEmail" /> | |||
| <span style={{ color: '#B00020' }}>*</span> | |||
| @@ -1638,7 +1665,7 @@ const CustomFormWizard = (props) => { | |||
| <OutlinedInput | |||
| fullWidth | |||
| error={Boolean(formik.touched.emailConfirm && formik.errors.emailConfirm)} | |||
| id="emailConfirm-signup" | |||
| id="emailConfirm-login" | |||
| type="email" | |||
| value={formik.values.emailConfirm.trim()} | |||
| name="emailConfirm" | |||
| @@ -781,7 +781,7 @@ const CustomFormWizard = (props) => { | |||
| <Grid container> | |||
| <Grid item xs={12} md={6}> | |||
| <Stack spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}> | |||
| <InputLabel htmlFor="email-signup"> | |||
| <InputLabel htmlFor="email-login"> | |||
| <Typography variant="h5"> | |||
| <FormattedMessage id="userContactEmail" /> | |||
| <span style={{ color: '#B00020' }}>*</span> | |||
| @@ -827,7 +827,7 @@ const CustomFormWizard = (props) => { | |||
| </Grid> | |||
| <Grid item xs={12} md={6}> | |||
| <Stack spacing={1} > | |||
| <InputLabel htmlFor="emailConfirm-signup"> | |||
| <InputLabel htmlFor="emailConfirm-login"> | |||
| <Typography variant="h5"> | |||
| <FormattedMessage id="confirmEmail" /> | |||
| <span style={{ color: '#B00020' }}>*</span> | |||