diff --git a/common/contest.ts b/common/contest.ts index b432e372..17399d4c 100644 --- a/common/contest.ts +++ b/common/contest.ts @@ -9,15 +9,3 @@ export const CONTEST_DATA = { } export const CONTEST_SLUGS = Object.keys(CONTEST_DATA) - -export function contestPath( - contestSlug: string, - subpath?: - | 'edit' - | 'markets' - | 'about' - | typeof GROUP_CHAT_SLUG - | 'leaderboards' -) { - return `/contest/${contestSlug}${subpath ? `/${subpath}` : ''}` -} diff --git a/web/pages/contest/[...slugs]/index.tsx b/web/pages/contest/[...slugs]/index.tsx index 9cd9f97d..37fae7b2 100644 --- a/web/pages/contest/[...slugs]/index.tsx +++ b/web/pages/contest/[...slugs]/index.tsx @@ -51,17 +51,19 @@ import { ENV_CONFIG } from 'common/envs/constants' import { useSaveReferral } from 'web/hooks/use-save-referral' import { Button } from 'web/components/button' import { SubmissionSearch } from 'web/components/submission-search' +import { ContestChat } from 'web/components/contest/contest-chat' +import { contestPath } from 'web/lib/firebase/contests' 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 contest = await getGroupBySlug(slugs[0]) + const members = contest && (await listMembers(contest)) + const creatorPromise = contest ? getUser(contest.creatorId) : null const contracts = - (group && (await listContractsByGroupSlug(group.slug))) ?? [] + (contest && (await listContractsByGroupSlug(contest.slug))) ?? [] const bets = await Promise.all( contracts.map((contract: Contract) => listAllBets(contract.id)) @@ -80,7 +82,7 @@ export async function getStaticPropz(props: { params: { slugs: string[] } }) { return { props: { - group, + contest, members, creator, traderScores, @@ -108,16 +110,16 @@ function toTopUsers(userScores: { [userId: string]: number }, users: User[]) { export async function getStaticPaths() { return { paths: [], fallback: 'blocking' } } -const groupSubpages = [ +const contestSubpages = [ undefined, GROUP_CHAT_SLUG, - 'markets', + 'submissions', 'leaderboards', 'about', ] as const -export default function GroupPage(props: { - group: Group | null +export default function ContestPage(props: { + contest: Group | null members: User[] creator: User traderScores: { [userId: string]: number } @@ -126,7 +128,7 @@ export default function GroupPage(props: { topCreators: User[] }) { props = usePropz(props, getStaticPropz) ?? { - group: null, + contest: null, members: [], creator: null, traderScores: {}, @@ -145,35 +147,35 @@ export default function GroupPage(props: { const router = useRouter() const { slugs } = router.query as { slugs: string[] } - const page = slugs?.[1] as typeof groupSubpages[number] + const page = slugs?.[1] as typeof contestSubpages[number] - const group = useGroup(props.group?.id) ?? props.group - const tips = useTipTxns({ groupId: group?.id }) + const contest = useGroup(props.contest?.id) ?? props.contest + const tips = useTipTxns({ groupId: contest?.id }) - const messages = useCommentsOnGroup(group?.id) + const messages = useCommentsOnGroup(contest?.id) const user = useUser() useSaveReferral(user, { defaultReferrer: creator.username, - groupId: group?.id, + groupId: contest?.id, }) const { width } = useWindowSize() - const chatDisabled = !group || group.chatDisabled + const chatDisabled = !contest || contest.chatDisabled const showChatSidebar = !chatDisabled && (width ?? 1280) >= 1280 const showChatTab = !chatDisabled && !showChatSidebar - if (group === null || !groupSubpages.includes(page) || slugs[2]) { + if (contest === null || !contestSubpages.includes(page) || slugs[2]) { return } - const { memberIds } = group - const isCreator = user && group && user.id === group.creatorId + const { memberIds } = contest + const isCreator = user && contest && user.id === contest.creatorId const isMember = user && memberIds.includes(user.id) const leaderboard = ( - - + ) const chatTab = ( {messages ? ( - + ) : ( )} @@ -213,7 +214,7 @@ export default function GroupPage(props: { defaultSort: getSavedSort() ?? 'newest', defaultFilter: 'open', }} - additionalFilter={{ groupSlug: group.slug }} + additionalFilter={{ groupSlug: contest.slug }} /> ) @@ -224,23 +225,23 @@ export default function GroupPage(props: { { title: 'Chat', content: chatTab, - href: groupPath(group.slug, GROUP_CHAT_SLUG), + href: contestPath(contest.slug, GROUP_CHAT_SLUG), }, ]), { - title: 'Markets', + title: 'Submissions', content: questionsTab, - href: groupPath(group.slug, 'markets'), + href: contestPath(contest.slug, 'submissions'), }, { title: 'Leaderboards', content: leaderboard, - href: groupPath(group.slug, 'leaderboards'), + href: contestPath(contest.slug, 'leaderboards'), }, { title: 'About', content: aboutTab, - href: groupPath(group.slug, 'about'), + href: contestPath(contest.slug, 'about'), }, ] @@ -253,9 +254,9 @@ export default function GroupPage(props: { className={showChatSidebar ? '!max-w-7xl !pb-0' : ''} > @@ -263,16 +264,16 @@ export default function GroupPage(props: {
- {group.name} + {contest.name}
- +
0 ? tabIndex : 0} tabs={tabs} @@ -281,170 +282,20 @@ export default function GroupPage(props: { ) } -function JoinOrAddQuestionsButtons(props: { - group: Group - user: User | null | undefined - isMember: boolean -}) { - const { group, user, isMember } = props - return user && isMember ? ( - - - - ) : group.anyoneCanJoin ? ( - - ) : null -} - -function GroupOverview(props: { - group: Group - creator: User - user: User | null | undefined - isCreator: boolean - members: User[] -}) { - const { group, creator, isCreator, user, members } = props - const anyoneCanJoinChoices: { [key: string]: string } = { - Closed: 'false', - Open: 'true', - } - const [anyoneCanJoin, setAnyoneCanJoin] = useState(group.anyoneCanJoin) - function updateAnyoneCanJoin(newVal: boolean) { - if (group.anyoneCanJoin == newVal || !isCreator) return - setAnyoneCanJoin(newVal) - toast.promise(updateGroup(group, { ...group, anyoneCanJoin: newVal }), { - loading: 'Updating group...', - success: 'Updated group!', - error: "Couldn't update group", - }) - } - - const postFix = user ? '?referrer=' + user.username : '' - const shareUrl = `https://${ENV_CONFIG.domain}${groupPath( - group.slug - )}${postFix}` +function ContestOverview(props: { contest: Group }) { + const { contest } = props return ( <> - -
-
Created by
- -
- {isCreator ? ( - - ) : ( - user && - group.memberIds.includes(user?.id) && ( - - - - ) - )} -
- +
- - Membership - {user && user.id === creator.id ? ( - - updateAnyoneCanJoin(choice.toString() === 'true') - } - toggleClassName={'h-10'} - className={'ml-2'} - /> - ) : ( - - {anyoneCanJoin ? 'Open' : 'Closed'} - - )} - - - {anyoneCanJoin && user && ( - -
Invite
-
- Invite a friend to this group and get M${REFERRAL_AMOUNT} if they - sign up! -
- - - - )} - - -
Members
- - ) } -function SearchBar(props: { setQuery: (query: string) => void }) { - const { setQuery } = props - const debouncedQuery = debounce(setQuery, 50) - return ( -
- - debouncedQuery(e.target.value)} - placeholder="Find a member" - className="input input-bordered mb-4 w-full pl-12" - /> -
- ) -} - -function GroupMemberSearch(props: { members: User[]; group: Group }) { - const [query, setQuery] = useState('') - const { group } = props - let { members } = props - - // Use static members on load, but also listen to member changes: - const listenToMembers = useMembers(group) - if (listenToMembers) { - members = listenToMembers - } - - // TODO use find-active-contracts to sort by? - const matches = sortBy(members, [(member) => member.name]).filter((m) => - searchInAny(query, m.name, m.username) - ) - const matchLimit = 25 - - return ( -
- - - {matches.length > 0 && ( - m.id)} /> - )} - {matches.length > 25 && ( -
- And {matches.length - matchLimit} more... -
- )} - -
- ) -} - function SortedLeaderboard(props: { users: User[] scoreFunction: (user: User) => number @@ -467,7 +318,7 @@ function SortedLeaderboard(props: { ) } -function GroupLeaderboards(props: { +function ContestLeaderboards(props: { traderScores: { [userId: string]: number } creatorScores: { [userId: string]: number } topTraders: User[] @@ -533,133 +384,3 @@ function GroupLeaderboards(props: { ) } - -function AddContractButton(props: { group: Group; user: User }) { - const { group, user } = props - const [open, setOpen] = useState(false) - const [contracts, setContracts] = useState([]) - const [loading, setLoading] = useState(false) - - async function addContractToCurrentGroup(contract: Contract) { - if (contracts.map((c) => c.id).includes(contract.id)) { - setContracts(contracts.filter((c) => c.id !== contract.id)) - } else setContracts([...contracts, contract]) - } - - async function doneAddingContracts() { - Promise.all( - contracts.map(async (contract) => { - setLoading(true) - await addContractToGroup(group, contract, user.id) - }) - ).then(() => { - setLoading(false) - setOpen(false) - setContracts([]) - }) - } - - return ( - <> -
- -
- - - - -
- Add a question to your group -
- - {contracts.length === 0 ? ( - - - -
- (or select old questions) -
- - ) : ( - - {!loading ? ( - - - - - ) : ( - - - - )} - - )} - - -
- c.id), - highlightClassName: '!bg-indigo-100 border-indigo-100 border-2', - }} - /> -
- -
- - ) -} - -function JoinGroupButton(props: { - group: Group - user: User | null | undefined -}) { - const { group, user } = props - function addUserToGroup() { - if (user && !group.memberIds.includes(user.id)) { - toast.promise(joinGroup(group, user.id), { - loading: 'Joining group...', - success: 'Joined group!', - error: "Couldn't join group, try again?", - }) - } - } - return ( -
- -
- ) -} diff --git a/web/pages/contests.tsx b/web/pages/contests.tsx index 2f44a538..2d849979 100644 --- a/web/pages/contests.tsx +++ b/web/pages/contests.tsx @@ -50,14 +50,13 @@ export default function Contests(props: { const contests = (useGroups() ?? props.groups).filter((group) => CONTEST_SLUGS.includes(group.slug) ) - //const contests = groups.filter((group) => CONTEST_SLUGS.includes(group.slug)) - console.log(contests) const user = useUser() - const memberGroupIds = useMemberGroupIds(user) || [] // useEffect(() => { // // Load User object for creator of new Groups. - // const newGroups = groups.filter(({ creatorId }) => !creatorsDict[creatorId]) + // const newGroups = contests.filter( + // ({ creatorId }) => !creatorsDict[creatorId] + // ) // if (newGroups.length > 0) { // Promise.all(newGroups.map(({ creatorId }) => getUser(creatorId))).then( // (newUsers) => { @@ -68,7 +67,7 @@ export default function Contests(props: { // } // ) // } - // }, [creatorsDict, groups]) + // }, [creatorsDict, contests]) const [query, setQuery] = useState('') @@ -86,21 +85,6 @@ export default function Contests(props: { ) ) - const matchesOrderedByRecentActivity = sortBy(contests, [ - (contest) => - -1 * - (contest.mostRecentChatActivityTime ?? - contest.mostRecentContractAddedTime ?? - contest.mostRecentActivityTime), - ]).filter((c) => - searchInAny( - query, - c.name, - c.about || '', - creatorsDict[c.creatorId].username - ) - ) - // Not strictly necessary, but makes the "hold delete" experience less laggy const debouncedQuery = debounce(setQuery, 50) @@ -164,39 +148,3 @@ export function ContestCard(props: { contest: Group }) { ) } - -function GroupMembersList(props: { group: Group }) { - const { group } = props - const maxMembersToShow = 3 - const members = useMembers(group, maxMembersToShow).filter( - (m) => m.id !== group.creatorId - ) - if (group.memberIds.length === 1) return
- return ( -
- Other members - {members.slice(0, maxMembersToShow).map((member, i) => ( -
- - {members.length > 1 && i !== members.length - 1 && ,} -
- ))} - {group.memberIds.length > maxMembersToShow && ( - & {group.memberIds.length - maxMembersToShow} more - )} -
- ) -} - -export function GroupLinkItem(props: { group: Group; className?: string }) { - const { group, className } = props - - return ( - - {group.name} - - ) -}