Clean up rendering of user bets list (#694)

* Clean up crufty markup in bets list

* Don't render bet tables in bets list until expanded

* Don't look up unfilled bets for every sell button
This commit is contained in:
Marshall Polaris 2022-07-26 00:10:22 -07:00 committed by GitHub
parent 7e4f4b9a87
commit ad46a60c4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3,6 +3,7 @@ import { groupBy, mapValues, sortBy, partition, sumBy } from 'lodash'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { useEffect, useMemo, useState } from 'react' import { useEffect, useMemo, useState } from 'react'
import clsx from 'clsx' import clsx from 'clsx'
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/solid'
import { Bet } from 'web/lib/firebase/bets' import { Bet } from 'web/lib/firebase/bets'
import { User } from 'web/lib/firebase/users' import { User } from 'web/lib/firebase/users'
@ -277,13 +278,7 @@ function ContractBets(props: {
bets bets
) )
return ( return (
<div <div tabIndex={0} className="relative bg-white p-4 pr-6">
tabIndex={0}
className={clsx(
'collapse collapse-arrow relative bg-white p-4 pr-6',
collapsed ? 'collapse-close' : 'collapse-open pb-2'
)}
>
<Row <Row
className="cursor-pointer flex-wrap gap-2" className="cursor-pointer flex-wrap gap-2"
onClick={() => setCollapsed((collapsed) => !collapsed)} onClick={() => setCollapsed((collapsed) => !collapsed)}
@ -300,10 +295,11 @@ function ContractBets(props: {
</Link> </Link>
{/* Show carrot for collapsing. Hack the positioning. */} {/* Show carrot for collapsing. Hack the positioning. */}
<div {collapsed ? (
className="collapse-title absolute h-0 min-h-0 w-0 p-0" <ChevronDownIcon className="absolute top-5 right-4 h-6 w-6" />
style={{ top: -10, right: 0 }} ) : (
/> <ChevronUpIcon className="absolute top-5 right-4 h-6 w-6" />
)}
</Row> </Row>
<Row className="flex-1 items-center gap-2 text-sm text-gray-500"> <Row className="flex-1 items-center gap-2 text-sm text-gray-500">
@ -335,55 +331,42 @@ function ContractBets(props: {
</Row> </Row>
</Col> </Col>
<Row className="mr-5 justify-end sm:mr-8"> <Col className="mr-5 sm:mr-8">
<Col>
<div className="whitespace-nowrap text-right text-lg"> <div className="whitespace-nowrap text-right text-lg">
{formatMoney(metric === 'profit' ? profit : payout)} {formatMoney(metric === 'profit' ? profit : payout)}
</div> </div>
<div className="text-right"> <ProfitBadge className="text-right" profitPercent={profitPercent} />
<ProfitBadge profitPercent={profitPercent} />
</div>
</Col> </Col>
</Row> </Row>
</Row>
<div
className="collapse-content !px-0"
style={{ backgroundColor: 'white' }}
>
<Spacer h={8} />
{!collapsed && (
<div className="bg-white">
<BetsSummary <BetsSummary
className="mr-5 flex-1 sm:mr-8" className="mt-8 mr-5 flex-1 sm:mr-8"
contract={contract} contract={contract}
bets={bets} bets={bets}
isYourBets={isYourBets} isYourBets={isYourBets}
/> />
<Spacer h={4} />
{contract.mechanism === 'cpmm-1' && limitBets.length > 0 && ( {contract.mechanism === 'cpmm-1' && limitBets.length > 0 && (
<>
<div className="max-w-md"> <div className="max-w-md">
<div className="bg-gray-50 px-4 py-2">Limit orders</div> <div className="mt-4 bg-gray-50 px-4 py-2">Limit orders</div>
<LimitOrderTable <LimitOrderTable
contract={contract} contract={contract}
limitBets={limitBets} limitBets={limitBets}
isYou={true} isYou={true}
/> />
</div> </div>
</>
)} )}
<Spacer h={4} /> <div className="mt-4 bg-gray-50 px-4 py-2">Bets</div>
<div className="bg-gray-50 px-4 py-2">Bets</div>
<ContractBetsTable <ContractBetsTable
contract={contract} contract={contract}
bets={bets} bets={bets}
isYourBets={isYourBets} isYourBets={isYourBets}
/> />
</div> </div>
)}
</div> </div>
) )
} }
@ -427,7 +410,6 @@ export function BetsSummary(props: {
return ( return (
<Row className={clsx('flex-wrap gap-4 sm:flex-nowrap sm:gap-6', className)}> <Row className={clsx('flex-wrap gap-4 sm:flex-nowrap sm:gap-6', className)}>
<Row className="flex-wrap gap-4 sm:gap-6">
{!isCpmm && ( {!isCpmm && (
<Col> <Col>
<div className="whitespace-nowrap text-sm text-gray-500"> <div className="whitespace-nowrap text-sm text-gray-500">
@ -440,29 +422,22 @@ export function BetsSummary(props: {
<Col> <Col>
<div className="text-sm text-gray-500">Payout</div> <div className="text-sm text-gray-500">Payout</div>
<div className="whitespace-nowrap"> <div className="whitespace-nowrap">
{formatMoney(payout)}{' '} {formatMoney(payout)} <ProfitBadge profitPercent={profitPercent} />
<ProfitBadge profitPercent={profitPercent} />
</div> </div>
</Col> </Col>
) : ( ) : isBinary ? (
<>
{isBinary ? (
<> <>
<Col> <Col>
<div className="whitespace-nowrap text-sm text-gray-500"> <div className="whitespace-nowrap text-sm text-gray-500">
Payout if <YesLabel /> Payout if <YesLabel />
</div> </div>
<div className="whitespace-nowrap"> <div className="whitespace-nowrap">{formatMoney(yesWinnings)}</div>
{formatMoney(yesWinnings)}
</div>
</Col> </Col>
<Col> <Col>
<div className="whitespace-nowrap text-sm text-gray-500"> <div className="whitespace-nowrap text-sm text-gray-500">
Payout if <NoLabel /> Payout if <NoLabel />
</div> </div>
<div className="whitespace-nowrap"> <div className="whitespace-nowrap">{formatMoney(noWinnings)}</div>
{formatMoney(noWinnings)}
</div>
</Col> </Col>
</> </>
) : isPseudoNumeric ? ( ) : isPseudoNumeric ? (
@ -471,17 +446,13 @@ export function BetsSummary(props: {
<div className="whitespace-nowrap text-sm text-gray-500"> <div className="whitespace-nowrap text-sm text-gray-500">
Payout if {'>='} {formatLargeNumber(contract.max)} Payout if {'>='} {formatLargeNumber(contract.max)}
</div> </div>
<div className="whitespace-nowrap"> <div className="whitespace-nowrap">{formatMoney(yesWinnings)}</div>
{formatMoney(yesWinnings)}
</div>
</Col> </Col>
<Col> <Col>
<div className="whitespace-nowrap text-sm text-gray-500"> <div className="whitespace-nowrap text-sm text-gray-500">
Payout if {'<='} {formatLargeNumber(contract.min)} Payout if {'<='} {formatLargeNumber(contract.min)}
</div> </div>
<div className="whitespace-nowrap"> <div className="whitespace-nowrap">{formatMoney(noWinnings)}</div>
{formatMoney(noWinnings)}
</div>
</Col> </Col>
</> </>
) : ( ) : (
@ -492,8 +463,6 @@ export function BetsSummary(props: {
<div className="whitespace-nowrap">{formatMoney(payout)}</div> <div className="whitespace-nowrap">{formatMoney(payout)}</div>
</Col> </Col>
)} )}
</>
)}
<Col> <Col>
<div className="whitespace-nowrap text-sm text-gray-500">Profit</div> <div className="whitespace-nowrap text-sm text-gray-500">Profit</div>
<div className="whitespace-nowrap"> <div className="whitespace-nowrap">
@ -528,7 +497,6 @@ export function BetsSummary(props: {
</div> </div>
</Col> </Col>
</Row> </Row>
</Row>
) )
} }
@ -689,7 +657,13 @@ function BetRow(props: {
!isClosed && !isClosed &&
!isSold && !isSold &&
!isAnte && !isAnte &&
!isNumeric && <SellButton contract={contract} bet={bet} />} !isNumeric && (
<SellButton
contract={contract}
bet={bet}
unfilledBets={unfilledBets}
/>
)}
</td> </td>
{isCPMM && <td>{shares >= 0 ? 'BUY' : 'SELL'}</td>} {isCPMM && <td>{shares >= 0 ? 'BUY' : 'SELL'}</td>}
<td> <td>
@ -729,8 +703,12 @@ function BetRow(props: {
) )
} }
function SellButton(props: { contract: Contract; bet: Bet }) { function SellButton(props: {
const { contract, bet } = props contract: Contract
bet: Bet
unfilledBets: LimitBet[]
}) {
const { contract, bet, unfilledBets } = props
const { outcome, shares, loanAmount } = bet const { outcome, shares, loanAmount } = bet
const [isSubmitting, setIsSubmitting] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false)
@ -740,8 +718,6 @@ function SellButton(props: { contract: Contract; bet: Bet }) {
outcome === 'NO' ? 'YES' : outcome outcome === 'NO' ? 'YES' : outcome
) )
const unfilledBets = useUnfilledBets(contract.id) ?? []
const outcomeProb = getProbabilityAfterSale( const outcomeProb = getProbabilityAfterSale(
contract, contract,
outcome, outcome,
@ -787,8 +763,8 @@ function SellButton(props: { contract: Contract; bet: Bet }) {
) )
} }
function ProfitBadge(props: { profitPercent: number }) { function ProfitBadge(props: { profitPercent: number; className?: string }) {
const { profitPercent } = props const { profitPercent, className } = props
if (!profitPercent) return null if (!profitPercent) return null
const colors = const colors =
profitPercent > 0 profitPercent > 0
@ -799,7 +775,8 @@ function ProfitBadge(props: { profitPercent: number }) {
<span <span
className={clsx( className={clsx(
'ml-1 inline-flex items-center rounded-full px-3 py-0.5 text-sm font-medium', 'ml-1 inline-flex items-center rounded-full px-3 py-0.5 text-sm font-medium',
colors colors,
className
)} )}
> >
{(profitPercent > 0 ? '+' : '') + profitPercent.toFixed(1) + '%'} {(profitPercent > 0 ? '+' : '') + profitPercent.toFixed(1) + '%'}