Remove resolved panel, move info into contract overview.

This commit is contained in:
jahooma 2021-12-14 12:51:30 -06:00
parent 72f77c668f
commit 6e61b38a9b
5 changed files with 75 additions and 102 deletions

View File

@ -1,17 +1,31 @@
import React from 'react' import React from 'react'
import { compute, Contract } from '../lib/firebase/contracts' import { compute, Contract, deleteContract } from '../lib/firebase/contracts'
import { Col } from './layout/col' import { Col } from './layout/col'
import { Spacer } from './layout/spacer' import { Spacer } from './layout/spacer'
import { ContractProbGraph } from './contract-prob-graph' import { ContractProbGraph } from './contract-prob-graph'
import { ContractDetails } from './contracts-list' import { ContractDetails } from './contracts-list'
import router from 'next/router'
import { useUser } from '../hooks/use-user'
export const ContractOverview = (props: { export const ContractOverview = (props: {
contract: Contract contract: Contract
className?: string className?: string
}) => { }) => {
const { contract, className } = props const { contract, className } = props
const { probPercent } = compute(contract) const { resolution, creatorId, isResolved } = contract
const { probPercent, volume } = compute(contract)
const user = useUser()
const isCreator = user?.id === creatorId
const resolutionColor =
resolution === 'YES'
? 'text-primary'
: resolution === 'NO'
? 'text-red-400'
: resolution === 'CANCEL'
? 'text-yellow-400'
: ''
return ( return (
<Col className={className}> <Col className={className}>
<Col className="justify-between md:flex-row"> <Col className="justify-between md:flex-row">
@ -23,12 +37,17 @@ export const ContractOverview = (props: {
<ContractDetails contract={contract} /> <ContractDetails contract={contract} />
</Col> </Col>
{!contract.resolution && {resolution ? (
<Col className="text-4xl mt-4 md:mt-2 md:ml-4 md:mr-6 items-end self-center md:self-start">
<div className="text-xl text-gray-500">Resolved:</div>
<div className={resolutionColor}>{resolution}</div>
</Col>
) : (
<Col className="text-4xl mt-4 md:mt-2 md:ml-4 md:mr-6 text-primary items-end self-center md:self-start"> <Col className="text-4xl mt-4 md:mt-2 md:ml-4 md:mr-6 text-primary items-end self-center md:self-start">
{probPercent} {probPercent}
<div className="text-xl">chance</div> <div className="text-xl">chance</div>
</Col> </Col>
} )}
</Col> </Col>
<Spacer h={4} /> <Spacer h={4} />
@ -40,6 +59,23 @@ export const ContractOverview = (props: {
<div className="text-gray-600 whitespace-pre-line"> <div className="text-gray-600 whitespace-pre-line">
{contract.description} {contract.description}
</div> </div>
{/* Show a delete button for contracts without any trading */}
{isCreator && (volume === 0 || isResolved) && (
<>
<Spacer h={8} />
<button
className="btn btn-xs btn-error btn-outline mt-1 max-w-fit self-end"
onClick={async (e) => {
e.preventDefault()
await deleteContract(contract.id)
router.push('/markets')
}}
>
Delete
</button>
</>
)}
</Col> </Col>
) )
} }

View File

@ -4,19 +4,21 @@ import { Row } from '../components/layout/row'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { useUser } from '../hooks/use-user' import { useUser } from '../hooks/use-user'
import { compute, Contract, listContracts } from '../lib/firebase/contracts' import { compute, Contract, listContracts } from '../lib/firebase/contracts'
import { formatWithCommas } from '../lib/util/format' import { formatMoney } from '../lib/util/format'
export function ContractDetails(props: { contract: Contract }) { export function ContractDetails(props: { contract: Contract }) {
const { contract } = props const { contract } = props
const { volume, createdDate } = compute(contract) const { volume, createdDate, resolvedDate } = compute(contract)
return ( return (
<Row className="flex-wrap text-sm text-gray-500"> <Row className="flex-wrap text-sm text-gray-500">
<div className="whitespace-nowrap">By {contract.creatorName}</div> <div className="whitespace-nowrap">By {contract.creatorName}</div>
<div className="mx-2"></div> <div className="mx-2"></div>
<div className="whitespace-nowrap">{createdDate}</div> <div className="whitespace-nowrap">
{resolvedDate ? `${createdDate} - ${resolvedDate}` : createdDate}
</div>
<div className="mx-2"></div> <div className="mx-2"></div>
<div className="whitespace-nowrap">{formatWithCommas(volume)} vol</div> <div className="whitespace-nowrap">{formatMoney(volume)} pot</div>
</Row> </Row>
) )
} }
@ -26,15 +28,14 @@ function ContractCard(props: { contract: Contract }) {
const { probPercent } = compute(contract) const { probPercent } = compute(contract)
const { resolution } = contract const { resolution } = contract
const resolutionColor = ( const resolutionColor =
resolution === 'YES' resolution === 'YES'
? 'text-primary' ? 'text-primary'
: resolution === 'NO' : resolution === 'NO'
? 'text-red-400' ? 'text-red-400'
: resolution === 'CANCEL' : resolution === 'CANCEL'
? 'text-yellow-400' ? 'text-yellow-400'
: '' : ''
)
return ( return (
<Link href={`/contract/${contract.id}`}> <Link href={`/contract/${contract.id}`}>
@ -53,7 +54,9 @@ function ContractCard(props: { contract: Contract }) {
{/* Right side of card */} {/* Right side of card */}
<Col> <Col>
<Col className={'text-4xl mx-auto items-end ' + resolutionColor}> <Col
className={'text-4xl mx-auto items-end ' + resolutionColor}
>
{contract.resolution || ( {contract.resolution || (
<div className="text-primary"> <div className="text-primary">
{probPercent} {probPercent}

View File

@ -1,74 +0,0 @@
import clsx from 'clsx'
import dayjs from 'dayjs'
import { useRouter } from 'next/router'
import React from 'react'
import { Contract, deleteContract } from '../lib/firebase/contracts'
import { formatMoney } from '../lib/util/format'
import { Col } from './layout/col'
import { Spacer } from './layout/spacer'
export function ResolvedPanel(props: {
contract: Contract
className?: string
}) {
const router = useRouter()
const { contract, className } = props
const { resolution, resolutionTime, pot, seedAmounts } = contract
const total = pot.YES + pot.NO - seedAmounts.YES - seedAmounts.NO
const color =
resolution === 'YES'
? 'text-primary'
: resolution === 'NO'
? 'text-red-400'
: resolution === 'CANCEL'
? 'text-yellow-400'
: 'text-gray-500'
return (
<Col
className={clsx(
'bg-gray-100 shadow-xl px-8 py-6 rounded-md w-full md:w-auto',
className
)}
>
<div className={clsx('font-bold font-sans text-5xl')}>
Resolved: <span className={color}>{resolution}</span>
</div>
<Spacer h={4} />
<div className="text-gray-500">
{dayjs(resolutionTime).format('MMM D, HH:mma')}
</div>
<Spacer h={4} />
<div className="text-gray-700">
{resolution === 'YES' ? (
<>Yes bettors have collectively won {formatMoney(total)}.</>
) : resolution === 'NO' ? (
<>No bettors have collectively won {formatMoney(total)}.</>
) : (
<>All bets have been returned.</>
)}
</div>
{/* Show a delete button for contracts without any trading */}
{total === 0 && (
<button
className="btn btn-xs btn-error btn-outline mt-1 max-w-fit"
onClick={async (e) => {
e.preventDefault()
await deleteContract(contract.id)
router.push('/markets')
}}
>
Delete
</button>
)}
</Col>
)
}

View File

@ -37,12 +37,13 @@ export type Contract = {
} }
export function compute(contract: Contract) { export function compute(contract: Contract) {
const { pot, seedAmounts, createdTime } = contract const { pot, seedAmounts, createdTime, resolutionTime, isResolved } = contract
const volume = pot.YES + pot.NO - seedAmounts.YES - seedAmounts.NO const volume = pot.YES + pot.NO - seedAmounts.YES - seedAmounts.NO
const prob = pot.YES ** 2 / (pot.YES ** 2 + pot.NO ** 2) const prob = pot.YES ** 2 / (pot.YES ** 2 + pot.NO ** 2)
const probPercent = Math.round(prob * 100) + '%' const probPercent = Math.round(prob * 100) + '%'
const createdDate = dayjs(createdTime).format('MMM D') const createdDate = dayjs(createdTime).format('MMM D')
return { volume, probPercent, createdDate } const resolvedDate = isResolved ? dayjs(resolutionTime).format('MMM D') : undefined
return { volume, probPercent, createdDate, resolvedDate }
} }
const db = getFirestore(app) const db = getFirestore(app)

View File

@ -7,7 +7,7 @@ import { BetPanel } from '../../components/bet-panel'
import { Col } from '../../components/layout/col' import { Col } from '../../components/layout/col'
import { useUser } from '../../hooks/use-user' import { useUser } from '../../hooks/use-user'
import { ResolutionPanel } from '../../components/resolution-panel' import { ResolutionPanel } from '../../components/resolution-panel'
import { ResolvedPanel } from '../../components/resolved-panel' import clsx from 'clsx'
export default function ContractPage() { export default function ContractPage() {
const user = useUser() const user = useUser()
@ -29,25 +29,32 @@ export default function ContractPage() {
const isCreator = user?.id === creatorId const isCreator = user?.id === creatorId
return ( return (
<div className="max-w-7xl mx-auto sm:px-6 lg:px-8"> <Col className="max-w-7xl mx-auto sm:px-6 lg:px-8">
<Header /> <Header />
<Col className="w-full items-start md:justify-between md:flex-row mt-4"> <Col
className={clsx(
'w-full items-start md:flex-row mt-4',
isResolved ? 'md:justify-center' : 'md:justify-between'
)}
>
<ContractOverview <ContractOverview
contract={contract} contract={contract}
className="max-w-4xl w-full p-4" className="max-w-4xl w-full p-4"
/> />
<div className="mt-12 md:mt-0 md:ml-8" /> {!isResolved && (
<>
<div className="mt-12 md:mt-0 md:ml-8" />
{isResolved ? ( {isCreator ? (
<ResolvedPanel contract={contract} /> <ResolutionPanel creator={user} contract={contract} />
) : isCreator ? ( ) : (
<ResolutionPanel creator={user} contract={contract} /> <BetPanel contract={contract} />
) : ( )}
<BetPanel contract={contract} /> </>
)} )}
</Col> </Col>
</div> </Col>
) )
} }