on master help sign in
hinder users from exiting while invite in progress
3bc0841Liam Fitzgerald
src/lib/useBlockWindowClose.js+16
@@ -15,3 +15,19 @@ export default function useBlockWindowClose() {
15 };
15 };
16 });
16 });
17}
17}
18+
19+export function useConditionalBlockWindowClose(condition) {
20+ return useEffect(() => {
21+ if (condition) {
22+ window.addEventListener('beforeunload', onBeforeUnload);
23+ } else {
24+ window.removeEventListener('beforeunload', onBeforeUnload);
25+ }
26+
27+ return function cleanup() {
28+ if (condition) {
29+ window.removeEventListener('beforeunload', onBeforeUnload);
30+ }
31+ };
32+ });
33+}
src/views/Invite/Email.js+5−1
@@ -34,7 +34,7 @@ const STATUS = {
34 FAILURE: 'FAILURE',
34 FAILURE: 'FAILURE',
35};
35};
36
36
37−const InviteMail = () => {
37+const InviteMail = ({ setSubmitting }) => {
38 const { progress, txStatus, needFunds, generateInvites } = useInviter();
38 const { progress, txStatus, needFunds, generateInvites } = useInviter();
39
39
40 const { sendMail, getHasReceived } = useMailer();
40 const { sendMail, getHasReceived } = useMailer();
@@ -75,17 +75,21 @@ const InviteMail = () => {
75 const emailCount = values.emails.length;
75 const emailCount = values.emails.length;
76 setCount(emailCount);
76 setCount(emailCount);
77 setStatus(STATUS.SENDING);
77 setStatus(STATUS.SENDING);
78+ setSubmitting(true);
78 const { errors, invites } = await generateInvites(emailCount);
79 const { errors, invites } = await generateInvites(emailCount);
79 if (errors) {
80 if (errors) {
80 setStatus(STATUS.FAILED);
81 setStatus(STATUS.FAILED);
82+ setSubmitting(false);
81 return errors;
83 return errors;
82 }
84 }
83 const mailErrors = await sendInvites(values.emails, invites);
85 const mailErrors = await sendInvites(values.emails, invites);
84 if (mailErrors) {
86 if (mailErrors) {
85 console.log(mailErrors);
87 console.log(mailErrors);
86 setStatus(STATUS.FAILED);
88 setStatus(STATUS.FAILED);
89+ setSubmitting(false);
87 return mailErrors;
90 return mailErrors;
88 }
91 }
92+ setSubmitting(false);
89 setStatus(STATUS.SUCCESS);
93 setStatus(STATUS.SUCCESS);
90 },
94 },
91 [generateInvites, setCount, setStatus, sendInvites]
95 [generateInvites, setCount, setStatus, sendInvites]
src/views/Invite/Inviter.js+16−2
@@ -1,6 +1,8 @@
1−import React, { useState } from 'react';
1+import React, { useState, useCallback } from 'react';
2import { Grid } from 'indigo-react';
2import { Grid } from 'indigo-react';
3
3
4+import { useConditionalBlockWindowClose } from 'lib/useBlockWindowClose';
5+
4import Tabs from 'components/Tabs';
6import Tabs from 'components/Tabs';
5
7
6import InviteMail from 'views/Invite/Email';
8import InviteMail from 'views/Invite/Email';
@@ -8,6 +10,17 @@ import InviteUrl from 'views/Invite/Url';
8
10
9const Inviter = () => {
11const Inviter = () => {
10 const [tab, setTab] = useState(NAMES.MAIL);
12 const [tab, setTab] = useState(NAMES.MAIL);
13+ const [submitting, setSubmitting] = useState(false);
14+
15+ useConditionalBlockWindowClose(submitting);
16+ const onTabChange = useCallback(
17+ newTab => {
18+ if (!submitting) {
19+ setTab(newTab);
20+ }
21+ },
22+ [submitting, setTab]
23+ );
11 return (
24 return (
12 <Grid.Item
25 <Grid.Item
13 full
26 full
@@ -17,7 +30,8 @@ const Inviter = () => {
17 views={VIEWS}
30 views={VIEWS}
18 options={OPTIONS}
31 options={OPTIONS}
19 currentTab={tab}
32 currentTab={tab}
20− onTabChange={setTab}
33+ onTabChange={onTabChange}
34+ setSubmitting={setSubmitting}
21 />
35 />
22 );
36 );
23};
37};
src/views/Invite/Url.js+7−7
@@ -19,12 +19,13 @@ const STATUS = {
19 FAILURE: 'FAILURE',
19 FAILURE: 'FAILURE',
20};
20};
21
21
22−const InviteUrl = () => {
22+const InviteUrl = ({ setSubmitting }) => {
23 const { txStatus, needFunds, invites, generateInvites } = useInviter();
23 const { txStatus, needFunds, invites, generateInvites } = useInviter();
24
24
25 const [error, setError] = useState();
25 const [error, setError] = useState();
26
26
27 const generateInvite = useCallback(async () => {
27 const generateInvite = useCallback(async () => {
28+ setSubmitting(true);
28 const { errors } = await generateInvites(1);
29 const { errors } = await generateInvites(1);
29 if (hasErrors(errors)) {
30 if (hasErrors(errors)) {
30 setError(errors);
31 setError(errors);
@@ -92,12 +93,11 @@ const InviteUrl = () => {
92 )}
93 )}
93 {invites.length === 0 && renderGenerateButton()}
94 {invites.length === 0 && renderGenerateButton()}
94 {needFunds && <Grid.Item full as={NeedFundsNotice} {...needFunds} />}
95 {needFunds && <Grid.Item full as={NeedFundsNotice} {...needFunds} />}
95− {error[FORM_ERROR] ||
96+ {error && (
96− (error[WARNING] && (
97− <Grid.Item as={ErrorText}>
97+ <Grid.Item as={ErrorText}>
98− {error[FORM_ERROR] || error[WARNING]}
98+ {error[FORM_ERROR] || error[WARNING]}
99− </Grid.Item>
99+ </Grid.Item>
100− ))}
100+ )}
101 </Grid.Item>
101 </Grid.Item>
102 );
102 );
103};
103};