on fe6ee13 help sign in
bridge/src/views/Point.js
261 lines 7.3 kB history raw
1import React, { useCallback, useState } from 'react';
2import cn from 'classnames';
3import { Just } from 'folktale/maybe';
4import { Grid, Flex, Button } from 'indigo-react';
5import { azimuth } from 'azimuth-js';
7import { usePointCursor } from 'store/pointCursor';
8import { useWallet } from 'store/wallet';
10import View from 'components/View';
11import Greeting from 'components/Greeting';
12import Passport from 'components/Passport';
13import { ForwardButton, BootUrbitOSButton } from 'components/Buttons';
14import CopyButton from 'components/CopyButton';
15import Blinky, { matchBlinky } from 'components/Blinky';
16import BarGraph from 'components/BarGraph';
17import Chip from 'components/Chip';
18import InviteSigilList from 'components/InviteSigilList';
20import * as need from 'lib/need';
21import useInvites from 'lib/useInvites';
22import { useSyncOwnedPoints } from 'lib/useSyncPoints';
23import useCurrentPermissions from 'lib/useCurrentPermissions';
24import { useLocalRouter } from 'lib/LocalRouter';
25import useKeyfileGenerator from 'lib/useKeyfileGenerator';
27import Inviter from 'views/Invite/Inviter';
29export default function Point() {
30 const { pop, push, names } = useLocalRouter();
31 const { pointCursor } = usePointCursor();
33 const { wallet } = useWallet();
34 const point = need.point(pointCursor);
36 const { code, notice } = useKeyfileGenerator();
38 const {
39 isParent,
40 isActiveOwner,
41 canManage,
42 canSpawn,
43 canVote,
44 isOwner,
45 } = useCurrentPermissions();
47 // fetch the invites for the current cursor
48 const invites = useInvites(point);
49 const {
50 availableInvites,
51 sentInvites,
52 acceptedInvites,
53 pendingPoints,
54 acceptedPoints,
55 } = invites;
57 const showInvites = !(
58 acceptedInvites.getOrElse(0) === 0 && sentInvites.getOrElse(0) === 0
59 );
61 const hasInvites = showInvites || availableInvites.getOrElse(0) !== 0;
63 const _totalInvites =
64 sentInvites.getOrElse(0) + availableInvites.getOrElse(0);
65 const _pendingInvites = pendingPoints.getOrElse([]).length;
67 const loadedInvites = Just.hasInstance(availableInvites);
68 //
69 // availableInvites.getOrElse(0) === 0
71 const goAdmin = useCallback(() => push(names.ADMIN), [push, names]);
73 const goSenate = useCallback(() => push(names.SENATE), [push, names]);
75 const goSigil = useCallback(() => push(names.SIGIL_GENERATOR), [push, names]);
77 const goCohort = useCallback(() => push(names.INVITE_COHORT), [push, names]);
79 const goPartiesSetPoolSize = useCallback(
80 () => push(names.PARTY_SET_POOL_SIZE),
81 [push, names]
82 );
84 const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
85 names.ISSUE_CHILD,
86 push,
87 ]);
89 const isPlanet = azimuth.getPointSize(point) === azimuth.PointSize.Planet;
91 const [showInviteForm, setShowInviteForm] = useState(false);
93 const inviteButton = (() => {
94 if (azimuth.getPointSize(point) === azimuth.PointSize.Star) {
95 return (
96 <>
97 <Grid.Item
98 full
99 as={ForwardButton}
100 disabled={!isActiveOwner}
101 onClick={goPartiesSetPoolSize}>
102 Manage Invite Pools
103 </Grid.Item>
104 <Grid.Divider />
105 </>
106 );
107 }
109 return null;
110 })();
112 const senateButton = (() => {
113 if (azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy) {
114 return null;
115 }
116 return (
117 <>
118 <Grid.Item
119 full
120 as={ForwardButton}
121 disabled={!canVote}
122 onClick={goSenate}>
123 Senate
124 </Grid.Item>
125 <Grid.Divider />
126 </>
127 );
128 })();
130 // sync the current cursor
131 useSyncOwnedPoints([point]);
133 const address = need.addressFromWallet(wallet);
135 return (
136 <View pop={pop} inset>
137 <Greeting point={point} />
138 <Passport
139 point={Just(point)}
140 address={Just(address)}
141 animationMode={'slide'}
142 />
143 <Grid gap={3}>
144 {isPlanet && hasInvites && (
145 <>
146 <Grid.Item cols={[1, 11]}>
147 Invite Group
148 <br />
149 </Grid.Item>
151 <Grid.Item
152 className={cn('t-right underline pointer-hover', {
153 gray4: sentInvites.getOrElse(0) === 0,
154 })}
155 onClick={goCohort}
156 cols={[11, 13]}>
157 View
158 </Grid.Item>
159 <Grid.Item full>
160 <Flex align="center">
161 <Flex.Item>
162 {acceptedInvites.getOrElse(0)} / {_totalInvites}
163 </Flex.Item>
164 {_pendingInvites > 0 && (
165 <Flex.Item as={Chip} className="bg-yellow1 yellow4">
166 {_pendingInvites} pending
167 </Flex.Item>
168 )}
169 </Flex>
170 </Grid.Item>
172 {showInvites && (
173 <>
174 <Grid.Item
175 full
176 as={BarGraph}
177 available={availableInvites}
178 sent={sentInvites}
179 accepted={acceptedInvites}
180 />
181 <Grid.Item
182 full
183 as={InviteSigilList}
184 pendingPoints={pendingPoints}
185 acceptedPoints={acceptedPoints}
186 />
187 </>
188 )}
189 {!showInvites && (
190 <>
191 <Grid.Item full className="b-gray4 b-dotted b1 self-center">
192 <div className="p4 pv8 t-center gray4">
193 Start your invite group by adding members
194 </div>
195 </Grid.Item>
196 </>
197 )}
198 {!showInviteForm && availableInvites.getOrElse(0) > 0 && isOwner && (
199 <Grid.Item
200 full
201 solid
202 as={Button}
203 center
204 onClick={() => setShowInviteForm(true)}>
205 Add Members
206 </Grid.Item>
207 )}
208 {showInviteForm && <Inviter />}
209 <Grid.Item full className="mb2" />
210 </>
211 )}
212 {!loadedInvites && isPlanet && (
213 <Grid.Item className="mv2" full>
214 Invite Group <Blinky />
215 </Grid.Item>
216 )}
217 </Grid>
218 <Grid className="pt2">
219 {inviteButton}
220 <Grid.Item full as={ForwardButton} onClick={goSigil}>
221 Sigil
222 </Grid.Item>
223 <Grid.Divider />
224 <Grid.Item
225 full
226 as={ForwardButton}
227 disabled={!canManage}
228 onClick={goAdmin}>
229 Admin
230 </Grid.Item>
231 <Grid.Divider />
233 {isParent && (
234 <>
235 <Grid.Item
236 full
237 as={ForwardButton}
238 disabled={!canSpawn}
239 onClick={goIssuePoint}>
240 Issue Point
241 </Grid.Item>
242 <Grid.Divider />
243 </>
244 )}
245 {senateButton}
246 <Grid.Item full as={BootUrbitOSButton} />
247 <Grid.Divider />
248 <Grid.Item
249 full
250 as={ForwardButton}
251 accessory={code && <CopyButton text={code} />}
252 detail={code || notice}
253 disabled={!code}
254 detailClassName="mono">
255 Login Code
256 </Grid.Item>
257 <Grid.Divider />
258 </Grid>
259 </View>
260 );