aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar haraldox <hnaumann+github@gmail.com>2018-01-29 12:33:52 +0100
committerLibravatar haraldox <hnaumann+github@gmail.com>2018-01-29 12:33:52 +0100
commit54f63bb93fe742c1d01c95febee303392c0a290a (patch)
treeda9748af37cfa6f00294592f1a6e6cd770aff3a5
parentreturn to account screen from invite screen (diff)
parentalternative UX implementation of check for email address count > 0 (diff)
downloadferdium-app-54f63bb93fe742c1d01c95febee303392c0a290a.tar.gz
ferdium-app-54f63bb93fe742c1d01c95febee303392c0a290a.tar.zst
ferdium-app-54f63bb93fe742c1d01c95febee303392c0a290a.zip
Merge branch 'fix-invite-screen' into feature/invite-button
-rw-r--r--src/components/auth/Invite.js48
-rw-r--r--src/helpers/validation-helpers.js2
-rw-r--r--src/i18n/locales/en-US.json1
-rw-r--r--src/lib/Form.js5
-rw-r--r--src/models/User.js2
-rw-r--r--src/styles/invite.scss4
-rw-r--r--src/styles/main.scss1
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
19export function url({ field }) { 19export 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';