on 5ca3bf8 help sign in
bridge/src/views/Login.js
153 lines 4.1 kB history raw
1import React, { useCallback, useState } from 'react';
2import { P, H4, H5, Grid, Text, Button, Flex, LinkButton } from 'indigo-react';
3import { Just } from 'folktale/maybe';
4import ob from 'urbit-ob';
6import { version } from '../../package.json';
8import { useHistory } from 'store/history';
9import { useWallet } from 'store/wallet';
10import { usePointCursor } from 'store/pointCursor';
12import { WALLET_TYPES } from 'lib/wallet';
13import { COMMANDS, useFlowCommand } from 'lib/flowCommand';
15import View from 'components/View';
16import Tabs from 'components/Tabs';
17import Crumbs from 'components/Crumbs';
18import Footer from 'components/Footer';
19import { ForwardButton, OfflineButton } from 'components/Buttons';
21import Ticket from './Login/Ticket';
22import Other from './Login/Other';
24const NAMES = {
25 TICKET: 'TICKET',
26 OTHER: 'OTHER',
27};
29const VIEWS = {
30 [NAMES.TICKET]: Ticket,
31 [NAMES.OTHER]: Other,
32};
34const OPTIONS = [
35 { text: 'Master Ticket', value: NAMES.TICKET },
36 { text: 'Other', value: NAMES.OTHER },
37];
39const walletTypeToViewName = walletType => {
40 if (walletType === WALLET_TYPES.TICKET || !walletType) {
41 return NAMES.TICKET;
42 }
43 return NAMES.OTHER;
44};
46export default function Login() {
47 // globals
48 const { pop, push, names } = useHistory();
49 const { walletType } = useWallet();
50 const { setPointCursor } = usePointCursor();
51 const flow = useFlowCommand();
53 // inputs
54 const [isOther, setisOther] = useState(false);
56 const goToActivate = useCallback(() => push(names.ACTIVATE), [
57 push,
58 names.ACTIVATE,
59 ]);
61 const goHome = useCallback(() => {
62 if (!flow) {
63 push(names.POINTS);
64 } else {
65 switch (flow.kind) {
66 case COMMANDS.INVITE:
67 setPointCursor(Just(ob.patp2dec(flow.as)));
68 push(names.JUST_INVITE);
69 break;
70 //
71 default:
72 throw new Error('unimplemented flow ' + flow.kind);
73 break;
74 }
75 }
76 }, [flow, push, names]);
78 const flowDescription = command => {
79 switch (command.kind) {
80 case COMMANDS.INVITE:
81 return (
82 <>
83 To send an invite, please sign in as <b>{command.as}</b>.
84 </>
85 );
86 break;
87 }
88 };
90 return (
91 <View inset>
92 <Grid>
93 <Grid.Item full as={Text} className="flex justify-center mt9 mb7">
94 <Grid.Item as={Text} className="gray3">
95 Urbit ID /&nbsp;
96 </Grid.Item>
97 <Grid.Item as={Text}>Login</Grid.Item>
98 </Grid.Item>
99 {flow && (
100 <Grid.Item full as={Text} className="t-center mb4">
101 {flowDescription(flow)}
102 </Grid.Item>
103 )}
104 <Grid.Item full as={isOther ? Other : Ticket} goHome={goHome} />
105 {!isOther && (
106 <>
107 <Grid.Item full className="t-center mv4 gray4">
108 or
109 </Grid.Item>
110 <Grid.Item
111 full
112 as={Button}
113 className="b-solid b1 b-black"
114 center
115 onClick={() => setisOther(true)}>
116 Metamask, Mnemonic, Hardware Wallet...
117 </Grid.Item>
118 {!flow && (
119 <Grid.Item
120 full
121 onClick={goToActivate}
122 className="mv10 t-center f6">
123 <span className="gray4">New Urbit ID? </span>
124 <LinkButton>Activate</LinkButton>
125 </Grid.Item>
126 )}
127 </>
128 )}
129 {isOther && (
130 <Grid.Item
131 as={LinkButton}
132 onClick={() => setisOther(false)}
133 full
134 className="t-center underline f6 mt8">
135 Back
136 </Grid.Item>
137 )}
138 </Grid>
140 <Footer>
141 <Flex className="mb8 f6" justify="between">
142 <Flex.Item
143 as="a"
144 href="https://github.com/urbit/bridge/releases"
145 className="us-none pointer">
146 <span className="underline">Offline</span> ↗
147 </Flex.Item>
148 <Flex.Item className="gray4">v{version}</Flex.Item>
149 </Flex>
150 </Footer>
151 </View>
152 );