diff --git a/src/pages/authentication/IAmSmartRegister.js b/src/pages/authentication/IAmSmartRegister.js
new file mode 100644
index 0000000..ec59c4c
--- /dev/null
+++ b/src/pages/authentication/IAmSmartRegister.js
@@ -0,0 +1,217 @@
+// import { Link } from 'react-router-dom';
+import React, {
+ useState
+ // ,useEffect
+} from 'react';
+
+// material-ui
+import {
+ Stepper,
+ Step,
+ StepButton,
+ // Grid,
+ Stack,
+ Typography,
+ Button,
+} from '@mui/material';
+import VisibilityIcon from '@mui/icons-material/Visibility';
+import { GET_USERNAME } from "utils/ApiPathConst";
+
+// project import
+import Loadable from 'components/Loadable';
+import { lazy } from 'react';
+import { notifyActionError } from 'utils/CommonFunction';
+import axios from "axios";
+const CustomFormWizard = Loadable(lazy(() => import('./auth-forms/IAmSmartFormWizard')));
+const AuthWrapper = Loadable(lazy(() => import('./AuthWrapperCustom')));
+// ================================|| REGISTER ||================================ //
+const stepStyle = {
+ width: "40%",
+ boxShadow: 1,
+ backgroundColor: "#FFFFFF",
+ padding: 2,
+ "& .Mui-active": {
+ "&.MuiStepIcon-root": {
+ color: "warning.main",
+ fontSize: "2rem",
+ },
+ "& .MuiStepConnector-line": {
+ borderColor: "warning.main"
+ }
+ },
+ "& .Mui-completed": {
+ "&.MuiStepIcon-root": {
+ color: "secondary.main",
+ fontSize: "2rem",
+ },
+ "& .MuiStepConnector-line": {
+ borderColor: "secondary.main"
+ }
+ }
+}
+const steps = ['個人資料', '預覽', '完成提交'];
+
+const Register = () => {
+ const [activeStep, setActiveStep] = useState(0);
+ const [completed, setCompleted] = useState([false]);
+ const [updateValid, setUpdateValid] = useState(false);
+ const [username, setUsername] = useState("");
+
+ const totalSteps = () => {
+ return steps.length;
+ };
+
+ const completedSteps = () => {
+ return Object.keys(completed).length;
+ };
+
+ const isLastStep = () => {
+ return activeStep === totalSteps() - 1;
+ };
+
+ const allStepsCompleted = () => {
+ return completedSteps() === totalSteps();
+ };
+
+ const handleCheckUsername = async () => {
+ const response = await axios.get(`${GET_USERNAME}`, {
+ params: {
+ username: username,
+ }
+ })
+ return Number(response.data[0]) === 1
+ }
+
+ const handleNext = async () => {
+ const test = await handleCheckUsername()
+ if (test) {
+ notifyActionError("此用戶登入名稱已被注冊,請使用其他用戶登入名稱")
+ } else {
+ const newActiveStep =
+ isLastStep() && !allStepsCompleted()
+ ? // It's the last step, but not all steps have been completed,
+ // find the first step that has been completed
+ steps.findIndex((step, i) => !(i in completed))
+ : activeStep + 1;
+ setActiveStep(newActiveStep);
+ scrollToTop();
+ }
+ };
+
+ const handleBack = () => {
+ scrollToTop();
+ setActiveStep((prevActiveStep) => prevActiveStep - 1);
+ };
+
+ const scrollToTop = () => {
+ window.scrollTo(0, 0);
+ };
+
+ const handleReset = () => {
+ setActiveStep(0);
+ setCompleted({});
+ };
+
+ return (
+ //
+
+
+ {steps.map((label, index) => (
+
+ {
+ index < 2 ?
+ (
+ {label}
+ ) :
+ (}
+ // onClick={handleStep(index)}
+ >
+ {label}
+ )
+ }
+
+
+ ))}
+
+ {allStepsCompleted() ? (
+
+
+ All steps completed - you're finished
+
+
+
+
+
+
+ ) : (
+
+
+
+ {/* */}
+
+
+ {activeStep === 2 || activeStep === 0 ? (
+
+ ) : (
+
+ )
+ }
+
+ {activeStep === totalSteps() - 2 ?
+ (
+
+ ) : (activeStep === totalSteps() - 1 ?
+ (
+
+ ) :
+ (
+ //
+
+ )}
+
+ //
+ );
+};
+
+export default Register;
diff --git a/src/pages/authentication/auth-forms/IAmSmartFormWizard.js b/src/pages/authentication/auth-forms/IAmSmartFormWizard.js
new file mode 100644
index 0000000..eb6b26e
--- /dev/null
+++ b/src/pages/authentication/auth-forms/IAmSmartFormWizard.js
@@ -0,0 +1,1020 @@
+import { useEffect, useState, } from 'react';
+
+// material-ui
+import {
+ Button,
+ FormHelperText,
+ Grid, IconButton,
+ InputLabel, OutlinedInput,
+ Stack,
+ Typography,
+ FormGroup,
+ TextField,
+ Checkbox
+ // MenuItem
+} from '@mui/material';
+import { useForm, } from 'react-hook-form'
+import Autocomplete from "@mui/material/Autocomplete";
+
+// third party
+import { useFormik, FormikProvider } from 'formik';
+import * as yup from 'yup';
+
+import axios from "axios";
+import { POST_PUBLIC_USER_REGISTER, POST_CAPTCHA, GET_USER_EMAIL } from "utils/ApiPathConst";
+
+import * as ComboData from "utils/ComboData";
+
+import Loadable from 'components/Loadable';
+import { lazy } from 'react';
+const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingComponent')));
+
+import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
+import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined';
+import iAmSmartICon from 'assets/images/icons/icon_iAmSmart.png';
+
+import { Link } from 'react-router-dom';
+import * as HttpUtils from "../../../utils/HttpUtils";
+import LoopIcon from '@mui/icons-material/Loop';
+import { useTheme } from '@mui/material/styles';
+import { useLocation } from "react-router-dom";
+
+// ============================|| FIREBASE - REGISTER ||============================ //
+
+const CustomFormWizard = (props) => {
+ const location = useLocation();
+ const theme = useTheme();
+
+ const [iAmSmartData, setIAmSmartData] = useState({});
+
+ const [checkUpload, setCheckUpload] = useState(false);
+ const [isLoading, setLoding] = useState(true);
+
+ const [captcha, setCaptcha] = useState([]);
+ const [captchaImg, setCaptchaImage] = useState([]);
+
+ const [selectedAddress4, setSelectedAddress4] = useState(null);
+ const [selectedAddress5, setSelectedAddress5] = useState(ComboData.country[0]);
+ const [termsAndConAccept, setTermsAndConAccept] = useState(false);
+ const [termsAndConNotAccept, setTermsAndConNotAccept] = useState(false);
+ const [isValid, setisValid] = useState(false);
+ const [checkCountry, setCheckCountry] = useState(false);
+ const email = document.getElementById("email-login")
+ const [checkEmail, setCheckEmail] = useState(false)
+ const [checkEmailBlur, setCheckEmailBlur] = useState(false)
+
+ const address4ComboList = ComboData.district;
+ const address5ComboList = ComboData.country;
+ const termsAndCon = "此網址由香港特別行政區政府物流服務署製作及管理。本署會盡力確保網址上的資料無誤,\n"
+ + "但有絕對酌情權隨時刪除、暫停登載或編輯各項資料而無須給予任何理由。\n由於任何與網址"
+ + "內資料有關的理由或原因,而導致出現申索、損失或損害,本署概不負責。\n使用者須自行評"
+ + "估本網址所載或與本網址有關連的各項資料,並應在根據該等資料行事前,參照印行的香港"
+ + "特別行政區憲報以核實該等資料,以及徵詢獨立意見。\n版權公告本網頁的內容,包括但不限"
+ + "於所有文本、平面圖像、圖畫、圖片、照片以及數據或其他資料的匯編,均受版權保障。\n香"
+ + "港特別行政區政府是本網頁內所有版權作品的擁有人,除非預先得到政府物流服務署的書面"
+ + "授權,否則嚴禁複製、改編、分發、發布或向公眾提供該等版權作品。"
+
+
+ const dataStr = "{\"emailAddress\":\"test@gmail.com\",\"postalAddress\":{\"EngPremisesAddress\":{\"EngDistrict\":{\"DcDistrict\":\"KC\",\"Sub-district\":\"TSING YI\"},\"EngEstate\":{\"EstateName\":\"Cheung Hang Estate\",\"EngPhase\":{\"PhaseName\":\"N/A\"}},\"BuildingName\":\"Hang Lai House\",\"EngBlock\":{\"BlockDescriptor\":\"Block\",\"BlockNo\":\"2\"},\"Region\":\"NT\",\"EngStreet\":{\"StreetName\":\"Liu To Road\",\"BuildingNoFrom\":\"6\"},\"Eng3dAddress\":{\"EngFloor\":{\"FloorNum\":\"33\"},\"EngUnit\":{\"UnitDescriptor\":\"Room\",\"UnitNo\":\"3301\"}}}},\"mobileNumber\":{\"CountryCode\":\"852\",\"SubscriberNumber\":\"99999999\"},\"residentialAddress\":{\"ChiPremisesAddress\":{\"Chi3dAddress\":{\"ChiUnit\":{\"UnitDescriptor\":\"室\",\"UnitNo\":\"1010\"},\"ChiFloor\":{\"FloorNum\":\"10\"}},\"ChiBlock\":{\"BlockDescriptor\":\"座\",\"BlockNo\":\"2\"},\"BuildingName\":\"亨麗樓(第2座)\",\"ChiDistrict\":{\"DcDistrict\":\"KC\",\"Sub-district\":\"青衣\"},\"Region\":\"新界\",\"ChiEstate\":{\"EstateName\":\"長亨邨\"},\"ChiStreet\":{\"StreetName\":\"寮肚路\",\"BuildingNoFrom\":\"6\"}}},\"enName\":{\"UnstructuredName\":\"Testing Co One\"},\"idNo\":{\"Identification\":\"G561107\",\"CheckDigit\":\"4\"},\"chName\":{\"ChineseName\":\"測試商一\"}}";
+
+ useEffect(() => {
+ location.state?.responseData ?? {}
+ onCaptchaChange();
+ responseToData();
+ }, []);
+
+ const responseToData = () => {
+ let rd = JSON.parse(dataStr);
+ let data = {
+ "enName": rd.enName?.UnstructuredName ?? "",
+ "chName": rd.chName?.ChineseName ?? "",
+ "idNo": rd.idNo?.Identification ?? "",
+ "checkDigit": rd.idNo?.CheckDigit ?? "",
+ "email": rd.emailAddress ?? "",
+ "phone": rd.mobileNumber?.SubscriberNumber ?? "",
+ "phoneCountryCode": rd.mobileNumber?.CountryCode ?? "",
+ };
+
+ if (rd.postalAddress) {
+ if (rd.postalAddress.EngPremisesAddress) {
+ data["address1"] = getAddressEng(rd.postalAddress.EngPremisesAddress);
+ } else if (rd.postalAddress.ChiPremisesAddress) {
+ data["address1"] = getAddressChi(rd.postalAddress.ChiPremisesAddress);
+ }
+ } else if (rd.residentialAddress) {
+ if (rd.residentialAddress.EngPremisesAddress) {
+ data["address1"] = getAddressEng(rd.residentialAddress.EngPremisesAddress);
+ } else if (rd.residentialAddress.ChiPremisesAddress) {
+ data["address1"] = getAddressChi(rd.residentialAddress.ChiPremisesAddress);
+ }
+ }
+
+ setIAmSmartData(data);
+
+ }
+
+
+ const getAddressEng = (pAdd) => {
+ let unit = (pAdd.Eng3dAddress?.EngUnit?.UnitDescriptor ?? "") + " " + (pAdd.Eng3dAddress?.EngUnit?.UnitNo ?? "");
+ let block = (pAdd.EngBlock?.BlockDescriptor ?? "") + " " + (pAdd.EngBlock?.BlockNo ?? "");
+ let floor = pAdd.Eng3dAddress?.EngFloor?.FloorNum ? pAdd.Eng3dAddress?.EngFloor?.FloorNum + "/F " : "";
+ let street = (pAdd.EngStreet?.EngUnit?.UnitDescriptor ?? "") + " " + (pAdd.Eng3dAddress?.EngUnit?.UnitNo ?? "");
+ //let region = pAdd.Region ?? "";
+ let buildingName = pAdd.BuildingName ?? "";
+ let estate = pAdd.EngEstate?.EstateName ?? "";
+ let district = pAdd.EngDistrict["Sub - district"] ?? "";
+ return getAddressStr([unit, block, floor, buildingName, estate, street, district]);
+ }
+
+ const getAddressChi = (pAdd) => {
+ let unit = (pAdd.Chi3dAddress?.ChiUnit?.UnitDescriptor ?? "") + " " + (pAdd.Chi3dAddress?.ChiUnit?.UnitNo ?? "");
+ let block = (pAdd.ChiBlock?.BlockDescriptor ?? "") + " " + (pAdd.ChiBlock?.BlockNo ?? "");
+ let floor = pAdd.Chi3dAddress?.ChiFloor?.FloorNum ? pAdd.Chi3dAddress?.ChiFloor?.FloorNum + "樓 " : "";
+ let street = (pAdd.ChiStreet?.ChiUnit?.UnitDescriptor ?? "") + " " + (pAdd.Chi3dAddress?.ChiUnit?.UnitNo ?? "");
+ //let region = pAdd.Region ?? "";
+ let buildingName = pAdd.BuildingName ?? "";
+ let estate = pAdd.ChiEstate?.EstateName ?? "";
+ let district = pAdd.ChiDistrict["Sub - district"] ?? "";
+ return getAddressStr([district, street, estate, buildingName, street, floor, block, unit ]);
+ }
+
+ const getAddressStr = (strs) => {
+ let add = ""
+ strs.forEach(str => {
+ add += str ? str + ", " : "";
+ });
+ add = add.trim();
+ if (add.slice(- 1) == ",") {
+ add = add.substring(0, add.length - 1);
+ }
+ return add;
+ }
+
+ const handleCheckEmail = async () => {
+ if (values?.email) {
+ const response = await axios.get(`${GET_USER_EMAIL}`, {
+ params: {
+ email: values.email,
+ }
+ })
+ setCheckEmail((Number(response.data[0]) === 1))
+ return Number(response.data[0]) === 1
+ }
+ }
+
+ useEffect(() => {
+ if (email) {
+ email.addEventListener("blur", function () {
+ setCheckEmailBlur(true)
+ })
+ }
+ }, [email])
+
+ useEffect(() => {
+ if (checkEmailBlur) {
+ handleCheckEmail()
+ setCheckEmailBlur(false)
+ }
+ }, [checkEmailBlur])
+
+ const onCaptchaChange = () => {
+ HttpUtils.post({
+ url: POST_CAPTCHA,
+ params: { width: 130, height: 40 },
+ onSuccess: (responseData) => {
+ localStorage.setItem("checkCode", responseData.checkCode);
+ localStorage.setItem("base64Url", responseData.base64Url);
+ setCaptcha(localStorage.getItem('checkCode'));
+ setCaptchaImage(localStorage.getItem('base64Url'));
+ }
+ });
+ }
+
+ const checkDataField = (data) => {
+ if (data.address1 !== "" &&
+ data.email !== "" &&
+ data.emailConfirm !== "" &&
+ data.email == data.emailConfirm &&
+ data.phone !== "" &&
+ data.phoneCountryCode !== "" &&
+ termsAndConAccept == true &&
+ data.captchaField &&
+ handleEmail(data.email) &&
+ handlePhone(data.phone) &&
+ handleCaptcha(data.captchaField) &&
+ !checkEmail
+ ) {
+ setisValid(true)
+ return isValid
+ } else {
+ setisValid(false)
+ return isValid
+ }
+ };
+
+ const handleCheckBoxChange = (event) => {
+ if (event.target.name == 'termsAndConAccept') {
+ setTermsAndConAccept(event.target.checked)
+ setTermsAndConNotAccept(!event.target.checked)
+ }
+ if (event.target.name == 'termsAndConNotAccept') {
+ setTermsAndConNotAccept(event.target.checked)
+ setTermsAndConAccept(!event.target.checked)
+ }
+ };
+
+ useEffect(() => {
+ props.setUpdateValid(isValid)
+ }, [isValid])
+
+ useEffect(() => {
+ checkDataField(values)
+ }, [
+ selectedAddress4, selectedAddress5,
+ termsAndConAccept, termsAndConNotAccept])
+
+ useEffect(() => {
+ props.step == 2 ? _onSubmit() : null;
+ onCaptchaChange();
+ checkDataField(values)
+ }, [props.step])
+
+ const { handleSubmit } = useForm({})
+ const _onSubmit = () => {
+ setLoding(true);
+ values.address4 = selectedAddress4
+ values.address5 = selectedAddress5
+ const userAddress = {
+ "addressLine1": "",
+ "addressLine2": "",
+ "addressLine3": "",
+ "district": "",
+ "country": ""
+ };
+ userAddress.addressLine1 = values.address1
+ userAddress.addressLine2 = values.address2
+ userAddress.addressLine3 = values.address3
+ userAddress.district = values.address4
+ userAddress.country = values.address5
+
+ const userFaxNo = {
+ "countryCode": values.faxCountryCode,
+ "faxNumber": values.fax,
+ };
+ const userMobileNumber = {
+ "countryCode": values.phoneCountryCode,
+ "phoneNumber": values.phone,
+ };
+ let tncFlag = false;
+ if (termsAndConAccept) {
+ tncFlag = true
+ }
+ if (termsAndConNotAccept) {
+ tncFlag = false
+ }
+
+ const user = {
+ enName: values.enName,
+ chName: values.chName,
+ emailAddress: values.email,
+ idDocType: values.idDocType,
+ identification: values.idNo,
+ checkDigit: values.checkDigit,
+ tncFlag: tncFlag,
+ type: "IND",
+ };
+
+ for (const [key, value] of Object.entries(user)) {
+ formData.append(key, value);
+ }
+
+ formData.append("userFaxNo", JSON.stringify(userFaxNo));
+ formData.append("userMobileNumber", JSON.stringify(userMobileNumber));
+ formData.append("userAddress", JSON.stringify(userAddress));
+
+ if (isValid) {
+ axios.post(POST_PUBLIC_USER_REGISTER, formData, {
+ headers: {
+ "Content-Type": "multipart/form-data"
+ }
+ })
+ .then((response) => {
+ console.log(response)
+ setCheckUpload(true)
+ setLoding(false);
+ })
+ .catch(error => {
+ console.error(error);
+ setLoding(false);
+ });
+ } else {
+ setLoding(false);
+ }
+ }
+
+ function handlePhone(phone) {
+ if (phone.length < 8) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ function handleCaptcha(captchaField) {
+ return captchaField == captcha;
+ }
+
+ function handleEmail(email) {
+ var validRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
+ if (!email.match(validRegex)) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ function displayErrorMsg(errorMsg) {
+ return {errorMsg}
+ }
+
+ const formik = useFormik({
+ initialValues: ({
+ email: '',
+ emailConfirm: '',
+ address1: '',
+ address2: '',
+ address3: '',
+ phone: '',
+ phoneCountryCode: '852',
+ submit: null,
+ fax: '',
+ faxCountryCode: '852',
+ captchaField: ''
+ }),
+ validationSchema: yup.object().shape({
+ address1: yup.string().max(255).required(displayErrorMsg('請輸入第一行地址')),
+ address2: yup.string().max(255).required(displayErrorMsg('請輸入第二行地址')),
+ address3: yup.string().max(255).required(displayErrorMsg('請輸入第三行地址')),
+ email: yup.string().email(displayErrorMsg('請輸入電郵格式')).max(255).required(displayErrorMsg('請輸入電郵')),
+ emailConfirm: yup.string().email(displayErrorMsg('請輸入電郵格式')).max(255).required(displayErrorMsg('請輸入電郵')).oneOf([yup.ref('email'), null], displayErrorMsg('請輸入相同電郵')),
+ phoneCountryCode: yup.string().min(2, displayErrorMsg('請輸入最少2位數字')).required(displayErrorMsg('請輸入國際區號')),
+ phone: yup.string().min(8, displayErrorMsg('請輸入最少8位數字')).required(displayErrorMsg('請輸入聯絡電話')),
+ captchaField: yup.string().required(displayErrorMsg('請輸入驗證')).oneOf([captcha], displayErrorMsg('請輸入有效驗證')),
+ }),
+ });
+
+
+ const { values } = formik
+
+ useEffect(() => {
+ checkDataField(values)
+ }, [values])
+
+ return (
+
+
+
+ );
+}
+
+export default CustomFormWizard;
diff --git a/src/pages/iAmSmart/AuthCallback/index.js b/src/pages/iAmSmart/AuthCallback/index.js
index aa61a40..0c03fbe 100644
--- a/src/pages/iAmSmart/AuthCallback/index.js
+++ b/src/pages/iAmSmart/AuthCallback/index.js
@@ -1,195 +1,42 @@
-// material-ui
-import {
- Grid,
- Typography,
- Stack,
- Card,
- FormHelperText,
- InputLabel, OutlinedInput,
-} from '@mui/material';
+
import * as React from "react";
-import { useFormik, FormikProvider } from 'formik';
-import * as yup from 'yup';
-import { useParams } from "react-router-dom";
import * as HttpUtils from "utils/HttpUtils";
import * as UrlUtils from "utils/ApiPathConst";
-//import { iAmSmartPath, clientId, getBowerType , iAmSmartCallbackPath} from 'auth/utils'
-
+import { useNavigate } from "react-router-dom";
import Loadable from 'components/Loadable';
const LoadingComponent = Loadable(React.lazy(() => import('pages/extra-pages/LoadingComponent')));
-import titleBackgroundImg from 'assets/images/dashboard/gazette-bar.png'
-const BackgroundHead = {
- backgroundImage: `url(${titleBackgroundImg})`,
- width: '100%',
- height: '100%',
- backgroundSize: 'contain',
- backgroundRepeat: 'no-repeat',
- backgroundColor: '#0C489E',
- backgroundPosition: 'right'
-}
// ==============================|| DASHBOARD - DEFAULT ||============================== //
const Index = () => {
- const params = useParams();
- const [onReady, setOnReady] = React.useState(false);
- const [checkUsername, setCheckUsername] = React.useState(false);
- const [props, setProps] = React.useState({});
+ const navigate = useNavigate()
React.useEffect(() => {
- if(params.code){
- setOnReady(true);
- setProps({});
- getPrfile();
- }
+ getPrfile();
}, []);
function getPrfile(){
- HttpUtils.post({
- url: UrlUtils.GET_SMART_PROFILE,
- params:{
- code: params.code
- },
- onSuccess: () => {
-
- }
- });
- }
-
- function displayErrorMsg(errorMsg) {
- return {errorMsg}
+ let params = new URLSearchParams(window.location.search)
+ if(params.get("code")){
+ HttpUtils.post({
+ url: UrlUtils.GET_SMART_PROFILE,
+ params:{
+ code: params.get("code")
+ },
+ onSuccess: (responseData) => {
+ navigate('/iAmSmartRegisterFrom', { state: { responseData: responseData } });
+ }
+ });
+ }
}
- const formik = useFormik({
- initialValues: ({
- username: '',
- enName: '',
- email: '',
- address1: '',
- address2: '',
- address3: '',
- password: '',
- phone: '',
- phoneCountryCode: '852',
- }),
-
- validationSchema: yup.object().shape({
- username: yup.string().min(6, displayErrorMsg('用戶名稱最少6位')).required(displayErrorMsg('請輸入用戶名稱'))
- .matches(/^[aA-zZ0-9\s]+$/, { message: displayErrorMsg("用戶名稱不包含特殊字符") })
- .matches(/^\S*$/, { message: displayErrorMsg('用戶名稱不包含空格') }),
- enName: yup.string().max(255).required(displayErrorMsg('請輸入英文姓名')),
- chName: yup.string().max(255).required(displayErrorMsg('請輸入中文姓名')),
- address1: yup.string().max(255).required(displayErrorMsg('請輸入第一行地址')),
- address2: yup.string().max(255).required(displayErrorMsg('請輸入第二行地址')),
- address3: yup.string().max(255).required(displayErrorMsg('請輸入第三行地址')),
- email: yup.string().email(displayErrorMsg('請輸入電郵格式')).max(255).required(displayErrorMsg('請輸入電郵')),
- phoneCountryCode: yup.string().min(2, displayErrorMsg('請輸入最少2位數字')).required(displayErrorMsg('請輸入國際區號')),
- phone: yup.string().min(8, displayErrorMsg('請輸入最少8位數字')).required(displayErrorMsg('請輸入聯絡電話')),
- }, ['username']),
-
- });
+
return (
- !onReady ?
- :
-
-
-
-
-
- iAmSmart 登記
-
-
-
- {/*row 1*/}
-
-
- *': {
- flexGrow: 1,
- flexBasis: '50%'
- },
- backgroundColor: "secondary",
- p:8,
- pl:16,
- pr:16
- }}
- >
-
-
-
-
- 成為個人用戶
-
- 註有*的項目必須輸入資料
- 用戶資料
- {/*
- Already have an account?
- */}
-
-
-
-
-
-
-
-
- 用戶登入名稱
- *
-
-
- {
- setCheckUsername(false)
- props.username = e.target.value
- formik.handleChange(e)
- }}
- placeholder="用戶登入名稱"
- fullWidth
- error={Boolean((formik.touched.username && formik.errors.username) || checkUsername)}
- onBlur={formik.handleBlur}
- inputProps={{
- onKeyDown: (e) => {
- if (e.key === 'Enter') {
- e.preventDefault();
- }
- },
- }}
- />
- {formik.touched.username && formik.errors.username && (
-
- {formik.errors.username}
-
- )}
- {checkUsername && (
-
- 此用戶登入名稱已被注冊,請使用其他用戶登入名稱
-
- )}
-
-
-
-
-
-
-
-
-
- {/*row 2*/}
-
-
-
);
};
diff --git a/src/routes/LoginRoutes.js b/src/routes/LoginRoutes.js
index d0adeb1..f32edfe 100644
--- a/src/routes/LoginRoutes.js
+++ b/src/routes/LoginRoutes.js
@@ -10,6 +10,7 @@ const AuthLogin = Loadable(lazy(() => import('pages/authentication/Login')));
const AuthRegister = Loadable(lazy(() => import('pages/authentication/RegisterCustom')));
const RegisterForm = Loadable(lazy(() => import('pages/authentication/Register')));
const BusRegisterForm = Loadable(lazy(() => import('pages/authentication/BusRegister')));
+const IAmSmartRegister = Loadable(lazy(() => import('pages/authentication/IAmSmartRegister')));
const ErrorPage = Loadable(lazy(() => import('pages/extra-pages/ErrorPage')));
const IAmSmart_FailCallback = Loadable(lazy(() => import('pages/iAmSmart/FailCallback')));
const IAmSmart_SuccessCallback = Loadable(lazy(() => import('pages/iAmSmart/SuccessCallback')));
@@ -45,6 +46,10 @@ const LoginRoutes = {
path: 'registerFromOrganization',
element:
},
+ {
+ path: 'iAmSmartRegisterFrom',
+ element:
+ },
{
path: 'error',
element: