aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/auth/Login.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/auth/Login.jsx')
-rw-r--r--src/components/auth/Login.jsx205
1 files changed, 205 insertions, 0 deletions
diff --git a/src/components/auth/Login.jsx b/src/components/auth/Login.jsx
new file mode 100644
index 000000000..33b4d3e0d
--- /dev/null
+++ b/src/components/auth/Login.jsx
@@ -0,0 +1,205 @@
1/* eslint jsx-a11y/anchor-is-valid: 0 */
2import { Component } from 'react';
3import PropTypes from 'prop-types';
4import { observer, inject } from 'mobx-react';
5import { defineMessages, injectIntl } from 'react-intl';
6
7import { mdiArrowLeftCircle } from '@mdi/js';
8import Icon from '../ui/icon';
9import { LIVE_FRANZ_API } from '../../config';
10import { API_VERSION } from '../../environment-remote';
11import { serverBase } from '../../api/apiBase'; // TODO: Remove this line after fixing password recovery in-app
12import Form from '../../lib/Form';
13import { required, email } from '../../helpers/validation-helpers';
14import Input from '../ui/Input';
15import Button from '../ui/button';
16import Link from '../ui/Link';
17
18import { globalError as globalErrorPropType } from '../../prop-types';
19import { H1 } from '../ui/headline';
20
21const messages = defineMessages({
22 headline: {
23 id: 'login.headline',
24 defaultMessage: 'Sign in',
25 },
26 emailLabel: {
27 id: 'login.email.label',
28 defaultMessage: 'Email address',
29 },
30 passwordLabel: {
31 id: 'login.password.label',
32 defaultMessage: 'Password',
33 },
34 submitButtonLabel: {
35 id: 'login.submit.label',
36 defaultMessage: 'Sign in',
37 },
38 invalidCredentials: {
39 id: 'login.invalidCredentials',
40 defaultMessage: 'Email or password not valid',
41 },
42 customServerQuestion: {
43 id: 'login.customServerQuestion',
44 defaultMessage: 'Using a custom Ferdium server?',
45 },
46 customServerSuggestion: {
47 id: 'login.customServerSuggestion',
48 defaultMessage: 'Try importing your Franz account',
49 },
50 tokenExpired: {
51 id: 'login.tokenExpired',
52 defaultMessage: 'Your session expired, please login again.',
53 },
54 serverLogout: {
55 id: 'login.serverLogout',
56 defaultMessage: 'Your session expired, please login again.',
57 },
58 signupLink: {
59 id: 'login.link.signup',
60 defaultMessage: 'Create a free account',
61 },
62 passwordLink: {
63 id: 'login.link.password',
64 defaultMessage: 'Reset password',
65 },
66});
67
68class Login extends Component {
69 static propTypes = {
70 onSubmit: PropTypes.func.isRequired,
71 isSubmitting: PropTypes.bool.isRequired,
72 isTokenExpired: PropTypes.bool.isRequired,
73 isServerLogout: PropTypes.bool.isRequired,
74 signupRoute: PropTypes.string.isRequired,
75 // passwordRoute: PropTypes.string.isRequired, // TODO: Uncomment this line after fixing password recovery in-app
76 error: globalErrorPropType.isRequired,
77 };
78
79 form = (() => {
80 const { intl } = this.props;
81 return new Form(
82 {
83 fields: {
84 email: {
85 label: intl.formatMessage(messages.emailLabel),
86 value: '',
87 validators: [required, email],
88 },
89 password: {
90 label: intl.formatMessage(messages.passwordLabel),
91 value: '',
92 validators: [required],
93 type: 'password',
94 },
95 },
96 },
97 intl,
98 );
99 })();
100
101 submit(e) {
102 e.preventDefault();
103 this.form.submit({
104 onSuccess: form => {
105 this.props.onSubmit(form.values());
106 },
107 onError: () => {},
108 });
109 }
110
111 render() {
112 const { form } = this;
113 const { intl } = this.props;
114 const {
115 isSubmitting,
116 isTokenExpired,
117 isServerLogout,
118 signupRoute,
119 // passwordRoute, // TODO: Uncomment this line after fixing password recovery in-app
120 error,
121 } = this.props;
122
123 return (
124 <div className="auth__container">
125 <form className="franz-form auth__form" onSubmit={e => this.submit(e)}>
126 <Link to="/auth/welcome">
127 <img src="./assets/images/logo.svg" className="auth__logo" alt="" />
128 </Link>
129 <H1>{intl.formatMessage(messages.headline)}</H1>
130 {isTokenExpired && (
131 <p className="error-message center">
132 {intl.formatMessage(messages.tokenExpired)}
133 </p>
134 )}
135 {isServerLogout && (
136 <p className="error-message center">
137 {intl.formatMessage(messages.serverLogout)}
138 </p>
139 )}
140 <Input field={form.$('email')} focus />
141 <Input field={form.$('password')} showPasswordToggle />
142 {error.code === 'invalid-credentials' && (
143 <>
144 <p className="error-message center">
145 {intl.formatMessage(messages.invalidCredentials)}
146 </p>
147 {window['ferdium'].stores.settings.all.app.server !==
148 LIVE_FRANZ_API && (
149 <p className="error-message center">
150 {intl.formatMessage(messages.customServerQuestion)}{' '}
151 <Link
152 to={`${window[
153 'ferdium'
154 ].stores.settings.all.app.server.replace(
155 API_VERSION,
156 '',
157 )}/import`}
158 target="_blank"
159 style={{ cursor: 'pointer', textDecoration: 'underline' }}
160 >
161 {intl.formatMessage(messages.customServerSuggestion)}
162 </Link>
163 </p>
164 )}
165 </>
166 )}
167 {isSubmitting ? (
168 <Button
169 className="auth__button is-loading"
170 buttonType="secondary"
171 label={`${intl.formatMessage(messages.submitButtonLabel)} ...`}
172 loaded={false}
173 disabled
174 />
175 ) : (
176 <Button
177 type="submit"
178 className="auth__button"
179 label={intl.formatMessage(messages.submitButtonLabel)}
180 />
181 )}
182 </form>
183 <div className="auth__links">
184 <Link to={signupRoute}>
185 {intl.formatMessage(messages.signupLink)}
186 </Link>
187 <Link
188 // to={passwordRoute} // TODO: Uncomment this line after fixing password recovery in-app
189 to={`${serverBase()}/user/forgot`} // TODO: Remove this line after fixing password recovery in-app
190 target="_blank" // TODO: Remove this line after fixing password recovery in-app
191 >
192 {intl.formatMessage(messages.passwordLink)}
193 </Link>
194 </div>
195 <div className="auth__help">
196 <Link to="/auth/welcome">
197 <Icon icon={mdiArrowLeftCircle} size={1.5} />
198 </Link>
199 </div>
200 </div>
201 );
202 }
203}
204
205export default injectIntl(inject('actions')(observer(Login)));