@@ -9,22 +9,16 @@ import { usePointCache } from 'store/pointCache';
9import { useWallet } from 'store/wallet';
9import { useWallet } from 'store/wallet';
11import View from 'components/View';
11import View from 'components/View';
12−import Tabs from 'components/Tabs';
13−import BarGraph from 'components/BarGraph';
14import MaybeSigil from 'components/MaybeSigil';
12import MaybeSigil from 'components/MaybeSigil';
15import { matchBlinky } from 'components/Blinky';
13import { matchBlinky } from 'components/Blinky';
16−import Chip from 'components/Chip';
18import { useLocalRouter } from 'lib/LocalRouter';
15import { useLocalRouter } from 'lib/LocalRouter';
19import useInvites from 'lib/useInvites';
16import useInvites from 'lib/useInvites';
20import * as need from 'lib/need';
17import * as need from 'lib/need';
21import * as wg from 'lib/walletgen';
18import * as wg from 'lib/walletgen';
23−import Inviter from 'views/Invite/Inviter';
25import { ReactComponent as SearchIcon } from 'assets/search.svg';
20import { ReactComponent as SearchIcon } from 'assets/search.svg';
26import CopyButton from 'components/copiable/CopyButton';
21import CopyButton from 'components/copiable/CopyButton';
27−import { useSyncDetails } from 'lib/useSyncPoints';
28import { useNetwork } from 'store/network';
22import { useNetwork } from 'store/network';
29import L2BackHeader from 'components/L2/Headers/L2BackHeader';
23import L2BackHeader from 'components/L2/Headers/L2BackHeader';
30import Window from 'components/L2/Window/Window';
24import Window from 'components/L2/Window/Window';
@@ -33,7 +27,6 @@ import { Icon, Row, StatelessTextInput } from '@tlon/indigo-react';
33import BodyPane from 'components/L2/Window/BodyPane';
27import BodyPane from 'components/L2/Window/BodyPane';
34import { useRollerStore } from 'store/roller';
28import { useRollerStore } from 'store/roller';
35import useRoller from 'lib/useRoller';
29import useRoller from 'lib/useRoller';
36−import { convertToInt } from 'lib/convertToInt';
37import FeeDropdown from 'components/L2/Dropdowns/FeeDropdown';
30import FeeDropdown from 'components/L2/Dropdowns/FeeDropdown';
38import LoadingOverlay from 'components/L2/LoadingOverlay';
31import LoadingOverlay from 'components/L2/LoadingOverlay';
39import { generateUrl } from 'lib/utils/invite';
32import { generateUrl } from 'lib/utils/invite';
@@ -41,6 +34,7 @@ import CopiableWithTooltip from 'components/copiable/CopiableWithTooltip';
41import Paginator from 'components/L2/Paginator';
34import Paginator from 'components/L2/Paginator';
43import './Cohort.scss';
36import './Cohort.scss';
37+import useInviter from 'lib/useInviter';
45const INVITES_PER_PAGE = 7;
39const INVITES_PER_PAGE = 7;
46const DEFAULT_NUM_INVITES = 5;
40const DEFAULT_NUM_INVITES = 5;
@@ -298,69 +292,57 @@ export default function InviteCohort() {
298 currentL2,
292 currentL2,
299 pendingTransactions,
293 pendingTransactions,
302 } = useRollerStore();
295 } = useRollerStore();
296+ const { generateInvites } = useInviter();
303− const { generateInviteCodes } = useRoller();
297+ const { generateInviteCodes, getPendingTransactions } = useRoller();
305 const { pointCursor } = usePointCursor();
299 const { pointCursor } = usePointCursor();
306 const point = need.point(pointCursor);
300 const point = need.point(pointCursor);
308− const _point = convertToInt(need.point(pointCursor), 10);
309 const [page, setPage] = useState(0);
302 const [page, setPage] = useState(0);
311− const invitesToDisplay = invites.slice(
304+ const { pendingPoints } = useInvites(point);
306+ const displayedInvites = currentL2 ? invites : pendingPoints.getOrElse([]);
308+ const invitesToDisplay = displayedInvites.slice(
312 page * INVITES_PER_PAGE,
309 page * INVITES_PER_PAGE,
313 (page + 1) * INVITES_PER_PAGE
310 (page + 1) * INVITES_PER_PAGE
322− } = useInvites(point);
324 const hasPending = Boolean(pendingTransactions.length);
313 const hasPending = Boolean(pendingTransactions.length);
325− const hasInvites = Boolean(invites.length);
314+ const hasInvites = Boolean(displayedInvites.length);
327 const [numInvites, setNumInvites] = useState(DEFAULT_NUM_INVITES);
316 const [numInvites, setNumInvites] = useState(DEFAULT_NUM_INVITES);
328 const [showInviteForm, setShowInviteForm] = useState(false);
317 const [showInviteForm, setShowInviteForm] = useState(false);
329− const [tab, setTab] = useState(NAMES.ALL);
330 const [loading, setLoading] = useState(false);
318 const [loading, setLoading] = useState(false);
331 const [error, setError] = useState(null);
319 const [error, setError] = useState(null);
333− const _acceptedPoints = acceptedPoints.getOrElse([]);
334− const _pendingPoints = pendingPoints.getOrElse([]);
335− const _pendingInvites = _pendingPoints.length;
336− const _acceptedInvites = _acceptedPoints.length;
337− const _totalInvites = availableInvites
338− .map(a => sentInvites.getOrElse(0) + a)
341− const [selectedInvite, _setSelectedInvite] = useState();
343− useSyncDetails([..._acceptedPoints, ..._pendingPoints]);
345− const setSelectedInvite = useCallback(
346− p => _setSelectedInvite(old => (old === p ? null : p)),
350− const generateInvites = useCallback(async () => {
321+ const createInvites = useCallback(async () => {
351 setLoading(true);
322 setLoading(true);
353− const invites = await generateInviteCodes(numInvites);
325+ const invites = await generateInviteCodes(numInvites);
354− console.log('INVITES', invites)
326+ console.log('INVITES', invites);
355− // TODO: store these invites somewhere. How do I recover the invites for future use?
327+ getPendingTransactions(point);
356− setInvites(invites);
328+ } else {
329+ const invites = await generateInvites(numInvites);
330+ console.log('INVITES', invites);
357 setShowInviteForm(false);
332 setShowInviteForm(false);
358 } catch (error) {
333 } catch (error) {
359 setError(error);
334 setError(error);
360 } finally {
335 } finally {
361 setLoading(false);
336 setLoading(false);
363− }, [generateInviteCodes, numInvites, setInvites]);
339+ generateInviteCodes,
341+ getPendingTransactions,
365 const getContent = () => {
347 const getContent = () => {
366 if (hasInvites) {
348 if (hasInvites) {
@@ -416,8 +398,8 @@ export default function InviteCohort() {
416 const header = (
398 const header = (
419− <span className="number-emphasis"> {invites.length} </span>
401+ <span className="number-emphasis"> {displayedInvites.length} </span>
420− Planet Code{invites.length > 1 ? 's' : ''}
402+ Planet Code{displayedInvites.length === 1 ? '' : 's'}
@@ -470,7 +452,7 @@ export default function InviteCohort() {
470 className="generate-codes"
452 className="generate-codes"
473− onClick={generateInvites}>
455+ onClick={createInvites}>
474 Generate Planet Codes ({numInvites})
456 Generate Planet Codes ({numInvites})
475 </Button>
457 </Button>
@@ -479,140 +461,57 @@ export default function InviteCohort() {
479 <LoadingOverlay loading={loading} />
461 <LoadingOverlay loading={loading} />
482− } else if (currentL2) {
489− header={<L2BackHeader />}>
495− <Row className="has-invites-header">
497− <div className="download-csv" onClick={() => null}>
498− <Icon icon="Download" />
505− <div className={`content ${!hasInvites ? 'center' : ''}`}>
508− {!hasPending && !hasInvites && (
511− className="generate-button"
514− onClick={() => setShowInviteForm(true)}>
521− numPerPage={INVITES_PER_PAGE}
522− numElements={invites.length}
523− goPrevious={() => setPage(page - 1)}
524− goNext={() => setPage(page + 1)}
529− {(hasInvites || hasPending) && (
531− onClick={() => setShowInviteForm(true)}
532− className="add-more"
533− accessory={<Icon icon="ChevronEast" />}>
542− <View pop={pop} inset className="cohort" hideBack>
467+ <View pop={pop} inset className="cohort" hideBack header={<L2BackHeader />}>
543− <Grid gap={3}>
468+ <Window>
544− <Grid.Item full>Invite Group</Grid.Item>
469+ <HeaderPane>
545− <Grid.Item full>
470+ {!hasInvites ? (
546− <Flex align="center">
471+ header
547− <Flex.Item>
472+ ) : (
548− {_acceptedInvites} / {_totalInvites}
473+ <Row className="has-invites-header">
549− </Flex.Item>
474+ {header}
550− {_pendingInvites !== 0 && (
475+ <div className="download-csv" onClick={() => null}>
551− <Flex.Item as={Chip} className="bg-yellow4 white">
476+ <Icon icon="Download" />
552− {_pendingInvites} pending
477+ <div>CSV</div>
553− </Flex.Item>
478+ </div>
556− </Grid.Item>
481+ </HeaderPane>
557− <Grid.Item
482+ <BodyPane>
558− full
483+ <div className={`content ${!hasInvites ? 'center' : ''}`}>
559− as={BarGraph}
484+ {getContent()}
560− available={availableInvites}
485+ </div>
561− sent={sentInvites}
486+ {!hasPending && !hasInvites && (
562− accepted={acceptedInvites}
487+ <Button
563− />
488+ as={'button'}
564− {availableInvites.getOrElse(0) !== 0 && !showInviteForm && (
489+ className="generate-button"
565− <Grid.Item
490+ center
568− center
492+ onClick={() => setShowInviteForm(true)}>
569− as={Button}
493+ Generate Codes
499+ numPerPage={INVITES_PER_PAGE}
500+ numElements={displayedInvites.length}
501+ goPrevious={() => setPage(page - 1)}
502+ goNext={() => setPage(page + 1)}
507+ {(hasInvites || hasPending) && (
570− onClick={() => setShowInviteForm(true)}>
509+ onClick={() => setShowInviteForm(true)}
571− Add Members
510+ className="add-more"
572− </Grid.Item>
511+ accessory={<Icon icon="ChevronEast" />}>
574− {showInviteForm && <Inviter />}
513+ </Button>
584− onTabChange={setTab}
585− acceptedPoints={_acceptedPoints}
586− pendingPoints={_pendingPoints}
587− onlyPending={tab === NAMES.PENDING}
588− onSelectInvite={setSelectedInvite}
591− {selectedInvite && (
595− as={CohortMemberExpanded}
597− point={selectedInvite}
598− onBack={() => setSelectedInvite(null)}
611− [NAMES.PENDING]: CohortList,
612− [NAMES.ALL]: CohortList,
616− { text: 'All', value: NAMES.ALL },
617− { text: 'Pending', value: NAMES.PENDING },