You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1219 lines
74 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} from "utils/ApiPathConst";
  30. import * as HttpUtils from 'utils/HttpUtils';
  31. import Loadable from 'components/Loadable';
  32. import { lazy } from 'react';
  33. const UploadFileTable = Loadable(lazy(() => import('./UploadFileTable')));
  34. const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingComponent')));
  35. // import UploadFileTable from './UploadFileTable';
  36. // import LoadingComponent from "../../extra-pages/LoadingComponent";
  37. // assets
  38. import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons';
  39. import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
  40. import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined';
  41. import { Link } from 'react-router-dom';
  42. // ============================|| FIREBASE - REGISTER ||============================ //
  43. const BusCustomFormWizard = (props) => {
  44. const [level, setLevel] = useState();
  45. const [showPassword, setShowPassword] = useState(false);
  46. const [showConfirmPassword, setshowConfirmPassword] = useState(false);
  47. const [fileList, setFileList] = useState([]);
  48. const [fileListData, setFileListData] = useState([]);
  49. const [checkUpload, setCheckUpload] = useState(false);
  50. const [isLoading, setLoding] = useState(true);
  51. const handleClickShowPassword = () => {
  52. setShowPassword(!showPassword);
  53. };
  54. const handleClickShowConfirmPassword = () => {
  55. setshowConfirmPassword(!showConfirmPassword);
  56. };
  57. const handleMouseDownPassword = (event) => {
  58. event.preventDefault();
  59. };
  60. const changePassword = (value) => {
  61. const temp = strengthIndicator(value);
  62. setLevel(strengthColorChi(temp));
  63. };
  64. const [selectedAddress4, setSelectedAddress4] = useState(null);
  65. const [selectedAddress5, setSelectedAddress5] = useState("香港");
  66. const [termsAndConAccept, setTermsAndConAccept] = useState(false);
  67. const [termsAndConNotAccept, setTermsAndConNotAccept] = useState(false);
  68. const [isValid, setisValid] = useState(false);
  69. const address4ComboList =
  70. ["北區","長洲區","大埔區","大嶼山區","東區","觀塘區","黃大仙區","九龍城區","葵青區","南區","南丫島區",
  71. "坪洲區","荃灣區","沙田區","深水埗區","屯門區","灣仔區","西貢區","油尖旺區","元朗區","中西區"];
  72. const address5ComboList = ["香港","內地","澳門"];
  73. const termsAndCon = "此網址由香港特別行政區政府物流服務署製作及管理。本署會盡力確保網址上的資料無誤,\n"
  74. + "但有絕對酌情權隨時刪除、暫停登載或編輯各項資料而無須給予任何理由。\n由於任何與網址"
  75. + "內資料有關的理由或原因,而導致出現申索、損失或損害,本署概不負責。\n使用者須自行評"
  76. + "估本網址所載或與本網址有關連的各項資料,並應在根據該等資料行事前,參照印行的香港"
  77. + "特別行政區憲報以核實該等資料,以及徵詢獨立意見。\n版權公告本網頁的內容,包括但不限"
  78. + "於所有文本、平面圖像、圖畫、圖片、照片以及數據或其他資料的匯編,均受版權保障。\n香"
  79. + "港特別行政區政府是本網頁內所有版權作品的擁有人,除非預先得到政府物流服務署的書面"
  80. + "授權,否則嚴禁複製、改編、分發、發布或向公眾提供該等版權作品。"
  81. useEffect(() => {
  82. changePassword('');
  83. }, []);
  84. const checkDataField = (data)=> {
  85. // console.log(data.brExpiryDate)
  86. if (data.username !==""&&
  87. data.password !==""&&
  88. data.confirmPassword !==""&&
  89. data.password == data.confirmPassword&&
  90. data.enCompanyName !==""&&
  91. data.enName !==""&&
  92. data.address1 !==""&&
  93. data.email !==""&&
  94. data.emailConfirm !==""&&
  95. data.phone !==""&&
  96. data.phoneCountryCode !==""&&
  97. termsAndConAccept == true&&
  98. fileList.length!==0&&
  99. handlePassword(data.password)&&
  100. handleEmail(data.email)&&
  101. handlePhone(data.phone)
  102. )
  103. {
  104. setisValid(true)
  105. return isValid
  106. }else{
  107. setisValid(false)
  108. return isValid
  109. }
  110. };
  111. const handleCheckBoxChange = (event) => {
  112. console.log (event.target)
  113. if(event.target.name == 'termsAndConAccept'){
  114. setTermsAndConAccept(event.target.checked)
  115. setTermsAndConNotAccept(!event.target.checked)
  116. }
  117. if(event.target.name == 'termsAndConNotAccept'){
  118. setTermsAndConNotAccept(event.target.checked)
  119. setTermsAndConAccept(!event.target.checked)
  120. }
  121. };
  122. const handleFileUpload = (event)=>{
  123. const uploadFileList = event.target.files;
  124. const saveFileList = [];
  125. var currentIndex = 0;
  126. if (!fileList.length==null){
  127. currentIndex = fileList.length;
  128. }
  129. for (let i = 0; i < uploadFileList.length; i++){
  130. const file = event.target.files[i]
  131. file.id = currentIndex+i+1
  132. saveFileList.push(file)
  133. }
  134. setFileListData(saveFileList)
  135. setFileList(uploadFileList);
  136. };
  137. useEffect(() => {
  138. props.setUpdateValid(isValid)
  139. }, [isValid])
  140. useEffect(() => {
  141. checkDataField(values)
  142. }, [selectedAddress4,selectedAddress5,
  143. termsAndConAccept,termsAndConNotAccept,fileList])
  144. useEffect(() => {
  145. props.step ==2?_onSubmit():null;
  146. }, [props.step])
  147. const {handleSubmit} = useForm({})
  148. const _onSubmit = () => {
  149. setLoding(true);
  150. values.address4 = selectedAddress4
  151. values.address5 = selectedAddress5
  152. // console.log(values)
  153. const busUserAddress = {
  154. "addressLine1":"",
  155. "addressLine2":"",
  156. "addressLine3":"",
  157. "district":"",
  158. "country":""
  159. };
  160. busUserAddress.addressLine1 = values.address1
  161. busUserAddress.addressLine2 = values.address2
  162. busUserAddress.addressLine3 = values.address3
  163. busUserAddress.district = values.address4
  164. busUserAddress.country = values.address5
  165. const userFaxNo = {
  166. "countryCode":values.faxCountryCode,
  167. "faxNumber":values.fax,
  168. };
  169. const busUserContactTel = {
  170. "countryCode":values.phoneCountryCode,
  171. "phoneNumber":values.phone,
  172. };
  173. let tncFlag = false;
  174. if (termsAndConAccept){
  175. tncFlag = true
  176. }
  177. if (termsAndConNotAccept){
  178. tncFlag = false
  179. }
  180. if (isValid){
  181. axios.post(`${apiPath}${POST_PUBLIC_USER_REGISTER}`, {
  182. username: values.username,
  183. password: values.password,
  184. name: values.username,
  185. enCompanyName: values.enCompanyName,
  186. chCompanyName: values.chCompanyName,
  187. emailBus: values.email,
  188. brNo:values.brNo,
  189. brExpiryDate:values.brExpiryDate,
  190. userFaxNo:userFaxNo,
  191. busUserContactTel:busUserContactTel,
  192. busUserAddress:busUserAddress,
  193. contactPerson: values.enName,
  194. tncFlag:tncFlag,
  195. type:"ORG"
  196. })
  197. .then((response) => {
  198. setCheckUpload(true)
  199. HttpUtils.fileUpload(
  200. {
  201. refType:"brFile",
  202. refId: response.data.id,
  203. file: fileList[0],
  204. onSuccess: (response)=>{
  205. console.log(response);
  206. setLoding(false);
  207. // setOpen(true);
  208. }
  209. }
  210. );
  211. })
  212. .catch(error => {
  213. console.error(error);
  214. setLoding(false);
  215. });
  216. }else{
  217. setLoding(false);
  218. }
  219. }
  220. function handlePhone(phone) {
  221. if (phone.length < 8) {
  222. return false;
  223. } else {
  224. return true;
  225. }
  226. }
  227. function handlePassword(password) {
  228. let new_pass = password;
  229. // regular expressions to validate password
  230. var lowerCase = /[a-z]/g;
  231. var upperCase = /[A-Z]/g;
  232. var numbers = /[0-9]/g;
  233. if (!new_pass.match(lowerCase)) {
  234. return false;
  235. } else if (!new_pass.match(upperCase)) {
  236. return false;
  237. } else if (!new_pass.match(numbers)) {
  238. return false;
  239. } else if (new_pass.length < 8) {
  240. return false;
  241. } else {
  242. return true;
  243. }
  244. }
  245. function handleEmail(email) {
  246. var validRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
  247. // var result = reg.test(email);
  248. var result = email.match(validRegex);
  249. console.log("test1: "+result)
  250. if (result == false) {
  251. return false;
  252. }
  253. return true;
  254. }
  255. const formik = useFormik({
  256. initialValues:({
  257. username:'',
  258. enName: '',
  259. enCompanyName: '',
  260. chCompanyName: '',
  261. email: '',
  262. address1: '',
  263. address2: '',
  264. address3: '',
  265. password: '',
  266. confirmPassword: '',
  267. phone:'',
  268. phoneCountryCode:'852',
  269. submit: null,
  270. fax:'',
  271. faxCountryCode:'852',
  272. brExpiryDate:'',
  273. brNo:'',
  274. }),
  275. validationSchema:yup.object().shape({
  276. username: yup.string().min(6,'用戶名稱最少6位').required('請輸入用戶名稱'),
  277. password: yup.string().min(8,'請輸入最少8位密碼').required('請輸入密碼')
  278. .matches(/^(?=.*[a-z])/, '請包括最少1個小寫字母')
  279. .matches(/^(?=.*[A-Z])/, '請包括最少1個大寫字母')
  280. .matches(/^(?=.*[0-9])/, '請包括最少1個數字')
  281. .matches(/^(?=.*[!@#%&])/, '請包括最少1個特殊字符'),
  282. confirmPassword: yup.string().min(8,'請最少輸入8位密碼').required('請確認密碼').oneOf([yup.ref('password'), null], '請輸入相同密碼'),
  283. enName: yup.string().max(255).required('請輸入英文姓名'),
  284. enCompanyName: yup.string().max(255).required('請輸入英文名稱'),
  285. chName: yup.string().max(255).required('請輸入中文姓名'),
  286. address1: yup.string().max(255).required('請輸入第一行地址'),
  287. address2: yup.string().max(255).required('請輸入第二行地址'),
  288. address3: yup.string().max(255).required('請輸入第三行地址'),
  289. email: yup.string().email('請輸入電郵格式').max(255).required('請輸入電郵'),
  290. emailConfirm: yup.string().email('請輸入電郵格式').max(255).required('請輸入電郵').oneOf([yup.ref('email'), null], '請輸入相同電郵'),
  291. phoneCountryCode: yup.string().min(3,'請輸入3位數字').required('請輸入國際區號'),
  292. faxCountryCode: yup.string().min(3,'請輸入3位數字'),
  293. phone: yup.string().min(8,'請輸入8位數字').required('請輸入聯絡電話'),
  294. fax: yup.string().min(8,'請輸入8位數字'),
  295. brExpiryDate: yup.string().min(8,'請輸入商業登記證有效日期'),
  296. brNo: yup.string().min(8,'請輸入商業登記證號碼'),
  297. })
  298. });
  299. const handleReset = (resetForm) => {
  300. resetForm();
  301. setSelectedAddress4("")
  302. };
  303. const { values } = formik
  304. useEffect(() => {
  305. checkDataField(values)
  306. }, [values])
  307. return (
  308. <FormikProvider value={formik}>
  309. <form onSubmit={handleSubmit(_onSubmit)}>
  310. {/* Input Form */}
  311. <FormGroup id={"inputForm"} sx={{ display: props.step === 0 ? "" : "none" }}>
  312. <Grid container spacing={3}>
  313. <Grid item xs={12} md={12}>
  314. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  315. <Button variant="outlined" type="reset" onClick={handleReset.bind(null, formik.resetForm)} sx={{ fontSize: 16,height:'30px'}}>重置</Button>
  316. <div style={{borderBottom: "3px solid #1A4399", width:"100%", margin_right: "15px"}}>
  317. <Typography display="inline" variant="h3" sx={{ color: '#1A4399'}}>成為新的機構/公司用戶</Typography>
  318. </div>
  319. <Typography mt={0.25} variant="h6" sx={{ fontSize: 12,color: '#f10000'}}>註有*的項目必須輸入資料</Typography>
  320. <Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary'}}>你的登入資料</Typography>
  321. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  322. Already have an account?
  323. </Typography> */}
  324. </Stack>
  325. </Grid>
  326. <Grid item xs={12} md={12}>
  327. <Grid container spacing={1}>
  328. <Grid item xs={12} md={12} >
  329. <Stack spacing={1}>
  330. <InputLabel htmlFor="username-signup">用戶登入名稱
  331. <span style={{color: '#f10000'}}>*</span>
  332. </InputLabel>
  333. <OutlinedInput
  334. id="username-login"
  335. type="text"
  336. value={formik.values.username}
  337. name="username"
  338. onChange={formik.handleChange}
  339. placeholder="用戶登入名稱"
  340. fullWidth
  341. error={Boolean(formik.touched.username && formik.errors.username)}
  342. onBlur={formik.handleBlur}
  343. inputProps={{
  344. onKeyDown: (e) => {
  345. if (e.key === 'Enter') {
  346. e.preventDefault();
  347. }
  348. },
  349. }}
  350. />
  351. {formik.touched.username && formik.errors.username && (
  352. <FormHelperText error id="helper-text-username-signup">
  353. {formik.errors.username}
  354. </FormHelperText>
  355. )}
  356. </Stack>
  357. </Grid>
  358. <Grid item xs={12} md={12}>
  359. <Grid container>
  360. <Grid item xs={12} md={6} >
  361. <Stack spacing={1} sx={{mr:{md:1},mb:1}}>
  362. <Stack direction="row" justifyContent="space-between">
  363. <InputLabel htmlFor="password-signup">密碼
  364. <span style={{color: '#f10000'}}>*</span>
  365. </InputLabel>
  366. <InputLabel htmlFor="password-rule">密碼規則</InputLabel>
  367. </Stack>
  368. <OutlinedInput
  369. fullWidth
  370. error={Boolean(formik.touched.password && formik.errors.password)}
  371. id="password-signup"
  372. type={showPassword ? 'text' : 'password'}
  373. value={formik.values.password}
  374. name="password"
  375. onChange={(e) => {
  376. formik.handleChange(e);
  377. changePassword(e.target.value);
  378. }}
  379. endAdornment={
  380. <InputAdornment position="end">
  381. <IconButton
  382. aria-label="toggle password visibility"
  383. onClick={handleClickShowPassword}
  384. onMouseDown={handleMouseDownPassword}
  385. edge="end"
  386. size="large"
  387. >
  388. {showPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  389. </IconButton>
  390. </InputAdornment>
  391. }
  392. placeholder="密碼"
  393. onBlur={formik.handleBlur}
  394. inputProps={{
  395. onKeyDown: (e) => {
  396. if (e.key === 'Enter') {
  397. e.preventDefault();
  398. }
  399. },
  400. }}
  401. />
  402. {formik.touched.password && formik.errors.password && (
  403. <FormHelperText error id="helper-text-password-signup">
  404. {formik.errors.password}
  405. </FormHelperText>
  406. )}
  407. </Stack>
  408. <FormControl fullWidth sx={{ mt: 2 }}>
  409. <Grid container spacing={2} alignItems="center">
  410. <Grid item>
  411. <Box sx={{ bgcolor: level?.color, width: 85, height: 8, borderRadius: '7px' }} />
  412. </Grid>
  413. <Grid item>
  414. <Typography variant="subtitle1" fontSize="0.75rem">
  415. {level?.label}
  416. </Typography>
  417. </Grid>
  418. </Grid>
  419. </FormControl>
  420. </Grid>
  421. <Grid item xs={12} md={6} >
  422. <Stack spacing={1}>
  423. <InputLabel htmlFor="confirmPassword-signup">確認密碼
  424. <span style={{color: '#f10000'}}>*</span>
  425. </InputLabel>
  426. <OutlinedInput
  427. id="confirmPassword-login"
  428. type={showConfirmPassword ? 'text' : 'password'}
  429. value={formik.values.confirmPassword}
  430. name="confirmPassword"
  431. onBlur={formik.handleBlur}
  432. onChange={(e) => {
  433. formik.handleChange(e);
  434. // changePassword(e.target.value);
  435. }}
  436. inputProps={{
  437. onKeyDown: (e) => {
  438. if (e.key === 'Enter') {
  439. e.preventDefault();
  440. }
  441. },
  442. }}
  443. endAdornment={
  444. <InputAdornment position="end">
  445. <IconButton
  446. aria-label="toggle password visibility"
  447. onClick={handleClickShowConfirmPassword}
  448. onMouseDown={handleMouseDownPassword}
  449. edge="end"
  450. size="large"
  451. >
  452. {showConfirmPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
  453. </IconButton>
  454. </InputAdornment>
  455. }
  456. placeholder="確認密碼"
  457. fullWidth
  458. error={Boolean(formik.touched.confirmPassword && formik.errors.confirmPassword)}
  459. />
  460. {formik.touched.confirmPassword && formik.errors.confirmPassword && (
  461. <FormHelperText error id="helper-text-confirmPassword-signup">
  462. {formik.errors.confirmPassword}
  463. </FormHelperText>
  464. )}
  465. </Stack>
  466. </Grid>
  467. </Grid>
  468. </Grid>
  469. <Grid item xs={12} mt={1} mb={1}>
  470. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  471. <Typography display="inline" variant="h4" sx={{ color: '#1A4399'}}>你的機構/公司資料</Typography>
  472. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  473. Already have an account?
  474. </Typography> */}
  475. </Stack>
  476. </Grid>
  477. <Grid item xs={12} md={6}>
  478. <Stack spacing={1}>
  479. <InputLabel htmlFor="enCompanyName-signup">機構/公司英文名稱
  480. <span style={{color: '#f10000'}}>*</span>
  481. </InputLabel>
  482. <OutlinedInput
  483. id="enCompanyName-login"
  484. type="enCompanyName"
  485. value={formik.values.enCompanyName}
  486. name="enCompanyName"
  487. onChange={formik.handleChange}
  488. placeholder="與與商業登記證相同如有"
  489. fullWidth
  490. error={Boolean(formik.touched.enCompanyName && formik.errors.enCompanyName)}
  491. onBlur={formik.handleBlur}
  492. inputProps={{
  493. onKeyDown: (e) => {
  494. if (e.key === 'Enter') {
  495. e.preventDefault();
  496. }
  497. },
  498. }}
  499. />
  500. {formik.touched.enCompanyName && formik.errors.enCompanyName && (
  501. <FormHelperText error id="helper-text-enCompanyName-signup">
  502. {formik.errors.enCompanyName}
  503. </FormHelperText>
  504. )}
  505. </Stack>
  506. </Grid>
  507. <Grid item xs={12} md={6}>
  508. <Stack spacing={1}>
  509. <InputLabel htmlFor="chCompanyName-signup">機構/公司中文名稱</InputLabel>
  510. <OutlinedInput
  511. fullWidth
  512. error={Boolean(formik.touched.chCompanyName && formik.errors.chCompanyName)}
  513. id="chCompanyName-signup"
  514. type="text"
  515. value={formik.values.chCompanyName}
  516. name="chCompanyName"
  517. onChange={formik.handleChange}
  518. placeholder="與與商業登記證相同如有"
  519. inputProps={{
  520. onKeyDown: (e) => {
  521. if (e.key === 'Enter') {
  522. e.preventDefault();
  523. }
  524. },
  525. }}
  526. />
  527. {formik.touched.chCompanyName && formik.errors.chCompanyName && (
  528. <FormHelperText error id="helper-text-chCompanyName-signup">
  529. {formik.errors.chCompanyName}
  530. </FormHelperText>
  531. )}
  532. </Stack>
  533. </Grid>
  534. <Grid item xs={12} md={6}>
  535. <Stack spacing={1}>
  536. <InputLabel htmlFor="brNo-signup">商業登記證號碼</InputLabel>
  537. <OutlinedInput
  538. fullWidth
  539. error={Boolean(formik.touched.brNo && formik.errors.brNo)}
  540. id="brNo-signup"
  541. type="text"
  542. value={formik.values.brNo}
  543. name="brNo"
  544. onChange={formik.handleChange}
  545. placeholder="與與商業登記證相同如有"
  546. inputProps={{
  547. onKeyDown: (e) => {
  548. if (e.key === 'Enter') {
  549. e.preventDefault();
  550. }
  551. },
  552. }}
  553. />
  554. {formik.touched.brNo && formik.errors.brNo && (
  555. <FormHelperText error id="helper-text-brNo-signup">
  556. {formik.errors.brNo}
  557. </FormHelperText>
  558. )}
  559. </Stack>
  560. </Grid>
  561. <Grid item xs={12} md={6}>
  562. <Stack spacing={1}>
  563. <InputLabel htmlFor="brExpiryDate-signup">商業登記證有效日期</InputLabel>
  564. <OutlinedInput
  565. fullWidth
  566. error={Boolean(formik.touched.brExpiryDate && formik.errors.brExpiryDate)}
  567. id="brExpiryDate-signup"
  568. type="date"
  569. value={formik.values.brExpiryDate}
  570. name="brExpiryDate"
  571. onChange={formik.handleChange}
  572. placeholder="與與商業登記證相同如有"
  573. inputProps={{
  574. onKeyDown: (e) => {
  575. if (e.key === 'Enter') {
  576. e.preventDefault();
  577. }
  578. },
  579. }}
  580. />
  581. {formik.touched.brExpiryDate && formik.errors.brExpiryDate && (
  582. <FormHelperText error id="helper-text-brExpiryDate-signup">
  583. {formik.errors.brExpiryDate}
  584. </FormHelperText>
  585. )}
  586. </Stack>
  587. </Grid>
  588. <Grid item xs={12}>
  589. <Stack spacing={1}>
  590. <InputLabel htmlFor="address1-signup">地址
  591. <span style={{color: '#f10000'}}>*</span>
  592. </InputLabel>
  593. <OutlinedInput
  594. fullWidth
  595. error={Boolean(formik.touched.address1 && formik.errors.address1)}
  596. id="address1-signup"
  597. value={formik.values.address1}
  598. name="address1"
  599. onChange={formik.handleChange}
  600. placeholder="第一行"
  601. onBlur={formik.handleBlur}
  602. inputProps={{
  603. onKeyDown: (e) => {
  604. if (e.key === 'Enter') {
  605. e.preventDefault();
  606. }
  607. },
  608. }}
  609. />
  610. <OutlinedInput
  611. fullWidth
  612. error={Boolean(formik.touched.address2 && formik.errors.address2)}
  613. id="address2-signup"
  614. value={formik.values.address2}
  615. name="address2"
  616. onChange={formik.handleChange}
  617. placeholder="第二行"
  618. inputProps={{
  619. onKeyDown: (e) => {
  620. if (e.key === 'Enter') {
  621. e.preventDefault();
  622. }
  623. },
  624. }}
  625. />
  626. <OutlinedInput
  627. fullWidth
  628. error={Boolean(formik.touched.address3 && formik.errors.address3)}
  629. id="address3-signup"
  630. value={formik.values.address3}
  631. name="address3"
  632. onChange={formik.handleChange}
  633. placeholder="第三行"
  634. inputProps={{
  635. onKeyDown: (e) => {
  636. if (e.key === 'Enter') {
  637. e.preventDefault();
  638. }
  639. },
  640. }}
  641. />
  642. <Autocomplete
  643. disablePortal
  644. id="address4-combo"
  645. value={selectedAddress4 === null ? null : selectedAddress4}
  646. options={address4ComboList}
  647. onChange={(event, newValue) => {
  648. if (newValue !== null){
  649. setSelectedAddress4(newValue);
  650. }
  651. }}
  652. sx={{"& .MuiInputBase-root": { height: "41px" },"#address4-combo":{padding: "0px 0px 0px 0px"}, "& .MuiAutocomplete-endAdornment": { top: "auto" },}}
  653. renderInput={(params) => <TextField {...params} placeholder="區域 (只適用於香港)"/>}
  654. />
  655. <Autocomplete
  656. disablePortal
  657. id="address5-combo"
  658. value={selectedAddress5}
  659. options={address5ComboList}
  660. onChange={(event, newValue) => {
  661. if (newValue !== null){
  662. setSelectedAddress5(newValue);
  663. }
  664. }}
  665. sx={{"& .MuiInputBase-root": { height: "41px" },"#address5-combo":{padding: "0px 0px 0px 0px"}, "& .MuiAutocomplete-endAdornment": { top: "auto" },}}
  666. renderInput={(params) => <TextField {...params} placeholder="國家/地區"/>}
  667. />
  668. {formik.touched.address1 && formik.errors.address1 && (
  669. <FormHelperText error id="helper-text-address1-signup">
  670. {formik.errors.address1}
  671. </FormHelperText>
  672. )}
  673. {formik.touched.address2 && formik.errors.address2 && (
  674. <FormHelperText error id="helper-text-address2-signup">
  675. {formik.errors.address2}
  676. </FormHelperText>
  677. )}
  678. {formik.touched.address3 && formik.errors.address3 && (
  679. <FormHelperText error id="helper-text-address3-signup">
  680. {formik.errors.address3}
  681. </FormHelperText>
  682. )}
  683. </Stack>
  684. </Grid>
  685. <Grid item xs={12} mt={1} mb={1}>
  686. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  687. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary'}}>你的聯絡資料</Typography>
  688. </Stack>
  689. </Grid>
  690. <Grid item xs={12} md={12}>
  691. <Stack spacing={1}>
  692. <InputLabel htmlFor="enName-signup">姓名
  693. <span style={{color: '#f10000'}}>*</span>
  694. </InputLabel>
  695. <OutlinedInput
  696. id="enName-login"
  697. type="enName"
  698. value={formik.values.enName}
  699. name="enName"
  700. onChange={formik.handleChange}
  701. placeholder=""
  702. fullWidth
  703. error={Boolean(formik.touched.enName && formik.errors.enName)}
  704. onBlur={formik.handleBlur}
  705. inputProps={{
  706. onKeyDown: (e) => {
  707. if (e.key === 'Enter') {
  708. e.preventDefault();
  709. }
  710. },
  711. }}
  712. />
  713. {formik.touched.enName && formik.errors.enName && (
  714. <FormHelperText error id="helper-text-enName-signup">
  715. {formik.errors.enName}
  716. </FormHelperText>
  717. )}
  718. </Stack>
  719. </Grid>
  720. <Grid item xs={12} md={12}>
  721. <Grid container>
  722. <Grid item xs={12} md={6}>
  723. <Stack spacing={1} sx={{mr:{md:1},mb:1}}>
  724. <InputLabel htmlFor="email-signup">電郵
  725. <span style={{color: '#f10000'}}>*</span>
  726. </InputLabel>
  727. <OutlinedInput
  728. fullWidth
  729. error={Boolean(formik.touched.email && formik.errors.email)}
  730. id="email-login"
  731. type="email"
  732. value={formik.values.email}
  733. name="email"
  734. onChange={formik.handleChange}
  735. placeholder="電郵"
  736. onBlur={formik.handleBlur}
  737. inputProps={{
  738. onKeyDown: (e) => {
  739. if (e.key === 'Enter') {
  740. e.preventDefault();
  741. }
  742. },
  743. }}
  744. />
  745. {formik.touched.email && formik.errors.email && (
  746. <FormHelperText error id="helper-text-email-signup">
  747. {formik.errors.email}
  748. </FormHelperText>
  749. )}
  750. </Stack>
  751. </Grid>
  752. <Grid item xs={12} md={6}>
  753. <Stack spacing={1} >
  754. <InputLabel htmlFor="emailConfirm-signup">確認電郵
  755. <span style={{color: '#f10000'}}>*</span>
  756. </InputLabel>
  757. <OutlinedInput
  758. fullWidth
  759. error={Boolean(formik.touched.emailConfirm && formik.errors.emailConfirm)}
  760. id="emailConfirm-login"
  761. type="email"
  762. value={formik.values.emailConfirm}
  763. name="emailConfirm"
  764. // onBlur={formik.handleBlur}
  765. onChange={formik.handleChange}
  766. placeholder="確認電郵"
  767. onBlur={formik.handleBlur}
  768. inputProps={{
  769. onKeyDown: (e) => {
  770. if (e.key === 'Enter') {
  771. e.preventDefault();
  772. }
  773. },
  774. }}
  775. />
  776. {formik.touched.emailConfirm && formik.errors.emailConfirm && (
  777. <FormHelperText error id="helper-text-emailConfirm-signup">
  778. {formik.errors.emailConfirm}
  779. </FormHelperText>
  780. )}
  781. </Stack>
  782. </Grid>
  783. </Grid>
  784. </Grid>
  785. <Grid item xs={12} md={12}>
  786. <Grid container>
  787. <Grid item xs={12} md={6}>
  788. <Grid container>
  789. <Grid item xs={12} md={12}>
  790. <Stack direction="column" spacing={1} sx={{mr:{md:1},mb:1}}>
  791. <InputLabel htmlFor="phone-signup">聯絡電話
  792. <span style={{color: '#f10000'}}>*</span>
  793. </InputLabel>
  794. <Stack direction="row">
  795. <OutlinedInput
  796. id="phoneCountryCode-login"
  797. type="phoneCountryCode"
  798. value={formik.values.phoneCountryCode}
  799. name="phoneCountryCode"
  800. // onBlur={formik.handleBlur}
  801. onChange={formik.handleChange}
  802. placeholder="國際區號"
  803. error={Boolean(formik.touched.phone && formik.errors.phone)}
  804. onBlur={formik.handleBlur}
  805. inputProps={{
  806. maxLength: 3,
  807. onKeyDown: (e) => {
  808. if (e.key === 'Enter') {
  809. e.preventDefault();
  810. }
  811. },
  812. }}
  813. sx={{width:'25%'}}
  814. />
  815. <OutlinedInput
  816. id="phone-login"
  817. type="phone"
  818. value={formik.values.phone}
  819. name="phone"
  820. onBlur={formik.handleBlur}
  821. onChange={formik.handleChange}
  822. placeholder="聯絡電話"
  823. error={Boolean(formik.touched.phone && formik.errors.phone)}
  824. inputProps={{
  825. maxLength: 8,
  826. onKeyDown: (e) => {
  827. if (e.key === 'Enter') {
  828. e.preventDefault();
  829. }
  830. },
  831. }}
  832. sx={{width:'75%'}}
  833. />
  834. </Stack>
  835. {formik.touched.phone && formik.errors.phone && (
  836. <FormHelperText error id="helper-text-phone-signup">
  837. {formik.errors.phone}
  838. </FormHelperText>
  839. )}
  840. </Stack>
  841. </Grid>
  842. </Grid>
  843. </Grid>
  844. <Grid item xs={12} md={6}>
  845. <Grid container>
  846. <Grid item xs={12} md={12}>
  847. <Stack spacing={1} direction="column">
  848. <InputLabel htmlFor="fax-signup">傳真號碼</InputLabel>
  849. <Stack direction="row">
  850. <OutlinedInput
  851. error={Boolean(formik.touched.fax && formik.errors.fax)}
  852. id="faxCountryCode-login"
  853. type="faxCountryCode"
  854. value={formik.values.faxCountryCode}
  855. name="faxCountryCode"
  856. // onBlur={formik.handleBlur}
  857. onChange={formik.handleChange}
  858. placeholder="國際區號"
  859. inputProps={{
  860. maxLength: 3,
  861. onKeyDown: (e) => {
  862. if (e.key === 'Enter') {
  863. e.preventDefault();
  864. }
  865. },
  866. }}
  867. sx={{width:'25%'}}
  868. />
  869. <OutlinedInput
  870. id="fax-login"
  871. type="fax"
  872. value={formik.values.fax}
  873. name="fax"
  874. // onBlur={formik.handleBlur}
  875. onChange={formik.handleChange}
  876. placeholder="傳真號碼"
  877. inputProps={{
  878. maxLength: 8,
  879. onKeyDown: (e) => {
  880. if (e.key === 'Enter') {
  881. e.preventDefault();
  882. }
  883. },
  884. }}
  885. sx={{width:'75%'}}
  886. />
  887. </Stack>
  888. </Stack>
  889. </Grid>
  890. </Grid>
  891. </Grid>
  892. </Grid>
  893. </Grid>
  894. <Grid item xs={12} md={12} mt={1} mb={1}>
  895. <Grid container>
  896. <Grid item xs={12} md={12}>
  897. <Stack spacing={1} direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  898. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary'}}>商業登記證及其他文件
  899. <span style={{color: '#f10000'}}>*</span>
  900. </Typography>
  901. <Typography display="inline" variant="h6" sx={{ fontSize: 12,color: 'primary.primary'}}>請上傳你的 有效商業登記證及其他文件 的數碼檔案,以驗證你的身份。</Typography>
  902. <Typography display="inline" variant="h6" sx={{ fontSize: 12,color: 'primary.primary'}}>如: 香港身份證; 護照; 中國內地身份證等</Typography>
  903. <Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}>
  904. <Button variant="contained" component="label" sx={{ fontSize: 12,height:'40px'}}>上傳商業登記證及其他文件
  905. <input
  906. accept="image/png, .jpg, .bmp, .pdf"
  907. //className={classes.input}
  908. id="contained-button-file"
  909. multiple
  910. type="file"
  911. onChange={handleFileUpload}
  912. style={{display: 'none'}}
  913. />
  914. </Button>
  915. {/* <Typography display="inline" variant="h6" sx={{ fontSize: 12, color: 'primary.primary'}}></Typography> */}
  916. </Stack>
  917. {fileList !=null?
  918. <UploadFileTable recordList={fileListData} />:null}
  919. {/* <Stack mt={1} direction="row" justifyContent="flex-start" alignItems="center" spacing={2}>
  920. <Button variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button>
  921. <Button disabled={!formik.isValid} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button>
  922. </Stack> */}
  923. </Stack>
  924. </Grid>
  925. </Grid>
  926. </Grid>
  927. </Grid>
  928. <Grid item xs={12} md={12}>
  929. <Grid container>
  930. <Grid item xs={12} md={12}>
  931. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary'}}>
  932. 條款和條件
  933. <span style={{color: '#f10000'}}>*</span>
  934. </Typography>
  935. </Grid>
  936. <Grid item xs={12} md={12}>
  937. <Grid container>
  938. <Grid item xs={12} md={12}>
  939. <Typography height="80%" sx={{textAlign: "left",overflow: "scroll",borderRadius: "inherit", borderStyle: "solid",borderWidth: "1px",borderColor: "#0C489E"}}>
  940. {termsAndCon}
  941. </Typography>
  942. </Grid>
  943. </Grid>
  944. <Grid item xs={12} s={12} md={12} lg={12}>
  945. <Grid container>
  946. <Grid item xs={6} s={6} md={2} lg={2}>
  947. <Grid container>
  948. <Grid item sx={{display: 'flex', alignItems: 'center'}}>
  949. <Checkbox
  950. checked={termsAndConAccept}
  951. onChange={handleCheckBoxChange}
  952. name="termsAndConAccept"
  953. color="primary"
  954. size="small"
  955. />
  956. <Typography>我接受</Typography>
  957. </Grid>
  958. </Grid>
  959. </Grid>
  960. <Grid item xs={6} s={6} md={2} lg={2}>
  961. <Grid container>
  962. <Grid item sx={{display: 'flex', alignItems: 'center'}}>
  963. <Checkbox
  964. checked={termsAndConNotAccept}
  965. onChange={handleCheckBoxChange}
  966. name="termsAndConNotAccept"
  967. color="primary"
  968. size="small"
  969. />
  970. <Typography>我不接受</Typography>
  971. </Grid>
  972. </Grid>
  973. </Grid>
  974. </Grid>
  975. </Grid>
  976. </Grid>
  977. </Grid>
  978. </Grid>
  979. </Grid>
  980. </Grid>
  981. </FormGroup>
  982. {/* Preview Form */}
  983. <FormGroup id={"previewForm"} sx={{ display: props.step === 1 ? "" : "none"}}>
  984. <Grid container spacing={2}>
  985. <Grid item xs={12}>
  986. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  987. <div style={{borderBottom: "3px solid #1A4399", width:"100%", margin_right: "15px"}}>
  988. <Typography display="inline" variant="h3" sx={{ color: '#1A4399'}}>成為新的機構/公司用戶</Typography>
  989. </div>
  990. {/* <Typography mt={0.25} variant="h6" sx={{ fontSize: 12,color: '#f10000'}}>註有*的項目必須輸入資料</Typography> */}
  991. <Typography mt={0.25} variant="h4" sx={{ color: 'primary.primary'}}>你的登入資料</Typography>
  992. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  993. Already have an account?
  994. </Typography> */}
  995. </Stack>
  996. </Grid>
  997. <Grid item xs={12}>
  998. <Grid container spacing={1}>
  999. <Grid item xs={12} >
  1000. <Stack spacing={1} direction="row">
  1001. <Typography>
  1002. 用戶登入名稱:
  1003. </Typography>
  1004. <Typography id="preview-username-login">
  1005. {formik.values.username}
  1006. </Typography>
  1007. </Stack>
  1008. </Grid>
  1009. <Grid item xs={12} mt={1} mb={1}>
  1010. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1011. <Typography display="inline" variant="h4" sx={{ color: '#1A4399'}}>你的機構/公司資料</Typography>
  1012. {/* <Typography component={Link} to="/login" variant="body1" sx={{ textDecoration: 'none' }} color="primary">
  1013. Already have an account?
  1014. </Typography> */}
  1015. </Stack>
  1016. </Grid>
  1017. <Grid item xs={12} md={6}>
  1018. <Stack spacing={1} direction="row">
  1019. <Typography>
  1020. 機構/公司英文名稱:
  1021. </Typography>
  1022. <Typography id="preview-enCompanyName-signup">
  1023. {formik.values.enCompanyName}
  1024. </Typography>
  1025. </Stack>
  1026. </Grid>
  1027. <Grid item xs={12} md={6}>
  1028. <Stack spacing={1} direction="row">
  1029. <Typography>
  1030. 機構/公司中文名稱:
  1031. </Typography>
  1032. <Typography id="preview-chCompanyName-signup">
  1033. {formik.values.chCompanyName}
  1034. </Typography>
  1035. </Stack>
  1036. </Grid>
  1037. <Grid item xs={12} md={12} >
  1038. <Stack spacing={1}>
  1039. <Typography>
  1040. 商業登記證
  1041. </Typography>
  1042. </Stack>
  1043. </Grid>
  1044. <Grid item xs={12} md={6}>
  1045. <Stack spacing={1} direction="row">
  1046. <Typography>
  1047. 商業登記證號碼:
  1048. </Typography>
  1049. <Typography id="brNo-login">
  1050. {formik.values.brNo}
  1051. </Typography>
  1052. </Stack>
  1053. </Grid>
  1054. <Grid item xs={12} md={6}>
  1055. <Stack spacing={1} direction="row">
  1056. <Typography>
  1057. 商業登記證有效日期:
  1058. </Typography>
  1059. <Typography id="brExpiryDate-login">
  1060. {formik.values.brExpiryDate}
  1061. </Typography>
  1062. </Stack>
  1063. </Grid>
  1064. <Grid item xs={12}>
  1065. <Stack spacing={1} direction="row">
  1066. <Typography>
  1067. 地址:
  1068. </Typography>
  1069. <Stack spacing={1} direction="column">
  1070. <Typography id="preview-address1-signup">
  1071. {formik.values.address1}
  1072. </Typography>
  1073. {formik.values.address2!=null?
  1074. <Typography id="preview-address2-signup">
  1075. {formik.values.address2}
  1076. </Typography>
  1077. :null}
  1078. {formik.values.address3!=null?
  1079. <Typography id="preview-address3-signup">
  1080. {formik.values.address3}
  1081. </Typography>
  1082. :null}
  1083. {selectedAddress5==("香港")?
  1084. <Typography id="preview-address4-signup">
  1085. 區域 (只適用於香港): {selectedAddress4}
  1086. </Typography>
  1087. :null}
  1088. <Typography id="preview-address5-signup">
  1089. 國家/地區: {selectedAddress5}
  1090. </Typography>
  1091. </Stack>
  1092. </Stack>
  1093. </Grid>
  1094. <Grid item xs={12} mt={1} mb={1}>
  1095. <Stack direction="column" justifyContent="space-between" alignItems="baseline" sx={{ mb: { xs: -0.5, sm: 0.5 } }}>
  1096. <Typography display="inline" variant="h4" sx={{ color: 'primary.primary'}}>你的聯絡資料</Typography>
  1097. </Stack>
  1098. </Grid>
  1099. <Grid item xs={12} md={12}>
  1100. <Stack spacing={1} direction="row">
  1101. <Typography>
  1102. 英文名稱:
  1103. </Typography>
  1104. <Typography id="preview-enName-signup">
  1105. {formik.values.enName}
  1106. </Typography>
  1107. </Stack>
  1108. </Grid>
  1109. <Grid item xs={12} md={12}>
  1110. <Stack spacing={1} direction="row">
  1111. <Typography>
  1112. 電郵:
  1113. </Typography>
  1114. <Typography id="preview-email-signup">
  1115. {formik.values.email}
  1116. </Typography>
  1117. </Stack>
  1118. </Grid>
  1119. <Grid item xs={12} md={6}>
  1120. <Stack spacing={1} direction="row">
  1121. <Typography>
  1122. 聯絡電話:
  1123. </Typography>
  1124. <Typography id="preview-phone-signup">
  1125. +{formik.values.phoneCountryCode} {formik.values.phone}
  1126. </Typography>
  1127. </Stack>
  1128. </Grid>
  1129. <Grid item xs={12} md={6}>
  1130. <Stack spacing={1} direction="row">
  1131. <Typography>
  1132. 傳真號碼:
  1133. </Typography>
  1134. <Typography id="preview-fax-signup">
  1135. +{formik.values.faxCountryCode} {formik.values.fax}
  1136. </Typography>
  1137. </Stack>
  1138. </Grid>
  1139. </Grid>
  1140. </Grid>
  1141. </Grid>
  1142. </FormGroup>
  1143. {/* Submit page */}
  1144. <FormGroup id={"submitForm"} sx={{ display: props.step === 2 ? "" : "none"}}>
  1145. <Grid container spacing={3}>
  1146. {isLoading ?
  1147. <LoadingComponent/>:
  1148. <Grid item xs={12}>
  1149. {checkUpload?
  1150. // SUCCESS page
  1151. <Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
  1152. <CheckCircleOutlineIcon color="success" sx={{width:"200px",height:"200px"}}/>
  1153. <Typography display="inline" variant="h4">帳戶申請已成功提交。</Typography>
  1154. <Typography display="inline" variant="h4">驗證電郵將發送到你的電郵地址,請要指示完成驗證及登入系統。</Typography>
  1155. <Button variant="outlined" component={Link} to="/login" sx={{ fontSize: 20,height:'60px'}}>返回登入頁面</Button>
  1156. </Stack>
  1157. :
  1158. // ERROR page
  1159. <Stack mt={1} direction="column" justifyContent="flex-start" alignItems="center" spacing={2}>
  1160. {/* <Button disabled={true} hidden={true} variant="contained" type="submit" sx={{ fontSize: 12,height:'25px'}}>Submit</Button> */}
  1161. <CancelOutlinedIcon color="error" sx={{width:"200px",height:"200px"}}/>
  1162. <Typography display="inline" variant="h4">申請失敗,請稍後嘗試</Typography>
  1163. <Button color="error" variant="outlined" component={Link} to="/login" sx={{ fontSize: 20,height:'60px'}}>返回登入頁面</Button>
  1164. </Stack>
  1165. }
  1166. </Grid>
  1167. }
  1168. </Grid>
  1169. </FormGroup>
  1170. </form>
  1171. </FormikProvider>
  1172. );
  1173. }
  1174. export default BusCustomFormWizard;