import { useEffect, useState } from 'react';
// material-ui
import {
Box,
Button, Checkbox
// MenuItem
, FormControl, FormGroup, FormHelperText,
Grid, IconButton,
InputAdornment,
InputLabel, OutlinedInput,
Stack, TextField, Typography
} from '@mui/material';
import Autocomplete from "@mui/material/Autocomplete";
import { useForm } from 'react-hook-form';
// third party
import { FormikProvider, useFormik } from 'formik';
import * as yup from 'yup';
// import axios from "axios";
// project import
// import AnimateButton from 'components/@extended/AnimateButton';
import { strengthColorChi, strengthIndicator } from 'utils/password-strength';
// import {apiPath} from "auth/utils";
import axios from "axios";
import { GET_USERNAME, GET_USER_EMAIL, POST_CAPTCHA, POST_PUBLIC_USER_REGISTER } from "utils/ApiPathConst";
// import * as HttpUtils from 'utils/HttpUtils';
import * as ComboData from "utils/ComboData";
import Loadable from 'components/Loadable';
import { lazy } from 'react';
const UploadFileTable = Loadable(lazy(() => import('./UploadFileTable')));
const PreviewUploadFileTable = Loadable(lazy(() => import('./PreviewUploadFileTable')));
const LoadingComponent = Loadable(lazy(() => import('../../extra-pages/LoadingComponent')));
// import UploadFileTable from './UploadFileTable';
// import LoadingComponent from "../../extra-pages/LoadingComponent";
// assets
import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons';
// import { Paper } from '../../../../node_modules/@mui/material/index';
import { ThemeProvider } from "@emotion/react";
import CancelOutlinedIcon from '@mui/icons-material/CancelOutlined';
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
import LoopIcon from '@mui/icons-material/Loop';
import { useTheme } from '@mui/material/styles';
import { FormattedMessage, useIntl } from "react-intl";
import { Link } from 'react-router-dom';
import { PNSPS_LONG_BUTTON_THEME } from "../../../themes/buttonConst";
import * as HttpUtils from "../../../utils/HttpUtils";
// ============================|| FIREBASE - REGISTER ||============================ //
const CustomFormWizard = (props) => {
const intl = useIntl();
const { locale } = intl;
const theme = useTheme()
const [level, setLevel] = useState();
const [showPassword, setShowPassword] = useState(false);
const [showConfirmPassword, setshowConfirmPassword] = useState(false);
const [showId, setshowId] = useState(false);
const [fileList, setFileList] = useState([]);
const [fileListData, setFileListData] = useState([]);
const [checkUpload, setCheckUpload] = useState(false);
const [isLoading, setLoding] = useState(true);
const [updateRows, setUpdateRows] = useState([]);
const [captchaImg, setCaptchaImage] = useState("");
const [base64Url, setBase64Url] = useState("")
const [checkCode, setCheckCode] = useState("")
const handleClickShowPassword = () => {
setShowPassword(!showPassword);
};
const handleClickShowConfirmPassword = () => {
setshowConfirmPassword(!showConfirmPassword);
};
const handleMouseDownPassword = (event) => {
event.preventDefault();
};
const handleClickShowId = () => {
setshowId(!showId);
};
const handleMouseDownId = (event) => {
event.preventDefault();
};
const changePassword = (value) => {
const temp = strengthIndicator(value);
setLevel(strengthColorChi(temp));
};
const [selectedIdDocType, setSelectedIdDocType] = useState({});
const [selectedIdDocInputType, setSelectedIdDocInputType] = 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 username = document.getElementById("username-login")
const [checkUsername, setCheckUsername] = useState(false);
const [checkUsernameBlur, setCheckUsernameBlur] = useState(false)
const email = document.getElementById("email-login")
const [checkEmail, setCheckEmail] = useState(false)
const [checkEmailBlur, setCheckEmailBlur] = useState(false)
const [districtErrStr, setDistrictErrStr] = useState("")
const idDocTypeComboList = ComboData.idDocType;
const refType = "identification";
useEffect(() => {
changePassword('');
if (captchaImg == ""){
onCaptchaChange();
}
}, []);
const handleCheckUsername = async () => {
if (values?.username) {
const response = await axios.get(`${GET_USERNAME}`, {
params: {
username: values.username,
}
})
setCheckUsername((Number(response.data[0]) === 1))
return Number(response.data[0]) === 1
}
}
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 (username) {
username.addEventListener("blur", function () {
setCheckUsernameBlur(true)
})
}
}, [username])
useEffect(() => {
if (checkUsernameBlur) {
handleCheckUsername()
setCheckUsernameBlur(false)
}
}, [checkUsernameBlur])
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, captcha: captchaImg },
onSuccess: (responseData) => {
props.setBase64Url(responseData.base64Url)
setBase64Url(responseData.base64Url)
localStorage.setItem("base64Url", responseData.base64Url);
setCaptchaImage(localStorage.getItem('base64Url'));
}
});
}
const checkDataField = (data) => {
// console.log(data)
if (
handleCaptcha(data.captchaField) &&
data.username !== "" &&
data.password !== "" &&
data.confirmPassword !== "" &&
data.password == data.confirmPassword &&
selectedIdDocType.type !== "" &&
data.idNo !== "" &&
// (data.enName !== "" || selectedIdDocType.type === "CNID") &&
// data.chName !== "" &&
handleName(data.enName, data.chName) &&
data.address1 !== "" &&
data.email !== "" &&
data.emailConfirm !== "" &&
data.email == data.emailConfirm &&
data.phone !== "" &&
data.phoneCountryCode !== "" &&
termsAndConAccept == true &&
fileList.length !== 0 &&
// data.captchaField &&
handlePassword(data.password) &&
handleEmail(data.email) &&
handleIdNo(data.idNo, selectedIdDocType.type, data.checkDigit) &&
handlePhone(data.phone) &&
handleUsername(data.username) &&
!checkUsername &&
!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(() => {
let updateRowList = new DataTransfer();
var updateRowsIndex = updateRows.length;
const saveFileList = [];
if (updateRowsIndex != null) {
for (let i = 0; i < updateRowsIndex; i++) {
const file = updateRows[i]
file.id = i;
updateRowList.items.add(file);
saveFileList.push(file);
}
let updatedFileList = updateRowList.files;
setFileList(updatedFileList);
setFileListData(saveFileList)
}
}, [updateRows]);
const handleFileUpload = (event) => {
let updateList = new DataTransfer();
let currentFileList = fileListData;
const uploadFileList = event.target.files;
const saveFileList = [];
var currentIndex = 0;
if (currentFileList.length != null) {
currentIndex = currentFileList.length;
for (let i = 0; i < currentIndex; i++) {
const file = currentFileList[i]
// file.id = currentIndex;
updateList.items.add(file);
saveFileList.push(file);
}
}
for (let i = 0; i < uploadFileList.length && currentIndex < 5; i++) {
const file = event.target.files[i]
let isDuplicate = false;
// Check if the file name already exists in saveFileList
for (let j = 0; j < saveFileList.length; j++) {
if (saveFileList[j].name === file.name) {
isDuplicate = true;
break;
}
}
if (!isDuplicate && i + currentIndex < 5) {
file.id = currentIndex + i
saveFileList.push(file)
updateList.items.add(file);
}
}
let updatedFileList = updateList.files;
setFileListData(saveFileList)
setFileList(updatedFileList);
};
useEffect(() => {
props.setUpdateValid(isValid)
}, [isValid])
useEffect(() => {
props.setUpdateValid(isValid)
}, [isValid])
useEffect(() => {
checkDataField(values)
}, [
selectedIdDocType,
selectedAddress4, selectedAddress5,
termsAndConAccept, termsAndConNotAccept, fileList])
useEffect(() => {
setDistrictErrStr("");
if (selectedAddress5?.type === "hongKong") {
if (selectedAddress4 == null || selectedAddress4 == "" || selectedAddress4 == {})
setDistrictErrStr(getRequiredErrStr("district"))
}
}, [selectedAddress4, selectedAddress5])
useEffect(() => {
props.step == 2 ? _onSubmit() : null;
if (captchaImg == "")
onCaptchaChange();
checkDataField(values)
}, [props.step])
const { handleSubmit } = useForm({})
const _onSubmit = () => {
setLoding(true);
values.idDocType = selectedIdDocType.type
values.address4 = selectedAddress4 == null ? "" : selectedAddress4.type
values.address5 = selectedAddress5.type
// console.log(values)
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 preferLocale = locale === 'en' ? 'en': locale === 'zh-HK' ? 'zh_HK': 'zh-CN'
const user = {
username: values.username,
password: values.password,
name: values.username,
enName: values.enName,
chName: values.chName,
emailAddress: values.email,
idDocType: values.idDocType,
identification: values.idNo,
checkDigit: values.checkDigit,
tncFlag: tncFlag,
type: "IND",
captcha: base64Url,
checkCode: checkCode,
preferLocale: preferLocale
};
var formData = new FormData();
for (let i = 0; i < fileListData.length; i++) {
const file = fileListData[i]
formData.append("multipartFileList", file);
}
formData.append("refType", refType);
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));
// formData.append("preferLocale", "en");
// if(refCode){
// formData.append("refCode", refCode);
// }
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 {
// console.log("Phone true")
return true;
}
}
function handleUsername(username) {
var symbol = /^(?=.*[!@#%&])/;
var space = /\s/;
if (username.length < 6) {
return false;
} else if (username.match(symbol)) {
return false;
} else if (username.match(space)) {
return false;
} else {
return true;
}
}
function handleCaptcha(captchaField) {
// console.log(captchaField.length)
if (captchaField.length == 5 ){
return true
} else {
return false
}
}
function handleIdNo(idNo, selectedIdDocType, checkDigit) {
// var pattern = /^[A-Z][0-9]*$/;
var pattern_HKIDv1 = /^[A-Z]{1}[0-9]{6}$/;
var pattern_HKIDv2 = /^[A-Z]{2}[0-9]{6}$/;
var pattern_passport = /^[A-Z]{1}[0-9]{8}$/;
var pattern_CHID = /^[0-9]{6}(20|19)[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])[0-9]{3}[0-9X]{1}/;
var pattern_otherCert = /^[A-Z]{1}[0-9]{5,}/;
// var space = /\s/;
// if (!idNo.match(pattern)) {
// return false;
// } else if (selectedIdDocType=="HKID"&&checkDigit==""){
// return false;
// } else if (idNo.match(space)) {
// return false;
// } else if (idNo.length < 6) {
// return false;
// } else {
// // console.log("IdNo true")
// return true;
// }
switch (selectedIdDocType) {
case "HKID":
if (checkDigit === "") return false
if (idNo.match(pattern_HKIDv1)) {
return true
} else if (idNo.match(pattern_HKIDv2)) {
return true
} else {
return false
}
case "passport":
if (idNo.match(pattern_passport)) {
return true
} else {
return false
}
case "CNID":
if (idNo.match(pattern_CHID)) {
const subStr_year = idNo.substring(6, 10)
const subStr_month = idNo.substring(10, 12)
const subStr_date = idNo.substring(12, 14)
const today = new Date()
const inputDate = new Date(`${subStr_year}-${subStr_month}-${subStr_date}`)
if (inputDate > today || inputDate === "Invalid Date" || inputDate.getFullYear().toString() !== subStr_year || (inputDate.getMonth() + 1).toString().padStart(2, "0") !== subStr_month || inputDate.getDate().toString().padStart(2, "0") !== subStr_date) {
return false
} else {
return true
}
} else {
return false
}
case "otherCert":
if (idNo.match(pattern_otherCert)) {
return true
} else {
return false
}
default:
break;
}
}
function handleName(enName, chName) {
if (enName == "" && chName !== ""){
return true
} else if (enName !== "" && chName == ""){
return true
} else if (enName !== "" && chName !== "") {
return true
} else {
return false
}
}
function handlePassword(password) {
let new_pass = password;
// regular expressions to validate password
var lowerCase = /[a-z]/g;
var upperCase = /[A-Z]/g;
var numbers = /[0-9]/g;
var symbol = /^(?=.*[!@#%&])/;
var space = /\s/;
if (!new_pass.match(lowerCase)) {
return false;
} else if (!new_pass.match(upperCase)) {
return false;
} else if (!new_pass.match(numbers)) {
return false;
} else if (!new_pass.match(symbol)) {
return false;
} else if (new_pass.length < 8) {
return false;
}
else if (new_pass.match(space)) {
return false;
} else {
// console.log("password true")
return true;
}
}
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}
}
function getMaxErrStr(num, fieldname) {
return displayErrorMsg(intl.formatMessage({ id: 'noMoreThenNWords' }, { num: num, fieldname: fieldname ? intl.formatMessage({ id: fieldname }) + ": " : "" }));
}
function getRequiredErrStr(fieldname) {
return displayErrorMsg(intl.formatMessage({ id: 'require' }, { fieldname: fieldname ? intl.formatMessage({ id: fieldname }) : "" }));
}
const formik = useFormik({
initialValues: ({
username: '',
enName: '',
chName: '',
email: '',
emailConfirm: '',
address1: '',
address2: '',
address3: '',
password: '',
confirmPassword: '',
phone: '',
phoneCountryCode: '852',
idNo: '',
checkDigit: '',
submit: null,
fax: '',
faxCountryCode: '852',
idDocType: '',
captchaField: ''
}),
validationSchema: yup.object().shape({
username: yup.string().min(6, displayErrorMsg(intl.formatMessage({ id: 'atLeast6CharAccount' }))).max(30, getMaxErrStr(30)).required(displayErrorMsg(intl.formatMessage({ id: 'requireUsername' })))
.matches(/^[aA-zZ0-9\s]+$/, { message: displayErrorMsg(intl.formatMessage({ id: 'noSpecialCharAccount' })) })
.matches(/^\S*$/, { message: displayErrorMsg(intl.formatMessage({ id: 'noSpaceAccount' })) }),
password: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'atLeast8CharPassword' }))).max(60, getMaxErrStr(60)).required(displayErrorMsg(intl.formatMessage({ id: 'requirePassword' })))
.matches(/^\S*$/, { message: displayErrorMsg(intl.formatMessage({ id: 'noSpacePassword' })) })
.matches(/^(?=.*[a-z])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeastOneSmallLetter' })) })
.matches(/^(?=.*[A-Z])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeastOneCapLetter' })) })
.matches(/^(?=.*[0-9])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeast1Number' })) })
.matches(/^(?=.*[!@#%&])/, { message: displayErrorMsg(intl.formatMessage({ id: 'atLeast1SpecialChar' })) }),
confirmPassword: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'atLeast8CharPassword' }))).required(displayErrorMsg(intl.formatMessage({ id: 'pleaseConfirmPassword' }))).oneOf([yup.ref('password'), null], displayErrorMsg(intl.formatMessage({ id: 'samePassword' }))),
chName: yup.string().max(6, getMaxErrStr(6)),
enName: yup.string().max(40, getMaxErrStr(40)).when('chName', {
is: (chName) => chName?false:true,
then: yup.string().required(displayErrorMsg(intl.formatMessage({ id: 'registerNameLabel' })))
}),
address1: yup.string().max(40, getMaxErrStr(40, "addressLine1")).required(displayErrorMsg(intl.formatMessage({ id: 'validateAddressLine1' }))),
address2: yup.string().max(40, getMaxErrStr(40, "addressLine2")),
address3: yup.string().max(40, getMaxErrStr(40, "addressLine3")),
email: yup.string().email(displayErrorMsg(intl.formatMessage({ id: 'validEmailFormat' }))).max(128, getMaxErrStr(128)).required(displayErrorMsg(intl.formatMessage({ id: 'requireEmail' }))),
emailConfirm: yup.string().email(displayErrorMsg(intl.formatMessage({ id: 'validEmailFormat' }))).max(128, getMaxErrStr(128)).required(displayErrorMsg(intl.formatMessage({ id: 'requireEmail' }))).oneOf([yup.ref('email'), null], displayErrorMsg(intl.formatMessage({ id: 'validSameEmail' }))),
idNo: yup.string().required(getRequiredErrStr('number'))
.matches(/^[aA-zZ0-9\s]+$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpecialCharacter' })}`) })
.matches(/^\S*$/, { message: displayErrorMsg(`${selectedIdDocInputType}${intl.formatMessage({ id: 'noSpace' })}`) })
.test('checkIDCardFormat', displayErrorMsg(`${intl.formatMessage({ id: 'requiredValid' })}${selectedIdDocInputType}${intl.formatMessage({ id: 'number' })}`), function (value) {
const idDocType = selectedIdDocType.type;
var pattern_HKIDv1 = /^[A-Z]{1}[0-9]{6}$/;
var pattern_HKIDv2 = /^[A-Z]{2}[0-9]{6}$/;
var pattern_passport = /^[A-Z]{1}[0-9]{8}$/;
var pattern_CHID = /^[0-9]{6}(20|19)[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])[0-9]{3}[0-9X]{1}/;
var pattern_otherCert = /^[A-Z]{1}[0-9]{5,}/;
if (value !== undefined) {
switch (idDocType) {
case "HKID":
if (value.match(pattern_HKIDv1)) {
return true
} else if (value.match(pattern_HKIDv2)) {
return true
} else {
return false
}
case "passport":
if (value.match(pattern_passport)) {
return true
} else {
return false
}
case "CNID":
if (value.match(pattern_CHID)) {
const subStr_year = value.substring(6, 10)
const subStr_month = value.substring(10, 12)
const subStr_date = value.substring(12, 14)
const today = new Date()
const inputDate = new Date(`${subStr_year}-${subStr_month}-${subStr_date}`)
if (inputDate > today || inputDate === "Invalid Date" || inputDate.getFullYear().toString() !== subStr_year || (inputDate.getMonth() + 1).toString().padStart(2, "0") !== subStr_month || inputDate.getDate().toString().padStart(2, "0") !== subStr_date) {
return false
} else {
return true
}
} else {
return false
}
case "otherCert":
if (value.match(pattern_otherCert)) {
return true
} else {
return false
}
default:
break;
}
}
}),
checkDigit: yup.string().max(1, getMaxErrStr(1)).required(displayErrorMsg(intl.formatMessage({ id: 'requiredNumberInQuote' }))),
idDocType: yup.string().max(255, getMaxErrStr(255)).required(displayErrorMsg(intl.formatMessage({ id: 'requireIdDocType' }))),
phoneCountryCode: yup.string().min(2, displayErrorMsg(intl.formatMessage({ id: 'requireAtLeast2Number' }))).required(displayErrorMsg(intl.formatMessage({ id: 'requireDialingCode' }))),
// faxCountryCode: yup.string().min(3,'請輸入3位數字'),
phone: yup.string().min(8, displayErrorMsg(intl.formatMessage({ id: 'requireAtLeast8Number' }))).required(displayErrorMsg(intl.formatMessage({ id: 'requireContactNumber' }))),
// fax: yup.string().min(8,'請輸入8位數字'),
captchaField: yup.string().max(5, getMaxErrStr(5)).required(displayErrorMsg(intl.formatMessage({ id: 'requireVerify' }))).min(5, displayErrorMsg(intl.formatMessage({ id: 'requireVerify' }))),//.oneOf([captcha], displayErrorMsg('請輸入有效驗證')),
}),
});
const handleReset = (resetForm) => {
resetForm();
setSelectedAddress4("")
setSelectedAddress5(ComboData.country[0])
setCheckCountry(false)
setSelectedIdDocType({})
setSelectedIdDocInputType("");
setFileList([])
setFileListData([])
onCaptchaChange()
// setSelectedIdDocLabel("")
};
const handleCCPChange = (e) => {
e.preventDefault();
};
const { values } = formik
useEffect(() => {
checkDataField(values)
}, [values])
return (
);
}
export default CustomFormWizard;