@@ -1,4 +1,5 @@
11import React, { useState, useCallback } from 'react';
2+import cn from 'classnames';
23import { Grid, H4, Text, ErrorText } from 'indigo-react';
34
45import { useNetwork } from 'store/network';
@@ -18,13 +19,19 @@ import LoadingBar from 'components/LoadingBar';
1819import Highlighted from 'components/Highlighted';
1920
2021import { useActivateFlow } from './ActivateFlow';
22+import { RestartButton } from 'components/Buttons';
2123
22−export default function PassportTransfer({ className }) {
24+export default function PassportTransfer({ className, resetActivateRouter }) {
2325 const { replaceWith, names } = useHistory();
2426 const { setUrbitWallet } = useWallet();
2527 const { setPointCursor } = usePointCursor();
2628 const { web3, contracts } = useNetwork();
27− const { derivedWallet, derivedPoint, inviteWallet } = useActivateFlow();
29+ const {
30+ derivedWallet,
31+ derivedPoint,
32+ inviteWallet,
33+ reset: resetActivateFlow,
34+ } = useActivateFlow();
2835 const [generalError, setGeneralError] = useState();
2936 const [{ label, progress }, setState] = useState({
3037 label: 'Verify Passport',
@@ -43,10 +50,21 @@ export default function PassportTransfer({ className }) {
4350 [replaceWith, names]
4451 );
4552
46− const goToRestart = useCallback(
47− () => replaceWith([{ key: names.LANDING }, { key: names.ACTIVATE }]),
48− [replaceWith, names]
49− );
53+ const goToRestart = useCallback(() => {
54+ // NOTE: because we're already on the ACTIVATE view in the history,
55+ // react (intelligently) doesn't trigger a re-render and that means the
56+ // current state of the two nested routers (activate & passport) stick
57+ // around unless we manually clear them.
58+ // we only need to clear activate because that will unmount the passport
59+ // router (which will be set to initialRoutes when mounted again)
60+
61+ // 1) replace history
62+ replaceWith([{ key: names.LANDING }, { key: names.ACTIVATE }]);
63+ // 2) reset local router
64+ resetActivateRouter();
65+ // 3) clear the state
66+ resetActivateFlow();
67+ }, [replaceWith, names, resetActivateRouter, resetActivateFlow]);
5068
5169 const handleUpdate = useCallback(
5270 ({ type, state, value }) => {
@@ -65,13 +83,15 @@ export default function PassportTransfer({ className }) {
6583 );
6684
6785 const claimPoint = useCallback(async () => {
68− const _inviteWallet = need.wallet(inviteWallet);
69− const _wallet = need.wallet(derivedWallet);
70− const _point = need.point(derivedPoint);
71− const _web3 = need.web3(web3);
72− const _contracts = need.contracts(contracts);
86+ setGeneralError(false);
7387
7488 try {
89+ const _inviteWallet = need.wallet(inviteWallet);
90+ const _wallet = need.wallet(derivedWallet);
91+ const _point = need.point(derivedPoint);
92+ const _web3 = need.web3(web3);
93+ const _contracts = need.contracts(contracts);
94+
7595 await claimPointFromInvite({
7696 inviteWallet: _inviteWallet,
7797 wallet: _wallet,
@@ -80,11 +100,13 @@ export default function PassportTransfer({ className }) {
80100 contracts: _contracts,
81101 onUpdate: handleUpdate,
82102 });
103+
83104 // set the global wallet
84105 setUrbitWallet(derivedWallet);
85106 setPointCursor(derivedPoint);
86− await timeout(3000);
107+
87108 // and redirect to login
109+ await timeout(3000);
88110 goToLogin();
89111 } catch (error) {
90112 // some generic error
@@ -106,13 +128,54 @@ export default function PassportTransfer({ className }) {
106128 claimPoint();
107129 });
108130
131+ const renderAdditionalInfo = () => {
132+ if (generalError) {
133+ return (
134+ <>
135+ <Grid.Item full className="mt8">
136+ <ErrorText>{generalError.message.toString()}</ErrorText>
137+ </Grid.Item>
138+ <Grid.Item
139+ full
140+ className="mt3"
141+ as={RestartButton}
142+ onClick={goToRestart}
143+ />
144+ </>
145+ );
146+ }
147+
148+ if (needFunds) {
149+ return (
150+ <Grid.Item full className="mt8">
151+ <Highlighted>
152+ The address {needFunds.address} needs at least{' '}
153+ {fromWei(needFunds.minBalance)} ETH and currently has{' '}
154+ {fromWei(needFunds.balance)} ETH. Waiting until the account has
155+ enough funds.
156+ </Highlighted>
157+ </Grid.Item>
158+ );
159+ }
160+
161+ if (progress < 100) {
162+ return (
163+ <Grid.Item full as={WarningBox} className="mt8">
164+ Never give your Master Ticket to anyone
165+ </Grid.Item>
166+ );
167+ }
168+
169+ return null;
170+ };
171+
109172 return (
110− <Grid gap={4} className={className}>
111− <Grid.Item full as={Steps} num={2} total={3} />
173+ <Grid className={cn(className, 'auto-rows-min')}>
174+ <Grid.Item full as={Steps} num={3} total={3} />
112175 <Grid.Item full as={H4}>
113176 {label}
114177 </Grid.Item>
115− <Grid.Item full as={Grid}>
178+ <Grid.Item full as={Grid} className="mt3" gap={3}>
116179 <Grid.Item full as={LoadingBar} progress={progress} />
117180 <Grid.Item full>
118181 <Text className="f5 green4">
@@ -122,28 +185,7 @@ export default function PassportTransfer({ className }) {
122185 </Grid.Item>
123186 </Grid.Item>
124187
125− {progress < 0 && (
126− <Grid.Item full as={WarningBox}>
127− Never give your Master Ticket to anyone
128− </Grid.Item>
129− )}
130−
131− {needFunds && (
132− <Grid.Item full>
133− <Highlighted>
134− The address {needFunds.address} needs at least{' '}
135− {fromWei(needFunds.minBalance)} ETH and currently has{' '}
136− {fromWei(needFunds.balance)} ETH. Waiting until the account has
137− enough funds.
138− </Highlighted>
139− </Grid.Item>
140− )}
141−
142− {generalError && (
143− <Grid.Item full>
144− <ErrorText>{generalError.message.toString()}</ErrorText>
145− </Grid.Item>
146− )}
188+ {renderAdditionalInfo()}
147189 </Grid>
148190 );
149191}