Extract shared logic into ContractDetails

This commit is contained in:
Austin Chen 2021-12-14 02:23:32 -08:00
parent e2e168737a
commit dc90c4fa74
3 changed files with 38 additions and 49 deletions

View File

@ -1,42 +1,26 @@
import React from 'react' import React from 'react'
import dayjs from 'dayjs' import { compute, Contract } from '../lib/firebase/contracts'
import { Contract } from '../lib/firebase/contracts'
import { Col } from './layout/col' import { Col } from './layout/col'
import { Row } from './layout/row'
import { Spacer } from './layout/spacer' import { Spacer } from './layout/spacer'
import { formatWithCommas } from '../lib/util/format'
import { ContractProbGraph } from './contract-prob-graph' import { ContractProbGraph } from './contract-prob-graph'
import { ContractDetails } from '../pages/markets'
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 { pot, seedAmounts, createdTime } = contract const { probPercent } = compute(contract)
const volume = pot.YES + pot.NO - seedAmounts.YES - seedAmounts.NO
const prob = pot.YES ** 2 / (pot.YES ** 2 + pot.NO ** 2)
const probPercent = Math.round(prob * 100) + '%'
return ( return (
<Col className={className}> <Col className={className}>
<Col className="justify-between md:flex-row"> <Col className="justify-between md:flex-row">
<Col> <Col>
<div className="text-3xl font-medium p-2">{contract.question}</div> <div className="text-3xl text-indigo-700 mt-2 mb-4">
{contract.question}
</div>
<Row className="flex-wrap text-sm text-gray-600"> <ContractDetails contract={contract} />
<div className="p-2 whitespace-nowrap">
By {contract.creatorName}
</div>
<div className="py-2"></div>
<div className="p-2 whitespace-nowrap">
{dayjs(createdTime).format('MMM D')}
</div>
<div className="py-2"></div>
<div className="p-2 whitespace-nowrap">
{formatWithCommas(volume)} volume
</div>
</Row>
</Col> </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">

View File

@ -13,6 +13,7 @@ import {
getDoc, getDoc,
limit, limit,
} from 'firebase/firestore' } from 'firebase/firestore'
import dayjs from 'dayjs'
export type Contract = { export type Contract = {
id: string // Chosen by creator; must be unique id: string // Chosen by creator; must be unique
@ -35,6 +36,15 @@ export type Contract = {
resolution?: 'YES' | 'NO' | 'CANCEL' // Chosen by creator; must be one of outcomes resolution?: 'YES' | 'NO' | 'CANCEL' // Chosen by creator; must be one of outcomes
} }
export function compute(contract: Contract) {
const { pot, seedAmounts, createdTime } = contract
const volume = pot.YES + pot.NO - seedAmounts.YES - seedAmounts.NO
const prob = pot.YES ** 2 / (pot.YES ** 2 + pot.NO ** 2)
const probPercent = Math.round(prob * 100) + '%'
const createdDate = dayjs(createdTime).format('MMM D')
return { volume, probPercent, createdDate }
}
const db = getFirestore(app) const db = getFirestore(app)
const contractCollection = collection(db, 'contracts') const contractCollection = collection(db, 'contracts')

View File

@ -1,23 +1,31 @@
import dayjs from 'dayjs'
import Link from 'next/link' import Link from 'next/link'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { Header } from '../components/header' import { Header } from '../components/header'
import { Col } from '../components/layout/col' import { Col } from '../components/layout/col'
import { Row } from '../components/layout/row' import { Row } from '../components/layout/row'
import { Spacer } from '../components/layout/spacer'
import { Title } from '../components/title' import { Title } from '../components/title'
import { listAllContracts } from '../lib/firebase/contracts' import { compute, listAllContracts } from '../lib/firebase/contracts'
import { Contract } from '../lib/firebase/contracts' import { Contract } from '../lib/firebase/contracts'
import { formatWithCommas } from '../lib/util/format' import { formatWithCommas } from '../lib/util/format'
export function ContractDetails(props: { contract: Contract }) {
const { contract } = props
const { volume, createdDate } = compute(contract)
return (
<Row className="flex-wrap text-sm text-gray-500">
<div className="whitespace-nowrap">By {contract.creatorName}</div>
<div className="mx-2"></div>
<div className="whitespace-nowrap">{createdDate}</div>
<div className="mx-2"></div>
<div className="whitespace-nowrap">{formatWithCommas(volume)} vol</div>
</Row>
)
}
function ContractCard(props: { contract: Contract }) { function ContractCard(props: { contract: Contract }) {
const { contract } = props const { contract } = props
const { probPercent } = compute(contract)
// Copied from contract-overview.tsx
const { pot, seedAmounts, createdTime } = contract
const volume = pot.YES + pot.NO - seedAmounts.YES - seedAmounts.NO
const prob = pot.YES ** 2 / (pot.YES ** 2 + pot.NO ** 2)
const probPercent = Math.round(prob * 100) + '%'
return ( return (
<Link href={`/contract/${contract.id}`}> <Link href={`/contract/${contract.id}`}>
@ -28,28 +36,15 @@ function ContractCard(props: { contract: Contract }) {
<div className="flex justify-between gap-2"> <div className="flex justify-between gap-2">
{/* Left side of card */} {/* Left side of card */}
<div> <div>
<p className="font-medium text-indigo-700"> <p className="font-medium text-indigo-700 mb-8">
{contract.question} {contract.question}
</p> </p>
<Spacer h={8} /> <ContractDetails contract={contract} />
{/* Copied from contract-overview.tsx */}
<Row className="flex-wrap text-sm text-gray-500">
<div className="whitespace-nowrap">
By {contract.creatorName}
</div>
<div className="mx-2"></div>
<div className="whitespace-nowrap">
{dayjs(createdTime).format('MMM D')}
</div>
<div className="mx-2"></div>
<div className="whitespace-nowrap">
{formatWithCommas(volume)} vol
</div>
</Row>
</div> </div>
{/* Right side of card */} {/* Right side of card */}
<Col> <Col>
<Col className="text-4xl mx-auto items-end"> <Col className="text-4xl mx-auto items-end">
{contract.resolution || ( {contract.resolution || (
<div className="text-primary"> <div className="text-primary">
{probPercent} {probPercent}