You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1929 lines
118 KiB

  1. import { useEffect, useState } from 'react';
  2. // material-ui
  3. import {
  4. Box,
  5. Button, Checkbox
  6. // MenuItem
  7. , FormControl, FormGroup, FormHelperText,
  8. Grid, IconButton,
  9. InputAdornment,
  10. InputLabel, OutlinedInput,
  11. Stack, TextField, Typography
  12. } from '@mui/material';
  13. import Autocomplete from "@mui/material/Autocomplete";
  14. import { useForm } from 'react-hook-form';
  15. // third party
  16. import { FormikProvider, useFormik } from 'formik';
  17. import * as yup from 'yup';
  18. // import axios from "axios";
  19. // project import
  20. // import AnimateButton from 'components/@extended/AnimateButton';
  21. import { strengthColorChi, strengthIndicator } from 'utils/password-strength';
  22. // import {apiPath} from "auth/utils";
  23. import axios from "axios";
  24. import { GET_USERNAME, GET_USER_EMAIL, POST_CAPTCHA, POST_PUBLIC_USER_REGISTER } from "utils/ApiPathConst";
  25. // import * as HttpUtils from 'utils/HttpUtils';
  26. import * as ComboData from "utils/ComboData";
  27. import Loadable from 'components/Loadable';
  28. import { lazy } from 'react';
  29. const UploadFileTable = Loadable(lazy(() => import('./UploadFileTable')));
  30. const PreviewUploadFileTable = Loadable(lazy(() => import('./PreviewUploadFileTable')));
  31. const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingComponent')));
  32. // import UploadFileTable from './UploadFileTable';
  33. // import LoadingComponent from "../../extra-pages/LoadingComponent";
  34. // assets
  35. import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons';
  36. // import { Paper } from '../../../../node_modules/@mui/material/index';
  37. import { ThemeProvider } from "@emotion/react";
  38. import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined';
  39. import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
  40. import LoopIcon from '@mui/icons-material/Loop';
  41. import { useTheme } from '@mui/material/styles';
  42. import { FormattedMessage, useIntl } from "react-intl";
  43. import { Link } from 'react-router-dom';
  44. import { PNSPS_LONG_BUTTON_THEME } from "../../../themes/buttonConst";
  45. import * as HttpUtils from "../../../utils/HttpUtils";
  46. // ============================|| FIREBASE - REGISTER ||============================ //
  47. const CustomFormWizard = (props) => {
  48. const intl = useIntl();
  49. const { locale } = intl;
  50. const theme = useTheme()
  51. const [level, setLevel] = useState();
  52. const [showPassword, setShowPassword] = useState(false);
  53. const [showConfirmPassword, setshowConfirmPassword] = useState(false);
  54. const [showId, setshowId] = useState(false);
  55. const [fileList, setFileList] = useState([]);
  56. const [fileListData, setFileListData] = useState([]);
  57. const [checkUpload, setCheckUpload] = useState(false);
  58. const [isLoading, setLoding] = useState(true);
  59. const [updateRows, setUpdateRows] = useState([]);
  60. const [captchaImg, setCaptchaImage] = useState("");
  61. const [base64Url, setBase64Url] = useState("")
  62. const [checkCode, setCheckCode] = useState("")
  63. const handleClickShowPassword = () => {
  64. setShowPassword(!showPassword);
  65. };
  66. const handleClickShowConfirmPassword = () => {
  67. setshowConfirmPassword(!showConfirmPassword);
  68. };
  69. const handleMouseDownPassword = (event) => {
  70. event.preventDefault();
  71. };
  72. const handleClickShowId = () => {
  73. setshowId(!showId);
  74. };
  75. const handleMouseDownId = (event) => {
  76. event.preventDefault();
  77. };
  78. const changePassword = (value) => {
  79. const temp = strengthIndicator(value);
  80. setLevel(strengthColorChi(temp));
  81. };
  82. const [selectedIdDocType, setSelectedIdDocType] = useState({});
  83. const [selectedIdDocInputType, setSelectedIdDocInputType] = useState("");
  84. const [selectedAddress4, setSelectedAddress4] = useState(null);
  85. const [selectedAddress5, setSelectedAddress5] = useState(ComboData.country[0]);
  86. const [termsAndConAccept, setTermsAndConAccept] = useState(false);
  87. const [termsAndConNotAccept, setTermsAndConNotAccept] = useState(false);
  88. const [isValid, setisValid] = useState(false);
  89. const [checkCountry, setCheckCountry] = useState(false);
  90. const username = document.getElementById("username-login")
  91. const [checkUsername, setCheckUsername] = useState(false);
  92. const [checkUsernameBlur, setCheckUsernameBlur] = useState(false)
  93. const email = document.getElementById("email-login")
  94. const [checkEmail, setCheckEmail] = useState(false)
  95. const [checkEmailBlur, setCheckEmailBlur] = useState(false)
  96. const [districtErrStr, setDistrictErrStr] = useState("")
  97. const idDocTypeComboList = ComboData.idDocType;
  98. const refType = "identification";
  99. useEffect(() => {
  100. changePassword('');
  101. if (captchaImg == ""){
  102. onCaptchaChange();
  103. }
  104. }, []);
  105. const handleCheckUsername = async () => {
  106. if (values?.username) {
  107. const response = await axios.get(`${GET_USERNAME}`, {
  108. params: {
  109. username: values.username,
  110. }
  111. })
  112. setCheckUsername((Number(response.data[0]) === 1))
  113. return Number(response.data[0]) === 1
  114. }
  115. }
  116. const handleCheckEmail = async () => {
  117. if (values?.email) {
  118. const response = await axios.get(`${GET_USER_EMAIL}`, {
  119. params: {
  120. email: values.email,
  121. }
  122. })
  123. setCheckEmail((Number(response.data[0]) === 1))
  124. return Number(response.data[0]) === 1
  125. }
  126. }
  127. useEffect(() => {
  128. if (username) {
  129. username.addEventListener("blur", function () {
  130. setCheckUsernameBlur(true)
  131. })
  132. }
  133. }, [username])
  134. useEffect(() => {
  135. if (checkUsernameBlur) {
  136. handleCheckUsername()
  137. setCheckUsernameBlur(false)
  138. }
  139. }, [checkUsernameBlur])
  140. useEffect(() => {
  141. if (email) {
  142. email.addEventListener("blur", function () {
  143. setCheckEmailBlur(true)
  144. })
  145. }
  146. }, [email])
  147. useEffect(() => {
  148. if (checkEmailBlur) {
  149. handleCheckEmail()
  150. setCheckEmailBlur(false)
  151. }
  152. }, [checkEmailBlur])
  153. const onCaptchaChange = () => {
  154. HttpUtils.post({
  155. url: POST_CAPTCHA,
  156. params: { width: 130, height: 40, captcha: captchaImg },
  157. onSuccess: (responseData) => {
  158. props.setBase64Url(responseData.base64Url)
  159. setBase64Url(responseData.base64Url)
  160. localStorage.setItem("base64Url", responseData.base64Url);
  161. setCaptchaImage(localStorage.getItem('base64Url'));
  162. }
  163. });
  164. }
  165. const checkDataField = (data) => {
  166. // console.log(data)
  167. if (
  168. handleCaptcha(data.captchaField) &&
  169. data.username !== "" &&
  170. data.password !== "" &&
  171. data.confirmPassword !== "" &&
  172. data.password == data.confirmPassword &&
  173. selectedIdDocType.type !== "" &&
  174. data.idNo !== "" &&
  175. // (data.enName !== "" || selectedIdDocType.type === "CNID") &&
  176. // data.chName !== "" &&
  177. handleName(data.enName, data.chName) &&
  178. data.address1 !== "" &&
  179. data.email !== "" &&
  180. data.emailConfirm !== "" &&
  181. data.email == data.emailConfirm &&
  182. data.phone !== "" &&
  183. data.phoneCountryCode !== "" &&
  184. termsAndConAccept == true &&
  185. fileList.length !== 0 &&
  186. // data.captchaField &&
  187. handlePassword(data.password) &&
  188. handleEmail(data.email) &&
  189. handleIdNo(data.idNo, selectedIdDocType.type, data.checkDigit) &&
  190. handlePhone(data.phone) &&
  191. handleUsername(data.username) &&
  192. !checkUsername &&
  193. !checkEmail
  194. ) {
  195. setisValid(true)
  196. return isValid
  197. } else {
  198. setisValid(false)
  199. return isValid
  200. }
  201. };
  202. const handleCheckBoxChange = (event) => {
  203. if (event.target.name == 'termsAndConAccept') {
  204. setTermsAndConAccept(event.target.checked)
  205. setTermsAndConNotAccept(!event.target.checked)
  206. }
  207. if (event.target.name == 'termsAndConNotAccept') {
  208. setTermsAndConNotAccept(event.target.checked)
  209. setTermsAndConAccept(!event.target.checked)
  210. }
  211. };
  212. useEffect(() => {
  213. let updateRowList = new DataTransfer();
  214. var updateRowsIndex = updateRows.length;
  215. const saveFileList = [];
  216. if (updateRowsIndex != null) {
  217. for (let i = 0; i < updateRowsIndex; i++) {
  218. const file = updateRows[i]
  219. file.id = i;
  220. updateRowList.items.add(file);
  221. saveFileList.push(file);
  222. }
  223. let updatedFileList = updateRowList.files;
  224. setFileList(updatedFileList);
  225. setFileListData(saveFileList)
  226. }
  227. }, [updateRows]);
  228. const handleFileUpload = (event) => {
  229. let updateList = new DataTransfer();
  230. let currentFileList = fileListData;
  231. const uploadFileList = event.target.files;
  232. const saveFileList = [];
  233. var currentIndex = 0;
  234. if (currentFileList.length != null) {
  235. currentIndex = currentFileList.length;
  236. for (let i = 0; i < currentIndex; i++) {
  237. const file = currentFileList[i]
  238. // file.id = currentIndex;
  239. updateList.items.add(file);
  240. saveFileList.push(file);
  241. }
  242. }
  243. for (let i = 0; i < uploadFileList.length && currentIndex < 5; i++) {
  244. const file = event.target.files[i]
  245. let isDuplicate = false;
  246. // Check if the file name already exists in saveFileList
  247. for (let j = 0; j < saveFileList.length; j++) {
  248. if (saveFileList[j].name === file.name) {
  249. isDuplicate = true;
  250. break;
  251. }
  252. }
  253. if (!isDuplicate && i + currentIndex < 5) {
  254. file.id = currentIndex + i
  255. saveFileList.push(file)
  256. updateList.items.add(file);
  257. }
  258. }
  259. let updatedFileList = updateList.files;
  260. setFileListData(saveFileList)
  261. setFileList(updatedFileList);
  262. };
  263. useEffect(() => {
  264. props.setUpdateValid(isValid)
  265. }, [isValid])
  266. useEffect(() => {
  267. props.setUpdateValid(isValid)
  268. }, [isValid])
  269. useEffect(() => {
  270. checkDataField(values)
  271. }, [
  272. selectedIdDocType,
  273. selectedAddress4, selectedAddress5,
  274. termsAndConAccept, termsAndConNotAccept, fileList])
  275. useEffect(() => {
  276. setDistrictErrStr("");
  277. if (selectedAddress5?.type === "hongKong") {
  278. if (selectedAddress4 == null || selectedAddress4 == "" || selectedAddress4 == {})
  279. setDistrictErrStr(getRequiredErrStr("district"))
  280. }
  281. }, [selectedAddress4, selectedAddress5])
  282. useEffect(() => {
  283. props.step == 2 ? _onSubmit() : null;
  284. if (captchaImg == "")
  285. onCaptchaChange();
  286. checkDataField(values)
  287. }, [props.step])
  288. const { handleSubmit } = useForm({})
  289. const _onSubmit = () => {
  290. setLoding(true);
  291. values.idDocType = selectedIdDocType.type
  292. values.address4 = selectedAddress4 == null ? "" : selectedAddress4.type
  293. values.address5 = selectedAddress5.type
  294. // console.log(values)
  295. const userAddress = {
  296. "addressLine1": "",
  297. "addressLine2": "",
  298. "addressLine3": "",
  299. "district": "",
  300. "country": ""
  301. };
  302. userAddress.addressLine1 = values.address1
  303. userAddress.addressLine2 = values.address2
  304. userAddress.addressLine3 = values.address3
  305. userAddress.district = values.address4
  306. userAddress.country = values.address5
  307. const userFaxNo = {
  308. "countryCode": values.faxCountryCode,
  309. "faxNumber": values.fax,
  310. };
  311. const userMobileNumber = {
  312. "countryCode": values.phoneCountryCode,
  313. "phoneNumber": values.phone,
  314. };
  315. let tncFlag = false;
  316. if (termsAndConAccept) {
  317. tncFlag = true
  318. }
  319. if (termsAndConNotAccept) {
  320. tncFlag = false
  321. }
  322. const preferLocale = locale === 'en' ? 'en': locale === 'zh-HK' ? 'zh_HK': 'zh-CN'
  323. const user = {
  324. username: values.username,
  325. password: values.password,
  326. name: values.username,
  327. enName: values.enName,
  328. chName: values.chName,
  329. emailAddress: values.email,
  330. idDocType: values.idDocType,
  331. identification: values.idNo,
  332. checkDigit: values.checkDigit,
  333. tncFlag: tncFlag,
  334. type: "IND",
  335. captcha: base64Url,
  336. checkCode: checkCode,
  337. preferLocale: preferLocale
  338. };
  339. var formData = new FormData();
  340. for (let i = 0; i < fileListData.length; i++) {
  341. const file = fileListData[i]
  342. formData.append("multipartFileList", file);
  343. }
  344. formData.append("refType", refType);
  345. for (const [key, value] of Object.entries(user)) {
  346. formData.append(key, value);
  347. }
  348. formData.append("userFaxNo", JSON.stringify(userFaxNo));
  349. formData.append("userMobileNumber", JSON.stringify(userMobileNumber));
  350. formData.append("userAddress", JSON.stringify(userAddress));
  351. // formData.append("preferLocale", "en");
  352. // if(refCode){
  353. // formData.append("refCode", refCode);
  354. // }
  355. if (isValid) {
  356. axios.post(POST_PUBLIC_USER_REGISTER, formData, {
  357. headers: {
  358. "Content-Type": "multipart/form-data"
  359. }
  360. })
  361. .then((
  362. // response
  363. ) => {
  364. // console.log(response)
  365. setCheckUpload(true)
  366. setLoding(false);
  367. })
  368. .catch(error => {
  369. console.error(error);
  370. setLoding(false);
  371. });
  372. } else {
  373. setLoding(false);
  374. }
  375. }
  376. function handlePhone(phone) {
  377. if (phone.length < 8) {
  378. return false;
  379. } else {
  380. // console.log("Phone true")
  381. return true;
  382. }
  383. }
  384. function handleUsername(username) {
  385. var symbol = /^(?=.*[!@#%&])/;
  386. var space = /\s/;
  387. if (username.length < 6) {
  388. return false;
  389. } else if (username.match(symbol)) {
  390. return false;
  391. } else if (username.match(space)) {
  392. return false;
  393. } else {
  394. return true;
  395. }
  396. }
  397. function handleCaptcha(captchaField) {
  398. // console.log(captchaField.length)
  399. if (captchaField.length == 5 ){
  400. return true
  401. } else {
  402. return false
  403. }
  404. }
  405. function handleIdNo(idNo, selectedIdDocType, checkDigit) {
  406. // var pattern = /^[A-Z][0-9]*$/;
  407. var pattern_HKIDv1 = /^[A-Z]{1}[0-9]{6}$/;
  408. var pattern_HKIDv2 = /^[A-Z]{2}[0-9]{6}$/;
  409. var pattern_passport = /^[A-Z]{1}[0-9]{8}$/;
  410. var pattern_CHID = /^[0-9]{6}(20|19)[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])[0-9]{3}[0-9X]{1}/;
  411. var pattern_otherCert = /^[A-Z]{1}[0-9]{5,}/;
  412. // var space = /\s/;
  413. // if (!idNo.match(pattern)) {
  414. // return false;
  415. // } else if (selectedIdDocType=="HKID"&&checkDigit==""){
  416. // return false;
  417. // } else if (idNo.match(space)) {
  418. // return false;
  419. // } else if (idNo.length < 6) {
  420. // return false;
  421. // } else {
  422. // // console.log("IdNo true")
  423. // return true;
  424. // }
  425. switch (selectedIdDocType) {
  426. case "HKID":
  427. if (checkDigit === "") return false
  428. if (idNo.match(pattern_HKIDv1)) {
  429. return true
  430. } else if (idNo.match(pattern_HKIDv2)) {
  431. return true
  432. } else {
  433. return false
  434. }
  435. case "passport":
  436. if (idNo.match(pattern_passport)) {
  437. return true
  438. } else {
  439. return false
  440. }
  441. case "CNID":
  442. if (idNo.match(pattern_CHID)) {
  443. const subStr_year = idNo.substring(6, 10)
  444. const subStr_month = idNo.substring(10, 12)
  445. const subStr_date = idNo.substring(12, 14)
  446. const today = new Date()
  447. const inputDate = new Date(`${subStr_year}-${subStr_month}-${subStr_date}`)
  448. if (inputDate > today || inputDate === "Invalid Date" || inputDate.getFullYear().toString() !== subStr_year || (inputDate.getMonth() + 1).toString().padStart(2, "0") !== subStr_month || inputDate.getDate().toString().padStart(2, "0") !== subStr_date) {
  449. return false
  450. } else {
  451. return true
  452. }
  453. } else {
  454. return false
  455. }
  456. case "otherCert":
  457. if (idNo.match(pattern_otherCert)) {
  458. return true
  459. } else {
  460. return false
  461. }
  462. default:
  463. break;
  464. }
  465. }
  466. function handleName(enName, chName) {
  467. if (enName == "" && chName !== ""){
  468. return true
  469. } else if (enName !== "" && chName == ""){
  470. return true
  471. } else if (enName !== "" && chName !== "") {
  472. return true
  473. } else {
  474. return false
  475. }
  476. }
  477. function handlePassword(password) {
  478. let new_pass = password;
  479. // regular expressions to validate password
  480. var lowerCase = /[a-z]/g;
  481. var upperCase = /[A-Z]/g;
  482. var numbers = /[0-9]/g;
  483. var symbol = /^(?=.*[!@#%&])/;
  484. var space = /\s/;
  485. if (!new_pass.match(lowerCase)) {
  486. return false;
  487. } else if (!new_pass.match(upperCase)) {
  488. return false;
  489. } else if (!new_pass.match(numbers)) {
  490. return false;
  491. } else if (!new_pass.match(symbol)) {
  492. return false;
  493. } else if (new_pass.length < 8) {
  494. return false;
  495. }
  496. else if (new_pass.match(space)) {
  497. return false;
  498. } else {
  499. // console.log("password true")
  500. return true;
  501. }
  502. }
  503. function handleEmail(email) {
  504. var validRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
  505. if (!email.match(validRegex)) {
  506. return false;
  507. } else {
  508. return true;
  509. }
  510. }
  511. function displayErrorMsg(errorMsg) {
  512. return <Typography variant="errorMessage1">{errorMsg}</Typography>
  513. }
  514. function getMaxErrStr(num, fieldname) {
  515. return displayErrorMsg(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: num, fieldname: fieldname ? intl.formatMessage({ id: fieldname }) + ": " : "" }));
  516. }
  517. function getRequiredErrStr(fieldname) {
  518. return displayErrorMsg(intl.formatMessage({ id: 'require' }, { fieldname: fieldname ? intl.formatMessage({ id: fieldname }) : "" }));
  519. }
  520. const formik = useFormik({
  521. initialValues: ({
  522. username: '',
  523. enName: '',
  524. chName: '',
  525. email: '',
  526. emailConfirm: '',
  527. address1: '',
  528. address2: '',
  529. address3: '',
  530. password: '',
  531. confirmPassword: '',
  532. phone: '',
  533. phoneCountryCode: '852',
  534. idNo: '',
  535. checkDigit: '',
  536. submit: null,
  537. fax: '',
  538. faxCountryCode: '852',
  539. idDocType: '',
  540. captchaField: ''
  541. }),
  542. validationSchema: yup.object().shape({
  543. username: yup.string().min(6, displayErrorMsg(intl.formatMessage({ id: 'atLeast6CharAccount' }))).max(30, getMaxErrStr(30)).required(displayErrorMsg(intl.formatMessage({ id: 'requireUsername' })))
  544. .matches(/^[aA-zZ0-9\s]+$/, { message: displayErrorMsg(intl.formatMessage({ id: 'noSpecialCharAccount' })) })
  545. .matches(/^\S*$/, { message: displayErrorMsg(intl.formatMessage({ id: 'noSpaceAccount' })) }),
  546. password: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'atLeast8CharPassword' }))).max(60, getMaxErrStr(60)).required(displayErrorMsg(intl.formatMessage({ id: 'requirePassword' })))
  547. .matches(/^\S*$/, { message: displayErrorMsg(intl.formatMessage({ id: 'noSpacePassword' })) })
  548. .matches(/^(?=.*[a-z])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeastOneSmallLetter' })) })
  549. .matches(/^(?=.*[A-Z])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeastOneCapLetter' })) })
  550. .matches(/^(?=.*[0-9])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeast1Number' })) })
  551. .matches(/^(?=.*[!@#%&])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeast1SpecialChar' })) }),
  552. confirmPassword: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'atLeast8CharPassword' }))).required(displayErrorMsg(intl.formatMessage({ id: 'pleaseConfirmPassword' }))).oneOf([yup.ref('password'), null], displayErrorMsg(intl.formatMessage({ id: 'samePassword' }))),
  553. chName: yup.string().max(6, getMaxErrStr(6)),
  554. enName: yup.string().max(40, getMaxErrStr(40)).when('chName', {
  555. is: (chName) => chName?false:true,
  556. then: yup.string().required(displayErrorMsg(intl.formatMessage({ id: 'registerNameLabel' })))
  557. }),
  558. address1: yup.string().max(40, getMaxErrStr(40, "addressLine1")).required(displayErrorMsg(intl.formatMessage({ id: 'validateAddressLine1' }))),
  559. address2: yup.string().max(40, getMaxErrStr(40, "addressLine2")),
  560. address3: yup.string().max(40, getMaxErrStr(40, "addressLine3")),
  561. email: yup.string().email(displayErrorMsg(intl.formatMessage({ id: 'validEmailFormat' }))).max(128, getMaxErrStr(128)).required(displayErrorMsg(intl.formatMessage({ id: 'requireEmail' }))),
  562. emailConfirm: yup.string().email(displayErrorMsg(intl.formatMessage({ id: 'validEmailFormat' }))).max(128, getMaxErrStr(128)).required(displayErrorMsg(intl.formatMessage({ id: 'requireEmail' }))).oneOf([yup.ref('email'), null], displayErrorMsg(intl.formatMessage({ id: 'validSameEmail' }))),
  563. idNo: yup.string().required(getRequiredErrStr('number'))
  564. .matches(/^[aA-zZ0-9\s]+$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpecialCharacter' })}`) })
  565. .matches(/^\S*$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpace' })}`) })
  566. .test('checkIDCardFormat', displayErrorMsg(`${intl.formatMessage({ id: 'requiredValid' })}${selectedIdDocInputType}${intl.formatMessage({ id: 'number' })}`), function (value) {
  567. const idDocType = selectedIdDocType.type;
  568. var pattern_HKIDv1 = /^[A-Z]{1}[0-9]{6}$/;
  569. var pattern_HKIDv2 = /^[A-Z]{2}[0-9]{6}$/;
  570. var pattern_passport = /^[A-Z]{1}[0-9]{8}$/;
  571. var pattern_CHID = /^[0-9]{6}(20|19)[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])[0-9]{3}[0-9X]{1}/;
  572. var pattern_otherCert = /^[A-Z]{1}[0-9]{5,}/;
  573. if (value !== undefined) {
  574. switch (idDocType) {
  575. case "HKID":
  576. if (value.match(pattern_HKIDv1)) {
  577. return true
  578. } else if (value.match(pattern_HKIDv2)) {
  579. return true
  580. } else {
  581. return false
  582. }
  583. case "passport":
  584. if (value.match(pattern_passport)) {
  585. return true
  586. } else {
  587. return false
  588. }
  589. case "CNID":
  590. if (value.match(pattern_CHID)) {
  591. const subStr_year = value.substring(6, 10)
  592. const subStr_month = value.substring(10, 12)
  593. const subStr_date = value.substring(12, 14)
  594. const today = new Date()
  595. const inputDate = new Date(`${subStr_year}-${subStr_month}-${subStr_date}`)
  596. if (inputDate > today || inputDate === "Invalid Date" || inputDate.getFullYear().toString() !== subStr_year || (inputDate.getMonth() + 1).toString().padStart(2, "0") !== subStr_month || inputDate.getDate().toString().padStart(2, "0") !== subStr_date) {
  597. return false
  598. } else {
  599. return true
  600. }
  601. } else {
  602. return false
  603. }
  604. case "otherCert":
  605. if (value.match(pattern_otherCert)) {
  606. return true
  607. } else {
  608. return false
  609. }
  610. default:
  611. break;
  612. }
  613. }
  614. }),
  615. checkDigit: yup.string().max(1, getMaxErrStr(1)).required(displayErrorMsg(intl.formatMessage({ id: 'requiredNumberInQuote' }))),
  616. idDocType: yup.string().max(255, getMaxErrStr(255)).required(displayErrorMsg(intl.formatMessage({ id: 'requireIdDocType' }))),
  617. phoneCountryCode: yup.string().min(2, displayErrorMsg(intl.formatMessage({ id: 'requireAtLeast2Number' }))).required(displayErrorMsg(intl.formatMessage({ id: 'requireDialingCode' }))),
  618. // faxCountryCode: yup.string().min(3,'請輸入3位數字'),
  619. phone: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'requireAtLeast8Number' }))).required(displayErrorMsg(intl.formatMessage({ id: 'requireContactNumber' }))),
  620. // fax: yup.string().min(8,'請輸入8位數字'),
  621. captchaField: yup.string().max(5, getMaxErrStr(5)).required(displayErrorMsg(intl.formatMessage({ id: 'requireVerify' }))).min(5, displayErrorMsg(intl.formatMessage({ id: 'requireVerify' }))),//.oneOf([captcha], displayErrorMsg('請輸入有效驗證')),
  622. }),
  623. });
  624. const handleReset = (resetForm) => {
  625. resetForm();
  626. setSelectedAddress4("")
  627. setSelectedAddress5(ComboData.country[0])
  628. setCheckCountry(false)
  629. setSelectedIdDocType({})
  630. setSelectedIdDocInputType("");
  631. setFileList([])
  632. setFileListData([])
  633. onCaptchaChange()
  634. // setSelectedIdDocLabel("")
  635. };
  636. const handleCCPChange = (e) => {
  637. e.preventDefault();
  638. };
  639. const { values } = formik
  640. useEffect(() => {
  641. checkDataField(values)
  642. }, [values])
  643. return (
  644. <FormikProvider value={formik}>
  645. <form onSubmit={handleSubmit(_onSubmit)}>
  646. {/* Input Form */}
  647. <FormGroup id={"inputForm"} sx={{ display: props.step === 0 ? "" : "none" }}>
  648. <Grid container spacing={3}>
  649. <Grid item xs={12} md={12}>
  650. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  651. <Button variant="outlined" type="reset" onClick={handleReset.bind(null, formik.resetForm)} sx={{ height: '40px' }}>
  652. <Typography variant="pnspsFormHeader">
  653. <FormattedMessage id="reset" />
  654. </Typography>
  655. </Button>
  656. <div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}>
  657. <Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>
  658. <FormattedMessage id="becomeNewPersonalUser" />
  659. </Typography>
  660. </div>
  661. <Typography mt={0.25} variant="h6" sx={{ color: '#f10000' }}>
  662. <FormattedMessage id="requireString" />
  663. </Typography>
  664. <Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary' }}>
  665. <FormattedMessage id="yourLoginInformation" />
  666. </Typography>
  667. </Stack>
  668. </Grid>
  669. <Grid item xs={12} md={12}>
  670. <Grid container spacing={1}>
  671. <Grid item xs={12} md={12} >
  672. <Stack spacing={1}>
  673. <InputLabel htmlFor="username-signup">
  674. <Typography variant="pnspsFormHeader">
  675. <FormattedMessage id="userLoginName" />
  676. <span style={{ color: '#f10000' }}>*</span>
  677. {/*<Button*/}
  678. {/* variant="contained"*/}
  679. {/* onClick={handleCheckUsername}*/}
  680. {/* sx={{ ml: 2, height: "40px" }}>*/}
  681. {/* <Typography variant="h6">檢查是否重覆</Typography>*/}
  682. {/*</Button> **/}
  683. </Typography>
  684. </InputLabel>
  685. <OutlinedInput
  686. id="username-login"
  687. type="text"
  688. value={formik.values.username.trim()}
  689. name="username"
  690. onChange={(e) => {
  691. setCheckUsername(false)
  692. props.setUsername(e.target.value)
  693. formik.handleChange(e)
  694. }}
  695. placeholder={intl.formatMessage({ id: 'userLoginName' })}
  696. fullWidth
  697. autoFocus
  698. error={Boolean((formik.touched.username && formik.errors.username) || checkUsername)}
  699. onBlur={formik.handleBlur}
  700. inputProps={{
  701. onKeyDown: (e) => {
  702. if (e.key === 'Enter') {
  703. e.preventDefault();
  704. }
  705. },
  706. }}
  707. />
  708. {formik.touched.username && formik.errors.username && (
  709. <FormHelperText error id="helper-text-username-signup">
  710. {formik.errors.username}
  711. </FormHelperText>
  712. )}
  713. {checkUsername && (
  714. <FormHelperText error id="helper-text-username-signup">
  715. <FormattedMessage id="usernameTaken" />
  716. </FormHelperText>
  717. )}
  718. </Stack>
  719. </Grid>
  720. <Grid item xs={12} md={12}>
  721. <Grid container>
  722. <Grid item xs={12} md={6} >
  723. <Stack spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}>
  724. <Stack direction="row" justifyContent="space-between">
  725. <InputLabel htmlFor="password-signup">
  726. <Typography variant="pnspsFormHeader">
  727. <FormattedMessage id="userPassword" />
  728. <span style={{ color: '#f10000' }}>*</span>
  729. </Typography>
  730. </InputLabel>
  731. </Stack>
  732. <OutlinedInput
  733. fullWidth
  734. error={Boolean(formik.touched.password && formik.errors.password)}
  735. id="password-signup"
  736. type={showPassword ? 'text' : 'password'}
  737. value={formik.values.password.trim()}
  738. name="password"
  739. onChange={(e) => {
  740. formik.handleChange(e);
  741. changePassword(e.target.value);
  742. }}
  743. endAdornment={
  744. <InputAdornment position="end">
  745. <IconButton
  746. aria-label="toggle password visibility"
  747. onClick={handleClickShowPassword}
  748. onMouseDown={handleMouseDownPassword}
  749. edge="end"
  750. size="large"
  751. >
  752. {showPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  753. </IconButton>
  754. </InputAdornment>
  755. }
  756. placeholder={intl.formatMessage({ id: 'userPassword' })}
  757. onBlur={formik.handleBlur}
  758. inputProps={{
  759. onKeyDown: (e) => {
  760. if (e.key === 'Enter') {
  761. e.preventDefault();
  762. }
  763. },
  764. }}
  765. />
  766. {formik.touched.password && formik.errors.password && (
  767. <FormHelperText error id="helper-text-password-signup">
  768. {formik.errors.password}
  769. </FormHelperText>
  770. )}
  771. </Stack>
  772. <FormControl fullWidth sx={{ mt: 2 }}>
  773. <Grid container spacing={2} alignItems="center">
  774. <Grid item>
  775. <Box sx={{ bgcolor: level?.color, width: 85, height: 8, borderRadius: '7px' }} />
  776. </Grid>
  777. <Grid item>
  778. <Typography variant="subtitle1">
  779. <FormattedMessage id={level ? level?.label : "pwWeak"} />
  780. </Typography>
  781. </Grid>
  782. </Grid>
  783. </FormControl>
  784. </Grid>
  785. <Grid item xs={12} md={6} >
  786. <Stack spacing={1}>
  787. <InputLabel htmlFor="confirmPassword-signup">
  788. <Typography variant="pnspsFormHeader">
  789. <FormattedMessage id="confirmPassword" />
  790. <span style={{ color: '#f10000' }}>*</span>
  791. </Typography>
  792. </InputLabel>
  793. <OutlinedInput
  794. id="confirmPassword-login"
  795. type={showConfirmPassword ? 'text' : 'password'}
  796. value={formik.values.confirmPassword.trim()}
  797. name="confirmPassword"
  798. onBlur={formik.handleBlur}
  799. onChange={(e) => {
  800. formik.handleChange(e);
  801. // changePassword(e.target.value);
  802. }}
  803. inputProps={{
  804. onKeyDown: (e) => {
  805. if (e.key === 'Enter') {
  806. e.preventDefault();
  807. }
  808. },
  809. }}
  810. endAdornment={
  811. <InputAdornment position="end">
  812. <IconButton
  813. aria-label="toggle password visibility"
  814. onClick={handleClickShowConfirmPassword}
  815. onMouseDown={handleMouseDownPassword}
  816. edge="end"
  817. size="large"
  818. >
  819. {showConfirmPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  820. </IconButton>
  821. </InputAdornment>
  822. }
  823. placeholder={intl.formatMessage({ id: 'confirmPassword' })}
  824. fullWidth
  825. error={Boolean(formik.touched.confirmPassword && formik.errors.confirmPassword)}
  826. />
  827. {formik.touched.confirmPassword && formik.errors.confirmPassword && (
  828. <FormHelperText error id="helper-text-confirmPassword-signup">
  829. {formik.errors.confirmPassword}
  830. </FormHelperText>
  831. )}
  832. </Stack>
  833. <Grid container spacing={2} alignItems="center">
  834. <Grid item sx={{ mt: 1 }}>
  835. <Typography variant="subtitle1">
  836. •<FormattedMessage id="pwRemark1" /><br />
  837. •<FormattedMessage id="pwRemark2" /><br />
  838. •<FormattedMessage id="pwRemark3" /><br />
  839. •<FormattedMessage id="pwRemark4" /><br />
  840. •<FormattedMessage id="pwRemark5"/><br />
  841. </Typography>
  842. </Grid>
  843. </Grid>
  844. </Grid>
  845. </Grid>
  846. </Grid>
  847. <Grid item xs={12} mt={1} mb={1}>
  848. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  849. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  850. <FormattedMessage id="yourPersonalInformation" />
  851. </Typography>
  852. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  853. Already have an account?
  854. </Typography> */}
  855. </Stack>
  856. </Grid>
  857. <Grid item xs={12} md={12} >
  858. <Grid container sx={{ mb: 1 }}>
  859. <Stack spacing={1}>
  860. <InputLabel htmlFor="idDocType-signup">
  861. <Typography variant="pnspsFormHeader">
  862. <FormattedMessage id="userIdDoc" />
  863. <span style={{ color: '#f10000' }}>*</span>
  864. </Typography>
  865. </InputLabel>
  866. {/* {formik.touched.enName && formik.errors.enName && (
  867. <FormHelperText error id="helper-text-enName-signup">
  868. {formik.errors.enName}
  869. </FormHelperText>
  870. )} */}
  871. </Stack>
  872. </Grid>
  873. <Grid container>
  874. <Grid item xs={12} md={6} >
  875. <Stack spacing={1} sx={{ mr: { md: 1 } }}>
  876. <Autocomplete
  877. disablePortal
  878. id="idDocType"
  879. //value={selectedIdDocType}
  880. size="small"
  881. options={idDocTypeComboList}
  882. onBlur={formik.handleBlur}
  883. filterOptions={(options) => options}
  884. inputValue={selectedIdDocInputType}
  885. getOptionLabel={(option) => option.label ? intl.formatMessage({ id: option.label }) : ""}
  886. onChange={(event, newValue) => {
  887. if (newValue != null) {
  888. setSelectedIdDocInputType(intl.formatMessage({ id: newValue.label }));
  889. setSelectedIdDocType(newValue);
  890. if (newValue.type !== "HKID") {
  891. formik.setFieldValue("checkDigit", "")
  892. }
  893. } else {
  894. setSelectedIdDocInputType("");
  895. setSelectedIdDocType({});
  896. }
  897. }}
  898. sx={{ "#address4-combo": { padding: "0px 0px 0px 0px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }}
  899. renderInput={(params) => <TextField
  900. {...params}
  901. error={formik.touched.idDocType && (selectedIdDocType === null || selectedIdDocType?.type == null)}
  902. placeholder={intl.formatMessage({ id: 'idDocType' })}
  903. />}
  904. />
  905. {formik.touched.idDocType && (
  906. selectedIdDocType === null || selectedIdDocType?.type == null ?
  907. <FormHelperText error id="helper-text-idDocType-signup" sx={{ fontSize: 16, fontWeight: 'bold', }}>
  908. <FormattedMessage id="requireIdDocType" />
  909. </FormHelperText> : ''
  910. )}
  911. </Stack>
  912. </Grid>
  913. {selectedIdDocType.type === "HKID" ?
  914. <>
  915. <Grid item xs={9} md={5}>
  916. <Stack spacing={1} sx={{ mr: { md: 1 } }}>
  917. <OutlinedInput
  918. id="idNo-login"
  919. type="text"
  920. name="idNo"
  921. value={formik.values.idNo}
  922. onChange={async (e) => {
  923. const ele = document.getElementById('idNo-login')
  924. const startPos = ele.selectionStart
  925. if (e.type === "change") {
  926. if (!(e.target.value.match(/\s/g))) {
  927. const newValue = await e.target.value.toUpperCase()
  928. await formik.setFieldValue("idNo", newValue)
  929. ele.setSelectionRange(startPos, startPos)
  930. } else {
  931. await formik.setFieldValue("idNo", formik.values.idNo)
  932. ele.setSelectionRange(startPos - 1, startPos - 1)
  933. }
  934. }
  935. }}
  936. placeholder={intl.formatMessage({ id: 'idDocNumber' })}
  937. fullWidth
  938. sx={{ mr: 1 }}
  939. error={Boolean(formik.touched.idNo && formik.errors.idNo)}
  940. onBlur={formik.handleBlur}
  941. inputProps={{
  942. maxLength: selectedIdDocType.type === 'HKID' ? 8 : 18,
  943. onKeyDown: (e) => {
  944. // console.log(e)
  945. if (e.key === 'Enter') {
  946. e.preventDefault();
  947. }
  948. },
  949. }}
  950. />
  951. {formik.touched.idNo && formik.errors.idNo && (
  952. <FormHelperText error id="helper-text-idNo-signup">
  953. {formik.errors.idNo}
  954. </FormHelperText>
  955. )}
  956. {formik.touched.checkDigit && formik.errors.checkDigit && (
  957. <FormHelperText error id="helper-text-checkDigit-signup">
  958. {formik.errors.checkDigit}
  959. </FormHelperText>
  960. )}
  961. </Stack>
  962. </Grid>
  963. <Grid item xs={3} md={1}>
  964. <Stack spacing={1}>
  965. <OutlinedInput
  966. id="checkDigit-login"
  967. type="text"
  968. value={formik.values.checkDigit.trim()}
  969. name="checkDigit"
  970. onChange={formik.handleChange}
  971. //placeholder="( )"
  972. // sx={{height:"53px"}}
  973. startAdornment={<InputAdornment position="start">(</InputAdornment>}
  974. endAdornment={<InputAdornment position="end">)</InputAdornment>}
  975. sx={{
  976. '& .MuiOutlinedInput-input': {
  977. padding: '5px 2px 5px 2px', // Set the desired padding inline
  978. },
  979. }}
  980. inputProps={{
  981. maxLength: 1,
  982. onKeyDown: (e) => {
  983. if (e.key === 'Enter') {
  984. e.preventDefault();
  985. }
  986. },
  987. }}
  988. fullWidth
  989. error={Boolean(formik.touched.checkDigit && formik.errors.checkDigit)}
  990. onBlur={formik.handleBlur}
  991. />
  992. </Stack>
  993. </Grid>
  994. </> :
  995. <Grid item xs={12} md={6}>
  996. <Stack spacing={1}>
  997. <OutlinedInput
  998. id="idNo-login"
  999. type="text"
  1000. value={formik.values.idNo}
  1001. name="idNo"
  1002. onChange={async (e) => {
  1003. const ele = document.getElementById('idNo-login')
  1004. const startPos = ele.selectionStart
  1005. if (e.type === "change") {
  1006. if (!(e.target.value.match(/\s/g))) {
  1007. const newValue = await e.target.value.toUpperCase()
  1008. await formik.setFieldValue("idNo", newValue)
  1009. ele.setSelectionRange(startPos, startPos)
  1010. } else {
  1011. await formik.setFieldValue("idNo", formik.values.idNo)
  1012. ele.setSelectionRange(startPos - 1, startPos - 1)
  1013. }
  1014. }
  1015. }}
  1016. placeholder={intl.formatMessage({ id: 'idDocNumber' })}
  1017. fullWidth
  1018. sx={{ mr: 1 }}
  1019. error={Boolean(formik.touched.idNo && formik.errors.idNo)}
  1020. onBlur={formik.handleBlur}
  1021. inputProps={{
  1022. maxLength: 18,
  1023. onKeyDown: (e) => {
  1024. if (e.key === 'Enter') {
  1025. e.preventDefault();
  1026. }
  1027. },
  1028. }}
  1029. />
  1030. {formik.touched.idNo && formik.errors.idNo && (
  1031. <FormHelperText error id="helper-text-idNo-signup">
  1032. {formik.errors.idNo}
  1033. </FormHelperText>
  1034. )}
  1035. </Stack>
  1036. </Grid>
  1037. }
  1038. </Grid>
  1039. </Grid>
  1040. <Grid item xs={12} md={12}>
  1041. <Typography variant="subtitle1">
  1042. <FormattedMessage id="registerNameLabel" />
  1043. </Typography>
  1044. </Grid>
  1045. <Grid item xs={12} md={6}>
  1046. <Stack spacing={1}>
  1047. <InputLabel htmlFor="enName-signup">
  1048. <Typography variant="pnspsFormHeader">
  1049. <FormattedMessage id="userEnglishName" />
  1050. {selectedIdDocType.type === "CNID" ? "" : <span style={{ color: '#f10000' }}></span>}
  1051. </Typography>
  1052. </InputLabel>
  1053. <OutlinedInput
  1054. id="enName-login"
  1055. type="enName"
  1056. value={formik.values.enName}
  1057. name="enName"
  1058. onChange={formik.handleChange}
  1059. placeholder={intl.formatMessage({ id: 'sameAsYourIdDoc' })}
  1060. fullWidth
  1061. error={Boolean(formik.touched.enName && formik.errors.enName && selectedIdDocType.type !== "CNID")}
  1062. onBlur={formik.handleBlur}
  1063. inputProps={{
  1064. onKeyDown: (e) => {
  1065. if (e.key === 'Enter') {
  1066. e.preventDefault();
  1067. }
  1068. },
  1069. }}
  1070. />
  1071. {formik.touched.enName && formik.errors.enName && selectedIdDocType.type !== "CNID" && (
  1072. <FormHelperText error id="helper-text-enName-signup">
  1073. {formik.errors.enName}
  1074. </FormHelperText>
  1075. )}
  1076. </Stack>
  1077. </Grid>
  1078. <Grid item xs={12} md={6}>
  1079. <Stack spacing={1}>
  1080. <InputLabel htmlFor="chName-signup">
  1081. <Typography variant="pnspsFormHeader">
  1082. <FormattedMessage id="userChineseName" />
  1083. <span style={{ color: '#f10000' }}></span>
  1084. </Typography>
  1085. </InputLabel>
  1086. <OutlinedInput
  1087. fullWidth
  1088. error={Boolean(formik.touched.chName && formik.errors.chName)}
  1089. id="chName-signup"
  1090. type="text"
  1091. value={formik.values.chName.trim()}
  1092. name="chName"
  1093. onChange={formik.handleChange}
  1094. placeholder={intl.formatMessage({ id: 'sameAsYourIdDoc' })}
  1095. onBlur={formik.handleBlur}
  1096. inputProps={{
  1097. maxLength: 6,
  1098. onKeyDown: (e) => {
  1099. if (e.key === 'Enter') {
  1100. e.preventDefault();
  1101. }
  1102. },
  1103. }}
  1104. />
  1105. {formik.touched.chName && formik.errors.chName && (
  1106. <FormHelperText error id="helper-text-chName-signup">
  1107. {formik.errors.chName}
  1108. </FormHelperText>
  1109. )}
  1110. </Stack>
  1111. </Grid>
  1112. <Grid item xs={12}>
  1113. <Stack spacing={1}>
  1114. <InputLabel htmlFor="address1-signup">
  1115. <Typography variant="pnspsFormHeader">
  1116. <FormattedMessage id="formAddress" />
  1117. <span style={{ color: '#f10000' }}>*</span>
  1118. </Typography>
  1119. </InputLabel>
  1120. <OutlinedInput
  1121. fullWidth
  1122. error={Boolean(formik.touched.address1 && formik.errors.address1)}
  1123. id="address1-signup"
  1124. value={formik.values.address1}
  1125. name="address1"
  1126. onChange={formik.handleChange}
  1127. placeholder={intl.formatMessage({ id: 'addressLine1' })}
  1128. onBlur={formik.handleBlur}
  1129. inputProps={{
  1130. onKeyDown: (e) => {
  1131. if (e.key === 'Enter') {
  1132. e.preventDefault();
  1133. }
  1134. },
  1135. }}
  1136. />
  1137. <OutlinedInput
  1138. fullWidth
  1139. error={Boolean(formik.touched.address2 && formik.errors.address2)}
  1140. id="address2-signup"
  1141. value={formik.values.address2}
  1142. name="address2"
  1143. onChange={formik.handleChange}
  1144. onBlur={formik.handleBlur}
  1145. placeholder={intl.formatMessage({ id: 'addressLine2' })}
  1146. inputProps={{
  1147. onKeyDown: (e) => {
  1148. if (e.key === 'Enter') {
  1149. e.preventDefault();
  1150. }
  1151. },
  1152. }}
  1153. />
  1154. <OutlinedInput
  1155. fullWidth
  1156. error={Boolean(formik.touched.address3 && formik.errors.address3)}
  1157. id="address3-signup"
  1158. value={formik.values.address3}
  1159. name="address3"
  1160. onChange={formik.handleChange}
  1161. onBlur={formik.handleBlur}
  1162. placeholder={intl.formatMessage({ id: 'addressLine3' })}
  1163. inputProps={{
  1164. onKeyDown: (e) => {
  1165. if (e.key === 'Enter') {
  1166. e.preventDefault();
  1167. }
  1168. },
  1169. }}
  1170. />
  1171. <Autocomplete
  1172. disablePortal
  1173. id="address4-combo"
  1174. value={selectedAddress4}
  1175. options={ComboData.district}
  1176. disabled={checkCountry}
  1177. error={Boolean(districtErrStr != "")}
  1178. onBlur={formik.handleBlur}
  1179. getOptionLabel={(option) => option.type ? intl.formatMessage({ id: option.type }) : ""}
  1180. onChange={(event, newValue) => {
  1181. setSelectedAddress4(newValue);
  1182. }}
  1183. sx={{
  1184. "& .MuiInputBase-root": { height: "41px" },
  1185. "#address4-combo": { padding: "0px 0px 0px 3px" },
  1186. "& .MuiAutocomplete-endAdornment": { top: "auto" },
  1187. }}
  1188. renderInput={(params) => <TextField {...params} placeholder={intl.formatMessage({ id: 'region' })}
  1189. />}
  1190. />
  1191. <Autocomplete
  1192. disablePortal
  1193. id="address5-combo"
  1194. value={selectedAddress5}
  1195. options={ComboData.country}
  1196. getOptionLabel={(option) => option.type ? intl.formatMessage({ id: option.type }) : ""}
  1197. onChange={(event, newValue) => {
  1198. if (newValue !== null) {
  1199. setSelectedAddress5(newValue);
  1200. if (newValue.type === 'hongKong') {
  1201. setCheckCountry(false)
  1202. } else {
  1203. setSelectedAddress4("");
  1204. setCheckCountry(true)
  1205. }
  1206. } else {
  1207. setSelectedAddress4("");
  1208. setCheckCountry(true)
  1209. }
  1210. }}
  1211. sx={{ "& .MuiInputBase-root": { height: "41px" }, "#address5-combo": { padding: "0px 0px 0px 3px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }}
  1212. renderInput={(params) => <TextField {...params} placeholder={intl.formatMessage({ id: 'regionOrCountry' })} />}
  1213. />
  1214. {formik.touched.address1 && formik.errors.address1 && (
  1215. <FormHelperText error id="helper-text-address1-signup">
  1216. {formik.errors.address1}
  1217. </FormHelperText>
  1218. )}
  1219. {formik.touched.address2 && formik.errors.address2 && (
  1220. <FormHelperText error id="helper-text-address2-signup">
  1221. {formik.errors.address2}
  1222. </FormHelperText>
  1223. )}
  1224. {formik.touched.address3 && formik.errors.address3 && (
  1225. <FormHelperText error id="helper-text-address3-signup">
  1226. {formik.errors.address3}
  1227. </FormHelperText>
  1228. )}
  1229. {/* {districtErrStr != "" && (
  1230. <FormHelperText error >
  1231. {districtErrStr}
  1232. </FormHelperText>
  1233. )} */}
  1234. </Stack>
  1235. </Grid>
  1236. <Grid item xs={12} mt={1} mb={1}>
  1237. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1238. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1239. <FormattedMessage id="yourContact" />
  1240. </Typography>
  1241. </Stack>
  1242. </Grid>
  1243. <Grid item xs={12} md={12}>
  1244. <Grid container>
  1245. <Grid item xs={12} md={6}>
  1246. <Stack spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}>
  1247. <InputLabel htmlFor="email-signup">
  1248. <Typography variant="pnspsFormHeader">
  1249. <FormattedMessage id="userContactEmail" />
  1250. <span style={{ color: '#f10000' }}>*</span>
  1251. </Typography>
  1252. </InputLabel>
  1253. <OutlinedInput
  1254. fullWidth
  1255. error={Boolean((formik.touched.email && formik.errors.email) || checkEmail)}
  1256. id="email-login"
  1257. type="email"
  1258. value={formik.values.email.trim()}
  1259. name="email"
  1260. onChange={formik.handleChange}
  1261. placeholder={intl.formatMessage({ id: 'userContactEmail' })}
  1262. onBlur={formik.handleBlur}
  1263. inputProps={{
  1264. onKeyDown: (e) => {
  1265. if (e.key === 'Enter') {
  1266. e.preventDefault();
  1267. }
  1268. },
  1269. }}
  1270. />
  1271. {formik.touched.email && formik.errors.email && (
  1272. <FormHelperText error id="helper-text-email-signup">
  1273. {formik.errors.email}
  1274. </FormHelperText>
  1275. )}
  1276. {checkEmail && (
  1277. <FormHelperText error id="helper-text-email-signup">
  1278. <FormattedMessage id="emailUsed" />
  1279. </FormHelperText>
  1280. )}
  1281. </Stack>
  1282. </Grid>
  1283. <Grid item xs={12} md={6}>
  1284. <Stack spacing={1} >
  1285. <InputLabel htmlFor="emailConfirm-signup">
  1286. <Typography variant="pnspsFormHeader">
  1287. <FormattedMessage id="confirmEmail" />
  1288. <span style={{ color: '#f10000' }}>*</span>
  1289. </Typography>
  1290. </InputLabel>
  1291. <OutlinedInput
  1292. fullWidth
  1293. error={Boolean(formik.touched.emailConfirm && formik.errors.emailConfirm)}
  1294. id="emailConfirm-login"
  1295. type="email"
  1296. value={formik.values.emailConfirm.trim()}
  1297. name="emailConfirm"
  1298. // onBlur={formik.handleBlur}
  1299. onChange={formik.handleChange}
  1300. placeholder={intl.formatMessage({ id: 'confirmEmail' })}
  1301. onBlur={formik.handleBlur}
  1302. onCut={handleCCPChange}
  1303. onCopy={handleCCPChange}
  1304. onPaste={handleCCPChange}
  1305. inputProps={{
  1306. onKeyDown: (e) => {
  1307. if (e.key === 'Enter') {
  1308. e.preventDefault();
  1309. }
  1310. },
  1311. }}
  1312. />
  1313. {formik.touched.emailConfirm && formik.errors.emailConfirm && (
  1314. <FormHelperText error id="helper-text-emailConfirm-signup">
  1315. {formik.errors.emailConfirm}
  1316. </FormHelperText>
  1317. )}
  1318. </Stack>
  1319. </Grid>
  1320. </Grid>
  1321. </Grid>
  1322. <Grid item xs={12} md={12}>
  1323. <Grid container>
  1324. <Grid item xs={12} md={6}>
  1325. <Grid container>
  1326. <Grid item xs={12} md={12}>
  1327. <Stack direction="column" spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}>
  1328. <InputLabel htmlFor="phone-signup">
  1329. <Typography variant="pnspsFormHeader">
  1330. <FormattedMessage id="userContactNumber" />
  1331. <span style={{ color: '#f10000' }}>*</span>
  1332. </Typography>
  1333. </InputLabel>
  1334. <Stack direction="row">
  1335. <OutlinedInput
  1336. id="phoneCountryCode-login"
  1337. type="phoneCountryCode"
  1338. value={formik.values.phoneCountryCode.trim()}
  1339. name="phoneCountryCode"
  1340. // onBlur={formik.handleBlur}
  1341. // onChange={formik.handleChange}
  1342. onChange={(event) => {
  1343. const value = event.target.value;
  1344. if (value.match(/[^0-9]/)) {
  1345. return event.preventDefault();
  1346. }
  1347. formik.setFieldValue("phoneCountryCode", value);
  1348. }}
  1349. placeholder={intl.formatMessage({ id: 'dialingCode' })}
  1350. error={Boolean(formik.touched.phone && formik.errors.phone)}
  1351. onBlur={formik.handleBlur}
  1352. endAdornment={<InputAdornment position="end">-</InputAdornment>}
  1353. inputProps={{
  1354. maxLength: 3,
  1355. onKeyDown: (e) => {
  1356. if (e.key === 'Enter') {
  1357. e.preventDefault();
  1358. }
  1359. },
  1360. }}
  1361. sx={{ width: '33%', mr: 1 }}
  1362. />
  1363. <OutlinedInput
  1364. id="phone-login"
  1365. type="phone"
  1366. value={formik.values.phone.trim()}
  1367. name="phone"
  1368. // onBlur={formik.handleBlur}
  1369. // onChange={formik.handleChange}
  1370. onChange={(event) => {
  1371. const value = event.target.value;
  1372. if (value.match(/[^0-9]/)) {
  1373. return event.preventDefault();
  1374. }
  1375. formik.setFieldValue("phone", value);
  1376. }}
  1377. placeholder={intl.formatMessage({ id: 'userContactNumber' })}
  1378. error={Boolean(formik.touched.phone && formik.errors.phone)}
  1379. onBlur={formik.handleBlur}
  1380. inputProps={{
  1381. maxLength: 11,
  1382. onKeyDown: (e) => {
  1383. if (e.key === 'Enter') {
  1384. e.preventDefault();
  1385. }
  1386. },
  1387. }}
  1388. sx={{ width: '66%' }}
  1389. />
  1390. </Stack>
  1391. {formik.touched.phone && formik.errors.phone && (
  1392. <FormHelperText error id="helper-text-phone-signup">
  1393. {formik.errors.phone}
  1394. </FormHelperText>
  1395. )}
  1396. </Stack>
  1397. </Grid>
  1398. </Grid>
  1399. </Grid>
  1400. <Grid item xs={12} md={6}>
  1401. <Grid container>
  1402. <Grid item xs={12} md={12}>
  1403. <Stack spacing={1} direction="column">
  1404. <InputLabel htmlFor="fax-signup">
  1405. <Typography variant="pnspsFormHeader">
  1406. <FormattedMessage id="userFaxNumber" />
  1407. </Typography>
  1408. </InputLabel>
  1409. <Stack direction="row">
  1410. <OutlinedInput
  1411. error={Boolean(formik.touched.fax && formik.errors.fax)}
  1412. id="faxCountryCode-login"
  1413. type="faxCountryCode"
  1414. value={formik.values.faxCountryCode.trim()}
  1415. name="faxCountryCode"
  1416. // onChange={formik.handleChange}
  1417. onChange={(event) => {
  1418. const value = event.target.value;
  1419. if (value.match(/[^0-9]/)) {
  1420. return event.preventDefault();
  1421. }
  1422. formik.setFieldValue("faxCountryCode", value);
  1423. }}
  1424. placeholder={intl.formatMessage({ id: 'dialingCode' })}
  1425. onBlur={formik.handleBlur}
  1426. endAdornment={<InputAdornment position="end">-</InputAdornment>}
  1427. inputProps={{
  1428. maxLength: 3,
  1429. onKeyDown: (e) => {
  1430. if (e.key === 'Enter') {
  1431. e.preventDefault();
  1432. }
  1433. },
  1434. }}
  1435. sx={{ width: '33%', mr: 1 }}
  1436. />
  1437. <OutlinedInput
  1438. id="fax-login"
  1439. type="fax"
  1440. value={formik.values.fax.trim()}
  1441. name="fax"
  1442. onBlur={formik.handleBlur}
  1443. // onChange={formik.handleChange}
  1444. onChange={(event) => {
  1445. const value = event.target.value;
  1446. if (value.match(/[^0-9]/)) {
  1447. return event.preventDefault();
  1448. }
  1449. formik.setFieldValue("fax", value);
  1450. }}
  1451. placeholder={intl.formatMessage({ id: 'userFaxNumber' })}
  1452. inputProps={{
  1453. maxLength: 8,
  1454. onKeyDown: (e) => {
  1455. if (e.key === 'Enter') {
  1456. e.preventDefault();
  1457. }
  1458. },
  1459. }}
  1460. sx={{ width: '66%' }}
  1461. />
  1462. </Stack>
  1463. </Stack>
  1464. </Grid>
  1465. </Grid>
  1466. </Grid>
  1467. </Grid>
  1468. </Grid>
  1469. <Grid item xs={12} md={12} mt={1} mb={1}>
  1470. <Grid container>
  1471. <Grid item xs={12} md={12}>
  1472. <Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1473. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1474. <FormattedMessage id="userIdDoc" />
  1475. <span style={{ color: '#f10000' }}>*</span></Typography>
  1476. <Typography display="inline" variant="subtitle1" sx={{ color: 'primary.primary' }}>
  1477. <FormattedMessage id="pleaseUploadIdDoc" />
  1478. </Typography>
  1479. <Typography display="inline" variant="subtitle1" sx={{ color: 'primary.primary' }}>
  1480. <FormattedMessage id="pleaseUploadIdDocSubTitle" />
  1481. </Typography>
  1482. <Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}>
  1483. <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}>
  1484. <Button variant="contained" component="label" sx={{ height: '40px' }}>
  1485. <FormattedMessage id="uploadIdDoc" />
  1486. <input
  1487. accept="image/png, .jpg, .bmp, .pdf"
  1488. //className={classes.input}
  1489. id="contained-button-file"
  1490. multiple
  1491. type="file"
  1492. onChange={handleFileUpload}
  1493. style={{ display: 'none' }}
  1494. />
  1495. </Button>
  1496. </ThemeProvider>
  1497. {/*<Typography xs={12} sm={9} md={3} display="inline" variant="subtitle1" sx={{ color: 'primary.primary' }}>如: 香港身份證; 護照; 中國內地身份證等</Typography>*/}
  1498. </Stack>
  1499. {fileList != null ?
  1500. <UploadFileTable key="uploadTable" recordList={fileListData} setUpdateRows={setUpdateRows} /> : null}
  1501. {/* <Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}>
  1502. <Button variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button>
  1503. <Button disabled={!formik.isValid} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button>
  1504. </Stack> */}
  1505. </Stack>
  1506. </Grid>
  1507. </Grid>
  1508. </Grid>
  1509. </Grid>
  1510. <Grid item xs={12} md={12}>
  1511. <Grid container>
  1512. <Grid item xs={12} md={12}>
  1513. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1514. <FormattedMessage id="termsAndCondition" />
  1515. <span style={{ color: '#f10000' }}>*</span>
  1516. </Typography>
  1517. </Grid>
  1518. <Grid item xs={12} md={12}>
  1519. <Grid container>
  1520. <Grid item xs={12} md={12}>
  1521. <Typography variant="h6" height="100%" sx={{ textAlign: "left", /*overflow: "scroll",*/ borderRadius: "inherit", borderStyle: "solid", borderWidth: "1px", borderColor: "#0C489E" }}>
  1522. <div style={{padding: 12}} dangerouslySetInnerHTML={{__html: intl.formatMessage({id: "termsAndCon"})}} />
  1523. </Typography>
  1524. </Grid>
  1525. </Grid>
  1526. <Grid item xs={12} s={12} md={12} lg={12}>
  1527. <Grid container>
  1528. <Grid item xs={6} s={6} md={2} lg={2}>
  1529. <Grid container>
  1530. <Grid item sx={{ display: 'flex', alignItems: 'center' }}>
  1531. <Checkbox
  1532. checked={termsAndConAccept}
  1533. onChange={handleCheckBoxChange}
  1534. name="termsAndConAccept"
  1535. color="primary"
  1536. size="small"
  1537. />
  1538. <Typography variant="pnspsFormHeader">
  1539. <FormattedMessage id="acceptTerms" />
  1540. </Typography>
  1541. </Grid>
  1542. </Grid>
  1543. </Grid>
  1544. <Grid item xs={6} s={6} md={3} lg={3}>
  1545. <Grid container>
  1546. <Grid item sx={{ display: 'flex', alignItems: 'center' }}>
  1547. <Checkbox
  1548. checked={termsAndConNotAccept}
  1549. onChange={handleCheckBoxChange}
  1550. name="termsAndConNotAccept"
  1551. color="primary"
  1552. size="small"
  1553. />
  1554. <Typography variant="pnspsFormHeader">
  1555. <FormattedMessage id="rejectTerms" />
  1556. </Typography>
  1557. </Grid>
  1558. </Grid>
  1559. </Grid>
  1560. </Grid>
  1561. </Grid>
  1562. </Grid>
  1563. </Grid>
  1564. </Grid>
  1565. <Grid item xs={12} lg={12}>
  1566. <Grid container>
  1567. <Stack direction="column">
  1568. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1569. <FormattedMessage id="verify" />
  1570. <span style={{ color: '#f10000' }}>*</span>
  1571. </Typography>
  1572. <Stack spacing={1} direction="row">
  1573. <Grid item xs={5} lg={5} style={{ "border": "1px solid black" }}>
  1574. <img src={captchaImg} alt="" />
  1575. </Grid>
  1576. <Grid item xs={1} lg={1} style={{ "border": "0px solid black" }}>
  1577. <IconButton aria-label="refrashCaptcha" size="large" onClick={() => { onCaptchaChange() }}>
  1578. <LoopIcon fontSize="inherit" />
  1579. </IconButton>
  1580. </Grid>
  1581. <Grid item xs={6} lg={6}>
  1582. <OutlinedInput
  1583. fullWidth
  1584. id="captchaField"
  1585. type="text"
  1586. value={formik.values.captchaField.trim()}
  1587. onBlur={formik.handleBlur}
  1588. error={Boolean(formik.touched.captchaField && formik.errors.captchaField)}
  1589. name="captchaField"
  1590. onChange={(event) => {
  1591. const value = event.target.value;
  1592. props.setCheckCode(event.target.value);
  1593. setCheckCode(event.target.value);
  1594. formik.setFieldValue("captchaField", value);
  1595. }}
  1596. sx={{ width: '75%' }}
  1597. />
  1598. </Grid>
  1599. </Stack>
  1600. {formik.touched.captchaField && formik.errors.captchaField && (
  1601. <FormHelperText error id="helper-text-captcha-signup">
  1602. {formik.errors.captchaField}
  1603. </FormHelperText>
  1604. )}
  1605. </Stack>
  1606. </Grid>
  1607. </Grid>
  1608. </Grid>
  1609. </Grid>
  1610. </FormGroup>
  1611. {/* Preview Form */}
  1612. <FormGroup id={"previewForm"} sx={{ display: props.step === 1 ? "" : "none" }}>
  1613. <Grid container spacing={3}>
  1614. <Grid item xs={12} md={12}>
  1615. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1616. <div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}>
  1617. <Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>
  1618. <FormattedMessage id="becomeNewPersonalUser" />
  1619. </Typography>
  1620. </div>
  1621. {/* <Typography mt={0.25} variant="h6" sx={{ fontSize: 12,color: '#f10000'}}>註有*的項目必須輸入資料</Typography> */}
  1622. <Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary' }}>
  1623. <FormattedMessage id="yourLoginInformation" />
  1624. </Typography>
  1625. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  1626. Already have an account?
  1627. </Typography> */}
  1628. </Stack>
  1629. </Grid>
  1630. <Grid item xs={12} md={12}>
  1631. <Grid container spacing={2}>
  1632. <Grid item xs={12} >
  1633. <Stack spacing={2} direction="row">
  1634. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1635. <FormattedMessage id="userLoginName" />:
  1636. </Typography>
  1637. <Typography variant="pnspsFormHeader" id="preview-username-login">
  1638. {formik.values.username}
  1639. </Typography>
  1640. </Stack>
  1641. </Grid>
  1642. <Grid item xs={12} mt={1} mb={1}>
  1643. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1644. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1645. <FormattedMessage id="yourPersonalInformation" />
  1646. </Typography>
  1647. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  1648. Already have an account?
  1649. </Typography> */}
  1650. </Stack>
  1651. </Grid>
  1652. {/* <Grid item xs={12} md={12} >
  1653. <Stack spacing={1}>
  1654. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1655. <FormattedMessage id="userIdDoc" />
  1656. </Typography>
  1657. </Stack>
  1658. </Grid> */}
  1659. <Grid item xs={12} md={6} >
  1660. <Stack spacing={1} direction="row" >
  1661. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1662. <FormattedMessage id="idDocType" />:
  1663. </Typography>
  1664. <Typography variant="pnspsFormHeader" name="preview-idDocType">
  1665. {selectedIdDocType?.label? intl.formatMessage({ id: selectedIdDocType.label}): " "}
  1666. </Typography>
  1667. </Stack>
  1668. </Grid>
  1669. <Grid item xs={12} md={6}>
  1670. <Stack direction="row" >
  1671. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]} sx={{mr:1}}>
  1672. <FormattedMessage id="idDocNumber" />:
  1673. </Typography>
  1674. <Typography variant="pnspsFormHeader" id="idNo-f4-login">
  1675. {formik.values.idNo.slice(0, 4)}
  1676. </Typography>
  1677. <Typography variant="pnspsFormHeader" id="idNo-exf4-login"
  1678. type={showId ? "text" : "password"}
  1679. >
  1680. {showId ?formik.values.idNo.slice(4):"****"}{showId ?selectedIdDocType.type == "HKID" ? '(' + formik.values.checkDigit + ')' : null:null}
  1681. </Typography>
  1682. <IconButton
  1683. aria-label="toggle id visibility"
  1684. onClick={handleClickShowId}
  1685. onMouseDown={handleMouseDownId}
  1686. edge="end"
  1687. size="medium"
  1688. >
  1689. {showId ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  1690. </IconButton>
  1691. </Stack>
  1692. </Grid>
  1693. <Grid item xs={12} md={6}>
  1694. <Stack spacing={1} direction="row">
  1695. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1696. <FormattedMessage id="userEnglishName" />:
  1697. </Typography>
  1698. <Typography variant="pnspsFormHeader" id="preview-enName-signup">
  1699. {formik.values.enName}
  1700. </Typography>
  1701. </Stack>
  1702. </Grid>
  1703. <Grid item xs={12} md={6}>
  1704. <Stack spacing={1} direction="row">
  1705. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1706. <FormattedMessage id="userChineseName" />:
  1707. </Typography>
  1708. <Typography variant="pnspsFormHeader" id="preview-chName-signup">
  1709. {formik.values.chName}
  1710. </Typography>
  1711. </Stack>
  1712. </Grid>
  1713. <Grid item xs={12}>
  1714. <Stack spacing={1} direction="column">
  1715. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1716. <FormattedMessage id="formAddress" />:
  1717. </Typography>
  1718. <Stack spacing={1} direction="column">
  1719. <Typography variant="pnspsFormHeader" id="preview-address1-signup">
  1720. {formik.values.address1}
  1721. </Typography>
  1722. {formik.values.address2 != null ?
  1723. <Typography variant="pnspsFormHeader" id="preview-address2-signup">
  1724. {formik.values.address2}
  1725. </Typography>
  1726. : null}
  1727. {formik.values.address3 != null ?
  1728. <Typography variant="pnspsFormHeader" id="preview-address3-signup">
  1729. {formik.values.address3}
  1730. </Typography>
  1731. : null}
  1732. {selectedAddress5.type === "hongKong" ?
  1733. <Stack direction="column">
  1734. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]} id="preview-address4-signup">
  1735. <FormattedMessage id="region" />:
  1736. </Typography>
  1737. <Typography variant="pnspsFormHeader">
  1738. {!selectedAddress4 ? "" : intl.formatMessage({ id: selectedAddress4.type })}
  1739. </Typography>
  1740. </Stack>
  1741. : null}
  1742. <Stack direction="column">
  1743. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]} id="preview-address5-signup">
  1744. <FormattedMessage id="regionOrCountry" />:
  1745. </Typography>
  1746. <Typography variant="pnspsFormHeader">
  1747. {intl.formatMessage({ id: selectedAddress5.type })}
  1748. </Typography>
  1749. </Stack>
  1750. </Stack>
  1751. </Stack>
  1752. </Grid>
  1753. <Grid item xs={12} mt={1} mb={1}>
  1754. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1755. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1756. <FormattedMessage id="yourContact" />
  1757. </Typography>
  1758. </Stack>
  1759. </Grid>
  1760. <Grid item xs={12} md={12}>
  1761. <Stack spacing={1} direction="row">
  1762. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1763. <FormattedMessage id="userContactEmail" />:
  1764. </Typography>
  1765. <Typography variant="pnspsFormHeader" id="preview-email-signup">
  1766. {formik.values.email}
  1767. </Typography>
  1768. </Stack>
  1769. </Grid>
  1770. <Grid item xs={12} md={6}>
  1771. <Stack spacing={1} direction="row">
  1772. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1773. <FormattedMessage id="userContactNumber" />:
  1774. </Typography>
  1775. <Typography variant="pnspsFormHeader" id="preview-phone-signup">
  1776. +{formik.values.phoneCountryCode} {formik.values.phone}
  1777. </Typography>
  1778. </Stack>
  1779. </Grid>
  1780. {formik.values.faxCountryCode != "" && formik.values.fax != "" ?
  1781. <Grid item xs={12} md={6}>
  1782. <Stack spacing={1} direction="row">
  1783. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1784. <FormattedMessage id="userFaxNumber" />:
  1785. </Typography>
  1786. <Typography variant="pnspsFormHeader" id="preview-fax-signup">
  1787. +{formik.values.faxCountryCode} {formik.values.fax}
  1788. </Typography>
  1789. </Stack>
  1790. </Grid>
  1791. : null}
  1792. <Grid item xs={12} md={12} mt={1} mb={1}>
  1793. <Grid container>
  1794. <Grid item xs={12} md={12}>
  1795. <Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1796. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1797. <FormattedMessage id="userIdDoc" />
  1798. </Typography>
  1799. {fileList != null ?
  1800. <PreviewUploadFileTable key="previewTable" recordList={fileListData} /> : null}
  1801. </Stack>
  1802. </Grid>
  1803. </Grid>
  1804. </Grid>
  1805. </Grid>
  1806. </Grid>
  1807. </Grid>
  1808. </FormGroup>
  1809. {/* Submit page */}
  1810. <FormGroup id={"submitForm"} sx={{ display: props.step === 2 ? "" : "none" }}>
  1811. <Grid container spacing={3}>
  1812. {isLoading ?
  1813. <LoadingComponent /> :
  1814. <Grid item xs={12}>
  1815. {checkUpload ?
  1816. // SUCCESS page
  1817. <Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
  1818. <CheckCircleOutlineIcon color="success" sx={{ width: "200px", height: "200px" }} />
  1819. <Typography display="inline" variant="h4">
  1820. <FormattedMessage id="registerSubmitted" />
  1821. </Typography>
  1822. <Typography display="inline" variant="h4">
  1823. <FormattedMessage id="emailSent" />
  1824. </Typography>
  1825. <Button variant="outlined" component={Link} to="/login" ><Typography variant="pnspsFormHeader">
  1826. <FormattedMessage id="backToLogin" />
  1827. </Typography></Button>
  1828. </Stack>
  1829. :
  1830. // ERROR page
  1831. <Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
  1832. {/* <Button disabled={true} hidden={true} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> */}
  1833. <CancelOutlinedIcon color="error" sx={{ width: "200px", height: "200px" }} />
  1834. <Typography display="inline" variant="h4">
  1835. <FormattedMessage id="registerFail" />
  1836. </Typography>
  1837. <Button color="error" variant="outlined" component={Link} to="/login" ><Typography variant="pnspsFormHeader">
  1838. <FormattedMessage id="backToLogin" />
  1839. </Typography></Button>
  1840. </Stack>
  1841. }
  1842. </Grid>
  1843. }
  1844. </Grid>
  1845. </FormGroup>
  1846. </form>
  1847. </FormikProvider>
  1848. );
  1849. }
  1850. export default CustomFormWizard;