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

1543 行
94 KiB

  1. import { useEffect, useState, } 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, GET_USERNAME } 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 { Invaild } from 'utils/IconUtils';
  48. // ============================|| FIREBASE - REGISTER ||============================ //
  49. const BusCustomFormWizard = (props) => {
  50. const theme = useTheme()
  51. const [level, setLevel] = useState();
  52. const [showPassword, setShowPassword] = useState(false);
  53. const [showConfirmPassword, setshowConfirmPassword] = useState(false);
  54. const [fileList, setFileList] = useState([]);
  55. const [fileListData, setFileListData] = useState([]);
  56. const [checkUpload, setCheckUpload] = useState(false);
  57. const [isLoading, setLoding] = useState(true);
  58. const [updateRows, setUpdateRows] = useState([]);
  59. const [userNameList, setUserNameList] = useState([]);
  60. const [captcha, setCaptcha] = useState([]);
  61. const [captchaImg, setCaptchaImage] = useState([]);
  62. const handleClickShowPassword = () => {
  63. setShowPassword(!showPassword);
  64. };
  65. const handleClickShowConfirmPassword = () => {
  66. setshowConfirmPassword(!showConfirmPassword);
  67. };
  68. const handleMouseDownPassword = (event) => {
  69. event.preventDefault();
  70. };
  71. const changePassword = (value) => {
  72. const temp = strengthIndicator(value);
  73. setLevel(strengthColorChi(temp));
  74. };
  75. const [selectedAddress4, setSelectedAddress4] = useState(null);
  76. const [selectedAddress5, setSelectedAddress5] = useState(ComboData.country[0]);
  77. const [termsAndConAccept, setTermsAndConAccept] = useState(false);
  78. const [termsAndConNotAccept, setTermsAndConNotAccept] = useState(false);
  79. const [isValid, setisValid] = useState(false);
  80. const [checkCountry, setCheckCountry] = useState(false);
  81. const address4ComboList = ComboData.district;
  82. const address5ComboList = ComboData.country;
  83. const termsAndCon = "此網址由香港特別行政區政府物流服務署製作及管理。本署會盡力確保網址上的資料無誤,\n"
  84. + "但有絕對酌情權隨時刪除、暫停登載或編輯各項資料而無須給予任何理由。\n由於任何與網址"
  85. + "內資料有關的理由或原因,而導致出現申索、損失或損害,本署概不負責。\n使用者須自行評"
  86. + "估本網址所載或與本網址有關連的各項資料,並應在根據該等資料行事前,參照印行的香港"
  87. + "特別行政區憲報以核實該等資料,以及徵詢獨立意見。\n版權公告本網頁的內容,包括但不限"
  88. + "於所有文本、平面圖像、圖畫、圖片、照片以及數據或其他資料的匯編,均受版權保障。\n香"
  89. + "港特別行政區政府是本網頁內所有版權作品的擁有人,除非預先得到政府物流服務署的書面"
  90. + "授權,否則嚴禁複製、改編、分發、發布或向公眾提供該等版權作品。"
  91. const refType = "identification";
  92. useEffect(() => {
  93. changePassword('');
  94. // if (localStorage.getItem('checkCode') != null){
  95. // setCaptcha(localStorage.getItem('checkCode'));
  96. // setCaptchaImage(localStorage.getItem('base64Url'));
  97. // localStorage.setItem("checkCode",null);
  98. // localStorage.setItem("base64Url",null);
  99. // }else{
  100. onCaptchaChange();
  101. // }
  102. axios.get(`${GET_USERNAME}`)
  103. .then((response) => {
  104. if (response.status === 200) {
  105. setUserNameList(response.data);
  106. }
  107. })
  108. .catch(error => {
  109. console.log(error);
  110. return false;
  111. });
  112. }, []);
  113. const onCaptchaChange = () => {
  114. HttpUtils.post({
  115. url: POST_CAPTCHA,
  116. params: { width: 130, height: 40 },
  117. onSuccess: (responseData) => {
  118. localStorage.setItem("checkCode", responseData.checkCode);
  119. localStorage.setItem("base64Url", responseData.base64Url);
  120. setCaptcha(localStorage.getItem('checkCode'));
  121. setCaptchaImage(localStorage.getItem('base64Url'));
  122. }
  123. });
  124. }
  125. const checkDataField = (data) => {
  126. // console.log(data.brExpiryDate)
  127. if (data.username !== "" &&
  128. data.password !== "" &&
  129. data.confirmPassword !== "" &&
  130. data.password == data.confirmPassword &&
  131. // (data.enCompanyName !=="" || selectedAddress5 ==="內地")&&
  132. (data.chCompanyName !== "" || data.enCompanyName !== "") &&
  133. data.enName !== "" &&
  134. data.chName !== "" &&
  135. data.address1 !== "" &&
  136. data.email !== "" &&
  137. data.emailConfirm !== "" &&
  138. data.email == data.emailConfirm &&
  139. data.phone !== "" &&
  140. data.phoneCountryCode !== "" &&
  141. termsAndConAccept == true &&
  142. fileList.length !== 0 &&
  143. data.captchaField &&
  144. data.brNo !== "" &&
  145. data.brExpiryDate !== "" &&
  146. handlePassword(data.password) &&
  147. handleEmail(data.email) &&
  148. handlePhone(data.phone) &&
  149. handleUserName(data.username) &&
  150. handleCaptcha(data.captchaField)
  151. ) {
  152. setisValid(true)
  153. return isValid
  154. } else {
  155. setisValid(false)
  156. return isValid
  157. }
  158. };
  159. const handleCheckBoxChange = (event) => {
  160. console.log(event.target)
  161. if (event.target.name == 'termsAndConAccept') {
  162. setTermsAndConAccept(event.target.checked)
  163. setTermsAndConNotAccept(!event.target.checked)
  164. }
  165. if (event.target.name == 'termsAndConNotAccept') {
  166. setTermsAndConNotAccept(event.target.checked)
  167. setTermsAndConAccept(!event.target.checked)
  168. }
  169. };
  170. useEffect(() => {
  171. let updateRowList = new DataTransfer();
  172. var updateRowsIndex = updateRows.length;
  173. const saveFileList = [];
  174. if (updateRowsIndex != null) {
  175. for (let i = 0; i < updateRowsIndex; i++) {
  176. const file = updateRows[i]
  177. file.id = i;
  178. updateRowList.items.add(file);
  179. saveFileList.push(file);
  180. }
  181. let updatedFileList = updateRowList.files;
  182. setFileList(updatedFileList);
  183. setFileListData(saveFileList)
  184. }
  185. }, [updateRows]);
  186. const handleFileUpload = (event) => {
  187. let updateList = new DataTransfer();
  188. let currentFileList = fileListData;
  189. const uploadFileList = event.target.files;
  190. const saveFileList = [];
  191. var currentIndex = 0;
  192. if (currentFileList.length != null) {
  193. currentIndex = currentFileList.length;
  194. for (let i = 0; i < currentIndex; i++) {
  195. const file = currentFileList[i]
  196. // file.id = currentIndex;
  197. updateList.items.add(file);
  198. saveFileList.push(file);
  199. }
  200. }
  201. for (let i = 0; i < uploadFileList.length && currentIndex < 5; i++) {
  202. const file = event.target.files[i]
  203. let isDuplicate = false;
  204. // Check if the file name already exists in saveFileList
  205. for (let j = 0; j < saveFileList.length; j++) {
  206. if (saveFileList[j].name === file.name) {
  207. isDuplicate = true;
  208. break;
  209. }
  210. }
  211. if (!isDuplicate && i + currentIndex < 5) {
  212. file.id = currentIndex + i
  213. saveFileList.push(file)
  214. updateList.items.add(file);
  215. }
  216. console.log("currentIndex")
  217. console.log(currentIndex)
  218. }
  219. let updatedFileList = updateList.files;
  220. setFileListData(saveFileList)
  221. setFileList(updatedFileList);
  222. };
  223. useEffect(() => {
  224. props.setUpdateValid(isValid)
  225. }, [isValid])
  226. useEffect(() => {
  227. checkDataField(values)
  228. }, [selectedAddress4, selectedAddress5,
  229. termsAndConAccept, termsAndConNotAccept, fileList])
  230. useEffect(() => {
  231. props.step == 2 ? _onSubmit() : null;
  232. onCaptchaChange();
  233. checkDataField(values)
  234. }, [props.step])
  235. const { handleSubmit } = useForm({})
  236. const _onSubmit = () => {
  237. setLoding(true);
  238. values.address4 = selectedAddress4
  239. values.address5 = selectedAddress5
  240. // console.log(values)
  241. const busUserAddress = {
  242. "addressLine1": "",
  243. "addressLine2": "",
  244. "addressLine3": "",
  245. "district": "",
  246. "country": ""
  247. };
  248. busUserAddress.addressLine1 = values.address1
  249. busUserAddress.addressLine2 = values.address2
  250. busUserAddress.addressLine3 = values.address3
  251. busUserAddress.district = values.address4
  252. busUserAddress.country = values.address5
  253. const userFaxNo = {
  254. "countryCode": values.faxCountryCode,
  255. "faxNumber": values.fax,
  256. };
  257. const busUserContactTel = {
  258. "countryCode": values.phoneCountryCode,
  259. "phoneNumber": values.phone,
  260. };
  261. let tncFlag = false;
  262. if (termsAndConAccept) {
  263. tncFlag = true
  264. }
  265. if (termsAndConNotAccept) {
  266. tncFlag = false
  267. }
  268. const user = {
  269. username: values.username,
  270. password: values.password,
  271. name: values.username,
  272. enCompanyName: values.enCompanyName,
  273. chCompanyName: values.chCompanyName,
  274. emailBus: values.email,
  275. brNo: values.brNo,
  276. brExpiryDate: values.brExpiryDate,
  277. contactPerson: values.enName,
  278. tncFlag: tncFlag,
  279. type: "ORG"
  280. };
  281. var formData = new FormData();
  282. for (let i = 0; i < fileListData.length; i++) {
  283. const file = fileListData[i]
  284. formData.append("multipartFileList", file);
  285. }
  286. formData.append("refType", refType);
  287. for (const [key, value] of Object.entries(user)) {
  288. formData.append(key, value);
  289. }
  290. formData.append("userFaxNo", JSON.stringify(userFaxNo));
  291. formData.append("busUserContactTel", JSON.stringify(busUserContactTel));
  292. formData.append("busUserAddress", JSON.stringify(busUserAddress));
  293. if (isValid) {
  294. axios.post(POST_PUBLIC_USER_REGISTER, formData, {
  295. headers: {
  296. "Content-Type": "multipart/form-data"
  297. }
  298. })
  299. .then((response) => {
  300. console.log(response)
  301. setCheckUpload(true)
  302. setLoding(false);
  303. })
  304. .catch(error => {
  305. console.error(error);
  306. setLoding(false);
  307. });
  308. } else {
  309. setLoding(false);
  310. }
  311. }
  312. function handlePhone(phone) {
  313. if (phone.length < 8) {
  314. return false;
  315. } else {
  316. return true;
  317. }
  318. }
  319. function handleUserName(username) {
  320. var symbol = /^(?=.*[!@#%&])/;
  321. var space = /\s/;
  322. if (username.length < 6) {
  323. return false;
  324. } else if (username.match(symbol)) {
  325. return false;
  326. } else if (username.match(space)) {
  327. return false;
  328. } else {
  329. return true;
  330. }
  331. }
  332. function handleCaptcha(captchaField) {
  333. return captchaField == captcha;
  334. }
  335. function handlePassword(password) {
  336. let new_pass = password;
  337. // regular expressions to validate password
  338. var lowerCase = /[a-z]/g;
  339. var upperCase = /[A-Z]/g;
  340. var numbers = /[0-9]/g;
  341. var symbol = /^(?=.*[!@#%&])/;
  342. var space = /\s/;
  343. if (!new_pass.match(lowerCase)) {
  344. return false;
  345. } else if (!new_pass.match(upperCase)) {
  346. return false;
  347. } else if (!new_pass.match(numbers)) {
  348. return false;
  349. } else if (!new_pass.match(symbol)) {
  350. return false;
  351. } else if (new_pass.length < 8) {
  352. return false;
  353. }
  354. else if (new_pass.match(space)) {
  355. return false;
  356. } else {
  357. // console.log("password true")
  358. return true;
  359. }
  360. }
  361. function handleEmail(email) {
  362. var validRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
  363. if (!email.match(validRegex)) {
  364. return false;
  365. } else {
  366. return true;
  367. }
  368. }
  369. function displayErrorMsg(errorMsg) {
  370. return <Typography variant="errorMessage1">{errorMsg}</Typography>
  371. }
  372. const formik = useFormik({
  373. initialValues: ({
  374. username: '',
  375. enName: '',
  376. enCompanyName: '',
  377. chCompanyName: '',
  378. email: '',
  379. address1: '',
  380. address2: '',
  381. address3: '',
  382. password: '',
  383. confirmPassword: '',
  384. phone: '',
  385. phoneCountryCode: '852',
  386. submit: null,
  387. fax: '',
  388. faxCountryCode: '852',
  389. brExpiryDate: '',
  390. brNo: '',
  391. emailConfirm: '',
  392. captchaField: ''
  393. }),
  394. validationSchema: yup.object().shape({
  395. username: yup.string().min(6, displayErrorMsg('用戶名稱最少6位')).required(displayErrorMsg('請輸入用戶名稱')).test(
  396. "checkUserNameUsed",
  397. displayErrorMsg("此用戶登入名稱已被注冊,請使用其他用戶登入名稱"),
  398. function (value) {
  399. if (userNameList.some(item => item.username === value)) {
  400. return false
  401. } else {
  402. return true
  403. }
  404. }
  405. )
  406. .matches(/^[aA-zZ0-9\s]+$/, {message: displayErrorMsg("用戶名稱不包含特殊字符")})
  407. .matches(/^\S*$/, {message: displayErrorMsg('用戶名稱不包含空格')}),
  408. password: yup.string().min(8, displayErrorMsg('請輸入最少8位密碼')).required(displayErrorMsg('請輸入密碼'))
  409. .matches(/^\S*$/, {message: displayErrorMsg('密碼不包含空格')})
  410. .matches(/^(?=.*[a-z])/, {message: displayErrorMsg('請包括最少1個小寫字母')})
  411. .matches(/^(?=.*[A-Z])/, {message: displayErrorMsg('請包括最少1個大寫字母')})
  412. .matches(/^(?=.*[0-9])/, {message: displayErrorMsg('請包括最少1個數字')})
  413. .matches(/^(?=.*[!@#%&])/, {message: displayErrorMsg('請包括最少1個特殊字符')}),
  414. confirmPassword: yup.string().min(8, displayErrorMsg('請最少輸入8位密碼')).required(displayErrorMsg('請確認密碼')).oneOf([yup.ref('password'), null], displayErrorMsg('請輸入相同密碼')),
  415. enName: yup.string().max(255).required(displayErrorMsg('請輸入英文姓名')),
  416. enCompanyName: yup.string().matches(/^[^$^*()]+$/, {message: displayErrorMsg('No special characters $/^/*/(/)')}).when('chCompanyName', {
  417. is: (chCompanyName) => !chCompanyName || chCompanyName.length === 0,
  418. then: yup.string().required(displayErrorMsg('Please enter either English or Chinese name')),
  419. }),
  420. chCompanyName: yup.string().matches(/^[^$^*()]+$/, {message: displayErrorMsg('不包含特殊字符 $/^/*/(/)')}).when('enCompanyName', {
  421. is: (enCompanyName) => !enCompanyName || enCompanyName.length === 0,
  422. then: yup.string().required(displayErrorMsg('請輸入英文或中文名稱')),
  423. }),
  424. chName: yup.string().max(255).required(displayErrorMsg('請輸入中文姓名')),
  425. address1: yup.string().max(255).required(displayErrorMsg('請輸入第一行地址')),
  426. address2: yup.string().max(255).required(displayErrorMsg('請輸入第二行地址')),
  427. address3: yup.string().max(255).required(displayErrorMsg('請輸入第三行地址')),
  428. email: yup.string().email(displayErrorMsg('請輸入電郵格式')).max(255).required(displayErrorMsg('請輸入電郵')),
  429. emailConfirm: yup.string().email(displayErrorMsg('請輸入電郵格式')).max(255).required(displayErrorMsg('請輸入電郵')).oneOf([yup.ref('email'), null], displayErrorMsg('請輸入相同電郵')),
  430. phoneCountryCode: yup.string().min(2, displayErrorMsg('請輸入最少2位數字')).required(displayErrorMsg('請輸入國際區號')),
  431. faxCountryCode: yup.string().min(2, displayErrorMsg('請輸入最少2位數字')),
  432. phone: yup.string().min(8, displayErrorMsg('請輸入最少8位數字')).required(displayErrorMsg('請輸入聯絡電話')),
  433. fax: yup.string().min(8, displayErrorMsg('請輸入最少8位數字')),
  434. brExpiryDate: yup.date().min(new Date().toISOString().split("T")[0], displayErrorMsg('請輸入商業登記證有效日期')).max("2099-12-31", displayErrorMsg('請輸入商業登記證有效日期')).required(displayErrorMsg('請輸入商業登記證有效日期')),
  435. brNo: yup.string().min(8, displayErrorMsg('請輸入商業登記證號碼')).required(displayErrorMsg('請輸入商業登記證號碼')),
  436. captchaField: yup.string().required(displayErrorMsg('請輸入驗證')).oneOf([captcha], displayErrorMsg('請輸入有效驗證')),
  437. }, ['enCompanyName', 'chCompanyName']),
  438. });
  439. const handleReset = (resetForm) => {
  440. resetForm();
  441. setSelectedAddress4("")
  442. setSelectedAddress5(ComboData.country[0])
  443. setCheckCountry(false)
  444. setFileList([])
  445. setFileListData([])
  446. onCaptchaChange()
  447. };
  448. const { values } = formik
  449. useEffect(() => {
  450. checkDataField(values)
  451. }, [values])
  452. return (
  453. <FormikProvider value={formik}>
  454. <form onSubmit={handleSubmit(_onSubmit)}>
  455. {/* Input Form */}
  456. <FormGroup id={"inputForm"} sx={{ display: props.step === 0 ? "" : "none" }}>
  457. <Grid container spacing={3}>
  458. <Grid item xs={12} md={12}>
  459. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  460. <Button variant="outlined" type="reset" onClick={handleReset.bind(null, formik.resetForm)} sx={{ height: '40px' }}><Typography variant="h5">重置</Typography></Button>
  461. <div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}>
  462. <Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>成為新的機構/公司用戶</Typography>
  463. </div>
  464. <Typography mt={0.25} variant="h6" sx={{ color: '#f10000' }}>註有*的項目必須輸入資料</Typography>
  465. <Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary' }}>你的登入資料</Typography>
  466. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  467. Already have an account?
  468. </Typography> */}
  469. </Stack>
  470. </Grid>
  471. <Grid item xs={12} md={12}>
  472. <Grid container spacing={1}>
  473. <Grid item xs={12} md={12} >
  474. <Stack spacing={1}>
  475. <InputLabel htmlFor="username-signup">
  476. <Typography variant="h5">
  477. 用戶登入名稱
  478. <span style={{ color: '#f10000' }}>*</span>
  479. </Typography>
  480. </InputLabel>
  481. <OutlinedInput
  482. id="username-login"
  483. type="text"
  484. value={formik.values.username.trim()}
  485. name="username"
  486. onChange={formik.handleChange}
  487. placeholder="用戶登入名稱"
  488. fullWidth
  489. error={Boolean(formik.touched.username && formik.errors.username)}
  490. onBlur={formik.handleBlur}
  491. inputProps={{
  492. onKeyDown: (e) => {
  493. if (e.key === 'Enter') {
  494. e.preventDefault();
  495. }
  496. },
  497. }}
  498. />
  499. {formik.touched.username && formik.errors.username && (
  500. <FormHelperText error id="helper-text-username-signup">
  501. {formik.errors.username}
  502. </FormHelperText>
  503. )}
  504. </Stack>
  505. </Grid>
  506. <Grid item xs={12} md={12}>
  507. <Grid container>
  508. <Grid item xs={12} md={6} >
  509. <Stack spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}>
  510. <Stack direction="row" justifyContent="space-between">
  511. <InputLabel htmlFor="password-signup">
  512. <Typography variant="h5">
  513. 密碼
  514. <span style={{ color: '#f10000' }}>*</span>
  515. </Typography>
  516. </InputLabel>
  517. </Stack>
  518. <OutlinedInput
  519. fullWidth
  520. error={Boolean(formik.touched.password && formik.errors.password)}
  521. id="password-signup"
  522. type={showPassword ? 'text' : 'password'}
  523. value={formik.values.password.trim()}
  524. name="password"
  525. onChange={(e) => {
  526. formik.handleChange(e);
  527. changePassword(e.target.value);
  528. }}
  529. endAdornment={
  530. <InputAdornment position="end">
  531. <IconButton
  532. aria-label="toggle password visibility"
  533. onClick={handleClickShowPassword}
  534. onMouseDown={handleMouseDownPassword}
  535. edge="end"
  536. size="large"
  537. >
  538. {showPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  539. </IconButton>
  540. </InputAdornment>
  541. }
  542. placeholder="密碼"
  543. onBlur={formik.handleBlur}
  544. inputProps={{
  545. onKeyDown: (e) => {
  546. if (e.key === 'Enter') {
  547. e.preventDefault();
  548. }
  549. },
  550. }}
  551. />
  552. {formik.touched.password && formik.errors.password && (
  553. <FormHelperText error id="helper-text-password-signup">
  554. {formik.errors.password}
  555. </FormHelperText>
  556. )}
  557. </Stack>
  558. <FormControl fullWidth sx={{ mt: 2 }}>
  559. <Grid container spacing={2} alignItems="center">
  560. <Grid item>
  561. <Box sx={{ bgcolor: level?.color, width: 85, height: 8, borderRadius: '7px' }} />
  562. </Grid>
  563. <Grid item>
  564. <Typography variant="subtitle1">
  565. {level?.label}
  566. </Typography>
  567. </Grid>
  568. </Grid>
  569. </FormControl>
  570. </Grid>
  571. <Grid item xs={12} md={6} >
  572. <Stack spacing={1}>
  573. <InputLabel htmlFor="confirmPassword-signup">
  574. <Typography variant="h5">
  575. 確認密碼
  576. <span style={{ color: '#f10000' }}>*</span>
  577. </Typography>
  578. </InputLabel>
  579. <OutlinedInput
  580. id="confirmPassword-login"
  581. type={showConfirmPassword ? 'text' : 'password'}
  582. value={formik.values.confirmPassword.trim()}
  583. name="confirmPassword"
  584. onBlur={formik.handleBlur}
  585. onChange={(e) => {
  586. formik.handleChange(e);
  587. // changePassword(e.target.value);
  588. }}
  589. inputProps={{
  590. onKeyDown: (e) => {
  591. if (e.key === 'Enter') {
  592. e.preventDefault();
  593. }
  594. },
  595. }}
  596. endAdornment={
  597. <InputAdornment position="end">
  598. <IconButton
  599. aria-label="toggle password visibility"
  600. onClick={handleClickShowConfirmPassword}
  601. onMouseDown={handleMouseDownPassword}
  602. edge="end"
  603. size="large"
  604. >
  605. {showConfirmPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  606. </IconButton>
  607. </InputAdornment>
  608. }
  609. placeholder="確認密碼"
  610. fullWidth
  611. error={Boolean(formik.touched.confirmPassword && formik.errors.confirmPassword)}
  612. />
  613. {formik.touched.confirmPassword && formik.errors.confirmPassword && (
  614. <FormHelperText error id="helper-text-confirmPassword-signup">
  615. {formik.errors.confirmPassword}
  616. </FormHelperText>
  617. )}
  618. </Stack>
  619. <Grid container spacing={2} alignItems="center">
  620. <Grid item>
  621. <Typography variant="subtitle1">
  622. <br />
  623. •至少8個字元,字元越多越好 <br />
  624. •字母和數字的混合<br />
  625. •英文字母大寫與小寫的混合<br />
  626. •至少包含一個特殊符號,例如,@ # ?
  627. </Typography>
  628. </Grid>
  629. </Grid>
  630. </Grid>
  631. </Grid>
  632. </Grid>
  633. <Grid item xs={12} mt={1} mb={1}>
  634. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  635. <Typography display="inline" variant="h4" sx={{ color: '#1A4399' }}>你的機構/公司資料</Typography>
  636. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  637. Already have an account?
  638. </Typography> */}
  639. </Stack>
  640. </Grid>
  641. <Grid item xs={12} md={12}>
  642. <Typography variant="subtitle1">
  643. <br />
  644. •請輸入機構/公司英文名稱或中文名稱<br />
  645. •Please enter the English/Chinese name of the organisation/company
  646. </Typography>
  647. </Grid>
  648. <Grid item xs={12} md={6}>
  649. <Stack spacing={1}>
  650. <InputLabel htmlFor="enCompanyName-signup">
  651. <Typography variant="h5">
  652. 機構/公司英文名稱
  653. </Typography>
  654. </InputLabel>
  655. <OutlinedInput
  656. id="enCompanyName-login"
  657. type="enCompanyName"
  658. value={formik.values.enCompanyName}
  659. name="enCompanyName"
  660. onChange={formik.handleChange}
  661. placeholder="與商業登記證相同"
  662. fullWidth
  663. error={Boolean(formik.touched.enCompanyName && formik.errors.enCompanyName && selectedAddress5 !== "內地")}
  664. onBlur={formik.handleBlur}
  665. inputProps={{
  666. onKeyDown: (e) => {
  667. if (e.key === 'Enter') {
  668. e.preventDefault();
  669. }
  670. },
  671. }}
  672. />
  673. {formik.touched.enCompanyName && formik.errors.enCompanyName && selectedAddress5 !== "內地" && (
  674. <FormHelperText error id="helper-text-enCompanyName-signup">
  675. {formik.errors.enCompanyName}
  676. </FormHelperText>
  677. )}
  678. </Stack>
  679. </Grid>
  680. <Grid item xs={12} md={6}>
  681. <Stack spacing={1}>
  682. <InputLabel htmlFor="chCompanyName-signup">
  683. <Typography variant="h5">
  684. 機構/公司中文名稱
  685. </Typography>
  686. </InputLabel>
  687. <OutlinedInput
  688. fullWidth
  689. error={Boolean(formik.touched.chCompanyName && formik.errors.chCompanyName)}
  690. id="chCompanyName-signup"
  691. type="text"
  692. value={formik.values.chCompanyName.trim()}
  693. name="chCompanyName"
  694. onChange={formik.handleChange}
  695. placeholder="與商業登記證相同"
  696. onBlur={formik.handleBlur}
  697. inputProps={{
  698. onKeyDown: (e) => {
  699. if (e.key === 'Enter') {
  700. e.preventDefault();
  701. }
  702. },
  703. }}
  704. />
  705. {formik.touched.chCompanyName && formik.errors.chCompanyName && (
  706. <FormHelperText error id="helper-text-chCompanyName-signup">
  707. {formik.errors.chCompanyName}
  708. </FormHelperText>
  709. )}
  710. </Stack>
  711. </Grid>
  712. <Grid item xs={12} md={6}>
  713. <Stack spacing={1}>
  714. <InputLabel htmlFor="brNo-signup">
  715. <Typography variant="h5">
  716. 商業登記證號碼
  717. <span style={{ color: '#f10000' }}>*</span>
  718. </Typography>
  719. </InputLabel>
  720. <OutlinedInput
  721. fullWidth
  722. error={Boolean(formik.touched.brNo && formik.errors.brNo)}
  723. id="brNo-signup"
  724. type="text"
  725. value={formik.values.brNo.trim()}
  726. name="brNo"
  727. onChange={formik.handleChange}
  728. onBlur={formik.handleBlur}
  729. placeholder="與商業登記證相同"
  730. inputProps={{
  731. onKeyDown: (e) => {
  732. if (e.key === 'Enter') {
  733. e.preventDefault();
  734. }
  735. },
  736. }}
  737. />
  738. {formik.touched.brNo && formik.errors.brNo && (
  739. <FormHelperText error id="helper-text-brNo-signup">
  740. {formik.errors.brNo}
  741. </FormHelperText>
  742. )}
  743. </Stack>
  744. </Grid>
  745. <Grid item xs={12} md={6}>
  746. <Stack spacing={1}>
  747. <InputLabel htmlFor="brExpiryDate-signup">
  748. <Typography variant="h5">
  749. 商業登記證有效日期
  750. <span style={{ color: '#f10000' }}>*</span>
  751. </Typography>
  752. </InputLabel>
  753. <OutlinedInput
  754. fullWidth
  755. error={Boolean(formik.touched.brExpiryDate && formik.errors.brExpiryDate)}
  756. id="brExpiryDate-signup"
  757. type="date"
  758. value={formik.values.brExpiryDate}
  759. name="brExpiryDate"
  760. onChange={formik.handleChange}
  761. onBlur={formik.handleBlur}
  762. placeholder="與商業登記證相同"
  763. inputProps={{
  764. max: "2099-12-31",
  765. min: new Date().toISOString().split("T")[0],
  766. onKeyDown: (e) => {
  767. if (e.key === 'Enter') {
  768. e.preventDefault();
  769. }
  770. },
  771. }}
  772. />
  773. {formik.touched.brExpiryDate && formik.errors.brExpiryDate && (
  774. <FormHelperText error id="helper-text-brExpiryDate-signup">
  775. {formik.errors.brExpiryDate}
  776. </FormHelperText>
  777. )}
  778. </Stack>
  779. </Grid>
  780. <Grid item xs={12}>
  781. <Stack spacing={1}>
  782. <InputLabel htmlFor="address1-signup">
  783. <Typography variant="h5">
  784. 地址
  785. <span style={{ color: '#f10000' }}>*</span>
  786. </Typography>
  787. </InputLabel>
  788. <OutlinedInput
  789. fullWidth
  790. error={Boolean(formik.touched.address1 && formik.errors.address1)}
  791. id="address1-signup"
  792. value={formik.values.address1}
  793. name="address1"
  794. onChange={formik.handleChange}
  795. placeholder="第一行"
  796. onBlur={formik.handleBlur}
  797. inputProps={{
  798. onKeyDown: (e) => {
  799. if (e.key === 'Enter') {
  800. e.preventDefault();
  801. }
  802. },
  803. }}
  804. />
  805. <OutlinedInput
  806. fullWidth
  807. error={Boolean(formik.touched.address2 && formik.errors.address2)}
  808. id="address2-signup"
  809. value={formik.values.address2}
  810. name="address2"
  811. onChange={formik.handleChange}
  812. placeholder="第二行"
  813. inputProps={{
  814. onKeyDown: (e) => {
  815. if (e.key === 'Enter') {
  816. e.preventDefault();
  817. }
  818. },
  819. }}
  820. />
  821. <OutlinedInput
  822. fullWidth
  823. error={Boolean(formik.touched.address3 && formik.errors.address3)}
  824. id="address3-signup"
  825. value={formik.values.address3}
  826. name="address3"
  827. onChange={formik.handleChange}
  828. placeholder="第三行"
  829. inputProps={{
  830. onKeyDown: (e) => {
  831. if (e.key === 'Enter') {
  832. e.preventDefault();
  833. }
  834. },
  835. }}
  836. />
  837. <Autocomplete
  838. disablePortal
  839. id="address4-combo"
  840. value={selectedAddress4}
  841. options={address4ComboList}
  842. disabled={checkCountry}
  843. onChange={(event, newValue) => {
  844. setSelectedAddress4(newValue);
  845. }}
  846. sx={{ "& .MuiInputBase-root": { height: "41px" }, "#address4-combo": { padding: "0px 0px 0px 0px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }}
  847. renderInput={(params) => <TextField {...params} placeholder="區域 (只適用於香港)" />}
  848. />
  849. <Autocomplete
  850. disablePortal
  851. id="address5-combo"
  852. value={selectedAddress5}
  853. options={address5ComboList}
  854. onChange={(event, newValue) => {
  855. if (newValue !== null) {
  856. setSelectedAddress5(newValue);
  857. if (newValue == '香港') {
  858. setCheckCountry(false)
  859. } else {
  860. setSelectedAddress4("");
  861. setCheckCountry(true)
  862. }
  863. } else {
  864. setSelectedAddress4("");
  865. setCheckCountry(true)
  866. }
  867. }}
  868. sx={{ "& .MuiInputBase-root": { height: "41px" }, "#address5-combo": { padding: "0px 0px 0px 0px" }, "& .MuiAutocomplete-endAdornment": { top: "auto" }, }}
  869. renderInput={(params) => <TextField {...params} placeholder="國家/地區" />}
  870. />
  871. {formik.touched.address1 && formik.errors.address1 && (
  872. <FormHelperText error id="helper-text-address1-signup">
  873. {formik.errors.address1}
  874. </FormHelperText>
  875. )}
  876. {formik.touched.address2 && formik.errors.address2 && (
  877. <FormHelperText error id="helper-text-address2-signup">
  878. {formik.errors.address2}
  879. </FormHelperText>
  880. )}
  881. {formik.touched.address3 && formik.errors.address3 && (
  882. <FormHelperText error id="helper-text-address3-signup">
  883. {formik.errors.address3}
  884. </FormHelperText>
  885. )}
  886. </Stack>
  887. </Grid>
  888. <Grid item xs={12} mt={1} mb={1}>
  889. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  890. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>你的聯絡資料</Typography>
  891. </Stack>
  892. </Grid>
  893. <Grid item xs={12} md={12}>
  894. <Stack spacing={1}>
  895. <InputLabel htmlFor="enName-signup">
  896. <Typography variant="h5">
  897. 姓名
  898. <span style={{ color: '#f10000' }}>*</span>
  899. </Typography>
  900. </InputLabel>
  901. <OutlinedInput
  902. id="enName-login"
  903. type="enName"
  904. value={formik.values.enName}
  905. name="enName"
  906. onChange={formik.handleChange}
  907. placeholder=""
  908. fullWidth
  909. error={Boolean(formik.touched.enName && formik.errors.enName)}
  910. onBlur={formik.handleBlur}
  911. inputProps={{
  912. onKeyDown: (e) => {
  913. if (e.key === 'Enter') {
  914. e.preventDefault();
  915. }
  916. },
  917. }}
  918. />
  919. {formik.touched.enName && formik.errors.enName && (
  920. <FormHelperText error id="helper-text-enName-signup">
  921. {formik.errors.enName}
  922. </FormHelperText>
  923. )}
  924. </Stack>
  925. </Grid>
  926. <Grid item xs={12} md={12}>
  927. <Grid container>
  928. <Grid item xs={12} md={6}>
  929. <Stack spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}>
  930. <InputLabel htmlFor="email-signup">
  931. <Typography variant="h5">
  932. 電郵
  933. <span style={{ color: '#f10000' }}>*</span>
  934. </Typography>
  935. </InputLabel>
  936. <OutlinedInput
  937. fullWidth
  938. error={Boolean(formik.touched.email && formik.errors.email)}
  939. id="email-login"
  940. type="email"
  941. value={formik.values.email.trim()}
  942. name="email"
  943. onChange={formik.handleChange}
  944. placeholder="電郵"
  945. onBlur={formik.handleBlur}
  946. inputProps={{
  947. onKeyDown: (e) => {
  948. if (e.key === 'Enter') {
  949. e.preventDefault();
  950. }
  951. },
  952. }}
  953. />
  954. {formik.touched.email && formik.errors.email && (
  955. <FormHelperText error id="helper-text-email-signup">
  956. {formik.errors.email}
  957. </FormHelperText>
  958. )}
  959. </Stack>
  960. </Grid>
  961. <Grid item xs={12} md={6}>
  962. <Stack spacing={1} >
  963. <InputLabel htmlFor="emailConfirm-signup">
  964. <Typography variant="h5">
  965. 確認電郵
  966. <span style={{ color: '#f10000' }}>*</span>
  967. </Typography>
  968. </InputLabel>
  969. <OutlinedInput
  970. fullWidth
  971. error={Boolean(formik.touched.emailConfirm && formik.errors.emailConfirm)}
  972. id="emailConfirm-login"
  973. type="email"
  974. value={formik.values.emailConfirm.trim()}
  975. name="emailConfirm"
  976. // onBlur={formik.handleBlur}
  977. onChange={formik.handleChange}
  978. placeholder="確認電郵"
  979. onBlur={formik.handleBlur}
  980. inputProps={{
  981. onKeyDown: (e) => {
  982. if (e.key === 'Enter') {
  983. e.preventDefault();
  984. }
  985. },
  986. }}
  987. />
  988. {formik.touched.emailConfirm && formik.errors.emailConfirm && (
  989. <FormHelperText error id="helper-text-emailConfirm-signup">
  990. {formik.errors.emailConfirm}
  991. </FormHelperText>
  992. )}
  993. </Stack>
  994. </Grid>
  995. </Grid>
  996. </Grid>
  997. <Grid item xs={12} md={12}>
  998. <Grid container>
  999. <Grid item xs={12} md={6}>
  1000. <Grid container>
  1001. <Grid item xs={12} md={12}>
  1002. <Stack direction="column" spacing={1} sx={{ mr: { md: 1 }, mb: 1 }}>
  1003. <InputLabel htmlFor="phone-signup">
  1004. <Typography variant="h5">
  1005. 聯絡電話
  1006. <span style={{ color: '#f10000' }}>*</span>
  1007. </Typography>
  1008. </InputLabel>
  1009. <Stack direction="row">
  1010. <OutlinedInput
  1011. id="phoneCountryCode-login"
  1012. type="phoneCountryCode"
  1013. value={formik.values.phoneCountryCode.trim()}
  1014. name="phoneCountryCode"
  1015. // onBlur={formik.handleBlur}
  1016. // onChange={formik.handleChange}
  1017. onChange={(event) => {
  1018. const value = event.target.value;
  1019. if (value.match(/[^0-9]/)) {
  1020. return event.preventDefault();
  1021. }
  1022. formik.setFieldValue("phoneCountryCode", value);
  1023. }}
  1024. placeholder="國際區號"
  1025. error={Boolean(formik.touched.phone && formik.errors.phone)}
  1026. onBlur={formik.handleBlur}
  1027. inputProps={{
  1028. maxLength: 3,
  1029. onKeyDown: (e) => {
  1030. if (e.key === 'Enter') {
  1031. e.preventDefault();
  1032. }
  1033. },
  1034. }}
  1035. sx={{ width: '25%' }}
  1036. />
  1037. <OutlinedInput
  1038. id="phone-login"
  1039. type="phone"
  1040. value={formik.values.phone.trim()}
  1041. name="phone"
  1042. onBlur={formik.handleBlur}
  1043. // onChange={formik.handleChange}
  1044. onChange={(event) => {
  1045. const value = event.target.value;
  1046. if (value.match(/[^0-9]/)) {
  1047. return event.preventDefault();
  1048. }
  1049. formik.setFieldValue("phone", value);
  1050. }}
  1051. placeholder="聯絡電話"
  1052. error={Boolean(formik.touched.phone && formik.errors.phone)}
  1053. inputProps={{
  1054. maxLength: 11,
  1055. onKeyDown: (e) => {
  1056. if (e.key === 'Enter') {
  1057. e.preventDefault();
  1058. }
  1059. },
  1060. }}
  1061. sx={{ width: '75%' }}
  1062. />
  1063. </Stack>
  1064. {formik.touched.phone && formik.errors.phone && (
  1065. <FormHelperText error id="helper-text-phone-signup">
  1066. {formik.errors.phone}
  1067. </FormHelperText>
  1068. )}
  1069. </Stack>
  1070. </Grid>
  1071. </Grid>
  1072. </Grid>
  1073. <Grid item xs={12} md={6}>
  1074. <Grid container>
  1075. <Grid item xs={12} md={12}>
  1076. <Stack spacing={1} direction="column">
  1077. <InputLabel htmlFor="fax-signup">
  1078. <Typography variant="h5">
  1079. 傳真號碼
  1080. </Typography>
  1081. </InputLabel>
  1082. <Stack direction="row">
  1083. <OutlinedInput
  1084. error={Boolean(formik.touched.fax && formik.errors.fax)}
  1085. id="faxCountryCode-login"
  1086. type="faxCountryCode"
  1087. value={formik.values.faxCountryCode.trim()}
  1088. name="faxCountryCode"
  1089. // onBlur={formik.handleBlur}
  1090. // onChange={formik.handleChange}
  1091. onChange={(event) => {
  1092. const value = event.target.value;
  1093. if (value.match(/[^0-9]/)) {
  1094. return event.preventDefault();
  1095. }
  1096. formik.setFieldValue("faxCountryCode", value);
  1097. }}
  1098. placeholder="國際區號"
  1099. inputProps={{
  1100. maxLength: 3,
  1101. onKeyDown: (e) => {
  1102. if (e.key === 'Enter') {
  1103. e.preventDefault();
  1104. }
  1105. },
  1106. }}
  1107. sx={{ width: '25%' }}
  1108. />
  1109. <OutlinedInput
  1110. id="fax-login"
  1111. type="fax"
  1112. value={formik.values.fax.trim()}
  1113. name="fax"
  1114. // onBlur={formik.handleBlur}
  1115. // onChange={formik.handleChange}
  1116. onChange={(event) => {
  1117. const value = event.target.value;
  1118. if (value.match(/[^0-9]/)) {
  1119. return event.preventDefault();
  1120. }
  1121. formik.setFieldValue("fax", value);
  1122. }}
  1123. placeholder="傳真號碼"
  1124. inputProps={{
  1125. maxLength: 8,
  1126. onKeyDown: (e) => {
  1127. if (e.key === 'Enter') {
  1128. e.preventDefault();
  1129. }
  1130. },
  1131. }}
  1132. sx={{ width: '75%' }}
  1133. />
  1134. </Stack>
  1135. </Stack>
  1136. </Grid>
  1137. </Grid>
  1138. </Grid>
  1139. </Grid>
  1140. </Grid>
  1141. <Grid item xs={12} md={12} mt={1} mb={1}>
  1142. <Grid container>
  1143. <Grid item xs={12} md={12}>
  1144. <Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1145. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>商業登記證及其他文件
  1146. <span style={{ color: '#f10000' }}>*</span>
  1147. </Typography>
  1148. <Typography display="inline" variant="h6" sx={{ color: 'primary.primary' }}>請上傳你的 有效商業登記證及其他文件 的數碼檔案,以驗證你的身份。</Typography>
  1149. {/* <Typography display="inline" variant="h6" sx={{ fontSize: 12,color: 'primary.primary'}}>如: 香港身份證; 護照; 中國內地身份證等</Typography> */}
  1150. <Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}>
  1151. <Button variant="contained" component="label" sx={{ height: '40px' }}><Typography variant="h6">上傳商業登記證及其他文件</Typography>
  1152. <input
  1153. accept="image/png, .jpg, .bmp, .pdf"
  1154. //className={classes.input}
  1155. id="contained-button-file"
  1156. multiple
  1157. type="file"
  1158. onChange={handleFileUpload}
  1159. style={{ display: 'none' }}
  1160. />
  1161. </Button>
  1162. {/* <Typography display="inline" variant="h6" sx={{ fontSize: 12, color: 'primary.primary'}}></Typography> */}
  1163. </Stack>
  1164. {fileList != null ?
  1165. <UploadFileTable key="uploadTable" recordList={fileListData} setUpdateRows={setUpdateRows} /> : null}
  1166. {/* <Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}>
  1167. <Button variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button>
  1168. <Button disabled={!formik.isValid} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button>
  1169. </Stack> */}
  1170. </Stack>
  1171. </Grid>
  1172. </Grid>
  1173. </Grid>
  1174. </Grid>
  1175. <Grid item xs={12} md={12}>
  1176. <Grid container>
  1177. <Grid item xs={12} md={12}>
  1178. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1179. 條款和條件
  1180. <span style={{ color: '#f10000' }}>*</span>
  1181. </Typography>
  1182. </Grid>
  1183. <Grid item xs={12} md={12}>
  1184. <Grid container>
  1185. <Grid item xs={12} md={12}>
  1186. <Typography variant="h6" height="80%" sx={{ textAlign: "left", overflow: "scroll", borderRadius: "inherit", borderStyle: "solid", borderWidth: "1px", borderColor: "#0C489E" }}>
  1187. {termsAndCon}
  1188. </Typography>
  1189. </Grid>
  1190. </Grid>
  1191. <Grid item xs={12} s={12} md={12} lg={12}>
  1192. <Grid container>
  1193. <Grid item xs={6} s={6} md={2} lg={2}>
  1194. <Grid container>
  1195. <Grid item sx={{ display: 'flex', alignItems: 'center' }}>
  1196. <Checkbox
  1197. checked={termsAndConAccept}
  1198. onChange={handleCheckBoxChange}
  1199. name="termsAndConAccept"
  1200. color="primary"
  1201. size="small"
  1202. />
  1203. <Typography variant="h5">我接受</Typography>
  1204. </Grid>
  1205. </Grid>
  1206. </Grid>
  1207. <Grid item xs={6} s={6} md={2} lg={2}>
  1208. <Grid container>
  1209. <Grid item sx={{ display: 'flex', alignItems: 'center' }}>
  1210. <Checkbox
  1211. checked={termsAndConNotAccept}
  1212. onChange={handleCheckBoxChange}
  1213. name="termsAndConNotAccept"
  1214. color="primary"
  1215. size="small"
  1216. />
  1217. <Typography variant="h5">我不接受</Typography>
  1218. </Grid>
  1219. </Grid>
  1220. </Grid>
  1221. </Grid>
  1222. </Grid>
  1223. </Grid>
  1224. </Grid>
  1225. </Grid>
  1226. <Grid item xs={12} lg={12}>
  1227. <Grid container>
  1228. <Stack direction="column">
  1229. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>
  1230. 驗證
  1231. <span style={{ color: '#f10000' }}>*</span>
  1232. </Typography>
  1233. <Stack spacing={1} direction="row">
  1234. <Grid item xs={5} lg={5} style={{ "border": "1px solid black" }}>
  1235. <img src={captchaImg} alt="" />
  1236. </Grid>
  1237. <Grid item xs={1} lg={1} style={{ "border": "0px solid black" }}>
  1238. <IconButton aria-label="refrashCaptcha" size="large" onClick={() => { onCaptchaChange() }}>
  1239. <LoopIcon fontSize="inherit" />
  1240. </IconButton>
  1241. </Grid>
  1242. <Grid item xs={6} lg={6}>
  1243. <OutlinedInput
  1244. fullWidth
  1245. id="captchaField"
  1246. type="text"
  1247. value={formik.values.captchaField.trim()}
  1248. onBlur={formik.handleBlur}
  1249. error={Boolean(formik.touched.captchaField && formik.errors.captchaField)}
  1250. name="captchaField"
  1251. onChange={(event) => {
  1252. const value = event.target.value;
  1253. formik.setFieldValue("captchaField", value);
  1254. }}
  1255. sx={{ width: '75%' }}
  1256. />
  1257. </Grid>
  1258. </Stack>
  1259. {formik.touched.captchaField && formik.errors.captchaField && (
  1260. <FormHelperText error id="helper-text-captcha-signup">
  1261. {formik.errors.captchaField}
  1262. </FormHelperText>
  1263. )}
  1264. </Stack>
  1265. </Grid>
  1266. </Grid>
  1267. </Grid>
  1268. </Grid>
  1269. </FormGroup>
  1270. {/* Preview Form */}
  1271. <FormGroup id={"previewForm"} sx={{ display: props.step === 1 ? "" : "none" }}>
  1272. <Grid container spacing={2}>
  1273. <Grid item xs={12}>
  1274. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1275. <div style={{ borderBottom: "3px solid #1A4399", width: "100%", margin_right: "15px" }}>
  1276. <Typography display="inline" variant="h3" sx={{ color: '#1A4399' }}>成為新的機構/公司用戶</Typography>
  1277. </div>
  1278. {/* <Typography mt={0.25} variant="h6" sx={{ fontSize: 12,color: '#f10000'}}>註有*的項目必須輸入資料</Typography> */}
  1279. <Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary' }}>你的登入資料</Typography>
  1280. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  1281. Already have an account?
  1282. </Typography> */}
  1283. </Stack>
  1284. </Grid>
  1285. <Grid item xs={12}>
  1286. <Grid container spacing={1}>
  1287. <Grid item xs={12} >
  1288. <Stack spacing={1} direction="row">
  1289. <Typography variant="h5" color={theme.palette.grey[600]}>
  1290. 用戶登入名稱:
  1291. </Typography>
  1292. <Typography variant="h5" id="preview-username-login">
  1293. {formik.values.username}
  1294. </Typography>
  1295. </Stack>
  1296. </Grid>
  1297. <Grid item xs={12} mt={1} mb={1}>
  1298. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1299. <Typography display="inline" variant="h4" sx={{ color: '#1A4399' }}>你的機構/公司資料</Typography>
  1300. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  1301. Already have an account?
  1302. </Typography> */}
  1303. </Stack>
  1304. </Grid>
  1305. <Grid item xs={12} md={6}>
  1306. <Stack spacing={1} direction="row">
  1307. <Typography variant="h5" color={theme.palette.grey[600]}>
  1308. 機構/公司英文名稱:
  1309. </Typography>
  1310. <Typography variant="h5" id="preview-enCompanyName-signup">
  1311. {formik.values.enCompanyName}
  1312. </Typography>
  1313. </Stack>
  1314. </Grid>
  1315. <Grid item xs={12} md={6}>
  1316. <Stack spacing={1} direction="row">
  1317. <Typography variant="h5" color={theme.palette.grey[600]}>
  1318. 機構/公司中文名稱:
  1319. </Typography>
  1320. <Typography variant="h5" id="preview-chCompanyName-signup">
  1321. {formik.values.chCompanyName}
  1322. </Typography>
  1323. </Stack>
  1324. </Grid>
  1325. <Grid item xs={12} md={12} >
  1326. <Stack spacing={1}>
  1327. <Typography variant="h5" color={theme.palette.grey[600]}>
  1328. 商業登記證
  1329. </Typography>
  1330. </Stack>
  1331. </Grid>
  1332. <Grid item xs={12} md={6}>
  1333. <Stack spacing={1} direction="row">
  1334. <Typography variant="h5" color={theme.palette.grey[600]}>
  1335. 商業登記證號碼:
  1336. </Typography>
  1337. <Typography variant="h5" id="brNo-login">
  1338. {formik.values.brNo}
  1339. </Typography>
  1340. </Stack>
  1341. </Grid>
  1342. <Grid item xs={12} md={6}>
  1343. <Stack spacing={1} direction="row">
  1344. <Typography variant="h5" color={theme.palette.grey[600]}>
  1345. 商業登記證有效日期:
  1346. </Typography>
  1347. <Typography variant="h5" id="brExpiryDate-login">
  1348. {formik.values.brExpiryDate}
  1349. </Typography>
  1350. </Stack>
  1351. </Grid>
  1352. <Grid item xs={12}>
  1353. <Stack spacing={1} direction="row">
  1354. <Typography variant="h5" color={theme.palette.grey[600]}>
  1355. 地址:
  1356. </Typography>
  1357. <Stack spacing={1} direction="column">
  1358. <Typography variant="h5" id="preview-address1-signup">
  1359. {formik.values.address1}
  1360. </Typography>
  1361. {formik.values.address2 != null ?
  1362. <Typography variant="h5" id="preview-address2-signup">
  1363. {formik.values.address2}
  1364. </Typography>
  1365. : null}
  1366. {formik.values.address3 != null ?
  1367. <Typography variant="h5" id="preview-address3-signup">
  1368. {formik.values.address3}
  1369. </Typography>
  1370. : null}
  1371. {selectedAddress5 == ("香港") ?
  1372. <Stack direction="row">
  1373. <Typography variant="h5" color={theme.palette.grey[600]} id="preview-address4-signup">
  1374. 區域 (只適用於香港):
  1375. </Typography>
  1376. <Typography variant="h5">
  1377. {selectedAddress4}
  1378. </Typography>
  1379. </Stack>
  1380. : null}
  1381. <Stack direction="row">
  1382. <Typography variant="h5" color={theme.palette.grey[600]} id="preview-address5-signup">
  1383. 國家/地區:
  1384. </Typography>
  1385. <Typography variant="h5">
  1386. {selectedAddress5}
  1387. </Typography>
  1388. </Stack>
  1389. </Stack>
  1390. </Stack>
  1391. </Grid>
  1392. <Grid item xs={12} mt={1} mb={1}>
  1393. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1394. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>你的聯絡資料</Typography>
  1395. </Stack>
  1396. </Grid>
  1397. <Grid item xs={12} md={12}>
  1398. <Stack spacing={1} direction="row">
  1399. <Typography variant="h5" color={theme.palette.grey[600]}>
  1400. 英文名稱:
  1401. </Typography>
  1402. <Typography variant="h5" id="preview-enName-signup">
  1403. {formik.values.enName}
  1404. </Typography>
  1405. </Stack>
  1406. </Grid>
  1407. <Grid item xs={12} md={12}>
  1408. <Stack spacing={1} direction="row">
  1409. <Typography variant="h5" color={theme.palette.grey[600]}>
  1410. 電郵:
  1411. </Typography>
  1412. <Typography variant="h5" id="preview-email-signup">
  1413. {formik.values.email}
  1414. </Typography>
  1415. </Stack>
  1416. </Grid>
  1417. <Grid item xs={12} md={6}>
  1418. <Stack spacing={1} direction="row">
  1419. <Typography variant="h5" color={theme.palette.grey[600]}>
  1420. 聯絡電話:
  1421. </Typography>
  1422. <Typography variant="h5" id="preview-phone-signup">
  1423. +{formik.values.phoneCountryCode} {formik.values.phone}
  1424. </Typography>
  1425. </Stack>
  1426. </Grid>
  1427. <Grid item xs={12} md={6}>
  1428. <Stack spacing={1} direction="row">
  1429. <Typography variant="h5" color={theme.palette.grey[600]}>
  1430. 傳真號碼:
  1431. </Typography>
  1432. <Typography variant="h5" id="preview-fax-signup">
  1433. +{formik.values.faxCountryCode} {formik.values.fax}
  1434. </Typography>
  1435. </Stack>
  1436. </Grid>
  1437. <Grid item xs={12} md={12} mt={1} mb={1}>
  1438. <Grid container>
  1439. <Grid item xs={12} md={12}>
  1440. <Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1441. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary' }}>身份證明文件</Typography>
  1442. {fileList != null ?
  1443. <PreviewUploadFileTable key="previewTable" recordList={fileListData} /> : null}
  1444. </Stack>
  1445. </Grid>
  1446. </Grid>
  1447. </Grid>
  1448. </Grid>
  1449. </Grid>
  1450. </Grid>
  1451. </FormGroup>
  1452. {/* Submit page */}
  1453. <FormGroup id={"submitForm"} sx={{ display: props.step === 2 ? "" : "none" }}>
  1454. <Grid container spacing={3}>
  1455. {isLoading ?
  1456. <LoadingComponent /> :
  1457. <Grid item xs={12}>
  1458. {checkUpload ?
  1459. // SUCCESS page
  1460. <Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
  1461. <CheckCircleOutlineIcon color="success" sx={{ width: "200px", height: "200px" }} />
  1462. <Typography display="inline" variant="h4">帳戶申請已成功提交。</Typography>
  1463. <Typography display="inline" variant="h4">驗證電郵將發送到你的電郵地址,請要指示完成驗證及登入系統。</Typography>
  1464. <Button variant="outlined" component={Link} to="/login" sx={{ fontSize: 20, height: '60px' }}><Typography variant="h5">返回登入頁面</Typography></Button>
  1465. </Stack>
  1466. :
  1467. // ERROR page
  1468. <Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
  1469. {/* <Button disabled={true} hidden={true} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> */}
  1470. <CancelOutlinedIcon color="error" sx={{ width: "200px", height: "200px" }} />
  1471. <Typography display="inline" variant="h4">申請失敗,請稍後嘗試</Typography>
  1472. <Button color="error" variant="outlined" component={Link} to="/login" sx={{ fontSize: 20, height: '60px' }}><Typography variant="h5">返回登入頁面</Typography></Button>
  1473. </Stack>
  1474. }
  1475. </Grid>
  1476. }
  1477. </Grid>
  1478. </FormGroup>
  1479. </form>
  1480. </FormikProvider>
  1481. );
  1482. }
  1483. export default BusCustomFormWizard;