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

1932 行
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 = /^(?=.*\W)/;
  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 = /^(?=.*\W)/;
  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(/^(?=.*\W)/, { 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. onCut={handleCCPChange}
  800. onCopy={handleCCPChange}
  801. onPaste={handleCCPChange}
  802. onChange={(e) => {
  803. formik.handleChange(e);
  804. // changePassword(e.target.value);
  805. }}
  806. inputProps={{
  807. onKeyDown: (e) => {
  808. if (e.key === 'Enter') {
  809. e.preventDefault();
  810. }
  811. },
  812. }}
  813. endAdornment={
  814. <InputAdornment position="end">
  815. <IconButton
  816. aria-label="toggle password visibility"
  817. onClick={handleClickShowConfirmPassword}
  818. onMouseDown={handleMouseDownPassword}
  819. edge="end"
  820. size="large"
  821. >
  822. {showConfirmPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  823. </IconButton>
  824. </InputAdornment>
  825. }
  826. placeholder={intl.formatMessage({ id: 'confirmPassword' })}
  827. fullWidth
  828. error={Boolean(formik.touched.confirmPassword && formik.errors.confirmPassword)}
  829. />
  830. {formik.touched.confirmPassword && formik.errors.confirmPassword && (
  831. <FormHelperText error id="helper-text-confirmPassword-signup">
  832. {formik.errors.confirmPassword}
  833. </FormHelperText>
  834. )}
  835. </Stack>
  836. <Grid container spacing={2} alignItems="center">
  837. <Grid item sx={{ mt: 1 }}>
  838. <Typography variant="subtitle1">
  839. •<FormattedMessage id="pwRemark1" /><br />
  840. •<FormattedMessage id="pwRemark2" /><br />
  841. •<FormattedMessage id="pwRemark3" /><br />
  842. •<FormattedMessage id="pwRemark4" /><br />
  843. •<FormattedMessage id="pwRemark5"/><br />
  844. </Typography>
  845. </Grid>
  846. </Grid>
  847. </Grid>
  848. </Grid>
  849. </Grid>
  850. <Grid item xs={12} mt={1} mb={1}>
  851. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  852. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  853. <FormattedMessage id="yourPersonalInformation" />
  854. </Typography>
  855. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  856. Already have an account?
  857. </Typography> */}
  858. </Stack>
  859. </Grid>
  860. <Grid item xs={12} md={12} >
  861. <Grid container sx={{ mb: 1 }}>
  862. <Stack spacing={1}>
  863. <InputLabel htmlFor="idDocType-signup">
  864. <Typography variant="pnspsFormHeader">
  865. <FormattedMessage id="userIdDoc" />
  866. <span style={{ color: '#f10000' }}>*</span>
  867. </Typography>
  868. </InputLabel>
  869. {/* {formik.touched.enName && formik.errors.enName && (
  870. <FormHelperText error id="helper-text-enName-signup">
  871. {formik.errors.enName}
  872. </FormHelperText>
  873. )} */}
  874. </Stack>
  875. </Grid>
  876. <Grid container>
  877. <Grid item xs={12} md={6} >
  878. <Stack spacing={1} sx={{ mr: { md: 1 } }}>
  879. <Autocomplete
  880. disablePortal
  881. id="idDocType"
  882. //value={selectedIdDocType}
  883. size="small"
  884. options={idDocTypeComboList}
  885. onBlur={formik.handleBlur}
  886. filterOptions={(options) => options}
  887. inputValue={selectedIdDocInputType}
  888. getOptionLabel={(option) => option.label ? intl.formatMessage({ id: option.label }) : ""}
  889. onChange={(event, newValue) => {
  890. if (newValue != null) {
  891. setSelectedIdDocInputType(intl.formatMessage({ id: newValue.label }));
  892. setSelectedIdDocType(newValue);
  893. if (newValue.type !== "HKID") {
  894. formik.setFieldValue("checkDigit", "")
  895. }
  896. } else {
  897. setSelectedIdDocInputType("");
  898. setSelectedIdDocType({});
  899. }
  900. }}
  901. sx={{ "#address4-combo": { padding: "0px 0px 0px 0px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }}
  902. renderInput={(params) => <TextField
  903. {...params}
  904. error={formik.touched.idDocType && (selectedIdDocType === null || selectedIdDocType?.type == null)}
  905. placeholder={intl.formatMessage({ id: 'idDocType' })}
  906. />}
  907. />
  908. {formik.touched.idDocType && (
  909. selectedIdDocType === null || selectedIdDocType?.type == null ?
  910. <FormHelperText error id="helper-text-idDocType-signup" sx={{ fontSize: 16, fontWeight: 'bold', }}>
  911. <FormattedMessage id="requireIdDocType" />
  912. </FormHelperText> : ''
  913. )}
  914. </Stack>
  915. </Grid>
  916. {selectedIdDocType.type === "HKID" ?
  917. <>
  918. <Grid item xs={9} md={5}>
  919. <Stack spacing={1} sx={{ mr: { md: 1 } }}>
  920. <OutlinedInput
  921. id="idNo-login"
  922. type="text"
  923. name="idNo"
  924. value={formik.values.idNo}
  925. onChange={async (e) => {
  926. const ele = document.getElementById('idNo-login')
  927. const startPos = ele.selectionStart
  928. if (e.type === "change") {
  929. if (!(e.target.value.match(/\s/g))) {
  930. const newValue = await e.target.value.toUpperCase()
  931. await formik.setFieldValue("idNo", newValue)
  932. ele.setSelectionRange(startPos, startPos)
  933. } else {
  934. await formik.setFieldValue("idNo", formik.values.idNo)
  935. ele.setSelectionRange(startPos - 1, startPos - 1)
  936. }
  937. }
  938. }}
  939. placeholder={intl.formatMessage({ id: 'idDocNumber' })}
  940. fullWidth
  941. sx={{ mr: 1 }}
  942. error={Boolean(formik.touched.idNo && formik.errors.idNo)}
  943. onBlur={formik.handleBlur}
  944. inputProps={{
  945. maxLength: selectedIdDocType.type === 'HKID' ? 8 : 18,
  946. onKeyDown: (e) => {
  947. // console.log(e)
  948. if (e.key === 'Enter') {
  949. e.preventDefault();
  950. }
  951. },
  952. }}
  953. />
  954. {formik.touched.idNo && formik.errors.idNo && (
  955. <FormHelperText error id="helper-text-idNo-signup">
  956. {formik.errors.idNo}
  957. </FormHelperText>
  958. )}
  959. {formik.touched.checkDigit && formik.errors.checkDigit && (
  960. <FormHelperText error id="helper-text-checkDigit-signup">
  961. {formik.errors.checkDigit}
  962. </FormHelperText>
  963. )}
  964. </Stack>
  965. </Grid>
  966. <Grid item xs={3} md={1}>
  967. <Stack spacing={1}>
  968. <OutlinedInput
  969. id="checkDigit-login"
  970. type="text"
  971. value={formik.values.checkDigit.trim()}
  972. name="checkDigit"
  973. onChange={formik.handleChange}
  974. //placeholder="( )"
  975. // sx={{height:"53px"}}
  976. startAdornment={<InputAdornment position="start">(</InputAdornment>}
  977. endAdornment={<InputAdornment position="end">)</InputAdornment>}
  978. sx={{
  979. '& .MuiOutlinedInput-input': {
  980. padding: '5px 2px 5px 2px', // Set the desired padding inline
  981. },
  982. }}
  983. inputProps={{
  984. maxLength: 1,
  985. onKeyDown: (e) => {
  986. if (e.key === 'Enter') {
  987. e.preventDefault();
  988. }
  989. },
  990. }}
  991. fullWidth
  992. error={Boolean(formik.touched.checkDigit && formik.errors.checkDigit)}
  993. onBlur={formik.handleBlur}
  994. />
  995. </Stack>
  996. </Grid>
  997. </> :
  998. <Grid item xs={12} md={6}>
  999. <Stack spacing={1}>
  1000. <OutlinedInput
  1001. id="idNo-login"
  1002. type="text"
  1003. value={formik.values.idNo}
  1004. name="idNo"
  1005. onChange={async (e) => {
  1006. const ele = document.getElementById('idNo-login')
  1007. const startPos = ele.selectionStart
  1008. if (e.type === "change") {
  1009. if (!(e.target.value.match(/\s/g))) {
  1010. const newValue = await e.target.value.toUpperCase()
  1011. await formik.setFieldValue("idNo", newValue)
  1012. ele.setSelectionRange(startPos, startPos)
  1013. } else {
  1014. await formik.setFieldValue("idNo", formik.values.idNo)
  1015. ele.setSelectionRange(startPos - 1, startPos - 1)
  1016. }
  1017. }
  1018. }}
  1019. placeholder={intl.formatMessage({ id: 'idDocNumber' })}
  1020. fullWidth
  1021. sx={{ mr: 1 }}
  1022. error={Boolean(formik.touched.idNo && formik.errors.idNo)}
  1023. onBlur={formik.handleBlur}
  1024. inputProps={{
  1025. maxLength: 18,
  1026. onKeyDown: (e) => {
  1027. if (e.key === 'Enter') {
  1028. e.preventDefault();
  1029. }
  1030. },
  1031. }}
  1032. />
  1033. {formik.touched.idNo && formik.errors.idNo && (
  1034. <FormHelperText error id="helper-text-idNo-signup">
  1035. {formik.errors.idNo}
  1036. </FormHelperText>
  1037. )}
  1038. </Stack>
  1039. </Grid>
  1040. }
  1041. </Grid>
  1042. </Grid>
  1043. <Grid item xs={12} md={12}>
  1044. <Typography variant="subtitle1">
  1045. <FormattedMessage id="registerNameLabel" />
  1046. </Typography>
  1047. </Grid>
  1048. <Grid item xs={12} md={6}>
  1049. <Stack spacing={1}>
  1050. <InputLabel htmlFor="enName-signup">
  1051. <Typography variant="pnspsFormHeader">
  1052. <FormattedMessage id="userEnglishName" />
  1053. {selectedIdDocType.type === "CNID" ? "" : <span style={{ color: '#f10000' }}></span>}
  1054. </Typography>
  1055. </InputLabel>
  1056. <OutlinedInput
  1057. id="enName-login"
  1058. type="enName"
  1059. value={formik.values.enName}
  1060. name="enName"
  1061. onChange={formik.handleChange}
  1062. placeholder={intl.formatMessage({ id: 'sameAsYourIdDoc' })}
  1063. fullWidth
  1064. error={Boolean(formik.touched.enName && formik.errors.enName && selectedIdDocType.type !== "CNID")}
  1065. onBlur={formik.handleBlur}
  1066. inputProps={{
  1067. onKeyDown: (e) => {
  1068. if (e.key === 'Enter') {
  1069. e.preventDefault();
  1070. }
  1071. },
  1072. }}
  1073. />
  1074. {formik.touched.enName && formik.errors.enName && selectedIdDocType.type !== "CNID" && (
  1075. <FormHelperText error id="helper-text-enName-signup">
  1076. {formik.errors.enName}
  1077. </FormHelperText>
  1078. )}
  1079. </Stack>
  1080. </Grid>
  1081. <Grid item xs={12} md={6}>
  1082. <Stack spacing={1}>
  1083. <InputLabel htmlFor="chName-signup">
  1084. <Typography variant="pnspsFormHeader">
  1085. <FormattedMessage id="userChineseName" />
  1086. <span style={{ color: '#f10000' }}></span>
  1087. </Typography>
  1088. </InputLabel>
  1089. <OutlinedInput
  1090. fullWidth
  1091. error={Boolean(formik.touched.chName && formik.errors.chName)}
  1092. id="chName-signup"
  1093. type="text"
  1094. value={formik.values.chName.trim()}
  1095. name="chName"
  1096. onChange={formik.handleChange}
  1097. placeholder={intl.formatMessage({ id: 'sameAsYourIdDoc' })}
  1098. onBlur={formik.handleBlur}
  1099. inputProps={{
  1100. maxLength: 6,
  1101. onKeyDown: (e) => {
  1102. if (e.key === 'Enter') {
  1103. e.preventDefault();
  1104. }
  1105. },
  1106. }}
  1107. />
  1108. {formik.touched.chName && formik.errors.chName && (
  1109. <FormHelperText error id="helper-text-chName-signup">
  1110. {formik.errors.chName}
  1111. </FormHelperText>
  1112. )}
  1113. </Stack>
  1114. </Grid>
  1115. <Grid item xs={12}>
  1116. <Stack spacing={1}>
  1117. <InputLabel htmlFor="address1-signup">
  1118. <Typography variant="pnspsFormHeader">
  1119. <FormattedMessage id="formAddress" />
  1120. <span style={{ color: '#f10000' }}>*</span>
  1121. </Typography>
  1122. </InputLabel>
  1123. <OutlinedInput
  1124. fullWidth
  1125. error={Boolean(formik.touched.address1 && formik.errors.address1)}
  1126. id="address1-signup"
  1127. value={formik.values.address1}
  1128. name="address1"
  1129. onChange={formik.handleChange}
  1130. placeholder={intl.formatMessage({ id: 'addressLine1' })}
  1131. onBlur={formik.handleBlur}
  1132. inputProps={{
  1133. onKeyDown: (e) => {
  1134. if (e.key === 'Enter') {
  1135. e.preventDefault();
  1136. }
  1137. },
  1138. }}
  1139. />
  1140. <OutlinedInput
  1141. fullWidth
  1142. error={Boolean(formik.touched.address2 && formik.errors.address2)}
  1143. id="address2-signup"
  1144. value={formik.values.address2}
  1145. name="address2"
  1146. onChange={formik.handleChange}
  1147. onBlur={formik.handleBlur}
  1148. placeholder={intl.formatMessage({ id: 'addressLine2' })}
  1149. inputProps={{
  1150. onKeyDown: (e) => {
  1151. if (e.key === 'Enter') {
  1152. e.preventDefault();
  1153. }
  1154. },
  1155. }}
  1156. />
  1157. <OutlinedInput
  1158. fullWidth
  1159. error={Boolean(formik.touched.address3 && formik.errors.address3)}
  1160. id="address3-signup"
  1161. value={formik.values.address3}
  1162. name="address3"
  1163. onChange={formik.handleChange}
  1164. onBlur={formik.handleBlur}
  1165. placeholder={intl.formatMessage({ id: 'addressLine3' })}
  1166. inputProps={{
  1167. onKeyDown: (e) => {
  1168. if (e.key === 'Enter') {
  1169. e.preventDefault();
  1170. }
  1171. },
  1172. }}
  1173. />
  1174. <Autocomplete
  1175. disablePortal
  1176. id="address4-combo"
  1177. value={selectedAddress4}
  1178. options={ComboData.district}
  1179. disabled={checkCountry}
  1180. // error={Boolean(districtErrStr != "")}
  1181. onBlur={formik.handleBlur}
  1182. getOptionLabel={(option) => option.type ? intl.formatMessage({ id: option.type }) : ""}
  1183. onChange={(event, newValue) => {
  1184. setSelectedAddress4(newValue);
  1185. }}
  1186. sx={{
  1187. "& .MuiInputBase-root": { height: "41px" },
  1188. "#address4-combo": { padding: "0px 0px 0px 3px" },
  1189. "& .MuiAutocomplete-endAdornment": { top: "auto" },
  1190. }}
  1191. renderInput={(params) => <TextField error={Boolean(districtErrStr != "")} {...params} placeholder={intl.formatMessage({ id: 'region' })}
  1192. />}
  1193. />
  1194. <Autocomplete
  1195. disablePortal
  1196. id="address5-combo"
  1197. value={selectedAddress5}
  1198. options={ComboData.country}
  1199. getOptionLabel={(option) => option.type ? intl.formatMessage({ id: option.type }) : ""}
  1200. onChange={(event, newValue) => {
  1201. if (newValue !== null) {
  1202. setSelectedAddress5(newValue);
  1203. if (newValue.type === 'hongKong') {
  1204. setCheckCountry(false)
  1205. } else {
  1206. setSelectedAddress4("");
  1207. setCheckCountry(true)
  1208. }
  1209. } else {
  1210. setSelectedAddress4("");
  1211. setCheckCountry(true)
  1212. }
  1213. }}
  1214. sx={{ "& .MuiInputBase-root": { height: "41px" }, "#address5-combo": { padding: "0px 0px 0px 3px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }}
  1215. renderInput={(params) => <TextField {...params} placeholder={intl.formatMessage({ id: 'regionOrCountry' })} />}
  1216. />
  1217. {formik.touched.address1 && formik.errors.address1 && (
  1218. <FormHelperText error id="helper-text-address1-signup">
  1219. {formik.errors.address1}
  1220. </FormHelperText>
  1221. )}
  1222. {formik.touched.address2 && formik.errors.address2 && (
  1223. <FormHelperText error id="helper-text-address2-signup">
  1224. {formik.errors.address2}
  1225. </FormHelperText>
  1226. )}
  1227. {formik.touched.address3 && formik.errors.address3 && (
  1228. <FormHelperText error id="helper-text-address3-signup">
  1229. {formik.errors.address3}
  1230. </FormHelperText>
  1231. )}
  1232. {districtErrStr != "" && (
  1233. <FormHelperText error >
  1234. {districtErrStr}
  1235. </FormHelperText>
  1236. )}
  1237. </Stack>
  1238. </Grid>
  1239. <Grid item xs={12} mt={1} mb={1}>
  1240. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1241. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1242. <FormattedMessage id="yourContact" />
  1243. </Typography>
  1244. </Stack>
  1245. </Grid>
  1246. <Grid item xs={12} md={12}>
  1247. <Grid container>
  1248. <Grid item xs={12} md={6}>
  1249. <Stack spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}>
  1250. <InputLabel htmlFor="email-signup">
  1251. <Typography variant="pnspsFormHeader">
  1252. <FormattedMessage id="userContactEmail" />
  1253. <span style={{ color: '#f10000' }}>*</span>
  1254. </Typography>
  1255. </InputLabel>
  1256. <OutlinedInput
  1257. fullWidth
  1258. error={Boolean((formik.touched.email && formik.errors.email) || checkEmail)}
  1259. id="email-login"
  1260. type="email"
  1261. value={formik.values.email.trim()}
  1262. name="email"
  1263. onChange={formik.handleChange}
  1264. placeholder={intl.formatMessage({ id: 'userContactEmail' })}
  1265. onBlur={formik.handleBlur}
  1266. inputProps={{
  1267. onKeyDown: (e) => {
  1268. if (e.key === 'Enter') {
  1269. e.preventDefault();
  1270. }
  1271. },
  1272. }}
  1273. />
  1274. {formik.touched.email && formik.errors.email && (
  1275. <FormHelperText error id="helper-text-email-signup">
  1276. {formik.errors.email}
  1277. </FormHelperText>
  1278. )}
  1279. {checkEmail && (
  1280. <FormHelperText error id="helper-text-email-signup">
  1281. <FormattedMessage id="emailUsed" />
  1282. </FormHelperText>
  1283. )}
  1284. </Stack>
  1285. </Grid>
  1286. <Grid item xs={12} md={6}>
  1287. <Stack spacing={1} >
  1288. <InputLabel htmlFor="emailConfirm-signup">
  1289. <Typography variant="pnspsFormHeader">
  1290. <FormattedMessage id="confirmEmail" />
  1291. <span style={{ color: '#f10000' }}>*</span>
  1292. </Typography>
  1293. </InputLabel>
  1294. <OutlinedInput
  1295. fullWidth
  1296. error={Boolean(formik.touched.emailConfirm && formik.errors.emailConfirm)}
  1297. id="emailConfirm-login"
  1298. type="email"
  1299. value={formik.values.emailConfirm.trim()}
  1300. name="emailConfirm"
  1301. // onBlur={formik.handleBlur}
  1302. onChange={formik.handleChange}
  1303. placeholder={intl.formatMessage({ id: 'confirmEmail' })}
  1304. onBlur={formik.handleBlur}
  1305. onCut={handleCCPChange}
  1306. onCopy={handleCCPChange}
  1307. onPaste={handleCCPChange}
  1308. inputProps={{
  1309. onKeyDown: (e) => {
  1310. if (e.key === 'Enter') {
  1311. e.preventDefault();
  1312. }
  1313. },
  1314. }}
  1315. />
  1316. {formik.touched.emailConfirm && formik.errors.emailConfirm && (
  1317. <FormHelperText error id="helper-text-emailConfirm-signup">
  1318. {formik.errors.emailConfirm}
  1319. </FormHelperText>
  1320. )}
  1321. </Stack>
  1322. </Grid>
  1323. </Grid>
  1324. </Grid>
  1325. <Grid item xs={12} md={12}>
  1326. <Grid container>
  1327. <Grid item xs={12} md={6}>
  1328. <Grid container>
  1329. <Grid item xs={12} md={12}>
  1330. <Stack direction="column" spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}>
  1331. <InputLabel htmlFor="phone-signup">
  1332. <Typography variant="pnspsFormHeader">
  1333. <FormattedMessage id="userContactNumber" />
  1334. <span style={{ color: '#f10000' }}>*</span>
  1335. </Typography>
  1336. </InputLabel>
  1337. <Stack direction="row">
  1338. <OutlinedInput
  1339. id="phoneCountryCode-login"
  1340. type="phoneCountryCode"
  1341. value={formik.values.phoneCountryCode.trim()}
  1342. name="phoneCountryCode"
  1343. // onBlur={formik.handleBlur}
  1344. // onChange={formik.handleChange}
  1345. onChange={(event) => {
  1346. const value = event.target.value;
  1347. if (value.match(/[^0-9]/)) {
  1348. return event.preventDefault();
  1349. }
  1350. formik.setFieldValue("phoneCountryCode", value);
  1351. }}
  1352. placeholder={intl.formatMessage({ id: 'dialingCode' })}
  1353. error={Boolean(formik.touched.phone && formik.errors.phone)}
  1354. onBlur={formik.handleBlur}
  1355. endAdornment={<InputAdornment position="end">-</InputAdornment>}
  1356. inputProps={{
  1357. maxLength: 3,
  1358. onKeyDown: (e) => {
  1359. if (e.key === 'Enter') {
  1360. e.preventDefault();
  1361. }
  1362. },
  1363. }}
  1364. sx={{ width: '33%', mr: 1 }}
  1365. />
  1366. <OutlinedInput
  1367. id="phone-login"
  1368. type="phone"
  1369. value={formik.values.phone.trim()}
  1370. name="phone"
  1371. // onBlur={formik.handleBlur}
  1372. // onChange={formik.handleChange}
  1373. onChange={(event) => {
  1374. const value = event.target.value;
  1375. if (value.match(/[^0-9]/)) {
  1376. return event.preventDefault();
  1377. }
  1378. formik.setFieldValue("phone", value);
  1379. }}
  1380. placeholder={intl.formatMessage({ id: 'userContactNumber' })}
  1381. error={Boolean(formik.touched.phone && formik.errors.phone)}
  1382. onBlur={formik.handleBlur}
  1383. inputProps={{
  1384. maxLength: 11,
  1385. onKeyDown: (e) => {
  1386. if (e.key === 'Enter') {
  1387. e.preventDefault();
  1388. }
  1389. },
  1390. }}
  1391. sx={{ width: '66%' }}
  1392. />
  1393. </Stack>
  1394. {formik.touched.phone && formik.errors.phone && (
  1395. <FormHelperText error id="helper-text-phone-signup">
  1396. {formik.errors.phone}
  1397. </FormHelperText>
  1398. )}
  1399. </Stack>
  1400. </Grid>
  1401. </Grid>
  1402. </Grid>
  1403. <Grid item xs={12} md={6}>
  1404. <Grid container>
  1405. <Grid item xs={12} md={12}>
  1406. <Stack spacing={1} direction="column">
  1407. <InputLabel htmlFor="fax-signup">
  1408. <Typography variant="pnspsFormHeader">
  1409. <FormattedMessage id="userFaxNumber" />
  1410. </Typography>
  1411. </InputLabel>
  1412. <Stack direction="row">
  1413. <OutlinedInput
  1414. error={Boolean(formik.touched.fax && formik.errors.fax)}
  1415. id="faxCountryCode-login"
  1416. type="faxCountryCode"
  1417. value={formik.values.faxCountryCode.trim()}
  1418. name="faxCountryCode"
  1419. // onChange={formik.handleChange}
  1420. onChange={(event) => {
  1421. const value = event.target.value;
  1422. if (value.match(/[^0-9]/)) {
  1423. return event.preventDefault();
  1424. }
  1425. formik.setFieldValue("faxCountryCode", value);
  1426. }}
  1427. placeholder={intl.formatMessage({ id: 'dialingCode' })}
  1428. onBlur={formik.handleBlur}
  1429. endAdornment={<InputAdornment position="end">-</InputAdornment>}
  1430. inputProps={{
  1431. maxLength: 3,
  1432. onKeyDown: (e) => {
  1433. if (e.key === 'Enter') {
  1434. e.preventDefault();
  1435. }
  1436. },
  1437. }}
  1438. sx={{ width: '33%', mr: 1 }}
  1439. />
  1440. <OutlinedInput
  1441. id="fax-login"
  1442. type="fax"
  1443. value={formik.values.fax.trim()}
  1444. name="fax"
  1445. onBlur={formik.handleBlur}
  1446. // onChange={formik.handleChange}
  1447. onChange={(event) => {
  1448. const value = event.target.value;
  1449. if (value.match(/[^0-9]/)) {
  1450. return event.preventDefault();
  1451. }
  1452. formik.setFieldValue("fax", value);
  1453. }}
  1454. placeholder={intl.formatMessage({ id: 'userFaxNumber' })}
  1455. inputProps={{
  1456. maxLength: 8,
  1457. onKeyDown: (e) => {
  1458. if (e.key === 'Enter') {
  1459. e.preventDefault();
  1460. }
  1461. },
  1462. }}
  1463. sx={{ width: '66%' }}
  1464. />
  1465. </Stack>
  1466. </Stack>
  1467. </Grid>
  1468. </Grid>
  1469. </Grid>
  1470. </Grid>
  1471. </Grid>
  1472. <Grid item xs={12} md={12} mt={1} mb={1}>
  1473. <Grid container>
  1474. <Grid item xs={12} md={12}>
  1475. <Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1476. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1477. <FormattedMessage id="userIdDoc" />
  1478. <span style={{ color: '#f10000' }}>*</span></Typography>
  1479. <Typography display="inline" variant="subtitle1" sx={{ color: 'primary.primary' }}>
  1480. <FormattedMessage id="pleaseUploadIdDoc" />
  1481. </Typography>
  1482. <Typography display="inline" variant="subtitle1" sx={{ color: 'primary.primary' }}>
  1483. <FormattedMessage id="pleaseUploadIdDocSubTitle" />
  1484. </Typography>
  1485. <Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}>
  1486. <ThemeProvider theme={PNSPS_LONG_BUTTON_THEME}>
  1487. <Button variant="contained" component="label" sx={{ height: '40px' }}>
  1488. <FormattedMessage id="uploadIdDoc" />
  1489. <input
  1490. accept="image/png, .jpg, .bmp, .pdf"
  1491. //className={classes.input}
  1492. id="contained-button-file"
  1493. multiple
  1494. type="file"
  1495. onChange={handleFileUpload}
  1496. style={{ display: 'none' }}
  1497. />
  1498. </Button>
  1499. </ThemeProvider>
  1500. {/*<Typography xs={12} sm={9} md={3} display="inline" variant="subtitle1" sx={{ color: 'primary.primary' }}>如: 香港身份證; 護照; 中國內地身份證等</Typography>*/}
  1501. </Stack>
  1502. {fileList != null ?
  1503. <UploadFileTable key="uploadTable" recordList={fileListData} setUpdateRows={setUpdateRows} /> : null}
  1504. {/* <Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}>
  1505. <Button variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button>
  1506. <Button disabled={!formik.isValid} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button>
  1507. </Stack> */}
  1508. </Stack>
  1509. </Grid>
  1510. </Grid>
  1511. </Grid>
  1512. </Grid>
  1513. <Grid item xs={12} md={12}>
  1514. <Grid container>
  1515. <Grid item xs={12} md={12}>
  1516. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1517. <FormattedMessage id="termsAndCondition" />
  1518. <span style={{ color: '#f10000' }}>*</span>
  1519. </Typography>
  1520. </Grid>
  1521. <Grid item xs={12} md={12}>
  1522. <Grid container>
  1523. <Grid item xs={12} md={12}>
  1524. <Typography variant="h6" height="100%" sx={{ textAlign: "left", /*overflow: "scroll",*/ borderRadius: "inherit", borderStyle: "solid", borderWidth: "1px", borderColor: "#0C489E" }}>
  1525. <div style={{padding: 12}} dangerouslySetInnerHTML={{__html: intl.formatMessage({id: "termsAndCon"})}} />
  1526. </Typography>
  1527. </Grid>
  1528. </Grid>
  1529. <Grid item xs={12} s={12} md={12} lg={12}>
  1530. <Grid container>
  1531. <Grid item xs={6} s={6} md={2} lg={2}>
  1532. <Grid container>
  1533. <Grid item sx={{ display: 'flex', alignItems: 'center' }}>
  1534. <Checkbox
  1535. checked={termsAndConAccept}
  1536. onChange={handleCheckBoxChange}
  1537. name="termsAndConAccept"
  1538. color="primary"
  1539. size="small"
  1540. />
  1541. <Typography variant="pnspsFormHeader">
  1542. <FormattedMessage id="acceptTerms" />
  1543. </Typography>
  1544. </Grid>
  1545. </Grid>
  1546. </Grid>
  1547. <Grid item xs={6} s={6} md={3} lg={3}>
  1548. <Grid container style={{ display: "none" }}>
  1549. <Grid item sx={{ display: 'flex', alignItems: 'center' }}>
  1550. <Checkbox
  1551. checked={termsAndConNotAccept}
  1552. onChange={handleCheckBoxChange}
  1553. name="termsAndConNotAccept"
  1554. color="primary"
  1555. size="small"
  1556. />
  1557. <Typography variant="pnspsFormHeader">
  1558. <FormattedMessage id="rejectTerms" />
  1559. </Typography>
  1560. </Grid>
  1561. </Grid>
  1562. </Grid>
  1563. </Grid>
  1564. </Grid>
  1565. </Grid>
  1566. </Grid>
  1567. </Grid>
  1568. <Grid item xs={12} lg={12}>
  1569. <Grid container>
  1570. <Stack direction="column">
  1571. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1572. <FormattedMessage id="verify" />
  1573. <span style={{ color: '#f10000' }}>*</span>
  1574. </Typography>
  1575. <Stack spacing={1} direction="row">
  1576. <Grid item xs={5} lg={5} style={{ "border": "1px solid black" }}>
  1577. <img src={captchaImg} alt="" />
  1578. </Grid>
  1579. <Grid item xs={1} lg={1} style={{ "border": "0px solid black" }}>
  1580. <IconButton aria-label="refrashCaptcha" size="large" onClick={() => { onCaptchaChange() }}>
  1581. <LoopIcon fontSize="inherit" />
  1582. </IconButton>
  1583. </Grid>
  1584. <Grid item xs={6} lg={6}>
  1585. <OutlinedInput
  1586. fullWidth
  1587. id="captchaField"
  1588. type="text"
  1589. value={formik.values.captchaField.trim()}
  1590. onBlur={formik.handleBlur}
  1591. error={Boolean(formik.touched.captchaField && formik.errors.captchaField)}
  1592. name="captchaField"
  1593. onChange={(event) => {
  1594. const value = event.target.value;
  1595. props.setCheckCode(event.target.value);
  1596. setCheckCode(event.target.value);
  1597. formik.setFieldValue("captchaField", value);
  1598. }}
  1599. sx={{ width: '75%' }}
  1600. />
  1601. </Grid>
  1602. </Stack>
  1603. {formik.touched.captchaField && formik.errors.captchaField && (
  1604. <FormHelperText error id="helper-text-captcha-signup">
  1605. {formik.errors.captchaField}
  1606. </FormHelperText>
  1607. )}
  1608. </Stack>
  1609. </Grid>
  1610. </Grid>
  1611. </Grid>
  1612. </Grid>
  1613. </FormGroup>
  1614. {/* Preview Form */}
  1615. <FormGroup id={"previewForm"} sx={{ display: props.step === 1 ? "" : "none" }}>
  1616. <Grid container spacing={3}>
  1617. <Grid item xs={12} md={12}>
  1618. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1619. <div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}>
  1620. <Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>
  1621. <FormattedMessage id="becomeNewPersonalUser" />
  1622. </Typography>
  1623. </div>
  1624. {/* <Typography mt={0.25} variant="h6" sx={{ fontSize: 12,color: '#f10000'}}>註有*的項目必須輸入資料</Typography> */}
  1625. <Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary' }}>
  1626. <FormattedMessage id="yourLoginInformation" />
  1627. </Typography>
  1628. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  1629. Already have an account?
  1630. </Typography> */}
  1631. </Stack>
  1632. </Grid>
  1633. <Grid item xs={12} md={12}>
  1634. <Grid container spacing={2}>
  1635. <Grid item xs={12} >
  1636. <Stack spacing={2} direction="row">
  1637. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1638. <FormattedMessage id="userLoginName" />:
  1639. </Typography>
  1640. <Typography variant="pnspsFormHeader" id="preview-username-login">
  1641. {formik.values.username}
  1642. </Typography>
  1643. </Stack>
  1644. </Grid>
  1645. <Grid item xs={12} mt={1} mb={1}>
  1646. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1647. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1648. <FormattedMessage id="yourPersonalInformation" />
  1649. </Typography>
  1650. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  1651. Already have an account?
  1652. </Typography> */}
  1653. </Stack>
  1654. </Grid>
  1655. {/* <Grid item xs={12} md={12} >
  1656. <Stack spacing={1}>
  1657. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1658. <FormattedMessage id="userIdDoc" />
  1659. </Typography>
  1660. </Stack>
  1661. </Grid> */}
  1662. <Grid item xs={12} md={6} >
  1663. <Stack spacing={1} direction="row" >
  1664. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1665. <FormattedMessage id="idDocType" />:
  1666. </Typography>
  1667. <Typography variant="pnspsFormHeader" name="preview-idDocType">
  1668. {selectedIdDocType?.label? intl.formatMessage({ id: selectedIdDocType.label}): " "}
  1669. </Typography>
  1670. </Stack>
  1671. </Grid>
  1672. <Grid item xs={12} md={6}>
  1673. <Stack direction="row" >
  1674. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]} sx={{mr:1}}>
  1675. <FormattedMessage id="idDocNumber" />:
  1676. </Typography>
  1677. <Typography variant="pnspsFormHeader" id="idNo-f4-login">
  1678. {formik.values.idNo.slice(0, 4)}
  1679. </Typography>
  1680. <Typography variant="pnspsFormHeader" id="idNo-exf4-login"
  1681. type={showId ? "text" : "password"}
  1682. >
  1683. {showId ?formik.values.idNo.slice(4):"****"}{showId ?selectedIdDocType.type == "HKID" ? '(' + formik.values.checkDigit + ')' : null:null}
  1684. </Typography>
  1685. <IconButton
  1686. aria-label="toggle id visibility"
  1687. onClick={handleClickShowId}
  1688. onMouseDown={handleMouseDownId}
  1689. edge="end"
  1690. size="medium"
  1691. >
  1692. {showId ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  1693. </IconButton>
  1694. </Stack>
  1695. </Grid>
  1696. <Grid item xs={12} md={6}>
  1697. <Stack spacing={1} direction="row">
  1698. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1699. <FormattedMessage id="userEnglishName" />:
  1700. </Typography>
  1701. <Typography variant="pnspsFormHeader" id="preview-enName-signup">
  1702. {formik.values.enName}
  1703. </Typography>
  1704. </Stack>
  1705. </Grid>
  1706. <Grid item xs={12} md={6}>
  1707. <Stack spacing={1} direction="row">
  1708. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1709. <FormattedMessage id="userChineseName" />:
  1710. </Typography>
  1711. <Typography variant="pnspsFormHeader" id="preview-chName-signup">
  1712. {formik.values.chName}
  1713. </Typography>
  1714. </Stack>
  1715. </Grid>
  1716. <Grid item xs={12}>
  1717. <Stack spacing={1} direction="column">
  1718. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1719. <FormattedMessage id="formAddress" />:
  1720. </Typography>
  1721. <Stack spacing={1} direction="column">
  1722. <Typography variant="pnspsFormHeader" id="preview-address1-signup">
  1723. {formik.values.address1}
  1724. </Typography>
  1725. {formik.values.address2 != null ?
  1726. <Typography variant="pnspsFormHeader" id="preview-address2-signup">
  1727. {formik.values.address2}
  1728. </Typography>
  1729. : null}
  1730. {formik.values.address3 != null ?
  1731. <Typography variant="pnspsFormHeader" id="preview-address3-signup">
  1732. {formik.values.address3}
  1733. </Typography>
  1734. : null}
  1735. {selectedAddress5.type === "hongKong" ?
  1736. <Stack direction="column">
  1737. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]} id="preview-address4-signup">
  1738. <FormattedMessage id="region" />:
  1739. </Typography>
  1740. <Typography variant="pnspsFormHeader">
  1741. {!selectedAddress4 ? "" : intl.formatMessage({ id: selectedAddress4.type })}
  1742. </Typography>
  1743. </Stack>
  1744. : null}
  1745. <Stack direction="column">
  1746. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]} id="preview-address5-signup">
  1747. <FormattedMessage id="regionOrCountry" />:
  1748. </Typography>
  1749. <Typography variant="pnspsFormHeader">
  1750. {intl.formatMessage({ id: selectedAddress5.type })}
  1751. </Typography>
  1752. </Stack>
  1753. </Stack>
  1754. </Stack>
  1755. </Grid>
  1756. <Grid item xs={12} mt={1} mb={1}>
  1757. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1758. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1759. <FormattedMessage id="yourContact" />
  1760. </Typography>
  1761. </Stack>
  1762. </Grid>
  1763. <Grid item xs={12} md={12}>
  1764. <Stack spacing={1} direction="row">
  1765. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1766. <FormattedMessage id="userContactEmail" />:
  1767. </Typography>
  1768. <Typography variant="pnspsFormHeader" id="preview-email-signup">
  1769. {formik.values.email}
  1770. </Typography>
  1771. </Stack>
  1772. </Grid>
  1773. <Grid item xs={12} md={6}>
  1774. <Stack spacing={1} direction="row">
  1775. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1776. <FormattedMessage id="userContactNumber" />:
  1777. </Typography>
  1778. <Typography variant="pnspsFormHeader" id="preview-phone-signup">
  1779. +{formik.values.phoneCountryCode} {formik.values.phone}
  1780. </Typography>
  1781. </Stack>
  1782. </Grid>
  1783. {formik.values.faxCountryCode != "" && formik.values.fax != "" ?
  1784. <Grid item xs={12} md={6}>
  1785. <Stack spacing={1} direction="row">
  1786. <Typography variant="pnspsFormHeader" color={theme.palette.grey[600]}>
  1787. <FormattedMessage id="userFaxNumber" />:
  1788. </Typography>
  1789. <Typography variant="pnspsFormHeader" id="preview-fax-signup">
  1790. +{formik.values.faxCountryCode} {formik.values.fax}
  1791. </Typography>
  1792. </Stack>
  1793. </Grid>
  1794. : null}
  1795. <Grid item xs={12} md={12} mt={1} mb={1}>
  1796. <Grid container>
  1797. <Grid item xs={12} md={12}>
  1798. <Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1799. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1800. <FormattedMessage id="userIdDoc" />
  1801. </Typography>
  1802. {fileList != null ?
  1803. <PreviewUploadFileTable key="previewTable" recordList={fileListData} /> : null}
  1804. </Stack>
  1805. </Grid>
  1806. </Grid>
  1807. </Grid>
  1808. </Grid>
  1809. </Grid>
  1810. </Grid>
  1811. </FormGroup>
  1812. {/* Submit page */}
  1813. <FormGroup id={"submitForm"} sx={{ display: props.step === 2 ? "" : "none" }}>
  1814. <Grid container spacing={3}>
  1815. {isLoading ?
  1816. <LoadingComponent /> :
  1817. <Grid item xs={12}>
  1818. {checkUpload ?
  1819. // SUCCESS page
  1820. <Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
  1821. <CheckCircleOutlineIcon color="success" sx={{ width: "200px", height: "200px" }} />
  1822. <Typography display="inline" variant="h4">
  1823. <FormattedMessage id="registerSubmitted" />
  1824. </Typography>
  1825. <Typography display="inline" variant="h4">
  1826. <FormattedMessage id="emailSent" />
  1827. </Typography>
  1828. <Button variant="outlined" component={Link} to="/login" ><Typography variant="pnspsFormHeader">
  1829. <FormattedMessage id="backToLogin" />
  1830. </Typography></Button>
  1831. </Stack>
  1832. :
  1833. // ERROR page
  1834. <Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
  1835. {/* <Button disabled={true} hidden={true} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> */}
  1836. <CancelOutlinedIcon color="error" sx={{ width: "200px", height: "200px" }} />
  1837. <Typography display="inline" variant="h4">
  1838. <FormattedMessage id="registerFail" />
  1839. </Typography>
  1840. <Button color="error" variant="outlined" component={Link} to="/login" ><Typography variant="pnspsFormHeader">
  1841. <FormattedMessage id="backToLogin" />
  1842. </Typography></Button>
  1843. </Stack>
  1844. }
  1845. </Grid>
  1846. }
  1847. </Grid>
  1848. </FormGroup>
  1849. </form>
  1850. </FormikProvider>
  1851. );
  1852. }
  1853. export default CustomFormWizard;