mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2025-03-31 10:23:21 +02:00
173 lines
5.2 KiB
TypeScript
173 lines
5.2 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import { FormattedMessage, useIntl } from 'react-intl';
|
|
import { Link as RouterLink, useNavigate } from 'react-router-dom';
|
|
import Header from '../layout/header';
|
|
import Footer from '../layout/footer';
|
|
import SubmitButton from '../form/submit-button';
|
|
import Input from '../form/input';
|
|
import GlobalError from '../form/global-error';
|
|
import FormContainer from '../layout/form-container';
|
|
import Typography from '@mui/material/Typography';
|
|
import FormControl from '@mui/material/FormControl';
|
|
import Link from '@mui/material/Link';
|
|
import ReactGA from 'react-ga4';
|
|
import Separator from '../common/separator';
|
|
import GoogleButton from '../common/google-button';
|
|
import AppConfig from '../../classes/app-config';
|
|
import CSRFInput from '../common/csrf-input';
|
|
import { useMutation } from 'react-query';
|
|
import { useSelector } from 'react-redux';
|
|
import Client, { ErrorInfo } from '../../classes/client';
|
|
import { activeInstance } from '../../redux/clientSlice';
|
|
|
|
export type Model = {
|
|
email: string;
|
|
password: string;
|
|
};
|
|
|
|
const defaultModel: Model = { email: '', password: '' };
|
|
|
|
const LoginError = () => {
|
|
// @Todo: This must be reviewed to be based on navigation state.
|
|
// Login error example: http://localhost:8080/c/login?login.error=2
|
|
const errorCode = new URLSearchParams(window.location.search).get('login_error');
|
|
const intl = useIntl();
|
|
|
|
let msg: null | string = null;
|
|
if (errorCode) {
|
|
switch (errorCode) {
|
|
case '3':
|
|
msg = intl.formatMessage({
|
|
id: 'login.userinactive',
|
|
defaultMessage:
|
|
"Sorry, your account has not been activated yet. You'll receive a notification email when it becomes active. Stay tuned!.",
|
|
});
|
|
break;
|
|
default:
|
|
msg = intl.formatMessage({
|
|
id: 'login.error',
|
|
defaultMessage: 'The email address or password you entered is not valid.',
|
|
});
|
|
}
|
|
}
|
|
return msg ? <GlobalError error={{ msg: msg }} /> : null;
|
|
};
|
|
|
|
const LoginPage = (): React.ReactElement => {
|
|
const intl = useIntl();
|
|
const [model, setModel] = useState<Model>(defaultModel);
|
|
const client: Client = useSelector(activeInstance);
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
document.title = intl.formatMessage({
|
|
id: 'login.page-title',
|
|
defaultMessage: 'Login | WiseMapping',
|
|
});
|
|
ReactGA.send({ hitType: 'pageview', page: window.location.pathname, title: 'Login' });
|
|
}, []);
|
|
|
|
const mutation = useMutation<void, ErrorInfo, Model>(
|
|
(model: Model) => client.login({ ...model }),
|
|
{
|
|
onSuccess: () => navigate('/c/maps/'),
|
|
onError: (error) => {
|
|
console.log(error);
|
|
},
|
|
},
|
|
);
|
|
|
|
const handleOnSubmit = (event: React.FormEvent<HTMLFormElement>): void => {
|
|
mutation.mutate(model);
|
|
event.preventDefault();
|
|
};
|
|
|
|
const handleOnChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
|
|
event.preventDefault();
|
|
|
|
const name = event.target.name;
|
|
const value = event.target.value;
|
|
setModel({ ...model, [name as keyof Model]: value });
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<Header type="only-signup" />
|
|
|
|
<FormContainer>
|
|
<Typography variant="h4" component="h1">
|
|
<FormattedMessage id="login.title" defaultMessage="Welcome" />
|
|
</Typography>
|
|
|
|
<Typography paragraph>
|
|
<FormattedMessage id="login.desc" defaultMessage="Log into your account" />
|
|
</Typography>
|
|
|
|
<LoginError />
|
|
|
|
<FormControl>
|
|
<form onSubmit={handleOnSubmit}>
|
|
<CSRFInput />
|
|
<Input
|
|
onChange={handleOnChange}
|
|
name="email"
|
|
type="email"
|
|
label={intl.formatMessage({
|
|
id: 'login.email',
|
|
defaultMessage: 'Email',
|
|
})}
|
|
required
|
|
autoComplete="email"
|
|
/>
|
|
<Input
|
|
onChange={handleOnChange}
|
|
name="password"
|
|
type="password"
|
|
label={intl.formatMessage({
|
|
id: 'login.password',
|
|
defaultMessage: 'Password',
|
|
})}
|
|
required
|
|
autoComplete="current-password"
|
|
/>
|
|
<SubmitButton
|
|
value={intl.formatMessage({
|
|
id: 'login.signin',
|
|
defaultMessage: 'Sign In',
|
|
})}
|
|
/>
|
|
</form>
|
|
</FormControl>
|
|
<Link component={RouterLink} to="/c/forgot-password">
|
|
<FormattedMessage id="login.forgotpwd" defaultMessage="Forgot Password ?" />
|
|
</Link>
|
|
<Separator
|
|
responsive={false}
|
|
text={intl.formatMessage({
|
|
id: 'login.division',
|
|
defaultMessage: 'or',
|
|
})}
|
|
/>
|
|
<GoogleButton
|
|
text={intl.formatMessage({
|
|
id: 'login.google.button',
|
|
defaultMessage: 'Sign in with Google',
|
|
})}
|
|
onClick={() => {
|
|
const authUrl = AppConfig.getGoogleOauth2Url();
|
|
if (authUrl) {
|
|
window.location.href = authUrl;
|
|
} else {
|
|
console.log('GoogleOauth2Url is not configured.');
|
|
}
|
|
}}
|
|
/>
|
|
</FormContainer>
|
|
|
|
<Footer />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default LoginPage;
|