import React, { useMemo, useEffect, useCallback, useState } from 'react'; import { Grid, Flex, Button } from 'indigo-react'; import * as ob from 'urbit-ob'; import { Just } from 'folktale/maybe'; import cn from 'classnames'; import { usePointCursor } from 'store/pointCursor'; import { usePointCache } from 'store/pointCache'; import View from 'components/View'; import Tabs from 'components/Tabs'; import BarGraph from 'components/BarGraph'; import MaybeSigil from 'components/MaybeSigil'; import { matchBlinky } from 'components/Blinky'; import Chip from 'components/Chip'; import Crumbs from 'components/Crumbs'; import { useLocalRouter } from 'lib/LocalRouter'; import useInvites from 'lib/useInvites'; import * as need from 'lib/need'; import Inviter from 'views/Invite/Inviter'; import { ReactComponent as SearchIcon } from 'assets/search.svg'; import NavHeader from 'components/NavHeader'; function SearchInput({ className, value, onChange }) { return ( ); } function CohortMember({ point, pending = false, className }) { const { sentInvites } = useInvites(point); const patp = useMemo(() => ob.patp(point), [point]); const colors = pending ? ['#ee892b', '#FFFFFF'] : ['#000000', '#FFFFFF']; const DetailText = useCallback( () => pending ? 'Pending' : <> {matchBlinky(sentInvites)} points invited , [pending, sentInvites] ); return ( {patp} ); } function CohortList({ acceptedPoints, pendingPoints, className, onlyPending }) { const { syncInvites } = usePointCache(); const [query, setQuery] = useState(''); useEffect(() => { acceptedPoints.map(syncInvites); }, [acceptedPoints, syncInvites]); const handleChange = useCallback( e => { setQuery(e.target.value); e.preventDefault(); }, [setQuery] ); const filterPoints = useCallback( points => points.filter(p => { const patp = ob.patp(p).slice(1); return patp.startsWith(query); }), [query] ); const _pendingPoints = filterPoints(pendingPoints); const _acceptedPoints = filterPoints(acceptedPoints); const offset = onlyPending ? 0 : _acceptedPoints.length; return ( <> {!onlyPending && _acceptedPoints.map((p, idx) => ( ))} {_pendingPoints.map((p, idx) => ( ))} {_pendingPoints.length === 0 && (_acceptedPoints.length === 0 || onlyPending) && ( {' '} No invites accepted yet. )} ); } export default function InviteCohort() { const { pop } = useLocalRouter(); const { pointCursor } = usePointCursor(); const point = need.point(pointCursor); const { acceptedInvites, acceptedPoints, pendingPoints, availableInvites, sentInvites, } = useInvites(point); const [showInviteForm, setShowInviteForm] = useState(false); const [tab, setTab] = useState(NAMES.ALL); const _acceptedPoints = acceptedPoints.getOrElse([]); const _pendingPoints = pendingPoints.getOrElse([]); const _pendingInvites = _pendingPoints.length; const _acceptedInvites = _acceptedPoints.length; const _totalInvites = availableInvites .map(a => sentInvites.getOrElse(0) + a) .getOrElse(0); return ( pop() }, { text: 'Invite Group' }, ]} /> Invite Group {_acceptedInvites} / {_totalInvites} {_pendingInvites !== 0 && ( {_pendingInvites} pending )} {availableInvites.getOrElse(0) !== 0 && !showInviteForm && ( setShowInviteForm(true)}> Add Members )} {showInviteForm && } ); } const NAMES = { ALL: 'ALL', PENDING: 'PENDING', }; const VIEWS = { [NAMES.PENDING]: CohortList, [NAMES.ALL]: CohortList, }; const OPTIONS = [ { text: 'All', value: NAMES.ALL }, { text: 'Pending', value: NAMES.PENDING }, ];