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

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