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.
 
 

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