on dc70bbd help sign in
bridge/src/views/Point.js
260 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 } = useCurrentPermissions();
46 // fetch the invites for the current cursor
47 const invites = useInvites(point);
48 const {
49 availableInvites,
50 sentInvites,
51 acceptedInvites,
52 pendingPoints,
53 acceptedPoints,
54 } = invites;
56 const showInvites = !(
57 acceptedInvites.getOrElse(0) === 0 && sentInvites.getOrElse(0) === 0
58 );
60 const hasInvites = showInvites || availableInvites.getOrElse(0) !== 0;
62 const _totalInvites =
63 sentInvites.getOrElse(0) + availableInvites.getOrElse(0);
64 const _pendingInvites = pendingPoints.getOrElse([]).length;
66 const loadedInvites = Just.hasInstance(availableInvites);
67 //
68 // availableInvites.getOrElse(0) === 0
70 const goAdmin = useCallback(() => push(names.ADMIN), [push, names]);
72 const goSenate = useCallback(() => push(names.SENATE), [push, names]);
74 const goSigil = useCallback(() => push(names.SIGIL_GENERATOR), [push, names]);
76 const goCohort = useCallback(() => push(names.INVITE_COHORT), [push, names]);
78 const goPartiesSetPoolSize = useCallback(
79 () => push(names.PARTY_SET_POOL_SIZE),
80 [push, names]
81 );
83 const goIssuePoint = useCallback(() => push(names.ISSUE_CHILD), [
84 names.ISSUE_CHILD,
85 push,
86 ]);
88 const isPlanet = azimuth.getPointSize(point) === azimuth.PointSize.Planet;
90 const [showInviteForm, setShowInviteForm] = useState(false);
92 const inviteButton = (() => {
93 if (azimuth.getPointSize(point) === azimuth.PointSize.Star) {
94 return (
95 <>
96 <Grid.Item
97 full
98 as={ForwardButton}
99 disabled={!isActiveOwner}
100 onClick={goPartiesSetPoolSize}>
101 Manage Invite Pools
102 </Grid.Item>
103 <Grid.Divider />
104 </>
105 );
106 }
108 return null;
109 })();
111 const senateButton = (() => {
112 if (azimuth.getPointSize(point) !== azimuth.PointSize.Galaxy) {
113 return null;
114 }
115 return (
116 <>
117 <Grid.Item
118 full
119 as={ForwardButton}
120 disabled={!canVote}
121 onClick={goSenate}>
122 Senate
123 </Grid.Item>
124 <Grid.Divider />
125 </>
126 );
127 })();
129 // sync the current cursor
130 useSyncOwnedPoints([point]);
132 const address = need.addressFromWallet(wallet);
134 return (
135 <View pop={pop} inset>
136 <Greeting point={point} />
137 <Passport
138 point={Just(point)}
139 address={Just(address)}
140 animationMode={'slide'}
141 />
142 <Grid gap={3}>
143 {isPlanet && hasInvites && (
144 <>
145 <Grid.Item cols={[1, 11]}>
146 Invite Group
147 <br />
148 </Grid.Item>
150 <Grid.Item
151 className={cn('t-right underline pointer-hover', {
152 gray4: sentInvites.getOrElse(0) === 0,
153 })}
154 onClick={goCohort}
155 cols={[11, 13]}>
156 View
157 </Grid.Item>
158 <Grid.Item full>
159 <Flex align="center">
160 <Flex.Item>
161 {acceptedInvites.getOrElse(0)} / {_totalInvites}
162 </Flex.Item>
163 {_pendingInvites > 0 && (
164 <Flex.Item as={Chip} className="bg-yellow1 yellow4">
165 {_pendingInvites} pending
166 </Flex.Item>
167 )}
168 </Flex>
169 </Grid.Item>
171 {showInvites && (
172 <>
173 <Grid.Item
174 full
175 as={BarGraph}
176 available={availableInvites}
177 sent={sentInvites}
178 accepted={acceptedInvites}
179 />
180 <Grid.Item
181 full
182 as={InviteSigilList}
183 pendingPoints={pendingPoints}
184 acceptedPoints={acceptedPoints}
185 />
186 </>
187 )}
188 {!showInvites && (
189 <>
190 <Grid.Item full className="b-gray4 b-dotted b1 self-center">
191 <div className="p4 pv8 t-center gray4">
192 Start your invite group by adding members
193 </div>
194 </Grid.Item>
195 </>
196 )}
197 {!showInviteForm && availableInvites.getOrElse(0) > 0 && (
198 <Grid.Item
199 full
200 solid
201 as={Button}
202 center
203 onClick={() => setShowInviteForm(true)}>
204 Add Members
205 </Grid.Item>
206 )}
207 {showInviteForm && <Inviter />}
208 <Grid.Item full className="mb2" />
209 </>
210 )}
211 {!loadedInvites && isPlanet && (
212 <Grid.Item className="mv2" full>
213 Invite Group <Blinky />
214 </Grid.Item>
215 )}
216 </Grid>
217 <Grid className="pt2">
218 {inviteButton}
219 <Grid.Item full as={ForwardButton} onClick={goSigil}>
220 Sigil
221 </Grid.Item>
222 <Grid.Divider />
223 <Grid.Item
224 full
225 as={ForwardButton}
226 disabled={!canManage}
227 onClick={goAdmin}>
228 Admin
229 </Grid.Item>
230 <Grid.Divider />
232 {isParent && (
233 <>
234 <Grid.Item
235 full
236 as={ForwardButton}
237 disabled={!canSpawn}
238 onClick={goIssuePoint}>
239 Issue Point
240 </Grid.Item>
241 <Grid.Divider />
242 </>
243 )}
244 {senateButton}
245 <Grid.Item full as={BootUrbitOSButton} />
246 <Grid.Divider />
247 <Grid.Item
248 full
249 as={ForwardButton}
250 accessory={code && <CopyButton text={code} />}
251 detail={code || notice}
252 disabled={!code}
253 detailClassName="mono">
254 Login Code
255 </Grid.Item>
256 <Grid.Divider />
257 </Grid>
258 </View>
259 );