fixing merge conflicts
This commit is contained in:
		
							parent
							
								
									a4e2cce4aa
								
							
						
					
					
						commit
						a322249f71
					
				|  | @ -1,15 +1,15 @@ | |||
| import { take, sortBy, debounce } from 'lodash' | ||||
| import PlusSmIcon from '@heroicons/react/solid/PlusSmIcon' | ||||
| 
 | ||||
| import { Group } from 'common/group' | ||||
| import { Group, GROUP_CHAT_SLUG } from 'common/group' | ||||
| import { Page } from 'web/components/page' | ||||
| import { listAllBets } from 'web/lib/firebase/bets' | ||||
| import { Contract } from 'web/lib/firebase/contracts' | ||||
| import { Contract, listContractsByGroupSlug } from 'web/lib/firebase/contracts' | ||||
| import { | ||||
|   groupPath, | ||||
|   getGroupBySlug, | ||||
|   getGroupContracts, | ||||
|   updateGroup, | ||||
|   addUserToGroup, | ||||
|   joinGroup, | ||||
|   addContractToGroup, | ||||
| } from 'web/lib/firebase/groups' | ||||
| import { Row } from 'web/components/layout/row' | ||||
|  | @ -33,38 +33,37 @@ import { SEO } from 'web/components/SEO' | |||
| import { Linkify } from 'web/components/linkify' | ||||
| import { fromPropz, usePropz } from 'web/hooks/use-propz' | ||||
| import { Tabs } from 'web/components/layout/tabs' | ||||
| import { ContractsGrid } from 'web/components/contract/contracts-list' | ||||
| import { | ||||
|   createButtonStyle, | ||||
|   CreateQuestionButton, | ||||
| } from 'web/components/create-question-button' | ||||
| import { CreateQuestionButton } from 'web/components/create-question-button' | ||||
| import React, { useEffect, useState } from 'react' | ||||
| import { GroupChat } from 'web/components/groups/group-chat' | ||||
| import { LoadingIndicator } from 'web/components/loading-indicator' | ||||
| import { Modal } from 'web/components/layout/modal' | ||||
| import { checkAgainstQuery } from 'web/hooks/use-sort-and-query-params' | ||||
| import { getSavedSort } 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 { ShareIconButton } from 'web/components/share-icon-button' | ||||
| import { REFERRAL_AMOUNT } from 'common/user' | ||||
| import { SiteLink } from 'web/components/site-link' | ||||
| import { ContractSearch } from 'web/components/contract-search' | ||||
| import clsx from 'clsx' | ||||
| import { FollowList } from 'web/components/follow-list' | ||||
| import { SearchIcon } from '@heroicons/react/outline' | ||||
| import { useTipTxns } from 'web/hooks/use-tip-txns' | ||||
| import { JoinOrLeaveGroupButton } from 'web/components/groups/groups-button' | ||||
| import { searchInAny } from 'common/util/parse' | ||||
| import { useWindowSize } from 'web/hooks/use-window-size' | ||||
| import { CopyLinkButton } from 'web/components/copy-link-button' | ||||
| import { ENV_CONFIG } from 'common/envs/constants' | ||||
| 
 | ||||
| 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 members = group && (await listMembers(group)) | ||||
|   const creatorPromise = group ? getUser(group.creatorId) : null | ||||
| 
 | ||||
|   const contracts = group ? await getGroupContracts(group).catch((_) => []) : [] | ||||
|   const contracts = | ||||
|     (group && (await listContractsByGroupSlug(group.slug))) ?? [] | ||||
| 
 | ||||
|   const bets = await Promise.all( | ||||
|     contracts.map((contract: Contract) => listAllBets(contract.id)) | ||||
|  | @ -72,10 +71,12 @@ export async function getStaticPropz(props: { params: { slugs: string[] } }) { | |||
| 
 | ||||
|   const creatorScores = scoreCreators(contracts) | ||||
|   const traderScores = scoreTraders(contracts, bets) | ||||
|   const [topCreators, topTraders] = await Promise.all([ | ||||
|     toTopUsers(creatorScores), | ||||
|     toTopUsers(traderScores), | ||||
|   ]) | ||||
|   const [topCreators, topTraders] = | ||||
|     (members && [ | ||||
|       toTopUsers(creatorScores, members), | ||||
|       toTopUsers(traderScores, members), | ||||
|     ]) ?? | ||||
|     [] | ||||
| 
 | ||||
|   const creator = await creatorPromise | ||||
| 
 | ||||
|  | @ -94,14 +95,14 @@ export async function getStaticPropz(props: { params: { slugs: string[] } }) { | |||
|   } | ||||
| } | ||||
| 
 | ||||
| async function toTopUsers(userScores: { [userId: string]: number }) { | ||||
| function toTopUsers(userScores: { [userId: string]: number }, users: User[]) { | ||||
|   const topUserPairs = take( | ||||
|     sortBy(Object.entries(userScores), ([_, score]) => -1 * score), | ||||
|     10 | ||||
|   ).filter(([_, score]) => score >= 0.5) | ||||
| 
 | ||||
|   const topUsers = await Promise.all( | ||||
|     topUserPairs.map(([userId]) => getUser(userId)) | ||||
|   const topUsers = topUserPairs.map( | ||||
|     ([userId]) => users.filter((user) => user.id === userId)[0] | ||||
|   ) | ||||
|   return topUsers.filter((user) => user) | ||||
| } | ||||
|  | @ -111,9 +112,9 @@ export async function getStaticPaths() { | |||
| } | ||||
| const groupSubpages = [ | ||||
|   undefined, | ||||
|   'chat', | ||||
|   GROUP_CHAT_SLUG, | ||||
|   'questions', | ||||
|   'rankings', | ||||
|   'leaderboards', | ||||
|   'about', | ||||
| ] as const | ||||
| 
 | ||||
|  | @ -149,26 +150,9 @@ export default function GroupPage(props: { | |||
|   const page = slugs?.[1] as typeof groupSubpages[number] | ||||
| 
 | ||||
|   const group = useGroup(props.group?.id) ?? props.group | ||||
|   const [contracts, setContracts] = useState<Contract[] | undefined>(undefined) | ||||
|   const [query, setQuery] = useState('') | ||||
|   const tips = useTipTxns({ groupId: group?.id }) | ||||
| 
 | ||||
|   const messages = useCommentsOnGroup(group?.id) | ||||
|   const debouncedQuery = debounce(setQuery, 50) | ||||
|   const filteredContracts = | ||||
|     query != '' && contracts | ||||
|       ? contracts.filter( | ||||
|           (c) => | ||||
|             checkAgainstQuery(query, c.question) || | ||||
|             checkAgainstQuery(query, c.creatorName) || | ||||
|             checkAgainstQuery(query, c.creatorUsername) | ||||
|         ) | ||||
|       : [] | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     if (group) | ||||
|       getGroupContracts(group).then((contracts) => setContracts(contracts)) | ||||
|   }, [group]) | ||||
| 
 | ||||
|   const user = useUser() | ||||
|   useEffect(() => { | ||||
|  | @ -176,9 +160,14 @@ export default function GroupPage(props: { | |||
|       referrer?: string | ||||
|     } | ||||
|     if (!user && router.isReady) | ||||
|       writeReferralInfo(creator.username, undefined, referrer, group?.slug) | ||||
|       writeReferralInfo(creator.username, undefined, referrer, group?.id) | ||||
|   }, [user, creator, group, router]) | ||||
| 
 | ||||
|   const { width } = useWindowSize() | ||||
|   const chatDisabled = !group || group.chatDisabled | ||||
|   const showChatSidebar = !chatDisabled && (width ?? 1280) >= 1280 | ||||
|   const showChatTab = !chatDisabled && !showChatSidebar | ||||
| 
 | ||||
|   if (group === null || !groupSubpages.includes(page) || slugs[2]) { | ||||
|     return <Custom404 /> | ||||
|   } | ||||
|  | @ -186,11 +175,6 @@ export default function GroupPage(props: { | |||
|   const isCreator = user && group && user.id === group.creatorId | ||||
|   const isMember = user && memberIds.includes(user.id) | ||||
| 
 | ||||
|   const rightSidebar = ( | ||||
|     <Col className="mt-6 hidden xl:block"> | ||||
|       <JoinOrCreateButton group={group} user={user} isMember={!!isMember} /> | ||||
|     </Col> | ||||
|   ) | ||||
|   const leaderboard = ( | ||||
|     <Col> | ||||
|       <GroupLeaderboards | ||||
|  | @ -211,70 +195,51 @@ export default function GroupPage(props: { | |||
|         creator={creator} | ||||
|         isCreator={!!isCreator} | ||||
|         user={user} | ||||
|         members={members} | ||||
|       /> | ||||
|     </Col> | ||||
|   ) | ||||
| 
 | ||||
|   const chatTab = ( | ||||
|     <Col className=""> | ||||
|       {messages ? ( | ||||
|         <GroupChat messages={messages} user={user} group={group} tips={tips} /> | ||||
|       ) : ( | ||||
|         <LoadingIndicator /> | ||||
|       )} | ||||
|     </Col> | ||||
|   ) | ||||
| 
 | ||||
|   const questionsTab = ( | ||||
|     <ContractSearch | ||||
|       querySortOptions={{ | ||||
|         shouldLoadFromStorage: true, | ||||
|         defaultSort: getSavedSort() ?? 'newest', | ||||
|         defaultFilter: 'open', | ||||
|       }} | ||||
|       additionalFilter={{ groupSlug: group.slug }} | ||||
|     /> | ||||
|   ) | ||||
| 
 | ||||
|   const tabs = [ | ||||
|     ...(group.chatDisabled | ||||
|     ...(!showChatTab | ||||
|       ? [] | ||||
|       : [ | ||||
|           { | ||||
|             title: 'Chat', | ||||
|             content: messages ? ( | ||||
|               <GroupChat | ||||
|                 messages={messages} | ||||
|                 user={user} | ||||
|                 group={group} | ||||
|                 tips={tips} | ||||
|               /> | ||||
|             ) : ( | ||||
|               <LoadingIndicator /> | ||||
|             ), | ||||
|             href: groupPath(group.slug, 'chat'), | ||||
|             content: chatTab, | ||||
|             href: groupPath(group.slug, GROUP_CHAT_SLUG), | ||||
|           }, | ||||
|         ]), | ||||
|     { | ||||
|       title: 'Questions', | ||||
|       content: ( | ||||
|         <div className={'mt-2 px-1'}> | ||||
|           {contracts ? ( | ||||
|             contracts.length > 0 ? ( | ||||
|               <> | ||||
|                 <input | ||||
|                   type="text" | ||||
|                   onChange={(e) => debouncedQuery(e.target.value)} | ||||
|                   placeholder="Search the group's questions" | ||||
|                   className="input input-bordered mb-4 w-full" | ||||
|                 /> | ||||
|                 <ContractsGrid | ||||
|                   contracts={query != '' ? filteredContracts : contracts} | ||||
|                   hasMore={false} | ||||
|                   loadMore={() => {}} | ||||
|                 /> | ||||
|               </> | ||||
|             ) : ( | ||||
|               <div className="p-2 text-gray-500"> | ||||
|                 No questions yet. Why not{' '} | ||||
|                 <SiteLink | ||||
|                   href={`/create/?groupId=${group.id}`} | ||||
|                   className={'font-bold text-gray-700'} | ||||
|                 > | ||||
|                   add one? | ||||
|                 </SiteLink> | ||||
|               </div> | ||||
|             ) | ||||
|           ) : ( | ||||
|             <LoadingIndicator /> | ||||
|           )} | ||||
|         </div> | ||||
|       ), | ||||
|       content: questionsTab, | ||||
|       href: groupPath(group.slug, 'questions'), | ||||
|     }, | ||||
|     { | ||||
|       title: 'Rankings', | ||||
|       title: 'Leaderboards', | ||||
|       content: leaderboard, | ||||
|       href: groupPath(group.slug, 'rankings'), | ||||
|       href: groupPath(group.slug, 'leaderboards'), | ||||
|     }, | ||||
|     { | ||||
|       title: 'About', | ||||
|  | @ -282,22 +247,24 @@ export default function GroupPage(props: { | |||
|       href: groupPath(group.slug, 'about'), | ||||
|     }, | ||||
|   ] | ||||
|   const tabIndex = tabs.map((t) => t.title).indexOf(page ?? 'chat') | ||||
|   const tabIndex = tabs.map((t) => t.title).indexOf(page ?? GROUP_CHAT_SLUG) | ||||
| 
 | ||||
|   return ( | ||||
|     <Page rightSidebar={rightSidebar} className="!pb-0"> | ||||
|     <Page | ||||
|       rightSidebar={showChatSidebar ? chatTab : undefined} | ||||
|       rightSidebarClassName={showChatSidebar ? '!top-0' : ''} | ||||
|       className={showChatSidebar ? '!max-w-7xl !pb-0' : ''} | ||||
|     > | ||||
|       <SEO | ||||
|         title={group.name} | ||||
|         description={`Created by ${creator.name}. ${group.about}`} | ||||
|         url={groupPath(group.slug)} | ||||
|       /> | ||||
| 
 | ||||
|       <Col className="px-3"> | ||||
|         <Row className={'items-center justify-between gap-4'}> | ||||
|           <div className={'sm:mb-1'}> | ||||
|             <div | ||||
|               className={ | ||||
|                 'line-clamp-1 my-1 text-lg text-indigo-700 sm:my-3 sm:text-2xl' | ||||
|               } | ||||
|               className={'line-clamp-1 my-2 text-2xl text-indigo-700 sm:my-3'} | ||||
|             > | ||||
|               {group.name} | ||||
|             </div> | ||||
|  | @ -305,19 +272,15 @@ export default function GroupPage(props: { | |||
|               <Linkify text={group.about} /> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div className="hidden sm:block xl:hidden"> | ||||
|             <JoinOrCreateButton | ||||
|           <div className="mt-2"> | ||||
|             <JoinOrAddQuestionsButtons | ||||
|               group={group} | ||||
|               user={user} | ||||
|               isMember={!!isMember} | ||||
|             /> | ||||
|           </div> | ||||
|         </Row> | ||||
|         <div className="block sm:hidden"> | ||||
|           <JoinOrCreateButton group={group} user={user} isMember={!!isMember} /> | ||||
|         </div> | ||||
|       </Col> | ||||
| 
 | ||||
|       <Tabs | ||||
|         currentPageForAnalytics={groupPath(group.slug)} | ||||
|         className={'mb-0 sm:mb-2'} | ||||
|  | @ -328,28 +291,14 @@ export default function GroupPage(props: { | |||
|   ) | ||||
| } | ||||
| 
 | ||||
| function JoinOrCreateButton(props: { | ||||
| function JoinOrAddQuestionsButtons(props: { | ||||
|   group: Group | ||||
|   user: User | null | undefined | ||||
|   isMember: boolean | ||||
| }) { | ||||
|   const { group, user, isMember } = props | ||||
|   return user && isMember ? ( | ||||
|     <Row | ||||
|       className={'-mt-2 justify-between sm:mt-0 sm:flex-col sm:justify-center'} | ||||
|     > | ||||
|       <CreateQuestionButton | ||||
|         user={user} | ||||
|         overrideText={'Add a new question'} | ||||
|         className={'hidden w-48 flex-shrink-0 sm:block'} | ||||
|         query={`?groupId=${group.id}`} | ||||
|       /> | ||||
|       <CreateQuestionButton | ||||
|         user={user} | ||||
|         overrideText={'New question'} | ||||
|         className={'block w-40 flex-shrink-0 sm:hidden'} | ||||
|         query={`?groupId=${group.id}`} | ||||
|       /> | ||||
|     <Row className={'mt-0 justify-end'}> | ||||
|       <AddContractButton group={group} user={user} /> | ||||
|     </Row> | ||||
|   ) : group.anyoneCanJoin ? ( | ||||
|  | @ -362,8 +311,9 @@ function GroupOverview(props: { | |||
|   creator: User | ||||
|   user: User | null | undefined | ||||
|   isCreator: boolean | ||||
|   members: User[] | ||||
| }) { | ||||
|   const { group, creator, isCreator, user } = props | ||||
|   const { group, creator, isCreator, user, members } = props | ||||
|   const anyoneCanJoinChoices: { [key: string]: string } = { | ||||
|     Closed: 'false', | ||||
|     Open: 'true', | ||||
|  | @ -379,6 +329,11 @@ function GroupOverview(props: { | |||
|     }) | ||||
|   } | ||||
| 
 | ||||
|   const postFix = user ? '?referrer=' + user.username : '' | ||||
|   const shareUrl = `https://${ENV_CONFIG.domain}${groupPath( | ||||
|     group.slug | ||||
|   )}${postFix}` | ||||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|       <Col className="gap-2 rounded-b bg-white p-2"> | ||||
|  | @ -423,22 +378,27 @@ function GroupOverview(props: { | |||
|             </span> | ||||
|           )} | ||||
|         </Row> | ||||
| 
 | ||||
|         {anyoneCanJoin && user && ( | ||||
|           <Row className={'flex-wrap items-center gap-1'}> | ||||
|             <span className={'text-gray-500'}>Share</span> | ||||
|             <ShareIconButton | ||||
|               group={group} | ||||
|               username={user.username} | ||||
|               buttonClassName={'hover:bg-gray-300 mt-1 !text-gray-700'} | ||||
|             > | ||||
|               <span className={'mx-2'}> | ||||
|                 Invite a friend and get M${REFERRAL_AMOUNT} if they sign up! | ||||
|               </span> | ||||
|             </ShareIconButton> | ||||
|           </Row> | ||||
|           <Col className="my-4 px-2"> | ||||
|             <div className="text-lg">Invite</div> | ||||
|             <div className={'mb-2 text-gray-500'}> | ||||
|               Invite a friend to this group and get M${REFERRAL_AMOUNT} if they | ||||
|               sign up! | ||||
|             </div> | ||||
| 
 | ||||
|             <CopyLinkButton | ||||
|               url={shareUrl} | ||||
|               tracking="copy group share link" | ||||
|               buttonClassName="btn-md rounded-l-none" | ||||
|               toastClassName={'-left-28 mt-1'} | ||||
|             /> | ||||
|           </Col> | ||||
|         )} | ||||
| 
 | ||||
|         <Col className={'mt-2'}> | ||||
|           <GroupMemberSearch group={group} /> | ||||
|           <div className="mb-2 text-lg">Members</div> | ||||
|           <GroupMemberSearch members={members} group={group} /> | ||||
|         </Col> | ||||
|       </Col> | ||||
|     </> | ||||
|  | @ -461,14 +421,20 @@ function SearchBar(props: { setQuery: (query: string) => void }) { | |||
|   ) | ||||
| } | ||||
| 
 | ||||
| function GroupMemberSearch(props: { group: Group }) { | ||||
| function GroupMemberSearch(props: { members: User[]; group: Group }) { | ||||
|   const [query, setQuery] = useState('') | ||||
|   const members = useMembers(props.group) | ||||
|   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) => | ||||
|       checkAgainstQuery(query, m.name) || checkAgainstQuery(query, m.username) | ||||
|   const matches = sortBy(members, [(member) => member.name]).filter((m) => | ||||
|     searchInAny(query, m.name, m.username) | ||||
|   ) | ||||
|   const matchLimit = 25 | ||||
| 
 | ||||
|  | @ -489,27 +455,6 @@ function GroupMemberSearch(props: { group: Group }) { | |||
|   ) | ||||
| } | ||||
| 
 | ||||
| export function GroupMembersList(props: { group: Group }) { | ||||
|   const { group } = props | ||||
|   const members = useMembers(group).filter((m) => m.id !== group.creatorId) | ||||
|   const maxMembersToShow = 3 | ||||
|   if (group.memberIds.length === 1) return <div /> | ||||
|   return ( | ||||
|     <div className="text-neutral flex flex-wrap gap-1"> | ||||
|       <span className={'text-gray-500'}>Other members</span> | ||||
|       {members.slice(0, maxMembersToShow).map((member, i) => ( | ||||
|         <div key={member.id} className={'flex-shrink'}> | ||||
|           <UserLink name={member.name} username={member.username} /> | ||||
|           {members.length > 1 && i !== members.length - 1 && <span>,</span>} | ||||
|         </div> | ||||
|       ))} | ||||
|       {members.length > maxMembersToShow && ( | ||||
|         <span> & {members.length - maxMembersToShow} more</span> | ||||
|       )} | ||||
|     </div> | ||||
|   ) | ||||
| } | ||||
| 
 | ||||
| function SortedLeaderboard(props: { | ||||
|   users: User[] | ||||
|   scoreFunction: (user: User) => number | ||||
|  | @ -553,14 +498,14 @@ function GroupLeaderboards(props: { | |||
|             <SortedLeaderboard | ||||
|               users={members} | ||||
|               scoreFunction={(user) => traderScores[user.id] ?? 0} | ||||
|               title="🏅 Bettor rankings" | ||||
|               title="🏅 Top bettors" | ||||
|               header="Profit" | ||||
|               maxToShow={maxToShow} | ||||
|             /> | ||||
|             <SortedLeaderboard | ||||
|               users={members} | ||||
|               scoreFunction={(user) => creatorScores[user.id] ?? 0} | ||||
|               title="🏅 Creator rankings" | ||||
|               title="🏅 Top creators" | ||||
|               header="Market volume" | ||||
|               maxToShow={maxToShow} | ||||
|             /> | ||||
|  | @ -600,7 +545,7 @@ function GroupLeaderboards(props: { | |||
| } | ||||
| 
 | ||||
| function AddContractButton(props: { group: Group; user: User }) { | ||||
|   const { group } = props | ||||
|   const { group, user } = props | ||||
|   const [open, setOpen] = useState(false) | ||||
| 
 | ||||
|   async function addContractToCurrentGroup(contract: Contract) { | ||||
|  | @ -610,16 +555,39 @@ function AddContractButton(props: { group: Group; user: User }) { | |||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|       <div className={'flex justify-center'}> | ||||
|         <button | ||||
|           className={clsx('btn btn-sm btn-outline')} | ||||
|           onClick={() => setOpen(true)} | ||||
|         > | ||||
|           <PlusSmIcon className="h-6 w-6" aria-hidden="true" /> question | ||||
|         </button> | ||||
|       </div> | ||||
| 
 | ||||
|       <Modal open={open} setOpen={setOpen} className={'sm:p-0'}> | ||||
|         <Col | ||||
|           className={ | ||||
|             'max-h-[60vh] min-h-[60vh] w-full gap-4 rounded-md bg-white p-8' | ||||
|             'max-h-[60vh] min-h-[60vh] w-full gap-4 rounded-md bg-white' | ||||
|           } | ||||
|         > | ||||
|           <div className={'text-lg text-indigo-700'}> | ||||
|             Add a question to your group | ||||
|           </div> | ||||
|           <div className={'overflow-y-scroll p-1'}> | ||||
|           <Col className="p-8 pb-0"> | ||||
|             <div className={'text-xl text-indigo-700'}> | ||||
|               Add a question to your group | ||||
|             </div> | ||||
| 
 | ||||
|             <Col className="items-center"> | ||||
|               <CreateQuestionButton | ||||
|                 user={user} | ||||
|                 overrideText={'New question'} | ||||
|                 className={'w-48 flex-shrink-0 '} | ||||
|                 query={`?groupId=${group.id}`} | ||||
|               /> | ||||
| 
 | ||||
|               <div className={'mt-2 text-lg text-indigo-700'}>or</div> | ||||
|             </Col> | ||||
|           </Col> | ||||
| 
 | ||||
|           <div className={'overflow-y-scroll sm:px-8'}> | ||||
|             <ContractSearch | ||||
|               hideOrderSelector={true} | ||||
|               onContractClick={addContractToCurrentGroup} | ||||
|  | @ -631,26 +599,6 @@ function AddContractButton(props: { group: Group; user: User }) { | |||
|           </div> | ||||
|         </Col> | ||||
|       </Modal> | ||||
|       <div className={'flex justify-center'}> | ||||
|         <button | ||||
|           className={clsx( | ||||
|             createButtonStyle, | ||||
|             'hidden w-48 whitespace-nowrap border border-black text-black hover:bg-black hover:text-white sm:block' | ||||
|           )} | ||||
|           onClick={() => setOpen(true)} | ||||
|         > | ||||
|           Add an old question | ||||
|         </button> | ||||
|         <button | ||||
|           className={clsx( | ||||
|             createButtonStyle, | ||||
|             'block w-40 whitespace-nowrap border border-black text-black hover:bg-black hover:text-white sm:hidden' | ||||
|           )} | ||||
|           onClick={() => setOpen(true)} | ||||
|         > | ||||
|           Old question | ||||
|         </button> | ||||
|       </div> | ||||
|     </> | ||||
|   ) | ||||
| } | ||||
|  | @ -660,19 +608,19 @@ function JoinGroupButton(props: { | |||
|   user: User | null | undefined | ||||
| }) { | ||||
|   const { group, user } = props | ||||
|   function joinGroup() { | ||||
|   function addUserToGroup() { | ||||
|     if (user && !group.memberIds.includes(user.id)) { | ||||
|       toast.promise(addUserToGroup(group, user.id), { | ||||
|       toast.promise(joinGroup(group, user.id), { | ||||
|         loading: 'Joining group...', | ||||
|         success: 'Joined group!', | ||||
|         error: "Couldn't join group", | ||||
|         error: "Couldn't join group, try again?", | ||||
|       }) | ||||
|     } | ||||
|   } | ||||
|   return ( | ||||
|     <div> | ||||
|       <button | ||||
|         onClick={user ? joinGroup : firebaseLogin} | ||||
|         onClick={user ? addUserToGroup : firebaseLogin} | ||||
|         className={'btn-md btn-outline btn whitespace-nowrap normal-case'} | ||||
|       > | ||||
|         {user ? 'Join group' : 'Login to join group'} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user