aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/auth
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/auth')
-rw-r--r--src/components/auth/AuthLayout.js4
-rw-r--r--src/components/auth/Import.js4
-rw-r--r--src/components/auth/Locked.js115
-rw-r--r--src/components/auth/Login.js46
-rw-r--r--src/components/auth/Pricing.js4
-rw-r--r--src/components/auth/Signup.js29
-rw-r--r--src/components/auth/Welcome.js36
7 files changed, 221 insertions, 17 deletions
diff --git a/src/components/auth/AuthLayout.js b/src/components/auth/AuthLayout.js
index 75a8cfc61..0c5198583 100644
--- a/src/components/auth/AuthLayout.js
+++ b/src/components/auth/AuthLayout.js
@@ -52,7 +52,7 @@ export default @observer class AuthLayout extends Component {
52 52
53 return ( 53 return (
54 <> 54 <>
55 {isWindows && !isFullScreen && <TitleBar menu={window.franz.menu.template} icon="assets/images/logo.svg" />} 55 {isWindows && !isFullScreen && <TitleBar menu={window.ferdi.menu.template} icon="assets/images/logo.svg" />}
56 <div className="auth"> 56 <div className="auth">
57 {!isOnline && ( 57 {!isOnline && (
58 <InfoBar 58 <InfoBar
@@ -87,7 +87,7 @@ export default @observer class AuthLayout extends Component {
87 })} 87 })}
88 </div> 88 </div>
89 {/* </div> */} 89 {/* </div> */}
90 <Link to="https://adlk.io" className="auth__adlk" target="_blank"> 90 <Link to="https://github.com/getferdi/ferdi" className="auth__adlk" target="_blank">
91 <img src="./assets/images/adlk.svg" alt="" /> 91 <img src="./assets/images/adlk.svg" alt="" />
92 </Link> 92 </Link>
93 </div> 93 </div>
diff --git a/src/components/auth/Import.js b/src/components/auth/Import.js
index 0d5feb274..3e34c3162 100644
--- a/src/components/auth/Import.js
+++ b/src/components/auth/Import.js
@@ -12,11 +12,11 @@ import Button from '../ui/Button';
12const messages = defineMessages({ 12const messages = defineMessages({
13 headline: { 13 headline: {
14 id: 'import.headline', 14 id: 'import.headline',
15 defaultMessage: '!!!Import your Franz 4 services', 15 defaultMessage: '!!!Import your Ferdi 4 services',
16 }, 16 },
17 notSupportedHeadline: { 17 notSupportedHeadline: {
18 id: 'import.notSupportedHeadline', 18 id: 'import.notSupportedHeadline',
19 defaultMessage: '!!!Services not yet supported in Franz 5', 19 defaultMessage: '!!!Services not yet supported in Ferdi 5',
20 }, 20 },
21 submitButtonLabel: { 21 submitButtonLabel: {
22 id: 'import.submit.label', 22 id: 'import.submit.label',
diff --git a/src/components/auth/Locked.js b/src/components/auth/Locked.js
new file mode 100644
index 000000000..045621d0a
--- /dev/null
+++ b/src/components/auth/Locked.js
@@ -0,0 +1,115 @@
1import React, { Component } from 'react';
2import PropTypes from 'prop-types';
3import { observer } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl';
5
6import Form from '../../lib/Form';
7import { required } from '../../helpers/validation-helpers';
8import Input from '../ui/Input';
9import Button from '../ui/Button';
10import Infobox from '../ui/Infobox';
11
12import { globalError as globalErrorPropType } from '../../prop-types';
13
14const messages = defineMessages({
15 headline: {
16 id: 'locked.headline',
17 defaultMessage: '!!!Locked',
18 },
19 info: {
20 id: 'locked.info',
21 defaultMessage: '!!!Ferdi is currently locked. Please unlock Ferdi with your password to see your messages.',
22 },
23 passwordLabel: {
24 id: 'locked.password.label',
25 defaultMessage: '!!!Password',
26 },
27 submitButtonLabel: {
28 id: 'locked.submit.label',
29 defaultMessage: '!!!Unlock',
30 },
31 invalidCredentials: {
32 id: 'locked.invalidCredentials',
33 defaultMessage: '!!!Password invalid',
34 },
35});
36
37export default @observer class Locked extends Component {
38 static propTypes = {
39 onSubmit: PropTypes.func.isRequired,
40 isSubmitting: PropTypes.bool.isRequired,
41 error: globalErrorPropType.isRequired,
42 };
43
44 static contextTypes = {
45 intl: intlShape,
46 };
47
48 form = new Form({
49 fields: {
50 password: {
51 label: this.context.intl.formatMessage(messages.passwordLabel),
52 value: '',
53 validators: [required],
54 type: 'password',
55 },
56 },
57 }, this.context.intl);
58
59 submit(e) {
60 e.preventDefault();
61 this.form.submit({
62 onSuccess: (form) => {
63 this.props.onSubmit(form.values());
64 },
65 onError: () => { },
66 });
67 }
68
69 render() {
70 const { form } = this;
71 const { intl } = this.context;
72 const {
73 isSubmitting,
74 error,
75 } = this.props;
76
77 return (
78 <div className="auth__container">
79 <form className="franz-form auth__form" onSubmit={e => this.submit(e)}>
80 <img
81 src="./assets/images/logo.svg"
82 className="auth__logo"
83 alt=""
84 />
85 <h1>{intl.formatMessage(messages.headline)}</h1>
86 <Infobox type="warning">
87 {intl.formatMessage(messages.info)}
88 </Infobox>
89 <Input
90 field={form.$('password')}
91 showPasswordToggle
92 />
93 {error.code === 'invalid-credentials' && (
94 <p className="error-message center">{intl.formatMessage(messages.invalidCredentials)}</p>
95 )}
96 {isSubmitting ? (
97 <Button
98 className="auth__button is-loading"
99 buttonType="secondary"
100 label={`${intl.formatMessage(messages.submitButtonLabel)} ...`}
101 loaded={false}
102 disabled
103 />
104 ) : (
105 <Button
106 type="submit"
107 className="auth__button"
108 label={intl.formatMessage(messages.submitButtonLabel)}
109 />
110 )}
111 </form>
112 </div>
113 );
114 }
115}
diff --git a/src/components/auth/Login.js b/src/components/auth/Login.js
index 5d21f8b60..e25121de0 100644
--- a/src/components/auth/Login.js
+++ b/src/components/auth/Login.js
@@ -1,11 +1,13 @@
1/* eslint jsx-a11y/anchor-is-valid: 0 */
1import React, { Component } from 'react'; 2import React, { Component } from 'react';
2import PropTypes from 'prop-types'; 3import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 4import { observer, inject } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 5import { defineMessages, intlShape } from 'react-intl';
5 6
6import { isDevMode, useLiveAPI } from '../../environment'; 7import { isDevMode, useLiveAPI } from '../../environment';
7import Form from '../../lib/Form'; 8import Form from '../../lib/Form';
8import { required, email } from '../../helpers/validation-helpers'; 9import { required, email } from '../../helpers/validation-helpers';
10import serverlessLogin from '../../helpers/serverless-helpers';
9import Input from '../ui/Input'; 11import Input from '../ui/Input';
10import Button from '../ui/Button'; 12import Button from '../ui/Button';
11import Link from '../ui/Link'; 13import Link from '../ui/Link';
@@ -34,6 +36,14 @@ const messages = defineMessages({
34 id: 'login.invalidCredentials', 36 id: 'login.invalidCredentials',
35 defaultMessage: '!!!Email or password not valid', 37 defaultMessage: '!!!Email or password not valid',
36 }, 38 },
39 customServerQuestion: {
40 id: 'login.customServerQuestion',
41 defaultMessage: '!!!Using a Franz account to log in?',
42 },
43 customServerSuggestion: {
44 id: 'login.customServerSuggestion',
45 defaultMessage: '!!!Try importing your Franz account into Ferdi',
46 },
37 tokenExpired: { 47 tokenExpired: {
38 id: 'login.tokenExpired', 48 id: 'login.tokenExpired',
39 defaultMessage: '!!!Your session expired, please login again.', 49 defaultMessage: '!!!Your session expired, please login again.',
@@ -46,13 +56,21 @@ const messages = defineMessages({
46 id: 'login.link.signup', 56 id: 'login.link.signup',
47 defaultMessage: '!!!Create a free account', 57 defaultMessage: '!!!Create a free account',
48 }, 58 },
59 changeServer: {
60 id: 'login.changeServer',
61 defaultMessage: '!!!Change server',
62 },
63 serverless: {
64 id: 'services.serverless',
65 defaultMessage: '!!!Use Ferdi without an Account',
66 },
49 passwordLink: { 67 passwordLink: {
50 id: 'login.link.password', 68 id: 'login.link.password',
51 defaultMessage: '!!!Forgot password', 69 defaultMessage: '!!!Forgot password',
52 }, 70 },
53}); 71});
54 72
55export default @observer class Login extends Component { 73export default @inject('actions') @observer class Login extends Component {
56 static propTypes = { 74 static propTypes = {
57 onSubmit: PropTypes.func.isRequired, 75 onSubmit: PropTypes.func.isRequired,
58 isSubmitting: PropTypes.bool.isRequired, 76 isSubmitting: PropTypes.bool.isRequired,
@@ -61,6 +79,7 @@ export default @observer class Login extends Component {
61 signupRoute: PropTypes.string.isRequired, 79 signupRoute: PropTypes.string.isRequired,
62 passwordRoute: PropTypes.string.isRequired, 80 passwordRoute: PropTypes.string.isRequired,
63 error: globalErrorPropType.isRequired, 81 error: globalErrorPropType.isRequired,
82 actions: PropTypes.object.isRequired,
64 }; 83 };
65 84
66 static contextTypes = { 85 static contextTypes = {
@@ -95,6 +114,10 @@ export default @observer class Login extends Component {
95 }); 114 });
96 } 115 }
97 116
117 useLocalServer() {
118 serverlessLogin(this.props.actions);
119 }
120
98 render() { 121 render() {
99 const { form } = this; 122 const { form } = this;
100 const { intl } = this.context; 123 const { intl } = this.context;
@@ -137,7 +160,22 @@ export default @observer class Login extends Component {
137 showPasswordToggle 160 showPasswordToggle
138 /> 161 />
139 {error.code === 'invalid-credentials' && ( 162 {error.code === 'invalid-credentials' && (
140 <p className="error-message center">{intl.formatMessage(messages.invalidCredentials)}</p> 163 <>
164 <p className="error-message center">{intl.formatMessage(messages.invalidCredentials)}</p>
165 { window.ferdi.stores.settings.all.app.server !== 'https://api.franzinfra.com' && (
166 <p className="error-message center">
167 {intl.formatMessage(messages.customServerQuestion)}
168 {' '}
169 <Link
170 to={`${window.ferdi.stores.settings.all.app.server.replace('v1', '')}/import`}
171 target="_blank"
172 style={{ cursor: 'pointer', textDecoration: 'underline' }}
173 >
174 {intl.formatMessage(messages.customServerSuggestion)}
175 </Link>
176 </p>
177 )}
178 </>
141 )} 179 )}
142 {isSubmitting ? ( 180 {isSubmitting ? (
143 <Button 181 <Button
@@ -156,6 +194,8 @@ export default @observer class Login extends Component {
156 )} 194 )}
157 </form> 195 </form>
158 <div className="auth__links"> 196 <div className="auth__links">
197 <Link to="/settings/app">{intl.formatMessage(messages.changeServer)}</Link>
198 <a onClick={this.useLocalServer.bind(this)}>{intl.formatMessage(messages.serverless)}</a>
159 <Link to={signupRoute}>{intl.formatMessage(messages.signupLink)}</Link> 199 <Link to={signupRoute}>{intl.formatMessage(messages.signupLink)}</Link>
160 <Link to={passwordRoute}>{intl.formatMessage(messages.passwordLink)}</Link> 200 <Link to={passwordRoute}>{intl.formatMessage(messages.passwordLink)}</Link>
161 </div> 201 </div>
diff --git a/src/components/auth/Pricing.js b/src/components/auth/Pricing.js
index 53ae046a0..593cb9c4b 100644
--- a/src/components/auth/Pricing.js
+++ b/src/components/auth/Pricing.js
@@ -58,7 +58,7 @@ const messages = defineMessages({
58 }, 58 },
59 ctaSkip: { 59 ctaSkip: {
60 id: 'pricing.trial.cta.skip', 60 id: 'pricing.trial.cta.skip',
61 defaultMessage: '!!!Continue to Franz', 61 defaultMessage: '!!!Continue to Ferdi',
62 }, 62 },
63 featuresHeadline: { 63 featuresHeadline: {
64 id: 'pricing.trial.features.headline', 64 id: 'pricing.trial.features.headline',
@@ -140,7 +140,7 @@ const styles = theme => ({
140 }, 140 },
141}); 141});
142 142
143export default @observer @injectSheet(styles) class Signup extends Component { 143export default @injectSheet(styles) @observer class Signup extends Component {
144 static propTypes = { 144 static propTypes = {
145 onSubmit: PropTypes.func.isRequired, 145 onSubmit: PropTypes.func.isRequired,
146 isLoadingRequiredData: PropTypes.bool.isRequired, 146 isLoadingRequiredData: PropTypes.bool.isRequired,
diff --git a/src/components/auth/Signup.js b/src/components/auth/Signup.js
index 0499d764b..a166155a7 100644
--- a/src/components/auth/Signup.js
+++ b/src/components/auth/Signup.js
@@ -1,11 +1,13 @@
1/* eslint jsx-a11y/anchor-is-valid: 0 */
1import React, { Component } from 'react'; 2import React, { Component } from 'react';
2import PropTypes from 'prop-types'; 3import PropTypes from 'prop-types';
3import { observer } from 'mobx-react'; 4import { observer, inject } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 5import { defineMessages, intlShape } from 'react-intl';
5 6
6import { isDevMode, useLiveAPI } from '../../environment'; 7import { isDevMode, useLiveAPI } from '../../environment';
7import Form from '../../lib/Form'; 8import Form from '../../lib/Form';
8import { required, email, minLength } from '../../helpers/validation-helpers'; 9import { required, email, minLength } from '../../helpers/validation-helpers';
10import serverlessLogin from '../../helpers/serverless-helpers';
9import Input from '../ui/Input'; 11import Input from '../ui/Input';
10import Button from '../ui/Button'; 12import Button from '../ui/Button';
11import Link from '../ui/Link'; 13import Link from '../ui/Link';
@@ -40,7 +42,7 @@ const messages = defineMessages({
40 }, 42 },
41 legalInfo: { 43 legalInfo: {
42 id: 'signup.legal.info', 44 id: 'signup.legal.info',
43 defaultMessage: '!!!By creating a Franz account you accept the', 45 defaultMessage: '!!!By creating a Ferdi account you accept the',
44 }, 46 },
45 terms: { 47 terms: {
46 id: 'signup.legal.terms', 48 id: 'signup.legal.terms',
@@ -58,18 +60,27 @@ const messages = defineMessages({
58 id: 'signup.link.login', 60 id: 'signup.link.login',
59 defaultMessage: '!!!Already have an account, sign in?', 61 defaultMessage: '!!!Already have an account, sign in?',
60 }, 62 },
63 changeServer: {
64 id: 'login.changeServer',
65 defaultMessage: '!!!Change server',
66 },
67 serverless: {
68 id: 'services.serverless',
69 defaultMessage: '!!!Use Ferdi without an Account',
70 },
61 emailDuplicate: { 71 emailDuplicate: {
62 id: 'signup.emailDuplicate', 72 id: 'signup.emailDuplicate',
63 defaultMessage: '!!!A user with that email address already exists', 73 defaultMessage: '!!!A user with that email address already exists',
64 }, 74 },
65}); 75});
66 76
67export default @observer class Signup extends Component { 77export default @inject('actions') @observer class Signup extends Component {
68 static propTypes = { 78 static propTypes = {
69 onSubmit: PropTypes.func.isRequired, 79 onSubmit: PropTypes.func.isRequired,
70 isSubmitting: PropTypes.bool.isRequired, 80 isSubmitting: PropTypes.bool.isRequired,
71 loginRoute: PropTypes.string.isRequired, 81 loginRoute: PropTypes.string.isRequired,
72 error: globalErrorPropType.isRequired, 82 error: globalErrorPropType.isRequired,
83 actions: PropTypes.object.isRequired,
73 }; 84 };
74 85
75 static contextTypes = { 86 static contextTypes = {
@@ -112,11 +123,17 @@ export default @observer class Signup extends Component {
112 }); 123 });
113 } 124 }
114 125
126 useLocalServer() {
127 serverlessLogin(this.props.actions);
128 }
129
115 render() { 130 render() {
116 const { form } = this; 131 const { form } = this;
117 const { intl } = this.context; 132 const { intl } = this.context;
118 const { isSubmitting, loginRoute, error } = this.props; 133 const { isSubmitting, loginRoute, error } = this.props;
119 134
135 const termsBase = window.ferdi.stores.settings.all.app.server !== 'https://api.franzinfra.com' ? window.ferdi.stores.settings.all.app.server : 'https://meetfranz.com';
136
120 return ( 137 return (
121 <div className="auth__scroll-container"> 138 <div className="auth__scroll-container">
122 <div className="auth__container auth__container--signup"> 139 <div className="auth__container auth__container--signup">
@@ -163,7 +180,7 @@ export default @observer class Signup extends Component {
163 {intl.formatMessage(messages.legalInfo)} 180 {intl.formatMessage(messages.legalInfo)}
164 <br /> 181 <br />
165 <Link 182 <Link
166 to="https://meetfranz.com/terms" 183 to={`${termsBase}/terms`}
167 target="_blank" 184 target="_blank"
168 className="link" 185 className="link"
169 > 186 >
@@ -171,7 +188,7 @@ export default @observer class Signup extends Component {
171 </Link> 188 </Link>
172 &nbsp;&amp;&nbsp; 189 &nbsp;&amp;&nbsp;
173 <Link 190 <Link
174 to="https://meetfranz.com/privacy" 191 to={`${termsBase}/privacy`}
175 target="_blank" 192 target="_blank"
176 className="link" 193 className="link"
177 > 194 >
@@ -181,6 +198,8 @@ export default @observer class Signup extends Component {
181 </p> 198 </p>
182 </form> 199 </form>
183 <div className="auth__links"> 200 <div className="auth__links">
201 <Link to="/settings/app">{intl.formatMessage(messages.changeServer)}</Link>
202 <a onClick={this.useLocalServer.bind(this)}>{intl.formatMessage(messages.serverless)}</a>
184 <Link to={loginRoute}>{intl.formatMessage(messages.loginLink)}</Link> 203 <Link to={loginRoute}>{intl.formatMessage(messages.loginLink)}</Link>
185 </div> 204 </div>
186 </div> 205 </div>
diff --git a/src/components/auth/Welcome.js b/src/components/auth/Welcome.js
index f6d77f70f..1453c1d7c 100644
--- a/src/components/auth/Welcome.js
+++ b/src/components/auth/Welcome.js
@@ -1,7 +1,9 @@
1/* eslint jsx-a11y/anchor-is-valid: 0 */
1import React, { Component } from 'react'; 2import React, { Component } from 'react';
2import PropTypes from 'prop-types'; 3import PropTypes from 'prop-types';
3import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; 4import { observer, PropTypes as MobxPropTypes, inject } from 'mobx-react';
4import { defineMessages, intlShape } from 'react-intl'; 5import { defineMessages, intlShape } from 'react-intl';
6import serverlessLogin from '../../helpers/serverless-helpers';
5 7
6import Link from '../ui/Link'; 8import Link from '../ui/Link';
7 9
@@ -14,19 +16,28 @@ const messages = defineMessages({
14 id: 'welcome.loginButton', 16 id: 'welcome.loginButton',
15 defaultMessage: '!!!Login to your account', 17 defaultMessage: '!!!Login to your account',
16 }, 18 },
19 serverless: {
20 id: 'services.serverless',
21 defaultMessage: '!!!Use Ferdi without an Account',
22 },
17}); 23});
18 24
19export default @observer class Login extends Component { 25export default @inject('actions') @observer class Login extends Component {
20 static propTypes = { 26 static propTypes = {
21 loginRoute: PropTypes.string.isRequired, 27 loginRoute: PropTypes.string.isRequired,
22 signupRoute: PropTypes.string.isRequired, 28 signupRoute: PropTypes.string.isRequired,
23 recipes: MobxPropTypes.arrayOrObservableArray.isRequired, 29 recipes: MobxPropTypes.arrayOrObservableArray.isRequired,
30 actions: PropTypes.object.isRequired,
24 }; 31 };
25 32
26 static contextTypes = { 33 static contextTypes = {
27 intl: intlShape, 34 intl: intlShape,
28 }; 35 };
29 36
37 useLocalServer() {
38 serverlessLogin(this.props.actions);
39 }
40
30 render() { 41 render() {
31 const { intl } = this.context; 42 const { intl } = this.context;
32 const { 43 const {
@@ -41,7 +52,7 @@ export default @observer class Login extends Component {
41 <img src="./assets/images/logo.svg" className="welcome__logo" alt="" /> 52 <img src="./assets/images/logo.svg" className="welcome__logo" alt="" />
42 {/* <img src="./assets/images/welcome.png" className="welcome__services" alt="" /> */} 53 {/* <img src="./assets/images/welcome.png" className="welcome__services" alt="" /> */}
43 <div className="welcome__text"> 54 <div className="welcome__text">
44 <h1>Franz</h1> 55 <h1>Ferdi</h1>
45 </div> 56 </div>
46 </div> 57 </div>
47 <div className="welcome__buttons"> 58 <div className="welcome__buttons">
@@ -51,6 +62,25 @@ export default @observer class Login extends Component {
51 <Link to={loginRoute} className="button"> 62 <Link to={loginRoute} className="button">
52 {intl.formatMessage(messages.loginButton)} 63 {intl.formatMessage(messages.loginButton)}
53 </Link> 64 </Link>
65 <br />
66 <br />
67 <a className="button" onClick={this.useLocalServer.bind(this)}>
68 {intl.formatMessage(messages.serverless)}
69 </a>
70 <br />
71 <br />
72
73
74 <Link to="settings/app">
75 <span style={{
76 textAlign: 'center',
77 width: '100%',
78 cursor: 'pointer',
79 }}
80 >
81 Change server
82 </span>
83 </Link>
54 </div> 84 </div>
55 <div className="welcome__featured-services"> 85 <div className="welcome__featured-services">
56 {recipes.map(recipe => ( 86 {recipes.map(recipe => (