diff --git a/web/components/widgets/short-toggle.tsx b/web/components/widgets/short-toggle.tsx new file mode 100644 index 00000000..3c307fda --- /dev/null +++ b/web/components/widgets/short-toggle.tsx @@ -0,0 +1,38 @@ +/* This example requires Tailwind CSS v2.0+ */ +import { Switch } from '@headlessui/react' +import clsx from 'clsx' + +export default function ShortToggle(props: { + enabled: boolean + setEnabled: (enabled: boolean) => void +}) { + const { enabled, setEnabled } = props + + return ( + + Use setting + + ) +} diff --git a/web/hooks/use-group.ts b/web/hooks/use-group.ts index de260f2f..f73fd04e 100644 --- a/web/hooks/use-group.ts +++ b/web/hooks/use-group.ts @@ -65,19 +65,18 @@ export const useMemberGroupIds = (user: User | null | undefined) => { export function useMembers(group: Group) { const [members, setMembers] = useState([]) useEffect(() => { - const { memberIds, creatorId } = group - if (memberIds.length > 1) - // get users via their user ids: - Promise.all( - memberIds.filter((mId) => mId !== creatorId).map(getUser) - ).then((users) => { - const members = users.filter((user) => user) - setMembers(members) - }) + const { memberIds } = group + if (memberIds.length > 0) { + listMembers(group).then((members) => setMembers(members)) + } }, [group]) return members } +export async function listMembers(group: Group) { + return await Promise.all(group.memberIds.map(getUser)) +} + export const useGroupsWithContract = (contractId: string | undefined) => { const [groups, setGroups] = useState() diff --git a/web/pages/group/[...slugs]/index.tsx b/web/pages/group/[...slugs]/index.tsx index f3e66c8d..593700f7 100644 --- a/web/pages/group/[...slugs]/index.tsx +++ b/web/pages/group/[...slugs]/index.tsx @@ -17,7 +17,7 @@ import { firebaseLogin, getUser, User } from 'web/lib/firebase/users' import { Spacer } from 'web/components/layout/spacer' import { Col } from 'web/components/layout/col' import { useUser } from 'web/hooks/use-user' -import { useGroup, useMembers } from 'web/hooks/use-group' +import { listMembers, useGroup, useMembers } from 'web/hooks/use-group' import { useRouter } from 'next/router' import { scoreCreators, scoreTraders } from 'common/scoring' import { Leaderboard } from 'web/components/leaderboard' @@ -39,12 +39,14 @@ import { checkAgainstQuery } from 'web/hooks/use-sort-and-query-params' import { ChoicesToggleGroup } from 'web/components/choices-toggle-group' import { toast } from 'react-hot-toast' import { useCommentsOnGroup } from 'web/hooks/use-comments' +import ShortToggle from 'web/components/widgets/short-toggle' export const getStaticProps = fromPropz(getStaticPropz) export async function getStaticPropz(props: { params: { slugs: string[] } }) { const { slugs } = props.params const group = await getGroupBySlug(slugs[0]) + const members = group ? await listMembers(group) : [] const creatorPromise = group ? getUser(group.creatorId) : null const contracts = group ? await getGroupContracts(group).catch((_) => []) : [] @@ -65,6 +67,7 @@ export async function getStaticPropz(props: { params: { slugs: string[] } }) { return { props: { group, + members, creator, traderScores, topTraders, @@ -95,6 +98,7 @@ const groupSubpages = [undefined, 'chat', 'questions', 'details'] as const export default function GroupPage(props: { group: Group | null + members: User[] creator: User traderScores: { [userId: string]: number } topTraders: User[] @@ -103,14 +107,21 @@ export default function GroupPage(props: { }) { props = usePropz(props, getStaticPropz) ?? { group: null, + members: [], creator: null, traderScores: {}, topTraders: [], creatorScores: {}, topCreators: [], } - const { creator, traderScores, topTraders, creatorScores, topCreators } = - props + const { + creator, + members, + traderScores, + topTraders, + creatorScores, + topCreators, + } = props const router = useRouter() const { slugs } = router.query as { slugs: string[] } @@ -175,15 +186,15 @@ export default function GroupPage(props: { user={user} /> - - - + + ) return ( @@ -312,7 +323,7 @@ function GroupOverview(props: { return ( - About group + About {group.name} {isCreator && } @@ -324,7 +335,6 @@ function GroupOverview(props: { username={creator.username} /> - Membership {user && user.id === creator.id ? ( @@ -343,14 +353,6 @@ function GroupOverview(props: { )} - {about && ( - <> - -
- -
- - )} ) @@ -381,46 +383,94 @@ export function GroupMembersList(props: { group: Group }) { ) } +function SortedLeaderboard(props: { + users: User[] + scoreFunction: (user: User) => number + title: string + header: string +}) { + const { users, scoreFunction, title, header } = props + const sortedUsers = users.sort((a, b) => scoreFunction(b) - scoreFunction(a)) + return ( + formatMoney(scoreFunction(user)) }, + ]} + /> + ) +} + function GroupLeaderboards(props: { traderScores: { [userId: string]: number } creatorScores: { [userId: string]: number } topTraders: User[] topCreators: User[] + members: User[] user: User | null | undefined }) { - const { traderScores, creatorScores, topTraders, topCreators } = props - - const topTraderScores = topTraders.map((user) => traderScores[user.id]) - const topCreatorScores = topCreators.map((user) => creatorScores[user.id]) + const { traderScores, creatorScores, members, topTraders, topCreators } = + props + const [includeOutsiders, setIncludeOutsiders] = useState(false) + // Consider hiding M$0 return ( - <> - - formatMoney(topTraderScores[topTraders.indexOf(user)]), - }, - ]} - /> + + + Include all users + + - - formatMoney(topCreatorScores[topCreators.indexOf(user)]), - }, - ]} - /> - +
+ {!includeOutsiders ? ( + <> + traderScores[user.id] ?? 0} + title="🏅 Top bettors" + header="Profit" + /> + creatorScores[user.id] ?? 0} + title="🏅 Top creators" + header="Market volume" + /> + + ) : ( + <> + formatMoney(traderScores[user.id] ?? 0), + }, + ]} + /> + + formatMoney(creatorScores[user.id] ?? 0), + }, + ]} + /> + + )} +
+ ) }