From cd9016ad4485e9e019ec70be26622cfaa652b71c Mon Sep 17 00:00:00 2001 From: Alex Cheung Date: Wed, 30 Aug 2023 07:00:06 +0800 Subject: [PATCH] update form validation --- package-lock.json | 11 + package.json | 1 + src/pages/authentication/BusRegister.js | 11 +- src/pages/authentication/Register.js | 18 +- .../auth-forms/BusCustomFormWizard.js | 210 +++++++++---- .../auth-forms/CustomFormWizard.js | 276 +++++++++++------- .../auth-forms/UploadFileTable.js | 2 +- yarn.lock | 5 + 8 files changed, 353 insertions(+), 181 deletions(-) diff --git a/package-lock.json b/package-lock.json index 571498c..b01ac7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@mui/lab": "^5.0.0-alpha.139", "@mui/material": "^5.10.6", "@mui/x-data-grid": "^6.11.1", + "@mui/x-date-pickers": "^6.12.0", "@reduxjs/toolkit": "^1.8.5", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", @@ -48,6 +49,7 @@ "react-router-dom": "^6.4.1", "react-scripts": "^5.0.1", "react-syntax-highlighter": "^15.5.0", + "react-to-print": "^2.14.13", "react-window": "^1.8.7", "redux": "^4.2.0", "simplebar": "^5.3.8", @@ -18407,6 +18409,15 @@ "react": ">= 0.14.0" } }, + "node_modules/react-to-print": { + "version": "2.14.13", + "resolved": "https://registry.npmjs.org/react-to-print/-/react-to-print-2.14.13.tgz", + "integrity": "sha512-PqUGgTRZvkyBzWgaZHVBECWPX2nGEc3HOUy6WNXof6HT4yTFI92wtIkqQtr4jfvHbadqjwTgzgh6vgN8KXlWWw==", + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-transition-group": { "version": "4.4.5", "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", diff --git a/package.json b/package.json index 66b897b..b66f8c1 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "react-router-dom": "^6.4.1", "react-scripts": "^5.0.1", "react-syntax-highlighter": "^15.5.0", + "react-to-print": "^2.14.13", "react-window": "^1.8.7", "redux": "^4.2.0", "simplebar": "^5.3.8", diff --git a/src/pages/authentication/BusRegister.js b/src/pages/authentication/BusRegister.js index 97de330..4cd86b0 100644 --- a/src/pages/authentication/BusRegister.js +++ b/src/pages/authentication/BusRegister.js @@ -48,11 +48,7 @@ const BusRegister = () => { const [activeStep, setActiveStep] = useState(0); const [completed, setCompleted] = useState([false]); - - const uploadStep = (value) => { - setActiveStep(value); - console.log(value) - }; + const [updateValid, setUpdateValid] = useState(false); const totalSteps = () => { return steps.length; @@ -71,7 +67,6 @@ }; const handleNext = () => { - console.log("test 1") const newActiveStep = isLastStep() && !allStepsCompleted() ? // It's the last step, but not all steps have been completed, @@ -140,7 +135,7 @@ ) : ( - + {/* */} @@ -178,7 +173,7 @@ ): ( - ) diff --git a/src/pages/authentication/Register.js b/src/pages/authentication/Register.js index fba488d..0e671dc 100644 --- a/src/pages/authentication/Register.js +++ b/src/pages/authentication/Register.js @@ -1,5 +1,7 @@ // import { Link } from 'react-router-dom'; - import React,{useState} from 'react'; + import React,{useState + // ,useEffect + } from 'react'; // material-ui import { @@ -48,11 +50,7 @@ const Register = () => { const [activeStep, setActiveStep] = useState(0); const [completed, setCompleted] = useState([false]); - - const uploadStep = (value) => { - setActiveStep(value); - console.log(value) - }; + const [updateValid, setUpdateValid] = useState(false); const totalSteps = () => { return steps.length; @@ -71,7 +69,6 @@ }; const handleNext = () => { - console.log("test 1") const newActiveStep = isLastStep() && !allStepsCompleted() ? // It's the last step, but not all steps have been completed, @@ -80,6 +77,7 @@ : activeStep + 1; setActiveStep(newActiveStep); console.log(newActiveStep) + }; const handleBack = () => { @@ -140,11 +138,11 @@ ) : ( - + {/* */} - { activeStep === totalSteps() - 1 ? ( + { activeStep === 2|| activeStep === 0? ( ) diff --git a/src/pages/authentication/auth-forms/BusCustomFormWizard.js b/src/pages/authentication/auth-forms/BusCustomFormWizard.js index 2fca667..a8446aa 100644 --- a/src/pages/authentication/auth-forms/BusCustomFormWizard.js +++ b/src/pages/authentication/auth-forms/BusCustomFormWizard.js @@ -21,7 +21,7 @@ import Autocomplete from "@mui/material/Autocomplete"; // third party import { useFormik,FormikProvider } from 'formik'; -import * as Yup from 'yup'; +import * as yup from 'yup'; // import axios from "axios"; // project import @@ -49,7 +49,6 @@ const BusCustomFormWizard = (props) => { const [showConfirmPassword, setshowConfirmPassword] = useState(false); const [fileList, setFileList] = useState([]); const [fileListData, setFileListData] = useState([]); - const [uploadStep, setUploadStep] = useState(0); const [checkUpload, setCheckUpload] = useState(false); const handleClickShowPassword = () => { @@ -72,33 +71,49 @@ const BusCustomFormWizard = (props) => { const [selectedAddress5, setSelectedAddress5] = useState("香港"); const [termsAndConAccept, setTermsAndConAccept] = useState(false); const [termsAndConNotAccept, setTermsAndConNotAccept] = useState(false); + const [isValid, setisValid] = useState(false); const address4ComboList = ["北區","長洲區","大埔區","大嶼山區","東區","觀塘區","黃大仙區","九龍城區","葵青區","南區","南丫島區", "坪洲區","荃灣區","沙田區","深水埗區","屯門區","灣仔區","西貢區","油尖旺區","元朗區","中西區"]; const address5ComboList = ["香港","內地","澳門"]; - const termsAndCon = "Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n"+"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" + const termsAndCon = "此網址由香港特別行政區政府物流服務署製作及管理。本署會盡力確保網址上的資料無誤,\n" + + "但有絕對酌情權隨時刪除、暫停登載或編輯各項資料而無須給予任何理由。\n由於任何與網址" + + "內資料有關的理由或原因,而導致出現申索、損失或損害,本署概不負責。\n使用者須自行評" + + "估本網址所載或與本網址有關連的各項資料,並應在根據該等資料行事前,參照印行的香港" + + "特別行政區憲報以核實該等資料,以及徵詢獨立意見。\n版權公告本網頁的內容,包括但不限" + + "於所有文本、平面圖像、圖畫、圖片、照片以及數據或其他資料的匯編,均受版權保障。\n香" + + "港特別行政區政府是本網頁內所有版權作品的擁有人,除非預先得到政府物流服務署的書面" + + "授權,否則嚴禁複製、改編、分發、發布或向公眾提供該等版權作品。" useEffect(() => { changePassword(''); }, []); const checkDataField = (data)=> { - if (data.username !=="", - data.password !=="", - data.enName !=="", - data.email !=="", - data.password !=="", - data.password !=="" + if (data.username !==""&& + data.password !==""&& + data.confirmPassword !==""&& + data.password == data.confirmPassword&& + data.enCompanyName !==""&& + data.enName !==""&& + data.address1 !==""&& + data.email !==""&& + data.emailConfirm !==""&& + data.phone !==""&& + data.phoneCountryCode !==""&& + termsAndConAccept == true&& + fileList.length!==0&& + handlePassword(data.password)&& + handleEmail(data.email)&& + handlePhone(data.phone) ) { - return true + setisValid(true) + return isValid + }else{ + setisValid(false) + return isValid } }; @@ -133,9 +148,17 @@ const BusCustomFormWizard = (props) => { setFileList(uploadFileList); }; + useEffect(() => { + props.setUpdateValid(isValid) + }, [isValid]) + + useEffect(() => { + checkDataField(values) + }, [selectedAddress4,selectedAddress5, + termsAndConAccept,termsAndConNotAccept,fileList]) + useEffect(() => { props.step ==2?_onSubmit():null; - setUploadStep(props.step) }, [props.step]) const {handleSubmit} = useForm({}) @@ -147,20 +170,14 @@ const BusCustomFormWizard = (props) => { "addressLine1":"", "addressLine2":"", "addressLine3":"", + "district":"", "country":"" }; - - if (values.address5=='香港'){ - busUserAddress.addressLine1 = values.address1 - busUserAddress.addressLine2 = values.address2 - busUserAddress.addressLine3 = values.address3 - busUserAddress.country = values.address5 - }else{ - busUserAddress.addressLine1 = values.address1 - busUserAddress.addressLine2 = values.address2 - busUserAddress.addressLine3 = values.address4 - busUserAddress.country = values.address5 - } + busUserAddress.addressLine1 = values.address1 + busUserAddress.addressLine2 = values.address2 + busUserAddress.addressLine3 = values.address3 + busUserAddress.district = values.address4 + busUserAddress.country = values.address5 const userFaxNo = { "countryCode":values.faxCountryCode, @@ -178,7 +195,7 @@ const BusCustomFormWizard = (props) => { tncFlag = false } - if (checkDataField(values)){ + if (isValid){ axios.post(`${apiPath}${POST_PUBLIC_USER_REGISTER}`, { username: values.username, password: values.password, @@ -188,7 +205,7 @@ const BusCustomFormWizard = (props) => { emailBus: values.email, brNo:values.brNo, brExpiryDate:values.brExpiryDate, - faxNo:userFaxNo, + userFaxNo:userFaxNo, busUserContactTel:busUserContactTel, busUserAddress:busUserAddress, contactPerson: values.enName, @@ -215,6 +232,43 @@ const BusCustomFormWizard = (props) => { } } + function handlePhone(phone) { + if (phone.length < 8) { + return false; + } else { + return true; + } + } + + function handlePassword(password) { + let new_pass = password; + // regular expressions to validate password + var lowerCase = /[a-z]/g; + var upperCase = /[A-Z]/g; + var numbers = /[0-9]/g; + if (!new_pass.match(lowerCase)) { + return false; + } else if (!new_pass.match(upperCase)) { + return false; + } else if (!new_pass.match(numbers)) { + return false; + } else if (new_pass.length < 8) { + return false; + } else { + return true; + } + } + + function handleEmail(email) { + var reg = /^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$/; + var result = reg.test(email); + + if (result == false) { + return false; + } + return true; + } + const formik = useFormik({ initialValues:({ username:'', @@ -235,34 +289,51 @@ const BusCustomFormWizard = (props) => { brExpiryDate:'', brNo:'', }), - validationSchema:Yup.object().shape({ - username: Yup.string().max(255).required('請輸入用戶名稱'), - password: Yup.string().max(255).required('請輸入密碼'), - confirmPassword: Yup.string().max(255).required('請確認密碼'), - enName: Yup.string().max(255).required('請輸入英文姓名'), - chName: Yup.string().max(255).required('請輸入中文姓名'), - address1: Yup.string().max(255).required('請輸入第一行地址'), - address2: Yup.string().max(255).required('請輸入第二行地址'), - address3: Yup.string().max(255).required('請輸入第三行地址'), - email: Yup.string().email('Must be a valid email').max(255).required('Email is required'), - idNo: Yup.string().max(255).required('請輸入證件號碼'), - checkDigit:Yup.string().max(1).required('請輸入證件號碼'), - idType: Yup.string().max(255).required('請輸入第三行地址')}) + validationSchema:yup.object().shape({ + username: yup.string().max(255).required('請輸入用戶名稱'), + password: yup.string().min(8,'請輸入最少8位密碼').required('請輸入密碼') + .matches(/^(?=.*[a-z])/, '請包括最少1個小寫字母') + .matches(/^(?=.*[A-Z])/, '請包括最少1個大寫字母') + .matches(/^(?=.*[0-9])/, '請包括最少1個數字') + .matches(/^(?=.*[!@#%&])/, '請包括最少1個特殊字符'), + confirmPassword: yup.string().min(8,'請最少輸入8位密碼').required('請確認密碼').oneOf([yup.ref('password'), null], '請輸入相同密碼'), + enName: yup.string().max(255).required('請輸入英文姓名'), + enCompanyName: yup.string().max(255).required('請輸入英文名稱'), + chName: yup.string().max(255).required('請輸入中文姓名'), + address1: yup.string().max(255).required('請輸入第一行地址'), + address2: yup.string().max(255).required('請輸入第二行地址'), + address3: yup.string().max(255).required('請輸入第三行地址'), + email: yup.string().email('請輸入電郵格式').max(255).required('請輸入電郵'), + emailConfirm: yup.string().email('請輸入電郵格式').max(255).required('請輸入電郵').oneOf([yup.ref('email'), null], '請輸入相同電郵'), + phoneCountryCode: yup.string().min(3,'請輸入3位數字').required('請輸入國際區號'), + faxCountryCode: yup.string().min(3,'請輸入3位數字'), + phone: yup.string().min(8,'請輸入8位數字').required('請輸入聯絡電話'), + fax: yup.string().min(8,'請輸入8位數字'), + brExpiryDate: yup.string().min(8,'請輸入商業登記證有效日期'), + brNo: yup.string().min(8,'請輸入商業登記證號碼'), + }) }); + const handleReset = (resetForm) => { + resetForm(); + setSelectedAddress4("") + }; + const { values } = formik useEffect(() => { + checkDataField(values) }, [values]) return (
{/* Input Form */} - + +
成為新的機構/公司用戶
@@ -289,6 +360,7 @@ const BusCustomFormWizard = (props) => { placeholder="用戶登入名稱" fullWidth error={Boolean(formik.touched.username && formik.errors.username)} + onBlur={formik.handleBlur} inputProps={{ onKeyDown: (e) => { if (e.key === 'Enter') { @@ -377,9 +449,10 @@ const BusCustomFormWizard = (props) => { type={showConfirmPassword ? 'text' : 'password'} value={formik.values.confirmPassword} name="confirmPassword" + onBlur={formik.handleBlur} onChange={(e) => { formik.handleChange(e); - changePassword(e.target.value); + // changePassword(e.target.value); }} inputProps={{ onKeyDown: (e) => { @@ -437,6 +510,7 @@ const BusCustomFormWizard = (props) => { placeholder="與與商業登記證相同如有" fullWidth error={Boolean(formik.touched.enCompanyName && formik.errors.enCompanyName)} + onBlur={formik.handleBlur} inputProps={{ onKeyDown: (e) => { if (e.key === 'Enter') { @@ -546,6 +620,7 @@ const BusCustomFormWizard = (props) => { name="address1" onChange={formik.handleChange} placeholder="第一行" + onBlur={formik.handleBlur} inputProps={{ onKeyDown: (e) => { if (e.key === 'Enter') { @@ -650,6 +725,7 @@ const BusCustomFormWizard = (props) => { placeholder="與你的身份證明文件相同" fullWidth error={Boolean(formik.touched.enName && formik.errors.enName)} + onBlur={formik.handleBlur} inputProps={{ onKeyDown: (e) => { if (e.key === 'Enter') { @@ -681,6 +757,7 @@ const BusCustomFormWizard = (props) => { name="email" onChange={formik.handleChange} placeholder="電郵" + onBlur={formik.handleBlur} inputProps={{ onKeyDown: (e) => { if (e.key === 'Enter') { @@ -711,6 +788,7 @@ const BusCustomFormWizard = (props) => { // onBlur={formik.handleBlur} onChange={formik.handleChange} placeholder="確認電郵" + onBlur={formik.handleBlur} inputProps={{ onKeyDown: (e) => { if (e.key === 'Enter') { @@ -747,6 +825,7 @@ const BusCustomFormWizard = (props) => { onChange={formik.handleChange} placeholder="eg:852" error={Boolean(formik.touched.phone && formik.errors.phone)} + onBlur={formik.handleBlur} inputProps={{ maxLength: 3, onKeyDown: (e) => { @@ -762,7 +841,7 @@ const BusCustomFormWizard = (props) => { type="phone" value={formik.values.phone} name="phone" - // onBlur={formik.handleBlur} + onBlur={formik.handleBlur} onChange={formik.handleChange} placeholder="聯絡電話" error={Boolean(formik.touched.phone && formik.errors.phone)} @@ -776,12 +855,12 @@ const BusCustomFormWizard = (props) => { }} sx={{width:'75%'}} /> - {formik.touched.phone && formik.errors.phone && ( - - {formik.errors.phone} - - )}
+ {formik.touched.phone && formik.errors.phone && ( + + {formik.errors.phone} + + )}
@@ -925,7 +1004,7 @@ const BusCustomFormWizard = (props) => {
{/* Preview Form */} - + @@ -984,7 +1063,7 @@ const BusCustomFormWizard = (props) => { - 商業登記證: + 商業登記證 @@ -1019,17 +1098,23 @@ const BusCustomFormWizard = (props) => { {formik.values.address1} - - {formik.values.address2} - + {formik.values.address2!=null? + + {formik.values.address2} + + :null} + {formik.values.address3!=null? {formik.values.address3} - - {formik.values.address4} - + :null} + {selectedAddress5==("香港")? + + 區域 (只適用於香港): {selectedAddress4} + + :null} - {formik.values.address5} + 國家/地區: {selectedAddress5} @@ -1085,13 +1170,12 @@ const BusCustomFormWizard = (props) => { {/* Submit page */} - + {checkUpload? // SUCCESS page - {/* */} 完成申請,請登入帳戶 diff --git a/src/pages/authentication/auth-forms/CustomFormWizard.js b/src/pages/authentication/auth-forms/CustomFormWizard.js index d1a6f01..f46aa69 100644 --- a/src/pages/authentication/auth-forms/CustomFormWizard.js +++ b/src/pages/authentication/auth-forms/CustomFormWizard.js @@ -48,7 +48,6 @@ const CustomFormWizard = (props) => { const [showConfirmPassword, setshowConfirmPassword] = useState(false); const [fileList, setFileList] = useState([]); const [fileListData, setFileListData] = useState([]); - const [uploadStep, setUploadStep] = useState(0); const [checkUpload, setCheckUpload] = useState(false); const handleClickShowPassword = () => { @@ -72,39 +71,56 @@ const CustomFormWizard = (props) => { const [selectedAddress5, setSelectedAddress5] = useState("香港"); const [termsAndConAccept, setTermsAndConAccept] = useState(false); const [termsAndConNotAccept, setTermsAndConNotAccept] = useState(false); - + const [isValid, setisValid] = useState(false); + const idDocTypeComboList = ["passport","HKID","CNID","BR","otherCert"]; const address4ComboList = ["北區","長洲區","大埔區","大嶼山區","東區","觀塘區","黃大仙區","九龍城區","葵青區","南區","南丫島區", "坪洲區","荃灣區","沙田區","深水埗區","屯門區","灣仔區","西貢區","油尖旺區","元朗區","中西區"]; const address5ComboList = ["香港","內地","澳門"]; - const termsAndCon = "Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n"+"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" - +"Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy Dummy \n" + const termsAndCon = "此網址由香港特別行政區政府物流服務署製作及管理。本署會盡力確保網址上的資料無誤,\n" + + "但有絕對酌情權隨時刪除、暫停登載或編輯各項資料而無須給予任何理由。\n由於任何與網址" + + "內資料有關的理由或原因,而導致出現申索、損失或損害,本署概不負責。\n使用者須自行評" + + "估本網址所載或與本網址有關連的各項資料,並應在根據該等資料行事前,參照印行的香港" + + "特別行政區憲報以核實該等資料,以及徵詢獨立意見。\n版權公告本網頁的內容,包括但不限" + + "於所有文本、平面圖像、圖畫、圖片、照片以及數據或其他資料的匯編,均受版權保障。\n香" + + "港特別行政區政府是本網頁內所有版權作品的擁有人,除非預先得到政府物流服務署的書面" + + "授權,否則嚴禁複製、改編、分發、發布或向公眾提供該等版權作品。" useEffect(() => { changePassword(''); }, []); const checkDataField = (data)=> { - if (data.username !=="", - data.password !=="", - data.enName !=="", - data.email !=="", - data.password !=="", - data.password !=="" + if (data.username !==""&& + data.password !==""&& + data.confirmPassword !==""&& + data.password == data.confirmPassword&& + selectedIdDocType !==""&& + data.idNo !==""&& + data.enName !==""&& + data.address1 !==""&& + data.email !==""&& + data.emailConfirm !==""&& + data.phone !==""&& + data.phoneCountryCode !==""&& + termsAndConAccept == true&& + fileList.length!==0&& + handlePassword(data.password)&& + handleEmail(data.email)&& + handleIdNo(data.idNo,selectedIdDocType)&& + handlePhone(data.phone) ) { - return true + setisValid(true) + return isValid + }else{ + setisValid(false) + return isValid } }; const handleCheckBoxChange = (event) => { - console.log (event.target) if(event.target.name == 'termsAndConAccept'){ setTermsAndConAccept(event.target.checked) setTermsAndConNotAccept(!event.target.checked) @@ -134,9 +150,17 @@ const CustomFormWizard = (props) => { setFileList(uploadFileList); }; + useEffect(() => { + props.setUpdateValid(isValid) + }, [isValid]) + + useEffect(() => { + checkDataField(values) + }, [selectedIdDocType,selectedAddress4,selectedAddress5, + termsAndConAccept,termsAndConNotAccept,fileList]) + useEffect(() => { props.step ==2?_onSubmit():null; - setUploadStep(props.step) }, [props.step]) const {handleSubmit} = useForm({}) @@ -144,26 +168,19 @@ const CustomFormWizard = (props) => { values.idDocType = selectedIdDocType values.address4 = selectedAddress4 values.address5 = selectedAddress5 - console.log(values) const userAddress = { "addressLine1":"", "addressLine2":"", "addressLine3":"", + "district":"", "country":"" }; - - if (values.address5=='香港'){ - userAddress.addressLine1 = values.address1 - userAddress.addressLine2 = values.address2 - userAddress.addressLine3 = values.address3 - userAddress.country = values.address5 - }else{ - userAddress.addressLine1 = values.address1 - userAddress.addressLine2 = values.address2 - userAddress.addressLine3 = values.address4 - userAddress.country = values.address5 - } - + userAddress.addressLine1 = values.address1 + userAddress.addressLine2 = values.address2 + userAddress.addressLine3 = values.address3 + userAddress.district = values.address4 + userAddress.country = values.address5 + const userFaxNo = { "countryCode":values.faxCountryCode, "faxNumber":values.fax, @@ -179,8 +196,8 @@ const CustomFormWizard = (props) => { if (termsAndConNotAccept){ tncFlag = false } - - if (checkDataField(values)){ + + if (isValid){ axios.post(`${apiPath}${POST_PUBLIC_USER_REGISTER}`, { username: values.username, password: values.password, @@ -217,12 +234,62 @@ const CustomFormWizard = (props) => { } } + function handlePhone(phone) { + if (phone.length < 8) { + return false; + } else { + return true; + } + } + + function handleIdNo(idNo,selectedIdDocType) { + var upperCase = /[A-Z]/g; + if (!idNo.match(upperCase)&&selectedIdDocType=="HKID") { + return false; + } + else if (idNo.length < 7) { + return false; + } else { + return true; + } + } + + function handlePassword(password) { + let new_pass = password; + // regular expressions to validate password + var lowerCase = /[a-z]/g; + var upperCase = /[A-Z]/g; + var numbers = /[0-9]/g; + if (!new_pass.match(lowerCase)) { + return false; + } else if (!new_pass.match(upperCase)) { + return false; + } else if (!new_pass.match(numbers)) { + return false; + } else if (new_pass.length < 8) { + return false; + } else { + return true; + } + } + + function handleEmail(email) { + var reg = /^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$/; + var result = reg.test(email); + + if (result == false) { + return false; + } + return true; + } + const formik = useFormik({ initialValues:({ username:'', enName: '', chName: '', email: '', + emailConfirm: '', address1: '', address2: '', address3: '', @@ -235,56 +302,58 @@ const CustomFormWizard = (props) => { submit: null, fax:'', faxCountryCode:'852', + idDocType:selectedIdDocType }), validationSchema:yup.object().shape({ username: yup.string().max(255).required('請輸入用戶名稱'), - password: yup.string().max(255).required('請輸入密碼'), - confirmPassword: yup.string().max(255).required('請確認密碼'), + password: yup.string().min(8,'請輸入最少8位密碼').required('請輸入密碼') + .matches(/^(?=.*[a-z])/, '請包括最少1個小寫字母') + .matches(/^(?=.*[A-Z])/, '請包括最少1個大寫字母') + .matches(/^(?=.*[0-9])/, '請包括最少1個數字') + .matches(/^(?=.*[!@#%&])/, '請包括最少1個特殊字符'), + confirmPassword: yup.string().min(8,'請最少輸入8位密碼').required('請確認密碼').oneOf([yup.ref('password'), null], '請輸入相同密碼'), enName: yup.string().max(255).required('請輸入英文姓名'), chName: yup.string().max(255).required('請輸入中文姓名'), address1: yup.string().max(255).required('請輸入第一行地址'), address2: yup.string().max(255).required('請輸入第二行地址'), address3: yup.string().max(255).required('請輸入第三行地址'), - email: yup.string().email('Must be a valid email').max(255).required('Email is required'), - idNo: yup.string().max(255).required('請輸入證件號碼'), - checkDigit:yup.string().max(1).required('請輸入證件號碼'), - idType: yup.string().max(255).required('請輸入第三行地址')}), + email: yup.string().email('請輸入電郵格式').max(255).required('請輸入電郵'), + emailConfirm: yup.string().email('請輸入電郵格式').max(255).required('請輸入電郵').oneOf([yup.ref('email'), null], '請輸入相同電郵'), + idNo: yup.string().min(7,"請輸入證件號碼").required('請輸入證件號碼'), + checkDigit:yup.string().max(1).required('請輸入括號內的數字或字母'), + idDocType: yup.string().max(255).required('請輸入證件類別'), + phoneCountryCode: yup.string().min(3,'請輸入3位數字').required('請輸入國際區號'), + faxCountryCode: yup.string().min(3,'請輸入3位數字'), + phone: yup.string().min(8,'請輸入8位數字').required('請輸入聯絡電話'), + fax: yup.string().min(8,'請輸入8位數字'), + }), }); - // const validationSchema =yup.object().shape({ - // username: yup.string().max(255).required('請輸入用戶名稱'), - // password: yup.string().max(255).required('請輸入密碼'), - // confirmPassword: yup.string().max(255).required('請確認密碼'), - // enName: yup.string().max(255).required('請輸入英文姓名'), - // chName: yup.string().max(255).required('請輸入中文姓名'), - // address1: yup.string().max(255).required('請輸入第一行地址'), - // address2: yup.string().max(255).required('請輸入第二行地址'), - // address3: yup.string().max(255).required('請輸入第三行地址'), - // email: yup.string().email('Must be a valid email').max(255).required('Email is required'), - // idNo: yup.string().max(255).required('請輸入證件號碼'), - // checkDigit:yup.string().max(1).required('請輸入證件號碼'), - // idType: yup.string().max(255).required('請輸入第三行地址')}); + const handleReset = (resetForm) => { + resetForm(); + setSelectedAddress4("") + setSelectedIdDocType("") + }; const { values } = formik useEffect(() => { + checkDataField(values) }, [values]) return ( {/* Input Form */} - + +
- 成為新的個人用戶 + 成為新的個人用戶
註有*的項目必須輸入資料 你的登入資料 - {/* - Already have an account? - */}
@@ -370,16 +439,16 @@ const CustomFormWizard = (props) => { )}
- - - - - - - {level?.label} - + + + + + + + {level?.label} + + -
@@ -395,7 +464,7 @@ const CustomFormWizard = (props) => { onBlur={formik.handleBlur} onChange={(e) => { formik.handleChange(e); - changePassword(e.target.value); + // changePassword(e.target.value); }} inputProps={{ onKeyDown: (e) => { @@ -457,17 +526,22 @@ const CustomFormWizard = (props) => { { - if (newValue !== null){ - setSelectedIdDocType(newValue); - } + setSelectedIdDocType(newValue); }} - sx={{"& .MuiInputBase-root": { height: "41px" },"#idDocType-combo":{padding: "0px 0px 0px 0px"}, "& .MuiAutocomplete-endAdornment": { top: "auto" },}} + sx={{"& .MuiInputBase-root": { height: "41px" },"#idDocType":{padding: "0px 0px 0px 0px"}, "& .MuiAutocomplete-endAdornment": { top: "auto" },}} renderInput={(params) => } /> + {formik.touched.idDocType && ( + selectedIdDocType===null? + + 請輸入證件類別 + :'' + )} {selectedIdDocType =="HKID"? @@ -495,10 +569,15 @@ const CustomFormWizard = (props) => { }} /> {formik.touched.idNo && formik.errors.idNo && ( - + {formik.errors.idNo} )} + {formik.touched.checkDigit && formik.errors.checkDigit && ( + + {formik.errors.checkDigit} + + )}
@@ -521,12 +600,8 @@ const CustomFormWizard = (props) => { }} fullWidth error={Boolean(formik.touched.checkDigit && formik.errors.checkDigit)} + onBlur={formik.handleBlur} /> - {formik.touched.checkDigit && formik.errors.checkDigit && ( - - {formik.errors.checkDigit} - - )} : @@ -542,6 +617,7 @@ const CustomFormWizard = (props) => { fullWidth sx={{mr:1}} error={Boolean(formik.touched.idNo && formik.errors.idNo)} + onBlur={formik.handleBlur} inputProps={{ onKeyDown: (e) => { if (e.key === 'Enter') { @@ -551,7 +627,7 @@ const CustomFormWizard = (props) => { }} /> {formik.touched.idNo && formik.errors.idNo && ( - + {formik.errors.idNo} )} @@ -574,6 +650,7 @@ const CustomFormWizard = (props) => { placeholder="與你的身份證明文件相同" fullWidth error={Boolean(formik.touched.enName && formik.errors.enName)} + onBlur={formik.handleBlur} inputProps={{ onKeyDown: (e) => { if (e.key === 'Enter') { @@ -629,6 +706,7 @@ const CustomFormWizard = (props) => { name="address1" onChange={formik.handleChange} placeholder="第一行" + onBlur={formik.handleBlur} inputProps={{ onKeyDown: (e) => { if (e.key === 'Enter') { @@ -672,12 +750,10 @@ const CustomFormWizard = (props) => { { - if (newValue !== null){ - setSelectedAddress4(newValue); - } + setSelectedAddress4(newValue); }} sx={{"& .MuiInputBase-root": { height: "41px" },"#address4-combo":{padding: "0px 0px 0px 0px"}, "& .MuiAutocomplete-endAdornment": { top: "auto" },}} @@ -689,9 +765,7 @@ const CustomFormWizard = (props) => { value={selectedAddress5} options={address5ComboList} onChange={(event, newValue) => { - if (newValue !== null){ - setSelectedAddress5(newValue); - } + setSelectedAddress5(newValue); }} sx={{"& .MuiInputBase-root": { height: "41px" },"#address5-combo":{padding: "0px 0px 0px 0px"}, "& .MuiAutocomplete-endAdornment": { top: "auto" },}} @@ -735,6 +809,7 @@ const CustomFormWizard = (props) => { name="email" onChange={formik.handleChange} placeholder="電郵" + onBlur={formik.handleBlur} inputProps={{ onKeyDown: (e) => { if (e.key === 'Enter') { @@ -765,6 +840,7 @@ const CustomFormWizard = (props) => { // onBlur={formik.handleBlur} onChange={formik.handleChange} placeholder="確認電郵" + onBlur={formik.handleBlur} inputProps={{ onKeyDown: (e) => { if (e.key === 'Enter') { @@ -801,6 +877,7 @@ const CustomFormWizard = (props) => { onChange={formik.handleChange} placeholder="eg:852" error={Boolean(formik.touched.phone && formik.errors.phone)} + onBlur={formik.handleBlur} inputProps={{ maxLength: 3, onKeyDown: (e) => { @@ -820,6 +897,7 @@ const CustomFormWizard = (props) => { onChange={formik.handleChange} placeholder="聯絡電話" error={Boolean(formik.touched.phone && formik.errors.phone)} + onBlur={formik.handleBlur} inputProps={{ maxLength: 8, onKeyDown: (e) => { @@ -830,12 +908,12 @@ const CustomFormWizard = (props) => { }} sx={{width:'75%'}} /> - {formik.touched.phone && formik.errors.phone && ( - - {formik.errors.phone} - - )} + {formik.touched.phone && formik.errors.phone && ( + + {formik.errors.phone} + + )} @@ -852,9 +930,9 @@ const CustomFormWizard = (props) => { type="faxCountryCode" value={formik.values.faxCountryCode} name="faxCountryCode" - // onBlur={formik.handleBlur} onChange={formik.handleChange} placeholder="eg:852" + onBlur={formik.handleBlur} inputProps={{ maxLength: 3, onKeyDown: (e) => { @@ -870,7 +948,7 @@ const CustomFormWizard = (props) => { type="fax" value={formik.values.fax} name="fax" - // onBlur={formik.handleBlur} + onBlur={formik.handleBlur} onChange={formik.handleChange} placeholder="傳真號碼" inputProps={{ @@ -977,7 +1055,7 @@ const CustomFormWizard = (props) => {
{/* Preview Form */} - + @@ -1127,7 +1205,7 @@ const CustomFormWizard = (props) => { :null} - + {/* 身份證明文件 請上傳你的 有效身份證明文件 的數碼檔案,以驗證你的身份。 @@ -1139,13 +1217,13 @@ const CustomFormWizard = (props) => { 如: 香港身份證; 護照; 中國內地身份證等 - + */} {/* Submit page */} - + {checkUpload? diff --git a/src/pages/authentication/auth-forms/UploadFileTable.js b/src/pages/authentication/auth-forms/UploadFileTable.js index 3a1a0ef..880c30d 100644 --- a/src/pages/authentication/auth-forms/UploadFileTable.js +++ b/src/pages/authentication/auth-forms/UploadFileTable.js @@ -78,7 +78,7 @@ export default function UploadFileTable({recordList}) { paginationModel: {page: 0, pageSize: 5}, }, }} - // pageSizeOptions={[5, 10]} + pageSizeOptions={[5, 10]} autoHeight /> diff --git a/yarn.lock b/yarn.lock index de6d8b4..9a00e71 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8866,6 +8866,11 @@ react-syntax-highlighter@^15.5.0: prismjs "^1.27.0" refractor "^3.6.0" +react-to-print@^2.14.13: + version "2.14.13" + resolved "https://registry.npmjs.org/react-to-print/-/react-to-print-2.14.13.tgz" + integrity sha512-PqUGgTRZvkyBzWgaZHVBECWPX2nGEc3HOUy6WNXof6HT4yTFI92wtIkqQtr4jfvHbadqjwTgzgh6vgN8KXlWWw== + react-transition-group@^4.0.0, react-transition-group@^4.4.0, react-transition-group@^4.4.5: version "4.4.5" resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz"