|
- import React, {
- useEffect,
- useState,
- lazy, useContext
- } from 'react';
- import { Link as RouterLink } from 'react-router-dom';
- import { useNavigate } from 'react-router-dom';
- import { useForm, } from 'react-hook-form'
- import { iAmSmartPath, clientId, getBowserType, isAppBowser, iAmSmartCallbackPath } from 'auth/utils'
- //iAmSmartAppPath
-
- // material-ui
- import {
- Button,
- //Checkbox,
- //Divider,
- //FormControlLabel,
- FormHelperText,
- Grid,
- Link,
- IconButton,
- InputAdornment,
- InputLabel,
- OutlinedInput,
- Stack,
- Typography
- } from '@mui/material';
-
- // third party
- import * as yup from 'yup';
- import { useFormik, FormikProvider } from 'formik';
-
- // project import
- //import FirebaseSocial from './FirebaseSocial';
- import AnimateButton from 'components/@extended/AnimateButton';
- import Loadable from 'components/Loadable';
- const PasswordAlertDialog = Loadable(lazy(() => import('./PasswordAlertDialog')));
-
- // assets
- import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons';
- // import axios from "axios";
- import iAmSmartICon from 'assets/images/icons/icon_iAmSmart.png';
- import { useDispatch } from "react-redux";
- import { handleLogin } from "auth/index";
- import useJwt from "../../../auth/jwt/useJwt";
- import { handleLogoutFunction } from 'auth/index';
- import {FormattedMessage, useIntl} from "react-intl";
- import LocaleContext from "../../../components/I18nProvider";
- // ============================|| FIREBASE - LOGIN ||============================ //
-
- const AuthLoginCustom = () => {
- const dispatch = useDispatch()
- const navigate = useNavigate()
- const intl = useIntl();
- const { setLocale } = useContext(LocaleContext);
-
- const [showPassword, setShowPassword] = useState(false);
- const handleClickShowPassword = () => {
- setShowPassword(!showPassword);
- };
-
- // let [posts, setPosts] = useState([]);
- const [isValid, setisValid] = useState(false);
- const [open, setOpen] = React.useState(false);
- const [isButtonDisabled, setIsButtonDisabled] = useState(true);
- const [errorMassage, setErrorMassage] = useState('');
-
- const handleMouseDownPassword = (event) => {
- event.preventDefault();
- };
-
- const tryLogin = () => {
- if (isValid) {
- dispatch(handleLogoutFunction());
- // setSumitting(true)
- useJwt
- .login({ username: values.username, password: values.password })
- .then((response) => {
- // console.log(response)
- const userData = {
- id: response.data.id,
- fullenName: response.data.name,
- fullchName: response.data.chName,
- email: response.data.email,
- type: response.data.type,
- role: response.data.role,
- abilities: response.data.abilities,
- creditor: response.data.creditor,
- locale: response.data.preferLocale,
- //avatar: require('src/assets/images/users/avatar-3.png').default,
- }
- const data = { ...userData, accessToken: response.data.accessToken, refreshToken: response.data.refreshToken }
- // setSuccess(true)
- // console.log(response.data);
- if(response.data.type === "GLD"){
- setLocale("en");
- localStorage.setItem('locale','en');
- }else{
- if (response.data.preferLocale ==="zh_HK"){
- setLocale("zh-HK");
- localStorage.setItem('locale','zh-HK');
- }
- if (response.data.preferLocale ==="zh-CN"){
- setLocale("zh-CN");
- localStorage.setItem('locale','zh-CN');
- }
- }
- dispatch(handleLogin(data))
- navigate('/dashboard');
- location.reload()
- // setSumitting(false)
- })
- .catch((error) => {
- // setSuccess(false)
- console.error(error)
- console.error(error.response.data.error)
- setErrorMassage(error.response.data.error)
- setOpen(true)
- });
- } else {
- setOpen(true)
- }
- }
-
- const formik = useFormik({
- initialValues: ({
- username: '',
- password: '',
- submit: null
- }),
- validationSchema: yup.object().shape({
- // username: yup.string().min(6,'用戶名稱最少6位').required('請輸入用戶名稱'),
- username: yup.string().required(intl.formatMessage({id: 'requireUsername'})),
- password: yup.string().min(8, intl.formatMessage({id: 'atLeast8CharPassword'})).required(intl.formatMessage({id: 'requirePassword'}))
- .matches(/^(?=.*[a-z])/, intl.formatMessage({id: 'atLeastOneSmallLetter'}))
- .matches(/^(?=.*[A-Z])/, intl.formatMessage({id: 'atLeastOneCapLetter'}))
- .matches(/^(?=.*[0-9])/, intl.formatMessage({id: 'atLeast1Number'}))
- .matches(/^(?=.*[!@#%&])/, intl.formatMessage({id: 'atLeast1SpecialChar'})),
- }),
- });
-
- const checkDataField = (data) => {
- if (data.username !== "" &&
- data.password !== "" &&
- handlePassword(data.password)
- // &&handle6Digi(data.username)
- ) {
- setisValid(true)
- setIsButtonDisabled(false);
- return isValid
- } else {
- setisValid(false)
- setIsButtonDisabled(true);
- return isValid
- }
- };
-
- 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 = /^(?=.*[!@#%&])/;
- 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 {
- return true;
- }
- }
-
- const handleClose = () => {
- setOpen(false);
- };
-
- const { values } = formik
- useEffect(() => {
- checkDataField(values)
- }, [values])
-
- const { handleSubmit } = useForm({})
-
- const getQRWithIAmSmart = () => {
- if (isAppBowser()) {
- openApp();
- } else {
- openQR();
- }
- }
-
- const openQR = () => {
- let callbackUrl = "https://" + iAmSmartCallbackPath() + "/iamsmart/authcallback";
- let url = iAmSmartPath + "/api/v1/auth/getQR"
- + "?clientID=" + clientId
- + "&responseType=code"
- + "&source=" + getBowserType()
- + "&redirectURI=" + encodeURIComponent(callbackUrl)
- + "&scope=" + encodeURIComponent("eidapi_auth eidapi_profiles")
- + "&lang=zh-HK"//en-US, zh-HK, or zh-CN
- //+"&state="
- + "&brokerPage=false"
- window.location=url;
- }
-
- const openApp = () => {
- // setTimeout(function () {
- // openQR();
- // }, 1000);
- // let callbackUrl = "https://" + iAmSmartCallbackPath() + "/iamsmart/authcallback";
-
- // let source = getBowserType()
- // console.log(source)
- // let url = iAmSmartAppPath + "auth"
- // + "?clientID=" + clientId
- // + "&responseType=code"
- // + "&source=" + getBowserType()
- // + "&redirectURI=" + encodeURIComponent(callbackUrl)
- // + "&scope=" + encodeURIComponent("eidapi_auth eidapi_profiles")
- // + "&lang=zh-HK"//en-US, zh-HK, or zh-CN
- // //+"&state="
- // + "&brokerPage=true"
- // window.location=url;
-
- let callbackUrl = "https://" + iAmSmartCallbackPath() + "/iamsmart/authcallback";
- let url = iAmSmartPath + "/api/v1/auth/getQR"
- + "?clientID=" + clientId
- + "&responseType=code"
- + "&source=" + getBowserType()
- + "&redirectURI=" + encodeURIComponent(callbackUrl)
- + "&scope=" + encodeURIComponent("eidapi_auth eidapi_profiles")
- + "&lang=zh-HK"//en-US, zh-HK, or zh-CN
- //+"&state="
- + "&brokerPage=true"
- window.location=url;
-
- }
-
-
- return (
- <FormikProvider value={formik}>
- <form onSubmit={handleSubmit(tryLogin)}>
- <Grid container spacing={3}>
- <Grid item xs={12}>
- <Stack spacing={1}>
- <InputLabel htmlFor="email-login">
- <Typography variant="h5">
- <FormattedMessage id="userLoginName"/>
- </Typography>
- </InputLabel>
- <OutlinedInput
- id="username"
- name="username"
- onChange={formik.handleChange}
- placeholder=""
- fullWidth
- value={formik.values.username}
- error={Boolean(formik.touched.username && formik.errors.username)}
- onBlur={formik.handleBlur}
- inputProps={{
- maxLength: 50,
- onKeyDown: (e) => {
- if (e.key === 'Enter') {
- e.preventDefault();
- }
- },
- }}
- />
- {formik.touched.username && formik.errors.username && (
- <FormHelperText error id="standard-weight-helper-text-username-login">
- {formik.errors.username}
- </FormHelperText>
- )}
- </Stack>
- </Grid>
- <Grid item xs={12}>
- <Stack spacing={1}>
- <InputLabel htmlFor="password-login"><Typography variant="h5">
- <FormattedMessage id="userPassword"/>
- </Typography></InputLabel>
- <OutlinedInput
- fullWidth
- id="password-login"
- type={showPassword ? 'text' : 'password'}
- name="password"
- value={formik.values.password}
- onChange={formik.handleChange}
- onBlur={formik.handleBlur}
- error={Boolean(formik.touched.password && formik.errors.password)}
- endAdornment={
- <InputAdornment position="end">
- <IconButton
- aria-label="toggle password visibility"
- onClick={handleClickShowPassword}
- onMouseDown={handleMouseDownPassword}
- edge="end"
- size="large"
- >
- {showPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
- </IconButton>
- </InputAdornment>
- }
- placeholder=""
- />
- {formik.touched.password && formik.errors.password && (
- <FormHelperText error id="standard-weight-helper-text-password-login">
- {formik.errors.password}
- </FormHelperText>
- )}
- </Stack>
- </Grid>
-
- <Grid item xs={12}>
- <AnimateButton>
- <Button disableElevation disabled={isButtonDisabled}
- fullWidth size="large" type="submit" variant="contained" color="primary"
- sx={{
- "&.Mui-disabled": {
- background: "#bbdefb",
- color: "#fff",
- border: "2px solid",
- borderColor: "#e7e7e7"
- }
- }}>
- <Typography variant="h5">
- <FormattedMessage id="login"/>
- </Typography>
- </Button>
- </AnimateButton>
- </Grid>
- <Grid item xs={12}>
- <Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}>
- <Link component={RouterLink} to="" color="primary">
- <Typography align="center" variant="h6">
- <FormattedMessage id="forgotUserPassword"/>?
- </Typography>
- </Link>
- </Stack>
- </Grid>
- <Grid item xs={12}>
- <Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}>
- <Button onClick={() => getQRWithIAmSmart()} color="iAmSmart" fullWidth size="large" variant="outlined" startIcon={<img src={iAmSmartICon} alt="iAM Smart" width="30" />}>
- <Typography variant="h5">
- <FormattedMessage id="iAmSmartLogin"/>
- </Typography>
- </Button>
- </Stack>
- </Grid>
- <Grid item xs={12}>
- <Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}>
- <Link href="https://www.iamsmart.gov.hk/tc/"><Typography align="center" variant="h6">
- { intl.formatMessage({id: 'learnMore'})+" >"}
- </Typography></Link>
- </Stack>
- </Grid>
- <Grid item xs={12}>
- <Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}>
- <Button fullWidth size="large" variant="outlined" href="/register" ><Typography variant="h5">
- <FormattedMessage id="createOrReActivate"/>
- </Typography></Button>
- </Stack>
- </Grid>
- </Grid>
- <PasswordAlertDialog open={open} handleClose={handleClose} errorMassage={errorMassage} />
- </form>
- </FormikProvider>
- );
- };
-
- export default AuthLoginCustom;
|