diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/auth/Invite.js | 48 | ||||
-rw-r--r-- | src/helpers/validation-helpers.js | 2 | ||||
-rw-r--r-- | src/i18n/locales/en-US.json | 1 | ||||
-rw-r--r-- | src/lib/Form.js | 5 | ||||
-rw-r--r-- | src/models/User.js | 2 | ||||
-rw-r--r-- | src/styles/invite.scss | 4 | ||||
-rw-r--r-- | src/styles/main.scss | 1 |
7 files changed, 48 insertions, 15 deletions
diff --git a/src/components/auth/Invite.js b/src/components/auth/Invite.js index d4d789781..1fe594d73 100644 --- a/src/components/auth/Invite.js +++ b/src/components/auth/Invite.js | |||
@@ -30,6 +30,10 @@ const messages = defineMessages({ | |||
30 | id: 'invite.skip.label', | 30 | id: 'invite.skip.label', |
31 | defaultMessage: '!!!I want to do this later', | 31 | defaultMessage: '!!!I want to do this later', |
32 | }, | 32 | }, |
33 | noEmailAddresses: { | ||
34 | id: 'invite.error.noEmails', | ||
35 | defaultMessage: '!!!At least one email address is required', | ||
36 | } | ||
33 | }); | 37 | }); |
34 | 38 | ||
35 | @observer | 39 | @observer |
@@ -45,17 +49,17 @@ export default class Invite extends Component { | |||
45 | form = new Form({ | 49 | form = new Form({ |
46 | fields: { | 50 | fields: { |
47 | invite: [...Array(3).fill({ | 51 | invite: [...Array(3).fill({ |
48 | name: { | 52 | fields: { |
49 | label: this.context.intl.formatMessage(messages.nameLabel), | 53 | name: { |
50 | // value: '', | 54 | label: this.context.intl.formatMessage(messages.nameLabel), |
51 | placeholder: this.context.intl.formatMessage(messages.nameLabel), | 55 | placeholder: this.context.intl.formatMessage(messages.nameLabel), |
52 | }, | 56 | }, |
53 | email: { | 57 | email: { |
54 | label: this.context.intl.formatMessage(messages.emailLabel), | 58 | label: this.context.intl.formatMessage(messages.emailLabel), |
55 | // value: '', | 59 | placeholder: this.context.intl.formatMessage(messages.emailLabel), |
56 | validate: [email], | 60 | validators: [email], |
57 | placeholder: this.context.intl.formatMessage(messages.emailLabel), | 61 | } |
58 | }, | 62 | } |
59 | })], | 63 | })], |
60 | }, | 64 | }, |
61 | }, this.context.intl); | 65 | }, this.context.intl); |
@@ -64,10 +68,22 @@ export default class Invite extends Component { | |||
64 | e.preventDefault(); | 68 | e.preventDefault(); |
65 | this.form.submit({ | 69 | this.form.submit({ |
66 | onSuccess: (form) => { | 70 | onSuccess: (form) => { |
71 | |||
67 | this.props.onSubmit({ | 72 | this.props.onSubmit({ |
68 | invites: form.values().invite, | 73 | invites: form.values().invite, |
69 | from: this.props.from | 74 | from: this.props.from |
70 | }); | 75 | }); |
76 | |||
77 | const atLeastOneEmailAddress = form.$('invite') | ||
78 | .map(invite => {return invite.$('email').value}) | ||
79 | .some(email => email.trim() !== '') | ||
80 | |||
81 | if (!atLeastOneEmailAddress) { | ||
82 | form.invalidate('no-email-addresses') | ||
83 | return | ||
84 | } | ||
85 | |||
86 | this.props.onSubmit({ invites: form.values().invite }); | ||
71 | }, | 87 | }, |
72 | onError: () => {}, | 88 | onError: () => {}, |
73 | }); | 89 | }); |
@@ -78,6 +94,10 @@ export default class Invite extends Component { | |||
78 | const { intl } = this.context; | 94 | const { intl } = this.context; |
79 | const { from } = this.props; | 95 | const { from } = this.props; |
80 | 96 | ||
97 | const atLeastOneEmailAddress = form.$('invite') | ||
98 | .map(invite => {return invite.$('email').value}) | ||
99 | .some(email => email.trim() !== '') | ||
100 | |||
81 | return ( | 101 | return ( |
82 | <div className="auth__container auth__container--signup"> | 102 | <div className="auth__container auth__container--signup"> |
83 | <form className="franz-form auth__form" onSubmit={e => this.submit(e)}> | 103 | <form className="franz-form auth__form" onSubmit={e => this.submit(e)}> |
@@ -97,9 +117,15 @@ export default class Invite extends Component { | |||
97 | </div> | 117 | </div> |
98 | </div> | 118 | </div> |
99 | ))} | 119 | ))} |
120 | {form.error === 'no-email-addresses' && ( | ||
121 | <p className="franz-form__error invite-form__error"> | ||
122 | {intl.formatMessage(messages.noEmailAddresses)} | ||
123 | </p> | ||
124 | )} | ||
100 | <Button | 125 | <Button |
101 | type="submit" | 126 | type="submit" |
102 | className="auth__button" | 127 | className="auth__button" |
128 | disabled={!atLeastOneEmailAddress} | ||
103 | label={intl.formatMessage(messages.submitButtonLabel)} | 129 | label={intl.formatMessage(messages.submitButtonLabel)} |
104 | /> | 130 | /> |
105 | <Link | 131 | <Link |
diff --git a/src/helpers/validation-helpers.js b/src/helpers/validation-helpers.js index eeb12cab7..a8a242d54 100644 --- a/src/helpers/validation-helpers.js +++ b/src/helpers/validation-helpers.js | |||
@@ -13,7 +13,7 @@ export function email({ field }) { | |||
13 | isValid = true; | 13 | isValid = true; |
14 | } | 14 | } |
15 | 15 | ||
16 | return [isValid, `${field.label} is not a valid email address`]; | 16 | return [isValid, `${field.label} not valid`]; |
17 | } | 17 | } |
18 | 18 | ||
19 | export function url({ field }) { | 19 | export function url({ field }) { |
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 6162455bb..c9e9b860b 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json | |||
@@ -45,6 +45,7 @@ | |||
45 | "invite.name.label": "Name", | 45 | "invite.name.label": "Name", |
46 | "invite.email.label": "Email address", | 46 | "invite.email.label": "Email address", |
47 | "invite.skip.label": "I want to do this later", | 47 | "invite.skip.label": "I want to do this later", |
48 | "invite.error.noEmails": "At least one email address is required", | ||
48 | "subscription.submit.label": "I want to support the development of Franz", | 49 | "subscription.submit.label": "I want to support the development of Franz", |
49 | "subscription.paymentSessionError": "Could not initialize payment form", | 50 | "subscription.paymentSessionError": "Could not initialize payment form", |
50 | "subscription.includedFeatures": "Paid Franz Premium Supporter Account includes", | 51 | "subscription.includedFeatures": "Paid Franz Premium Supporter Account includes", |
diff --git a/src/lib/Form.js b/src/lib/Form.js index a22699b45..9b8321948 100644 --- a/src/lib/Form.js +++ b/src/lib/Form.js | |||
@@ -21,8 +21,9 @@ export default class DefaultForm extends Form { | |||
21 | 21 | ||
22 | options() { | 22 | options() { |
23 | return { | 23 | return { |
24 | validateOnInit: false, | 24 | validateOnInit: false, // default: true |
25 | // validateOnBlur: true, | 25 | // validateOnBlur: true, // default: true |
26 | // validateOnChange: true // default: false | ||
26 | // // validationDebounceWait: { | 27 | // // validationDebounceWait: { |
27 | // // trailing: true, | 28 | // // trailing: true, |
28 | // // }, | 29 | // // }, |
diff --git a/src/models/User.js b/src/models/User.js index 2e5df4795..d2a455e20 100644 --- a/src/models/User.js +++ b/src/models/User.js | |||
@@ -10,7 +10,7 @@ export default class User { | |||
10 | @observable emailIsConfirmed = true; // better assume it's confirmed to avoid noise | 10 | @observable emailIsConfirmed = true; // better assume it's confirmed to avoid noise |
11 | @observable subscription = {}; | 11 | @observable subscription = {}; |
12 | @observable isSubscriptionOwner = false; | 12 | @observable isSubscriptionOwner = false; |
13 | @observable isPremium = false; | 13 | @observable isPremium = true; |
14 | @observable beta = false; | 14 | @observable beta = false; |
15 | @observable donor = {}; | 15 | @observable donor = {}; |
16 | @observable isDonor = false; | 16 | @observable isDonor = false; |
diff --git a/src/styles/invite.scss b/src/styles/invite.scss new file mode 100644 index 000000000..345095da8 --- /dev/null +++ b/src/styles/invite.scss | |||
@@ -0,0 +1,4 @@ | |||
1 | .invite-form__error { | ||
2 | text-align: center; | ||
3 | margin-bottom: 20px !important; /* otherwise overridden by rule: p:last-of-type */ | ||
4 | } | ||
diff --git a/src/styles/main.scss b/src/styles/main.scss index 261396f6f..20f1803e4 100644 --- a/src/styles/main.scss +++ b/src/styles/main.scss | |||
@@ -18,6 +18,7 @@ $mdi-font-path: '../node_modules/mdi/fonts'; | |||
18 | @import './type.scss'; | 18 | @import './type.scss'; |
19 | @import './welcome.scss'; | 19 | @import './welcome.scss'; |
20 | @import './auth.scss'; | 20 | @import './auth.scss'; |
21 | @import './invite.scss'; | ||
21 | @import './tooltip.scss'; | 22 | @import './tooltip.scss'; |
22 | @import './info-bar.scss'; | 23 | @import './info-bar.scss'; |
23 | @import './status-bar-target-url.scss'; | 24 | @import './status-bar-target-url.scss'; |