multi choice market page
This commit is contained in:
parent
3aa22a7772
commit
adba5135e2
|
@ -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) => ({
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}) {
|
}) {
|
||||||
|
|
|
@ -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' ||
|
||||||
<AnswersGraph contract={contract} bets={bets} />
|
(outcomeType === 'MULTIPLE_CHOICE' && (
|
||||||
)}
|
<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} />}
|
||||||
|
|
|
@ -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} />
|
||||||
|
|
Loading…
Reference in New Issue
Block a user