diff options
author | 2022-11-02 06:31:36 +0530 | |
---|---|---|
committer | 2022-11-02 01:01:36 +0000 | |
commit | 302d595f7c289387e53a0ef7df4d574ed4e25d70 (patch) | |
tree | 2385e59eaca9c78921d9b0b3681cfba1b3eef168 /src/components/auth | |
parent | Re-enable editing of the address bar to manually access a different url withi... (diff) | |
download | ferdium-app-302d595f7c289387e53a0ef7df4d574ed4e25d70.tar.gz ferdium-app-302d595f7c289387e53a0ef7df4d574ed4e25d70.tar.zst ferdium-app-302d595f7c289387e53a0ef7df4d574ed4e25d70.zip |
Transform to TS and refactored components w.r.t deletion if duplicated Input component (#729)
Diffstat (limited to 'src/components/auth')
-rw-r--r-- | src/components/auth/ChangeServer.tsx | 7 | ||||
-rw-r--r-- | src/components/auth/Invite.tsx (renamed from src/components/auth/Invite.js) | 127 | ||||
-rw-r--r-- | src/components/auth/Locked.tsx (renamed from src/components/auth/Locked.js) | 65 | ||||
-rw-r--r-- | src/components/auth/Login.tsx | 6 | ||||
-rw-r--r-- | src/components/auth/Password.tsx (renamed from src/components/auth/Password.js) | 64 | ||||
-rw-r--r-- | src/components/auth/Signup.tsx (renamed from src/components/auth/Signup.jsx) | 107 |
6 files changed, 199 insertions, 177 deletions
diff --git a/src/components/auth/ChangeServer.tsx b/src/components/auth/ChangeServer.tsx index d8509f599..c49e52673 100644 --- a/src/components/auth/ChangeServer.tsx +++ b/src/components/auth/ChangeServer.tsx | |||
@@ -4,7 +4,7 @@ import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; | |||
4 | import { mdiArrowLeftCircle } from '@mdi/js'; | 4 | import { mdiArrowLeftCircle } from '@mdi/js'; |
5 | import { noop } from 'lodash'; | 5 | import { noop } from 'lodash'; |
6 | import Form from '../../lib/Form'; | 6 | import Form from '../../lib/Form'; |
7 | import Input from '../ui/Input'; | 7 | import Input from '../ui/input/index'; |
8 | import Select from '../ui/Select'; | 8 | import Select from '../ui/Select'; |
9 | import Button from '../ui/button'; | 9 | import Button from '../ui/button'; |
10 | import Link from '../ui/Link'; | 10 | import Link from '../ui/Link'; |
@@ -128,7 +128,10 @@ class ChangeServer extends Component<IProps> { | |||
128 | )} | 128 | )} |
129 | <Select field={form.$('server')} /> | 129 | <Select field={form.$('server')} /> |
130 | {!this.defaultServers.includes(form.$('server').value) && ( | 130 | {!this.defaultServers.includes(form.$('server').value) && ( |
131 | <Input placeholder="Custom Server" field={form.$('customServer')} /> | 131 | <Input |
132 | placeholder="Custom Server" | ||
133 | {...form.$('customServer').bind()} | ||
134 | /> | ||
132 | )} | 135 | )} |
133 | <Button | 136 | <Button |
134 | type="submit" | 137 | type="submit" |
diff --git a/src/components/auth/Invite.js b/src/components/auth/Invite.tsx index 6b0e0e40b..7723ea1ac 100644 --- a/src/components/auth/Invite.js +++ b/src/components/auth/Invite.tsx | |||
@@ -1,15 +1,14 @@ | |||
1 | import { Component, Fragment } from 'react'; | 1 | import { Component } from 'react'; |
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | 2 | import { observer } from 'mobx-react'; |
4 | import { defineMessages, injectIntl } from 'react-intl'; | 3 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; |
5 | import { Link } from 'react-router-dom'; | 4 | import { Link } from 'react-router-dom'; |
6 | import classnames from 'classnames'; | 5 | import classnames from 'classnames'; |
7 | 6 | import { noop } from 'lodash'; | |
8 | import Infobox from '../ui/Infobox'; | 7 | import Infobox from '../ui/Infobox'; |
9 | import Appear from '../ui/effects/Appear'; | 8 | import Appear from '../ui/effects/Appear'; |
10 | import Form from '../../lib/Form'; | 9 | import Form from '../../lib/Form'; |
11 | import { email } from '../../helpers/validation-helpers'; | 10 | import { email, required } from '../../helpers/validation-helpers'; |
12 | import Input from '../ui/Input'; | 11 | import Input from '../ui/input/index'; |
13 | import Button from '../ui/button'; | 12 | import Button from '../ui/button'; |
14 | import { H1 } from '../ui/headline'; | 13 | import { H1 } from '../ui/headline'; |
15 | 14 | ||
@@ -44,55 +43,61 @@ const messages = defineMessages({ | |||
44 | }, | 43 | }, |
45 | }); | 44 | }); |
46 | 45 | ||
47 | class Invite extends Component { | 46 | interface IProps extends WrappedComponentProps { |
48 | static propTypes = { | 47 | onSubmit: (...args: any[]) => void; |
49 | onSubmit: PropTypes.func.isRequired, | 48 | embed?: boolean; |
50 | embed: PropTypes.bool, | 49 | isInviteSuccessful?: boolean; |
51 | isInviteSuccessful: PropTypes.bool, | 50 | isLoadingInvite?: boolean; |
52 | isLoadingInvite: PropTypes.bool, | 51 | } |
53 | }; | ||
54 | |||
55 | static defaultProps = { | ||
56 | embed: false, | ||
57 | isInviteSuccessful: false, | ||
58 | isLoadingInvite: false, | ||
59 | }; | ||
60 | 52 | ||
61 | state = { showSuccessInfo: false }; | 53 | interface IState { |
54 | showSuccessInfo: boolean; | ||
55 | } | ||
62 | 56 | ||
63 | componentDidMount() { | 57 | @observer |
64 | const { intl } = this.props; | 58 | class Invite extends Component<IProps, IState> { |
65 | this.form = new Form( | 59 | form: Form; |
66 | { | 60 | |
67 | fields: { | 61 | constructor(props: IProps) { |
68 | invite: [ | 62 | super(props); |
69 | ...Array.from({ length: 3 }).fill({ | 63 | |
70 | fields: { | 64 | this.state = { showSuccessInfo: false }; |
71 | name: { | 65 | this.form = new Form({ |
72 | label: intl.formatMessage(messages.nameLabel), | 66 | fields: { |
73 | placeholder: intl.formatMessage(messages.nameLabel), | 67 | invite: [ |
74 | onChange: () => { | 68 | ...Array.from({ length: 3 }).fill({ |
75 | this.setState({ showSuccessInfo: false }); | 69 | fields: { |
76 | }, | 70 | name: { |
77 | // related: ['invite.0.email'], // path accepted but does not work | 71 | label: this.props.intl.formatMessage(messages.nameLabel), |
72 | placeholder: this.props.intl.formatMessage(messages.nameLabel), | ||
73 | onChange: () => { | ||
74 | this.setState({ showSuccessInfo: false }); | ||
78 | }, | 75 | }, |
79 | email: { | 76 | validators: [required], |
80 | label: intl.formatMessage(messages.emailLabel), | 77 | // related: ['invite.0.email'], // path accepted but does not work |
81 | placeholder: intl.formatMessage(messages.emailLabel), | 78 | }, |
82 | onChange: () => { | 79 | email: { |
83 | this.setState({ showSuccessInfo: false }); | 80 | label: this.props.intl.formatMessage(messages.emailLabel), |
84 | }, | 81 | placeholder: this.props.intl.formatMessage(messages.emailLabel), |
85 | validators: [email], | 82 | onChange: () => { |
83 | this.setState({ showSuccessInfo: false }); | ||
86 | }, | 84 | }, |
85 | validators: [email], | ||
87 | }, | 86 | }, |
88 | }), | 87 | }, |
89 | ], | 88 | }), |
90 | }, | 89 | // TODO - [TS DEBT] need to fix this type once mobx-react-form is updated to next version |
90 | ] as any, | ||
91 | }, | 91 | }, |
92 | intl, | 92 | }); |
93 | ); | 93 | } |
94 | 94 | ||
95 | document.querySelector('input:first-child')?.focus(); | 95 | componentDidMount() { |
96 | const selector: HTMLElement | null = | ||
97 | document.querySelector('input:first-child'); | ||
98 | if (selector) { | ||
99 | selector.focus(); | ||
100 | } | ||
96 | } | 101 | } |
97 | 102 | ||
98 | submit(e) { | 103 | submit(e) { |
@@ -101,10 +106,15 @@ class Invite extends Component { | |||
101 | this.form?.submit({ | 106 | this.form?.submit({ |
102 | onSuccess: form => { | 107 | onSuccess: form => { |
103 | this.props.onSubmit({ invites: form.values().invite }); | 108 | this.props.onSubmit({ invites: form.values().invite }); |
104 | |||
105 | this.form?.clear(); | 109 | this.form?.clear(); |
106 | // this.form.$('invite.0.name').focus(); // path accepted but does not focus ;( | 110 | // this.form.$('invite.0.name').focus(); // path accepted but does not focus ;( |
107 | document.querySelector('input:first-child')?.focus(); | 111 | |
112 | const selector: HTMLElement | null = | ||
113 | document.querySelector('input:first-child'); | ||
114 | if (selector) { | ||
115 | selector.focus(); | ||
116 | } | ||
117 | |||
108 | this.setState({ showSuccessInfo: true }); | 118 | this.setState({ showSuccessInfo: true }); |
109 | }, | 119 | }, |
110 | onError: () => {}, | 120 | onError: () => {}, |
@@ -114,7 +124,11 @@ class Invite extends Component { | |||
114 | render() { | 124 | render() { |
115 | const { form } = this; | 125 | const { form } = this; |
116 | const { intl } = this.props; | 126 | const { intl } = this.props; |
117 | const { embed, isInviteSuccessful, isLoadingInvite } = this.props; | 127 | const { |
128 | embed = false, | ||
129 | isInviteSuccessful = false, | ||
130 | isLoadingInvite = false, | ||
131 | } = this.props; | ||
118 | 132 | ||
119 | const atLeastOneEmailAddress = form | 133 | const atLeastOneEmailAddress = form |
120 | .$('invite') | 134 | .$('invite') |
@@ -133,7 +147,7 @@ class Invite extends Component { | |||
133 | <Infobox | 147 | <Infobox |
134 | type="success" | 148 | type="success" |
135 | icon="checkbox-marked-circle-outline" | 149 | icon="checkbox-marked-circle-outline" |
136 | dismissable | 150 | dismissible |
137 | > | 151 | > |
138 | {intl.formatMessage(messages.inviteSuccessInfo)} | 152 | {intl.formatMessage(messages.inviteSuccessInfo)} |
139 | </Infobox> | 153 | </Infobox> |
@@ -144,14 +158,14 @@ class Invite extends Component { | |||
144 | {!embed && ( | 158 | {!embed && ( |
145 | <img src="./assets/images/logo.svg" className="auth__logo" alt="" /> | 159 | <img src="./assets/images/logo.svg" className="auth__logo" alt="" /> |
146 | )} | 160 | )} |
147 | <H1 className={embed && 'invite__embed'}> | 161 | <H1 className={embed ? 'invite__embed' : ''}> |
148 | {intl.formatMessage(messages.headline)} | 162 | {intl.formatMessage(messages.headline)} |
149 | </H1> | 163 | </H1> |
150 | {form.$('invite').map(invite => ( | 164 | {form.$('invite').map(invite => ( |
151 | <div className="grid" key={invite.key}> | 165 | <div className="grid" key={invite.key}> |
152 | <div className="grid__row"> | 166 | <div className="grid__row"> |
153 | <Input field={invite.$('name')} showLabel={false} /> | 167 | <Input {...invite.$('name').bind()} showLabel={false} /> |
154 | <Input field={invite.$('email')} showLabel={false} /> | 168 | <Input {...invite.$('email').bind()} showLabel={false} /> |
155 | </div> | 169 | </div> |
156 | </div> | 170 | </div> |
157 | ))} | 171 | ))} |
@@ -161,6 +175,7 @@ class Invite extends Component { | |||
161 | disabled={!atLeastOneEmailAddress} | 175 | disabled={!atLeastOneEmailAddress} |
162 | label={intl.formatMessage(messages.submitButtonLabel)} | 176 | label={intl.formatMessage(messages.submitButtonLabel)} |
163 | loaded={!isLoadingInvite} | 177 | loaded={!isLoadingInvite} |
178 | onClick={noop} | ||
164 | /> | 179 | /> |
165 | {!embed && ( | 180 | {!embed && ( |
166 | <Link | 181 | <Link |
@@ -195,4 +210,4 @@ class Invite extends Component { | |||
195 | } | 210 | } |
196 | } | 211 | } |
197 | 212 | ||
198 | export default injectIntl(observer(Invite)); | 213 | export default injectIntl(Invite); |
diff --git a/src/components/auth/Locked.js b/src/components/auth/Locked.tsx index 6e32dd980..8b4e26878 100644 --- a/src/components/auth/Locked.js +++ b/src/components/auth/Locked.tsx | |||
@@ -1,17 +1,14 @@ | |||
1 | import { systemPreferences } from '@electron/remote'; | 1 | import { systemPreferences } from '@electron/remote'; |
2 | import { Component } from 'react'; | 2 | import { Component } from 'react'; |
3 | import PropTypes from 'prop-types'; | ||
4 | import { observer } from 'mobx-react'; | 3 | import { observer } from 'mobx-react'; |
5 | import { defineMessages, injectIntl } from 'react-intl'; | 4 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; |
6 | 5 | import { noop } from 'lodash'; | |
7 | import Form from '../../lib/Form'; | 6 | import Form from '../../lib/Form'; |
8 | import Input from '../ui/Input'; | 7 | import Input from '../ui/input/index'; |
9 | import Button from '../ui/button'; | 8 | import Button from '../ui/button'; |
10 | import { H1 } from '../ui/headline'; | 9 | import { H1 } from '../ui/headline'; |
11 | import { isMac } from '../../environment'; | 10 | import { isMac } from '../../environment'; |
12 | 11 | ||
13 | import { globalError as globalErrorPropType } from '../../prop-types'; | ||
14 | |||
15 | const messages = defineMessages({ | 12 | const messages = defineMessages({ |
16 | headline: { | 13 | headline: { |
17 | id: 'locked.headline', | 14 | id: 'locked.headline', |
@@ -23,7 +20,7 @@ const messages = defineMessages({ | |||
23 | }, | 20 | }, |
24 | touchIdPrompt: { | 21 | touchIdPrompt: { |
25 | id: 'locked.touchIdPrompt', | 22 | id: 'locked.touchIdPrompt', |
26 | defaultMessage: 'unlock via Touch ID', | 23 | defaultMessage: 'Unlock with Touch ID', |
27 | }, | 24 | }, |
28 | passwordLabel: { | 25 | passwordLabel: { |
29 | id: 'locked.password.label', | 26 | id: 'locked.password.label', |
@@ -43,30 +40,31 @@ const messages = defineMessages({ | |||
43 | }, | 40 | }, |
44 | }); | 41 | }); |
45 | 42 | ||
46 | class Locked extends Component { | 43 | interface IProps extends WrappedComponentProps { |
47 | static propTypes = { | 44 | onSubmit: (...args: any[]) => void; |
48 | onSubmit: PropTypes.func.isRequired, | 45 | unlock: () => void; |
49 | unlock: PropTypes.func.isRequired, | 46 | isSubmitting: boolean; |
50 | isSubmitting: PropTypes.bool.isRequired, | 47 | useTouchIdToUnlock: boolean; |
51 | useTouchIdToUnlock: PropTypes.bool.isRequired, | 48 | error: boolean; |
52 | error: globalErrorPropType.isRequired, | 49 | } |
53 | }; | ||
54 | 50 | ||
55 | form = (() => { | 51 | @observer |
56 | const { intl } = this.props; | 52 | class Locked extends Component<IProps> { |
57 | return new Form( | 53 | form: Form; |
58 | { | 54 | |
59 | fields: { | 55 | constructor(props: IProps) { |
60 | password: { | 56 | super(props); |
61 | label: intl.formatMessage(messages.passwordLabel), | 57 | |
62 | value: '', | 58 | this.form = new Form({ |
63 | type: 'password', | 59 | fields: { |
64 | }, | 60 | password: { |
61 | label: this.props.intl.formatMessage(messages.passwordLabel), | ||
62 | value: '', | ||
63 | type: 'password', | ||
65 | }, | 64 | }, |
66 | }, | 65 | }, |
67 | intl, | 66 | }); |
68 | ); | 67 | } |
69 | })(); | ||
70 | 68 | ||
71 | submit(e) { | 69 | submit(e) { |
72 | e.preventDefault(); | 70 | e.preventDefault(); |
@@ -90,8 +88,7 @@ class Locked extends Component { | |||
90 | 88 | ||
91 | render() { | 89 | render() { |
92 | const { form } = this; | 90 | const { form } = this; |
93 | const { intl } = this.props; | 91 | const { isSubmitting, error, useTouchIdToUnlock, intl } = this.props; |
94 | const { isSubmitting, error, useTouchIdToUnlock } = this.props; | ||
95 | 92 | ||
96 | const touchIdEnabled = isMac | 93 | const touchIdEnabled = isMac |
97 | ? useTouchIdToUnlock && systemPreferences.canPromptTouchID() | 94 | ? useTouchIdToUnlock && systemPreferences.canPromptTouchID() |
@@ -118,8 +115,8 @@ class Locked extends Component { | |||
118 | </> | 115 | </> |
119 | )} | 116 | )} |
120 | 117 | ||
121 | <Input field={form.$('password')} showPasswordToggle focus /> | 118 | <Input {...form.$('password').bind()} showPasswordToggle focus /> |
122 | {error.code === 'invalid-credentials' && ( | 119 | {error && ( |
123 | <p className="error-message center"> | 120 | <p className="error-message center"> |
124 | {intl.formatMessage(messages.invalidCredentials)} | 121 | {intl.formatMessage(messages.invalidCredentials)} |
125 | </p> | 122 | </p> |
@@ -130,6 +127,7 @@ class Locked extends Component { | |||
130 | buttonType="secondary" | 127 | buttonType="secondary" |
131 | label={`${submitButtonLabel} ...`} | 128 | label={`${submitButtonLabel} ...`} |
132 | loaded={false} | 129 | loaded={false} |
130 | onClick={noop} | ||
133 | disabled | 131 | disabled |
134 | /> | 132 | /> |
135 | ) : ( | 133 | ) : ( |
@@ -137,6 +135,7 @@ class Locked extends Component { | |||
137 | type="submit" | 135 | type="submit" |
138 | className="auth__button" | 136 | className="auth__button" |
139 | label={submitButtonLabel} | 137 | label={submitButtonLabel} |
138 | onClick={noop} | ||
140 | /> | 139 | /> |
141 | )} | 140 | )} |
142 | </form> | 141 | </form> |
@@ -145,4 +144,4 @@ class Locked extends Component { | |||
145 | } | 144 | } |
146 | } | 145 | } |
147 | 146 | ||
148 | export default injectIntl(observer(Locked)); | 147 | export default injectIntl(Locked); |
diff --git a/src/components/auth/Login.tsx b/src/components/auth/Login.tsx index 66a567fe4..185a6ad48 100644 --- a/src/components/auth/Login.tsx +++ b/src/components/auth/Login.tsx | |||
@@ -9,7 +9,7 @@ import { API_VERSION } from '../../environment-remote'; | |||
9 | import { serverBase } from '../../api/apiBase'; // TODO: Remove this line after fixing password recovery in-app | 9 | import { serverBase } from '../../api/apiBase'; // TODO: Remove this line after fixing password recovery in-app |
10 | import Form from '../../lib/Form'; | 10 | import Form from '../../lib/Form'; |
11 | import { required, email } from '../../helpers/validation-helpers'; | 11 | import { required, email } from '../../helpers/validation-helpers'; |
12 | import Input from '../ui/Input'; | 12 | import Input from '../ui/input/index'; |
13 | import Button from '../ui/button'; | 13 | import Button from '../ui/button'; |
14 | import Link from '../ui/Link'; | 14 | import Link from '../ui/Link'; |
15 | import { H1 } from '../ui/headline'; | 15 | import { H1 } from '../ui/headline'; |
@@ -136,8 +136,8 @@ class Login extends Component<IProps> { | |||
136 | {intl.formatMessage(messages.serverLogout)} | 136 | {intl.formatMessage(messages.serverLogout)} |
137 | </p> | 137 | </p> |
138 | )} | 138 | )} |
139 | <Input field={form.$('email')} focus /> | 139 | <Input {...form.$('email').bind()} focus /> |
140 | <Input field={form.$('password')} showPasswordToggle /> | 140 | <Input {...form.$('password').bind()} showPasswordToggle /> |
141 | {error.code === 'invalid-credentials' && ( | 141 | {error.code === 'invalid-credentials' && ( |
142 | <> | 142 | <> |
143 | <p className="error-message center"> | 143 | <p className="error-message center"> |
diff --git a/src/components/auth/Password.js b/src/components/auth/Password.tsx index 5086b0bbd..53fdbf842 100644 --- a/src/components/auth/Password.js +++ b/src/components/auth/Password.tsx | |||
@@ -1,11 +1,11 @@ | |||
1 | import { Component } from 'react'; | 1 | import { Component, FormEvent } from 'react'; |
2 | import PropTypes from 'prop-types'; | 2 | import { observer } from 'mobx-react'; |
3 | import { observer, PropTypes as MobxPropTypes } from 'mobx-react'; | 3 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; |
4 | import { defineMessages, injectIntl } from 'react-intl'; | ||
5 | 4 | ||
5 | import { noop } from 'lodash'; | ||
6 | import Form from '../../lib/Form'; | 6 | import Form from '../../lib/Form'; |
7 | import { required, email } from '../../helpers/validation-helpers'; | 7 | import { required, email } from '../../helpers/validation-helpers'; |
8 | import Input from '../ui/Input'; | 8 | import Input from '../ui/input/index'; |
9 | import Button from '../ui/button'; | 9 | import Button from '../ui/button'; |
10 | import Link from '../ui/Link'; | 10 | import Link from '../ui/Link'; |
11 | import Infobox from '../ui/Infobox'; | 11 | import Infobox from '../ui/Infobox'; |
@@ -39,32 +39,33 @@ const messages = defineMessages({ | |||
39 | }, | 39 | }, |
40 | }); | 40 | }); |
41 | 41 | ||
42 | class Password extends Component { | 42 | interface IProps extends WrappedComponentProps { |
43 | static propTypes = { | 43 | onSubmit: (...args: any[]) => void; |
44 | onSubmit: PropTypes.func.isRequired, | 44 | isSubmitting: boolean; |
45 | isSubmitting: PropTypes.bool.isRequired, | 45 | signupRoute: string; |
46 | signupRoute: PropTypes.string.isRequired, | 46 | loginRoute: string; |
47 | loginRoute: PropTypes.string.isRequired, | 47 | status: string[]; |
48 | status: MobxPropTypes.arrayOrObservableArray.isRequired, | 48 | } |
49 | }; | 49 | |
50 | @observer | ||
51 | class Password extends Component<IProps> { | ||
52 | form: Form; | ||
53 | |||
54 | constructor(props: IProps) { | ||
55 | super(props); | ||
50 | 56 | ||
51 | form = (() => { | 57 | this.form = new Form({ |
52 | const { intl } = this.props; | 58 | fields: { |
53 | return new Form( | 59 | email: { |
54 | { | 60 | label: this.props.intl.formatMessage(messages.emailLabel), |
55 | fields: { | 61 | value: '', |
56 | email: { | 62 | validators: [required, email], |
57 | label: intl.formatMessage(messages.emailLabel), | ||
58 | value: '', | ||
59 | validators: [required, email], | ||
60 | }, | ||
61 | }, | 63 | }, |
62 | }, | 64 | }, |
63 | intl, | 65 | }); |
64 | ); | 66 | } |
65 | })(); | ||
66 | 67 | ||
67 | submit(e) { | 68 | submit(e: FormEvent<HTMLFormElement>): void { |
68 | e.preventDefault(); | 69 | e.preventDefault(); |
69 | this.form.submit({ | 70 | this.form.submit({ |
70 | onSuccess: form => { | 71 | onSuccess: form => { |
@@ -76,8 +77,7 @@ class Password extends Component { | |||
76 | 77 | ||
77 | render() { | 78 | render() { |
78 | const { form } = this; | 79 | const { form } = this; |
79 | const { intl } = this.props; | 80 | const { isSubmitting, signupRoute, loginRoute, status, intl } = this.props; |
80 | const { isSubmitting, signupRoute, loginRoute, status } = this.props; | ||
81 | 81 | ||
82 | return ( | 82 | return ( |
83 | <div className="auth__container"> | 83 | <div className="auth__container"> |
@@ -91,7 +91,7 @@ class Password extends Component { | |||
91 | {intl.formatMessage(messages.successInfo)} | 91 | {intl.formatMessage(messages.successInfo)} |
92 | </Infobox> | 92 | </Infobox> |
93 | )} | 93 | )} |
94 | <Input field={form.$('email')} focus /> | 94 | <Input {...form.$('email').bind()} focus /> |
95 | {status.length > 0 && status.includes('no-user') && ( | 95 | {status.length > 0 && status.includes('no-user') && ( |
96 | <p className="error-message center"> | 96 | <p className="error-message center"> |
97 | {intl.formatMessage(messages.noUser)} | 97 | {intl.formatMessage(messages.noUser)} |
@@ -103,6 +103,7 @@ class Password extends Component { | |||
103 | buttonType="secondary" | 103 | buttonType="secondary" |
104 | label={`${intl.formatMessage(globalMessages.submit)} ...`} | 104 | label={`${intl.formatMessage(globalMessages.submit)} ...`} |
105 | loaded={false} | 105 | loaded={false} |
106 | onClick={noop} | ||
106 | disabled | 107 | disabled |
107 | /> | 108 | /> |
108 | ) : ( | 109 | ) : ( |
@@ -110,6 +111,7 @@ class Password extends Component { | |||
110 | type="submit" | 111 | type="submit" |
111 | className="auth__button" | 112 | className="auth__button" |
112 | label={intl.formatMessage(globalMessages.submit)} | 113 | label={intl.formatMessage(globalMessages.submit)} |
114 | onClick={noop} | ||
113 | /> | 115 | /> |
114 | )} | 116 | )} |
115 | </form> | 117 | </form> |
@@ -124,4 +126,4 @@ class Password extends Component { | |||
124 | } | 126 | } |
125 | } | 127 | } |
126 | 128 | ||
127 | export default injectIntl(observer(Password)); | 129 | export default injectIntl(Password); |
diff --git a/src/components/auth/Signup.jsx b/src/components/auth/Signup.tsx index e0337656c..af14430aa 100644 --- a/src/components/auth/Signup.jsx +++ b/src/components/auth/Signup.tsx | |||
@@ -1,20 +1,18 @@ | |||
1 | /* eslint jsx-a11y/anchor-is-valid: 0 */ | ||
2 | import { Component } from 'react'; | 1 | import { Component } from 'react'; |
3 | import PropTypes from 'prop-types'; | ||
4 | import { observer, inject } from 'mobx-react'; | 2 | import { observer, inject } from 'mobx-react'; |
5 | import { defineMessages, injectIntl } from 'react-intl'; | 3 | import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl'; |
6 | |||
7 | import { mdiArrowLeftCircle } from '@mdi/js'; | 4 | import { mdiArrowLeftCircle } from '@mdi/js'; |
5 | import { noop } from 'lodash'; | ||
8 | import Form from '../../lib/Form'; | 6 | import Form from '../../lib/Form'; |
9 | import { required, email, minLength } from '../../helpers/validation-helpers'; | 7 | import { required, email, minLength } from '../../helpers/validation-helpers'; |
10 | import Input from '../ui/Input'; | 8 | import Input from '../ui/input/index'; |
11 | import Button from '../ui/button'; | 9 | import Button from '../ui/button'; |
12 | import Link from '../ui/Link'; | 10 | import Link from '../ui/Link'; |
13 | import Icon from '../ui/icon'; | 11 | import Icon from '../ui/icon'; |
14 | |||
15 | import { globalError as globalErrorPropType } from '../../prop-types'; | ||
16 | import { serverBase } from '../../api/apiBase'; | 12 | import { serverBase } from '../../api/apiBase'; |
17 | import { H1 } from '../ui/headline'; | 13 | import { H1 } from '../ui/headline'; |
14 | import { GlobalError } from '../../@types/ferdium-components.types'; | ||
15 | import { Actions } from '../../actions/lib/actions'; | ||
18 | 16 | ||
19 | const messages = defineMessages({ | 17 | const messages = defineMessages({ |
20 | headline: { | 18 | headline: { |
@@ -33,10 +31,10 @@ const messages = defineMessages({ | |||
33 | id: 'signup.email.label', | 31 | id: 'signup.email.label', |
34 | defaultMessage: 'Email address', | 32 | defaultMessage: 'Email address', |
35 | }, | 33 | }, |
36 | // companyLabel: { | 34 | companyLabel: { |
37 | // id: 'signup.company.label', | 35 | id: 'signup.company.label', |
38 | // defaultMessage: 'Company', | 36 | defaultMessage: 'Company', |
39 | // }, | 37 | }, |
40 | passwordLabel: { | 38 | passwordLabel: { |
41 | id: 'signup.password.label', | 39 | id: 'signup.password.label', |
42 | defaultMessage: 'Password', | 40 | defaultMessage: 'Password', |
@@ -67,45 +65,48 @@ const messages = defineMessages({ | |||
67 | }, | 65 | }, |
68 | }); | 66 | }); |
69 | 67 | ||
70 | class Signup extends Component { | 68 | interface IProps extends WrappedComponentProps { |
71 | static propTypes = { | 69 | onSubmit: (...args: any[]) => void; |
72 | onSubmit: PropTypes.func.isRequired, | 70 | isSubmitting: boolean; |
73 | isSubmitting: PropTypes.bool.isRequired, | 71 | loginRoute: string; |
74 | loginRoute: PropTypes.string.isRequired, | 72 | error: GlobalError; |
75 | error: globalErrorPropType.isRequired, | 73 | actions?: Actions; |
76 | }; | 74 | } |
77 | 75 | ||
78 | form = (() => { | 76 | @inject('actions') |
79 | const { intl } = this.props; | 77 | @observer |
80 | return new Form( | 78 | class Signup extends Component<IProps> { |
81 | { | 79 | form: Form; |
82 | fields: { | 80 | |
83 | firstname: { | 81 | constructor(props: IProps) { |
84 | label: intl.formatMessage(messages.firstnameLabel), | 82 | super(props); |
85 | value: '', | 83 | |
86 | validators: [required], | 84 | this.form = new Form({ |
87 | }, | 85 | fields: { |
88 | lastname: { | 86 | firstname: { |
89 | label: intl.formatMessage(messages.lastnameLabel), | 87 | label: this.props.intl.formatMessage(messages.firstnameLabel), |
90 | value: '', | 88 | value: '', |
91 | validators: [required], | 89 | validators: [required], |
92 | }, | 90 | }, |
93 | email: { | 91 | lastname: { |
94 | label: intl.formatMessage(messages.emailLabel), | 92 | label: this.props.intl.formatMessage(messages.lastnameLabel), |
95 | value: '', | 93 | value: '', |
96 | validators: [required, email], | 94 | validators: [required], |
97 | }, | 95 | }, |
98 | password: { | 96 | email: { |
99 | label: intl.formatMessage(messages.passwordLabel), | 97 | label: this.props.intl.formatMessage(messages.emailLabel), |
100 | value: '', | 98 | value: '', |
101 | validators: [required, minLength(6)], | 99 | validators: [required, email], |
102 | type: 'password', | 100 | }, |
103 | }, | 101 | password: { |
102 | label: this.props.intl.formatMessage(messages.passwordLabel), | ||
103 | value: '', | ||
104 | validators: [required, minLength(6)], | ||
105 | type: 'password', | ||
104 | }, | 106 | }, |
105 | }, | 107 | }, |
106 | intl, | 108 | }); |
107 | ); | 109 | } |
108 | })(); | ||
109 | 110 | ||
110 | submit(e) { | 111 | submit(e) { |
111 | e.preventDefault(); | 112 | e.preventDefault(); |
@@ -138,12 +139,12 @@ class Signup extends Component { | |||
138 | </Link> | 139 | </Link> |
139 | <H1>{intl.formatMessage(messages.headline)}</H1> | 140 | <H1>{intl.formatMessage(messages.headline)}</H1> |
140 | <div className="grid__row"> | 141 | <div className="grid__row"> |
141 | <Input field={form.$('firstname')} focus /> | 142 | <Input {...form.$('firstname').bind()} focus /> |
142 | <Input field={form.$('lastname')} /> | 143 | <Input {...form.$('lastname').bind()} /> |
143 | </div> | 144 | </div> |
144 | <Input field={form.$('email')} /> | 145 | <Input {...form.$('email').bind()} /> |
145 | <Input | 146 | <Input |
146 | field={form.$('password')} | 147 | {...form.$('password').bind()} |
147 | showPasswordToggle | 148 | showPasswordToggle |
148 | scorePassword | 149 | scorePassword |
149 | /> | 150 | /> |
@@ -158,12 +159,14 @@ class Signup extends Component { | |||
158 | label={`${intl.formatMessage(messages.submitButtonLabel)} ...`} | 159 | label={`${intl.formatMessage(messages.submitButtonLabel)} ...`} |
159 | loaded={false} | 160 | loaded={false} |
160 | disabled | 161 | disabled |
162 | onClick={noop} | ||
161 | /> | 163 | /> |
162 | ) : ( | 164 | ) : ( |
163 | <Button | 165 | <Button |
164 | type="submit" | 166 | type="submit" |
165 | className="auth__button" | 167 | className="auth__button" |
166 | label={intl.formatMessage(messages.submitButtonLabel)} | 168 | label={intl.formatMessage(messages.submitButtonLabel)} |
169 | onClick={noop} | ||
167 | /> | 170 | /> |
168 | )} | 171 | )} |
169 | <p className="legal"> | 172 | <p className="legal"> |
@@ -203,4 +206,4 @@ class Signup extends Component { | |||
203 | } | 206 | } |
204 | } | 207 | } |
205 | 208 | ||
206 | export default injectIntl(inject('actions')(observer(Signup))); | 209 | export default injectIntl(Signup); |