multi choice market page

This commit is contained in:
mantikoros 2022-07-27 18:05:52 -07:00
parent 3aa22a7772
commit adba5135e2
9 changed files with 33 additions and 24 deletions

View File

@ -23,6 +23,7 @@ import {
BinaryContract, BinaryContract,
FreeResponseContract, FreeResponseContract,
PseudoNumericContract, PseudoNumericContract,
MultipleChoiceContract,
} from './contract' } from './contract'
import { floatingEqual } from './util/math' import { floatingEqual } from './util/math'
@ -200,7 +201,9 @@ export function getContractBetNullMetrics() {
} }
} }
export function getTopAnswer(contract: FreeResponseContract) { export function getTopAnswer(
contract: FreeResponseContract | MultipleChoiceContract
) {
const { answers } = contract const { answers } = contract
const top = maxBy( const top = maxBy(
answers?.map((answer) => ({ answers?.map((answer) => ({

View File

@ -3,7 +3,7 @@ import { useEffect, useRef, useState } from 'react'
import { XIcon } from '@heroicons/react/solid' import { XIcon } from '@heroicons/react/solid'
import { Answer } from 'common/answer' import { Answer } from 'common/answer'
import { FreeResponseContract } from 'common/contract' import { FreeResponseContract, MultipleChoiceContract } from 'common/contract'
import { BuyAmountInput } from '../amount-input' import { BuyAmountInput } from '../amount-input'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { APIError, placeBet } from 'web/lib/firebase/api' import { APIError, placeBet } from 'web/lib/firebase/api'
@ -29,7 +29,7 @@ import { isIOS } from 'web/lib/util/device'
export function AnswerBetPanel(props: { export function AnswerBetPanel(props: {
answer: Answer answer: Answer
contract: FreeResponseContract contract: FreeResponseContract | MultipleChoiceContract
closePanel: () => void closePanel: () => void
className?: string className?: string
isModal?: boolean isModal?: boolean

View File

@ -1,7 +1,7 @@
import clsx from 'clsx' import clsx from 'clsx'
import { Answer } from 'common/answer' import { Answer } from 'common/answer'
import { FreeResponseContract } from 'common/contract' import { FreeResponseContract, MultipleChoiceContract } from 'common/contract'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { Row } from '../layout/row' import { Row } from '../layout/row'
import { Avatar } from '../avatar' import { Avatar } from '../avatar'
@ -13,7 +13,7 @@ import { Linkify } from '../linkify'
export function AnswerItem(props: { export function AnswerItem(props: {
answer: Answer answer: Answer
contract: FreeResponseContract contract: FreeResponseContract | MultipleChoiceContract
showChoice: 'radio' | 'checkbox' | undefined showChoice: 'radio' | 'checkbox' | undefined
chosenProb: number | undefined chosenProb: number | undefined
totalChosenProb?: number totalChosenProb?: number

View File

@ -2,7 +2,7 @@ import clsx from 'clsx'
import { sum } from 'lodash' import { sum } from 'lodash'
import { useState } from 'react' import { useState } from 'react'
import { Contract, FreeResponse } from 'common/contract' import { FreeResponseContract, MultipleChoiceContract } from 'common/contract'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { APIError, resolveMarket } from 'web/lib/firebase/api' import { APIError, resolveMarket } from 'web/lib/firebase/api'
import { Row } from '../layout/row' import { Row } from '../layout/row'
@ -11,7 +11,7 @@ import { ResolveConfirmationButton } from '../confirmation-button'
import { removeUndefinedProps } from 'common/util/object' import { removeUndefinedProps } from 'common/util/object'
export function AnswerResolvePanel(props: { export function AnswerResolvePanel(props: {
contract: Contract & FreeResponse contract: FreeResponseContract | MultipleChoiceContract
resolveOption: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined resolveOption: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined
setResolveOption: ( setResolveOption: (
option: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined option: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined

View File

@ -5,14 +5,14 @@ import { groupBy, sortBy, sumBy } from 'lodash'
import { memo } from 'react' import { memo } from 'react'
import { Bet } from 'common/bet' import { Bet } from 'common/bet'
import { FreeResponseContract } from 'common/contract' import { FreeResponseContract, MultipleChoiceContract } from 'common/contract'
import { getOutcomeProbability } from 'common/calculate' import { getOutcomeProbability } from 'common/calculate'
import { useWindowSize } from 'web/hooks/use-window-size' import { useWindowSize } from 'web/hooks/use-window-size'
const NUM_LINES = 6 const NUM_LINES = 6
export const AnswersGraph = memo(function AnswersGraph(props: { export const AnswersGraph = memo(function AnswersGraph(props: {
contract: FreeResponseContract contract: FreeResponseContract | MultipleChoiceContract
bets: Bet[] bets: Bet[]
height?: number height?: number
}) { }) {
@ -178,7 +178,7 @@ function formatTime(
return d.format(format) return d.format(format)
} }
const computeProbsByOutcome = (bets: Bet[], contract: FreeResponseContract) => { const computeProbsByOutcome = (bets: Bet[], contract: FreeResponseContract | MultipleChoiceContract) => {
const { totalBets } = contract const { totalBets } = contract
const betsByOutcome = groupBy(bets, (bet) => bet.outcome) const betsByOutcome = groupBy(bets, (bet) => bet.outcome)

View File

@ -1,7 +1,7 @@
import { sortBy, partition, sum, uniq } from 'lodash' import { sortBy, partition, sum, uniq } from 'lodash'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { FreeResponseContract } from 'common/contract' import { FreeResponseContract, MultipleChoiceContract } from 'common/contract'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { useUser } from 'web/hooks/use-user' import { useUser } from 'web/hooks/use-user'
import { getDpmOutcomeProbability } from 'common/calculate-dpm' import { getDpmOutcomeProbability } from 'common/calculate-dpm'
@ -25,9 +25,12 @@ import { UserLink } from 'web/components/user-page'
import { Linkify } from 'web/components/linkify' import { Linkify } from 'web/components/linkify'
import { BuyButton } from 'web/components/yes-no-selector' import { BuyButton } from 'web/components/yes-no-selector'
export function AnswersPanel(props: { contract: FreeResponseContract }) { export function AnswersPanel(props: {
contract: FreeResponseContract | MultipleChoiceContract
}) {
const { contract } = props const { contract } = props
const { creatorId, resolution, resolutions, totalBets } = contract const { creatorId, resolution, resolutions, totalBets, outcomeType } =
contract
const answers = useAnswers(contract.id) ?? contract.answers const answers = useAnswers(contract.id) ?? contract.answers
const [winningAnswers, losingAnswers] = partition( const [winningAnswers, losingAnswers] = partition(
@ -131,7 +134,8 @@ export function AnswersPanel(props: { contract: FreeResponseContract }) {
<div className="pb-4 text-gray-500">No answers yet...</div> <div className="pb-4 text-gray-500">No answers yet...</div>
)} )}
{tradingAllowed(contract) && {outcomeType === 'FREE_RESPONSE' &&
tradingAllowed(contract) &&
(!resolveOption || resolveOption === 'CANCEL') && ( (!resolveOption || resolveOption === 'CANCEL') && (
<CreateAnswerPanel contract={contract} /> <CreateAnswerPanel contract={contract} />
)} )}
@ -152,7 +156,7 @@ export function AnswersPanel(props: { contract: FreeResponseContract }) {
} }
function getAnswerItems( function getAnswerItems(
contract: FreeResponseContract, contract: FreeResponseContract | MultipleChoiceContract,
answers: Answer[], answers: Answer[],
user: User | undefined | null user: User | undefined | null
) { ) {
@ -178,7 +182,7 @@ function getAnswerItems(
} }
function OpenAnswer(props: { function OpenAnswer(props: {
contract: FreeResponseContract contract: FreeResponseContract | MultipleChoiceContract
answer: Answer answer: Answer
items: ActivityItem[] items: ActivityItem[]
type: string type: string

View File

@ -8,6 +8,7 @@ import {
BinaryContract, BinaryContract,
Contract, Contract,
FreeResponseContract, FreeResponseContract,
MultipleChoiceContract,
NumericContract, NumericContract,
PseudoNumericContract, PseudoNumericContract,
} from 'common/contract' } from 'common/contract'
@ -227,7 +228,7 @@ function FreeResponseTopAnswer(props: {
} }
export function FreeResponseResolutionOrChance(props: { export function FreeResponseResolutionOrChance(props: {
contract: FreeResponseContract contract: FreeResponseContract | MultipleChoiceContract
truncate: 'short' | 'long' | 'none' truncate: 'short' | 'long' | 'none'
className?: string className?: string
}) { }) {

View File

@ -85,13 +85,13 @@ export const ContractOverview = (props: {
{tradingAllowed(contract) && <BetRow contract={contract} />} {tradingAllowed(contract) && <BetRow contract={contract} />}
</Row> </Row>
) : ( ) : (
outcomeType === 'FREE_RESPONSE' && outcomeType === 'FREE_RESPONSE' ||
resolution && ( (outcomeType === 'MULTIPLE_CHOICE' && resolution && (
<FreeResponseResolutionOrChance <FreeResponseResolutionOrChance
contract={contract} contract={contract}
truncate="none" truncate="none"
/> />
) ))
)} )}
{outcomeType === 'NUMERIC' && ( {outcomeType === 'NUMERIC' && (
@ -110,9 +110,10 @@ export const ContractOverview = (props: {
{(isBinary || isPseudoNumeric) && ( {(isBinary || isPseudoNumeric) && (
<ContractProbGraph contract={contract} bets={bets} /> <ContractProbGraph contract={contract} bets={bets} />
)}{' '} )}{' '}
{outcomeType === 'FREE_RESPONSE' && ( {outcomeType === 'FREE_RESPONSE' ||
(outcomeType === 'MULTIPLE_CHOICE' && (
<AnswersGraph contract={contract} bets={bets} /> <AnswersGraph contract={contract} bets={bets} />
)} ))}
{outcomeType === 'NUMERIC' && <NumericGraph contract={contract} />} {outcomeType === 'NUMERIC' && <NumericGraph contract={contract} />}
{(contract.description || isCreator) && <Spacer h={6} />} {(contract.description || isCreator) && <Spacer h={6} />}
{isCreator && <ShareMarket className="px-2" contract={contract} />} {isCreator && <ShareMarket className="px-2" contract={contract} />}

View File

@ -217,7 +217,7 @@ export function ContractPageContent(
/> />
)} )}
{outcomeType === 'FREE_RESPONSE' && ( {outcomeType === 'FREE_RESPONSE' || outcomeType === 'MULTIPLE_CHOICE' && (
<> <>
<Spacer h={4} /> <Spacer h={4} />
<AnswersPanel contract={contract} /> <AnswersPanel contract={contract} />