Pull out quick bet display component
This commit is contained in:
parent
a204380f57
commit
8e746ce0cb
|
@ -25,7 +25,7 @@ import {
|
||||||
import { getOutcomeProbability, getTopAnswer } from 'common/calculate'
|
import { getOutcomeProbability, getTopAnswer } from 'common/calculate'
|
||||||
import { AvatarDetails, MiscDetails } from './contract-details'
|
import { AvatarDetails, MiscDetails } from './contract-details'
|
||||||
import { getExpectedValue, getValueFromBucket } from 'common/calculate-dpm'
|
import { getExpectedValue, getValueFromBucket } from 'common/calculate-dpm'
|
||||||
import { QuickBet, QuickOutcomeView, ProbBar, getColor } from './quick-bet'
|
import { QuickBet, ProbBar, getColor } from './quick-bet'
|
||||||
import { useContractWithPreload } from 'web/hooks/use-contract'
|
import { useContractWithPreload } from 'web/hooks/use-contract'
|
||||||
|
|
||||||
export function ContractCard(props: {
|
export function ContractCard(props: {
|
||||||
|
@ -90,7 +90,28 @@ export function ContractCard(props: {
|
||||||
<QuickBet contract={contract} />
|
<QuickBet contract={contract} />
|
||||||
) : (
|
) : (
|
||||||
<Col className="m-auto pl-2">
|
<Col className="m-auto pl-2">
|
||||||
<QuickOutcomeView contract={contract} />
|
{outcomeType === 'BINARY' && (
|
||||||
|
<BinaryResolutionOrChance
|
||||||
|
className="items-center"
|
||||||
|
contract={contract}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{outcomeType === 'NUMERIC' && (
|
||||||
|
<NumericResolutionOrExpectation
|
||||||
|
className="items-center"
|
||||||
|
contract={contract as NumericContract}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{outcomeType === 'FREE_RESPONSE' && (
|
||||||
|
<FreeResponseResolutionOrChance
|
||||||
|
className="self-end text-gray-600"
|
||||||
|
contract={contract as FullContract<DPM, FreeResponse>}
|
||||||
|
truncate="long"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<ProbBar contract={contract} />
|
||||||
</Col>
|
</Col>
|
||||||
)}
|
)}
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -103,10 +124,8 @@ export function BinaryResolutionOrChance(props: {
|
||||||
contract: FullContract<DPM | CPMM, Binary>
|
contract: FullContract<DPM | CPMM, Binary>
|
||||||
large?: boolean
|
large?: boolean
|
||||||
className?: string
|
className?: string
|
||||||
hideText?: boolean
|
|
||||||
override?: string
|
|
||||||
}) {
|
}) {
|
||||||
const { contract, large, className, hideText, override } = props
|
const { contract, large, className } = props
|
||||||
const { resolution } = contract
|
const { resolution } = contract
|
||||||
const textColor = `text-${getColor(contract)}`
|
const textColor = `text-${getColor(contract)}`
|
||||||
|
|
||||||
|
@ -127,13 +146,11 @@ export function BinaryResolutionOrChance(props: {
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className={clsx(textColor, 'transition-all')}>
|
<div className={clsx(textColor, 'transition-all')}>
|
||||||
{override ?? getBinaryProbPercent(contract)}
|
{getBinaryProbPercent(contract)}
|
||||||
</div>
|
</div>
|
||||||
{!hideText && (
|
|
||||||
<div className={clsx(textColor, large ? 'text-xl' : 'text-base')}>
|
<div className={clsx(textColor, large ? 'text-xl' : 'text-base')}>
|
||||||
chance
|
chance
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -162,10 +179,8 @@ export function FreeResponseResolutionOrChance(props: {
|
||||||
contract: FreeResponseContract
|
contract: FreeResponseContract
|
||||||
truncate: 'short' | 'long' | 'none'
|
truncate: 'short' | 'long' | 'none'
|
||||||
className?: string
|
className?: string
|
||||||
hideText?: boolean
|
|
||||||
override?: string
|
|
||||||
}) {
|
}) {
|
||||||
const { contract, truncate, className, hideText, override } = props
|
const { contract, truncate, className } = props
|
||||||
const { resolution } = contract
|
const { resolution } = contract
|
||||||
|
|
||||||
const topAnswer = getTopAnswer(contract)
|
const topAnswer = getTopAnswer(contract)
|
||||||
|
@ -188,10 +203,9 @@ export function FreeResponseResolutionOrChance(props: {
|
||||||
<Row className="items-center gap-6">
|
<Row className="items-center gap-6">
|
||||||
<Col className={clsx('text-3xl', textColor)}>
|
<Col className={clsx('text-3xl', textColor)}>
|
||||||
<div>
|
<div>
|
||||||
{override ??
|
{formatPercent(getOutcomeProbability(contract, topAnswer.id))}
|
||||||
formatPercent(getOutcomeProbability(contract, topAnswer.id))}
|
|
||||||
</div>
|
</div>
|
||||||
{!hideText && <div className="text-base">chance</div>}
|
<div className="text-base">chance</div>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
)
|
)
|
||||||
|
@ -203,10 +217,8 @@ export function FreeResponseResolutionOrChance(props: {
|
||||||
export function NumericResolutionOrExpectation(props: {
|
export function NumericResolutionOrExpectation(props: {
|
||||||
contract: NumericContract
|
contract: NumericContract
|
||||||
className?: string
|
className?: string
|
||||||
hideText?: boolean
|
|
||||||
override?: string
|
|
||||||
}) {
|
}) {
|
||||||
const { contract, className, hideText, override } = props
|
const { contract, className } = props
|
||||||
const { resolution } = contract
|
const { resolution } = contract
|
||||||
const textColor = `text-${getColor(contract)}`
|
const textColor = `text-${getColor(contract)}`
|
||||||
|
|
||||||
|
@ -223,11 +235,9 @@ export function NumericResolutionOrExpectation(props: {
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className={clsx('text-3xl', textColor)}>
|
<div className={clsx('text-3xl', textColor)}>
|
||||||
{override ?? formatLargeNumber(getExpectedValue(contract))}
|
{formatLargeNumber(getExpectedValue(contract))}
|
||||||
</div>
|
</div>
|
||||||
{!hideText && (
|
|
||||||
<div className={clsx('text-base', textColor)}>expected</div>
|
<div className={clsx('text-base', textColor)}>expected</div>
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
|
|
|
@ -13,14 +13,19 @@ import {
|
||||||
Binary,
|
Binary,
|
||||||
NumericContract,
|
NumericContract,
|
||||||
FreeResponse,
|
FreeResponse,
|
||||||
|
FreeResponseContract,
|
||||||
} from 'common/contract'
|
} from 'common/contract'
|
||||||
import { formatMoney, formatPercent } from 'common/util/format'
|
import {
|
||||||
|
formatLargeNumber,
|
||||||
|
formatMoney,
|
||||||
|
formatPercent,
|
||||||
|
} from 'common/util/format'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import toast from 'react-hot-toast'
|
import toast from 'react-hot-toast'
|
||||||
import { useUser } from 'web/hooks/use-user'
|
import { useUser } from 'web/hooks/use-user'
|
||||||
import { useUserContractBets } from 'web/hooks/use-user-bets'
|
import { useUserContractBets } from 'web/hooks/use-user-bets'
|
||||||
import { placeBet } from 'web/lib/firebase/api-call'
|
import { placeBet } from 'web/lib/firebase/api-call'
|
||||||
import { getBinaryProb } from 'web/lib/firebase/contracts'
|
import { getBinaryProb, getBinaryProbPercent } from 'web/lib/firebase/contracts'
|
||||||
import TriangleDownFillIcon from 'web/lib/icons/triangle-down-fill-icon'
|
import TriangleDownFillIcon from 'web/lib/icons/triangle-down-fill-icon'
|
||||||
import TriangleFillIcon from 'web/lib/icons/triangle-fill-icon'
|
import TriangleFillIcon from 'web/lib/icons/triangle-fill-icon'
|
||||||
import { Col } from '../layout/col'
|
import { Col } from '../layout/col'
|
||||||
|
@ -71,7 +76,7 @@ export function QuickBet(props: { contract: Contract }) {
|
||||||
// Catch any errors from hovering on an invalid option
|
// Catch any errors from hovering on an invalid option
|
||||||
}
|
}
|
||||||
|
|
||||||
const color = getColor(contract)
|
const color = getColor(contract, previewProb)
|
||||||
|
|
||||||
async function placeQuickBet(direction: 'UP' | 'DOWN') {
|
async function placeQuickBet(direction: 'UP' | 'DOWN') {
|
||||||
const betPromise = async () => {
|
const betPromise = async () => {
|
||||||
|
@ -170,8 +175,7 @@ export function QuickBet(props: { contract: Contract }) {
|
||||||
|
|
||||||
export function ProbBar(props: { contract: Contract; previewProb?: number }) {
|
export function ProbBar(props: { contract: Contract; previewProb?: number }) {
|
||||||
const { contract, previewProb } = props
|
const { contract, previewProb } = props
|
||||||
// TODO: Switch preview color as it changes from green to red
|
const color = getColor(contract, previewProb)
|
||||||
const color = getColor(contract)
|
|
||||||
const prob = previewProb ?? getProb(contract)
|
const prob = previewProb ?? getProb(contract)
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -195,47 +199,40 @@ export function ProbBar(props: { contract: Contract; previewProb?: number }) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: just directly code in the outcomes for quick bet, rather than relying on
|
function QuickOutcomeView(props: {
|
||||||
// code resuse. Too many differences anyways
|
|
||||||
export function QuickOutcomeView(props: {
|
|
||||||
contract: Contract
|
contract: Contract
|
||||||
previewProb?: number
|
previewProb?: number
|
||||||
|
caption?: 'chance' | 'expected'
|
||||||
}) {
|
}) {
|
||||||
const { contract, previewProb } = props
|
const { contract, previewProb, caption } = props
|
||||||
const { outcomeType } = contract
|
const { outcomeType } = contract
|
||||||
|
// If there's a preview probability,
|
||||||
const override =
|
const override =
|
||||||
previewProb === undefined ? undefined : formatPercent(previewProb)
|
previewProb === undefined ? undefined : formatPercent(previewProb)
|
||||||
|
const textColor = `text-${getColor(contract, previewProb)}`
|
||||||
|
|
||||||
|
let display: string | undefined
|
||||||
|
switch (outcomeType) {
|
||||||
|
case 'BINARY':
|
||||||
|
display = getBinaryProbPercent(contract)
|
||||||
|
break
|
||||||
|
case 'NUMERIC':
|
||||||
|
display = formatLargeNumber(getExpectedValue(contract as NumericContract))
|
||||||
|
break
|
||||||
|
case 'FREE_RESPONSE':
|
||||||
|
const topAnswer = getTopAnswer(contract as FreeResponseContract)
|
||||||
|
display =
|
||||||
|
topAnswer &&
|
||||||
|
formatPercent(getOutcomeProbability(contract, topAnswer.id))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Col className={clsx('items-center text-3xl', textColor)}>
|
||||||
{outcomeType === 'BINARY' && (
|
{override ?? display}
|
||||||
<BinaryResolutionOrChance
|
{caption && <div className="text-base">{caption}</div>}
|
||||||
className="items-center"
|
|
||||||
contract={contract}
|
|
||||||
hideText
|
|
||||||
override={override}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{outcomeType === 'NUMERIC' && (
|
|
||||||
<NumericResolutionOrExpectation
|
|
||||||
className="items-center"
|
|
||||||
contract={contract as NumericContract}
|
|
||||||
hideText
|
|
||||||
override={override}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{outcomeType === 'FREE_RESPONSE' && (
|
|
||||||
<FreeResponseResolutionOrChance
|
|
||||||
className="self-end text-gray-600"
|
|
||||||
contract={contract as FullContract<DPM, FreeResponse>}
|
|
||||||
truncate="long"
|
|
||||||
hideText
|
|
||||||
override={override}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<ProbBar contract={contract} previewProb={previewProb} />
|
<ProbBar contract={contract} previewProb={previewProb} />
|
||||||
</>
|
</Col>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +257,7 @@ function getNumericScale(contract: NumericContract) {
|
||||||
return (ev - min) / (max - min)
|
return (ev - min) / (max - min)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getColor(contract: Contract) {
|
export function getColor(contract: Contract, previewProb?: number) {
|
||||||
// TODO: Not sure why eg green-400 doesn't work here; try upgrading Tailwind
|
// TODO: Not sure why eg green-400 doesn't work here; try upgrading Tailwind
|
||||||
// TODO: Try injecting a gradient here
|
// TODO: Try injecting a gradient here
|
||||||
// return 'primary'
|
// return 'primary'
|
||||||
|
@ -278,9 +275,6 @@ export function getColor(contract: Contract) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const marketClosed = (contract.closeTime || Infinity) < Date.now()
|
const marketClosed = (contract.closeTime || Infinity) < Date.now()
|
||||||
return marketClosed
|
const prob = previewProb ?? getProb(contract)
|
||||||
? 'gray-400'
|
return marketClosed ? 'gray-400' : prob >= 0.5 ? 'primary' : 'red-400'
|
||||||
: getProb(contract) >= 0.5
|
|
||||||
? 'primary'
|
|
||||||
: 'red-400'
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user