on master help sign in
Inform users about invite send failures
71e9369Fang
src/bridge/views/InvitesSend.js+28−4
@@ -4,7 +4,7 @@ import * as azimuth from 'azimuth-js'
4
4
5import { BRIDGE_ERROR } from '../lib/error'
5import { BRIDGE_ERROR } from '../lib/error'
6import { hasReceived, sendMail } from '../lib/inviteMail'
6import { hasReceived, sendMail } from '../lib/inviteMail'
7−import { Row, Col, Button, Input } from '../components/Base'
7+import { Row, Col, Button, Input, H3, Warning } from '../components/Base'
8import { addressFromSecp256k1Public } from '../lib/wallet'
8import { addressFromSecp256k1Public } from '../lib/wallet'
9
9
10// for wallet generation
10// for wallet generation
@@ -48,6 +48,7 @@ class InvitesSend extends React.Component {
48 invited: Nothing(),
48 invited: Nothing(),
49 targets: [{ email: '', hasReceived: Nothing(), status: Nothing() }],
49 targets: [{ email: '', hasReceived: Nothing(), status: Nothing() }],
50 status: STATUS.INPUT,
50 status: STATUS.INPUT,
51+ errors: Nothing(),
51 //
52 //
52 invites: []
53 invites: []
53 }
54 }
@@ -206,21 +207,24 @@ class InvitesSend extends React.Component {
206 this.setEmailStatus(i, EMAIL_STATUS.DONE);
207 this.setEmailStatus(i, EMAIL_STATUS.DONE);
207 } else {
208 } else {
208 console.log('email send failed');
209 console.log('email send failed');
209− //TODO tell user to manually send email
210+ this.addError(
211+ 'Invite email failed to send for ' + invite.recipient +
212+ '. Please give them this ticket: ' + invite.ticket
213+ );
210 //TODO but this doesn't catch sender-side failures... we may
214 //TODO but this doesn't catch sender-side failures... we may
211 // just need really good monitoring for that...
215 // just need really good monitoring for that...
212 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
216 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
213 }
217 }
214 } else {
218 } else {
215 console.log('invite tx rejected');
219 console.log('invite tx rejected');
216− //TODO properly inform user?
220+ this.addError('Invite transaction failed for ' + invite.recipient);
217 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
221 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
218 }
222 }
219 });
223 });
220 })
224 })
221 .catch(err => {
225 .catch(err => {
222 console.error('invite tx sending failed', err);
226 console.error('invite tx sending failed', err);
223− //TODO properly inform user?
227+ this.addError('Invite transaction not sent for ' + invite.recipient);
224 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
228 this.setEmailStatus(i, EMAIL_STATUS.FAIL);
225 });
229 });
226 }
230 }
@@ -234,6 +238,14 @@ class InvitesSend extends React.Component {
234 this.setState({ targets });
238 this.setState({ targets });
235 }
239 }
236
240
241+ addError(error) {
242+ const newError = this.state.errors.matchWith({
243+ Nothing: () => [error],
244+ Just: errs => errs.value.push(error)
245+ });
246+ this.setState({ errors: Just(newError) });
247+ }
248+
237 askForFunding(address, minBalance, balance) {
249 askForFunding(address, minBalance, balance) {
238 this.setState({ message: Just(
250 this.setState({ message: Just(
239 `Please make sure ${address} has at least ${minBalance} wei,` +
251 `Please make sure ${address} has at least ${minBalance} wei,` +
@@ -309,6 +321,16 @@ class InvitesSend extends React.Component {
309 }
321 }
310 });
322 });
311
323
324+ let error = this.state.errors.matchWith({
325+ Nothing: () => null,
326+ Just: (errors) => (<Warning className={'mt-8'}>
327+ <H3 style={{marginTop: 0, paddingTop: 0}}>
328+ { 'Something went wrong!' }
329+ </H3>
330+ { errors.value.map(err => (<p>{err}</p>)) }
331+ </Warning>)
332+ });
333+
312 //TODO don't render inputs at all if STATUS.DONE
334 //TODO don't render inputs at all if STATUS.DONE
313
335
314 const inputDisabled = (this.state.status !== STATUS.INPUT);
336 const inputDisabled = (this.state.status !== STATUS.INPUT);
@@ -347,6 +369,8 @@ class InvitesSend extends React.Component {
347
369
348 <ul>{ invitesSent }</ul>
370 <ul>{ invitesSent }</ul>
349
371
372+ { error }
373+
350 <Button
374 <Button
351 prop-size={'s narrow'}
375 prop-size={'s narrow'}
352 className={'mt-8'}
376 className={'mt-8'}