您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

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