Style the Bounty type in a few more places

This commit is contained in:
Austin Chen 2022-08-14 21:09:48 -07:00
parent 2359b5b337
commit 5690444135
6 changed files with 84 additions and 26 deletions

View File

@ -18,6 +18,7 @@ export type AnyContractType =
| (DPM & FreeResponse) | (DPM & FreeResponse)
| (DPM & Numeric) | (DPM & Numeric)
| (DPM & MultipleChoice) | (DPM & MultipleChoice)
| (DPM & Bounty)
export type Contract<T extends AnyContractType = AnyContractType> = { export type Contract<T extends AnyContractType = AnyContractType> = {
id: string id: string
@ -65,11 +66,11 @@ export type PseudoNumericContract = Contract & PseudoNumeric
export type NumericContract = Contract & Numeric export type NumericContract = Contract & Numeric
export type FreeResponseContract = Contract & FreeResponse export type FreeResponseContract = Contract & FreeResponse
export type MultipleChoiceContract = Contract & MultipleChoice export type MultipleChoiceContract = Contract & MultipleChoice
export type BountyContract = Contract & Bounty
export type DPMContract = Contract & DPM export type DPMContract = Contract & DPM
export type CPMMContract = Contract & CPMM export type CPMMContract = Contract & CPMM
export type DPMBinaryContract = BinaryContract & DPM export type DPMBinaryContract = BinaryContract & DPM
export type CPMMBinaryContract = BinaryContract & CPMM export type CPMMBinaryContract = BinaryContract & CPMM
export type BountyContract = Contract & Bounty
export type DPM = { export type DPM = {
mechanism: 'dpm-2' mechanism: 'dpm-2'
@ -133,12 +134,15 @@ export type Bounty = {
outcomeType: 'BOUNTY' outcomeType: 'BOUNTY'
// One answer for each submission // One answer for each submission
answers: Answer[] answers: Answer[]
// Resolution = which answer id the bounty went to
resolution?: string | 'MKT' | 'CANCEL'
resolutions?: { [outcome: string]: number } // Used for MKT resolution
// Amount contributed to each bounty, and by who
prizes: { prizes: {
[giverId: string]: number [giverId: string]: number
} }
prizeTotal: number prizeTotal: number
// Resolution = which ID the bounty went to
resolution?: string | 'MKT' | 'CANCEL'
} }
export type outcomeType = AnyOutcomeType['outcomeType'] export type outcomeType = AnyOutcomeType['outcomeType']

View File

@ -1,6 +1,7 @@
import { range } from 'lodash' import { range } from 'lodash'
import { import {
Binary, Binary,
Bounty,
Contract, Contract,
CPMM, CPMM,
DPM, DPM,
@ -45,16 +46,22 @@ export function getNewContract(
) )
const lowercaseTags = tags.map((tag) => tag.toLowerCase()) const lowercaseTags = tags.map((tag) => tag.toLowerCase())
const propsByOutcomeType = const PROPS = {
outcomeType === 'BINARY' BINARY: getBinaryCpmmProps(initialProb, ante), // getBinaryDpmProps(initialProb, ante)
? getBinaryCpmmProps(initialProb, ante) // getBinaryDpmProps(initialProb, ante) PSEUDO_NUMERIC: getPseudoNumericCpmmProps(
: outcomeType === 'PSEUDO_NUMERIC' initialProb,
? getPseudoNumericCpmmProps(initialProb, ante, min, max, isLogScale) ante,
: outcomeType === 'NUMERIC' min,
? getNumericProps(ante, bucketCount, min, max) max,
: outcomeType === 'MULTIPLE_CHOICE' isLogScale
? getMultipleChoiceProps(ante, answers) ),
: getFreeAnswerProps(ante) FREE_RESPONSE: getFreeAnswerProps(ante),
MULTIPLE_CHOICE: getMultipleChoiceProps(ante, answers),
NUMERIC: getNumericProps(ante, bucketCount, min, max),
BOUNTY: getBountyProps(ante, creator),
}
const propsByOutcomeType = PROPS[outcomeType] || PROPS['FREE_RESPONSE']
const contract: Contract = removeUndefinedProps({ const contract: Contract = removeUndefinedProps({
id, id,
@ -157,6 +164,18 @@ const getFreeAnswerProps = (ante: number) => {
return system return system
} }
function getBountyProps(ante: number, creator: User) {
const system: DPM & Bounty = {
...getFreeAnswerProps(ante),
outcomeType: 'BOUNTY',
prizes: {
[creator.id]: ante,
},
prizeTotal: ante,
}
return system
}
const getMultipleChoiceProps = (ante: number, answers: string[]) => { const getMultipleChoiceProps = (ante: number, answers: string[]) => {
const numAnswers = answers.length const numAnswers = answers.length
const betAnte = ante / numAnswers const betAnte = ante / numAnswers

View File

@ -1,11 +1,16 @@
import clsx from 'clsx' import clsx from 'clsx'
import Link from 'next/link' import Link from 'next/link'
import { Row } from '../layout/row' import { Row } from '../layout/row'
import { formatLargeNumber, formatPercent } from 'common/util/format' import {
formatLargeNumber,
formatMoney,
formatPercent,
} from 'common/util/format'
import { contractPath, getBinaryProbPercent } from 'web/lib/firebase/contracts' import { contractPath, getBinaryProbPercent } from 'web/lib/firebase/contracts'
import { Col } from '../layout/col' import { Col } from '../layout/col'
import { import {
BinaryContract, BinaryContract,
BountyContract,
Contract, Contract,
FreeResponseContract, FreeResponseContract,
MultipleChoiceContract, MultipleChoiceContract,
@ -160,6 +165,13 @@ export function ContractCard(props: {
truncate="long" truncate="long"
/> />
)} )}
{outcomeType === 'BOUNTY' && (
<BountyValue
className="items-center self-center pr-5"
contract={contract}
/>
)}
<ProbBar contract={contract} /> <ProbBar contract={contract} />
</> </>
)} )}
@ -202,6 +214,23 @@ export function BinaryResolutionOrChance(props: {
) )
} }
export function BountyValue(props: {
contract: BountyContract
large?: boolean
className?: string
}) {
const { contract, large, className } = props
const textColor = `text-${getColor(contract)}`
return (
<Col className={clsx(large ? 'text-3xl' : 'text-2xl', className)}>
<div className={textColor}>{formatMoney(contract.prizeTotal)}</div>
<div className={clsx(textColor, large ? 'text-xl' : 'text-base')}>
bounty
</div>
</Col>
)
}
function FreeResponseTopAnswer(props: { function FreeResponseTopAnswer(props: {
contract: FreeResponseContract | MultipleChoiceContract contract: FreeResponseContract | MultipleChoiceContract
truncate: 'short' | 'long' | 'none' truncate: 'short' | 'long' | 'none'

View File

@ -32,14 +32,15 @@ export function ContractInfoDialog(props: { contract: Contract; bets: Bet[] }) {
'userId' 'userId'
).length ).length
const typeDisplay = const TYPES = {
outcomeType === 'BINARY' BINARY: 'YES / NO',
? 'YES / NO' FREE_RESPONSE: 'Free Response',
: outcomeType === 'FREE_RESPONSE' MULTIPLE_CHOICE: 'Multiple Choice',
? 'Free response' NUMERIC: 'Numeric (deprecated)',
: outcomeType === 'MULTIPLE_CHOICE' PSEUDO_NUMERIC: 'Numeric',
? 'Multiple choice' BOUNTY: 'Bounty',
: 'Numeric' }
const typeDisplay = TYPES[outcomeType] || 'Unknown'
return ( return (
<> <>

View File

@ -10,6 +10,7 @@ import { Row } from '../layout/row'
import { Linkify } from '../linkify' import { Linkify } from '../linkify'
import { import {
BinaryResolutionOrChance, BinaryResolutionOrChance,
BountyValue,
FreeResponseResolutionOrChance, FreeResponseResolutionOrChance,
NumericResolutionOrExpectation, NumericResolutionOrExpectation,
PseudoNumericResolutionOrExpectation, PseudoNumericResolutionOrExpectation,
@ -44,7 +45,6 @@ export const ContractOverview = (props: {
<div className="text-2xl text-indigo-700 md:text-3xl"> <div className="text-2xl text-indigo-700 md:text-3xl">
<Linkify text={question} /> <Linkify text={question} />
</div> </div>
{isBinary && ( {isBinary && (
<BinaryResolutionOrChance <BinaryResolutionOrChance
className="hidden items-end xl:flex" className="hidden items-end xl:flex"
@ -52,20 +52,24 @@ export const ContractOverview = (props: {
large large
/> />
)} )}
{isPseudoNumeric && ( {isPseudoNumeric && (
<PseudoNumericResolutionOrExpectation <PseudoNumericResolutionOrExpectation
contract={contract} contract={contract}
className="hidden items-end xl:flex" className="hidden items-end xl:flex"
/> />
)} )}
{outcomeType === 'NUMERIC' && ( {outcomeType === 'NUMERIC' && (
<NumericResolutionOrExpectation <NumericResolutionOrExpectation
contract={contract} contract={contract}
className="hidden items-end xl:flex" className="hidden items-end xl:flex"
/> />
)} )}
{outcomeType === 'BOUNTY' && (
<BountyValue
contract={contract}
className="hidden items-end xl:flex"
/>
)}
</Row> </Row>
{isBinary ? ( {isBinary ? (

View File

@ -4,6 +4,7 @@ import { getProbability } from 'common/calculate'
import { getValueFromBucket } from 'common/calculate-dpm' import { getValueFromBucket } from 'common/calculate-dpm'
import { import {
BinaryContract, BinaryContract,
BountyContract,
Contract, Contract,
FreeResponseContract, FreeResponseContract,
MultipleChoiceContract, MultipleChoiceContract,
@ -77,7 +78,7 @@ export function BinaryContractOutcomeLabel(props: {
} }
export function FreeResponseOutcomeLabel(props: { export function FreeResponseOutcomeLabel(props: {
contract: FreeResponseContract | MultipleChoiceContract contract: FreeResponseContract | MultipleChoiceContract | BountyContract
resolution: string | 'CANCEL' | 'MKT' resolution: string | 'CANCEL' | 'MKT'
truncate: 'short' | 'long' | 'none' truncate: 'short' | 'long' | 'none'
answerClassName?: string answerClassName?: string