Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

BusCustomFormWizard.js 117 KiB

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