import clsx from 'clsx' import Link from 'next/link' import { Row } from '../layout/row' import { formatLargeNumber, formatPercent } from 'common/util/format' import { Contract, contractPath, getBinaryProbPercent, getBinaryProb, } from 'web/lib/firebase/contracts' import { Col } from '../layout/col' import { Binary, CPMM, DPM, FreeResponse, FreeResponseContract, FullContract, NumericContract, } from 'common/contract' import { AnswerLabel, BinaryContractOutcomeLabel, FreeResponseOutcomeLabel, OUTCOME_TO_COLOR, } from '../outcome-label' import { getOutcomeProbability, getTopAnswer } from 'common/calculate' import { AvatarDetails, MiscDetails } from './contract-details' import { getExpectedValue, getValueFromBucket } from 'common/calculate-dpm' import { PaperAirplaneIcon } from '@heroicons/react/outline' import { PaperAirplaneIcon as SolidPlaneIcon } from '@heroicons/react/solid' // Return a number from 0 to 1 for this contract // Resolved contracts are set to 1, for coloring purposes (even if NO) function getProb(contract: Contract) { const { outcomeType, resolution } = contract return resolution ? 1 : outcomeType === 'BINARY' ? getBinaryProb(contract) : outcomeType === 'FREE_RESPONSE' ? getOutcomeProbability(contract, getTopAnswer(contract)?.id || '') : outcomeType === 'NUMERIC' ? getNumericScale(contract as NumericContract) : 1 // Should not happen } function getNumericScale(contract: NumericContract) { const { min, max } = contract const ev = getExpectedValue(contract) return (ev - min) / (max - min) } function getColor(contract: Contract) { // TODO: Not sure why eg green-400 doesn't work here; try upgrading Tailwind // TODO: Try injecting a gradient here // return 'primary' const { resolution } = contract if (resolution) { return ( // @ts-ignore; TODO: Have better typing for contract.resolution? OUTCOME_TO_COLOR[resolution] || // If resolved to a FR answer, use 'primary' 'primary' ) } if (contract.outcomeType === 'NUMERIC') { return 'blue-400' } const marketClosed = (contract.closeTime || Infinity) < Date.now() return marketClosed ? 'gray-400' : getProb(contract) >= 0.5 ? 'primary' : 'red-400' } export function ContractCard(props: { contract: Contract showHotVolume?: boolean showCloseTime?: boolean className?: string }) { const { contract, showHotVolume, showCloseTime, className } = props const { question, outcomeType } = contract const prob = getProb(contract) const color = getColor(contract) const marketClosed = (contract.closeTime || Infinity) < Date.now() const showTopBar = prob >= 0.5 || marketClosed return (

{question}

{outcomeType === 'FREE_RESPONSE' && ( } truncate="long" /> )} {contract.createdTime % 3 == 0 ? ( ) : ( )} {outcomeType === 'BINARY' && ( )} {outcomeType === 'NUMERIC' && ( )} {outcomeType === 'FREE_RESPONSE' && ( } truncate="long" /> )} {contract.createdTime % 3 == 2 ? ( ) : ( )}
) } export function BinaryResolutionOrChance(props: { contract: FullContract large?: boolean className?: string }) { const { contract, large, className } = props const { resolution } = contract const textColor = `text-${getColor(contract)}` return ( {resolution ? ( <>
Resolved
) : ( <>
{getBinaryProbPercent(contract)}
chance
)} ) } function FreeResponseTopAnswer(props: { contract: FreeResponseContract truncate: 'short' | 'long' | 'none' className?: string }) { const { contract, truncate, className } = props const { resolution } = contract const topAnswer = getTopAnswer(contract) return topAnswer ? ( ) : null } export function FreeResponseResolutionOrChance(props: { contract: FreeResponseContract truncate: 'short' | 'long' | 'none' className?: string }) { const { contract, truncate, className } = props const { resolution } = contract const topAnswer = getTopAnswer(contract) const textColor = `text-${getColor(contract)}` return ( {resolution ? ( <>
Resolved
) : ( topAnswer && (
{formatPercent(getOutcomeProbability(contract, topAnswer.id))}
chance
) )} ) } export function NumericResolutionOrExpectation(props: { contract: NumericContract className?: string }) { const { contract, className } = props const { resolution } = contract const textColor = `text-${getColor(contract)}` const resolutionValue = contract.resolutionValue ?? getValueFromBucket(resolution ?? '', contract) return ( {resolution ? ( <>
Resolved
{resolutionValue}
) : ( <>
{formatLargeNumber(getExpectedValue(contract))}
expected
)} ) }