Render your open bets (unfilled limit orders)

This commit is contained in:
James Grugett 2022-07-05 11:14:00 -04:00
parent 68abee86fb
commit 83557515ad
5 changed files with 75 additions and 7 deletions

View File

@ -45,6 +45,7 @@ import { ProbabilityInput } from './probability-input'
import { track } from 'web/lib/service/analytics'
import { removeUndefinedProps } from 'common/util/object'
import { useUnfilledBets } from 'web/hooks/use-bets'
import { OpenBets } from './open-bets'
export function BetPanel(props: {
contract: CPMMBinaryContract | PseudoNumericContract
@ -54,6 +55,7 @@ export function BetPanel(props: {
const user = useUser()
const userBets = useUserContractBets(user?.id, contract.id)
const unfilledBets = useUnfilledBets(contract.id) ?? []
const yourUnfilledBets = unfilledBets.filter((bet) => bet.userId === user?.id)
const { yesFloorShares, noFloorShares } = useSaveShares(contract, userBets)
const sharesOutcome = yesFloorShares
? 'YES'
@ -98,6 +100,9 @@ export function BetPanel(props: {
<SignUpPrompt />
</Col>
{yourUnfilledBets.length > 0 && (
<OpenBets className="mt-4" bets={yourUnfilledBets} />
)}
</Col>
)
}
@ -376,7 +381,7 @@ function BuyPanel(props: {
{isLimitOrder && (
<>
<div className="my-3 text-left text-sm text-gray-500">
Probability
{betChoice === 'YES' ? 'Max' : 'Min'} probability
</div>
<ProbabilityInput
inputClassName="w-full max-w-none"

View File

@ -0,0 +1,55 @@
import clsx from 'clsx'
import { LimitBet } from 'common/bet'
import { formatPercent } from 'common/lib/util/format'
import { formatMoney } from 'common/util/format'
import { sortBy, sumBy } from 'lodash'
import { Col } from './layout/col'
import { BinaryOutcomeLabel } from './outcome-label'
export function OpenBets(props: { bets: LimitBet[]; className?: string }) {
const { bets, className } = props
const recentBets = sortBy(bets, (bet) => bet.createdTime).reverse()
return (
<Col className={clsx(className, 'gap-2 rounded bg-white')}>
<div className="px-6 py-3 text-xl">Open bets</div>
<table className="table-compact table w-full rounded text-gray-500">
<tbody>
{recentBets.map((bet) => (
<LimitBet
key={bet.id}
bet={bet}
onCancel={() => {
console.log('Cancel', bet)
}}
/>
))}
</tbody>
</table>
</Col>
)
}
function LimitBet(props: { bet: LimitBet; onCancel: () => void }) {
const { bet, onCancel } = props
const filledAmount = sumBy(bet.fills, (fill) => fill.amount)
return (
<tr>
<td>
<div className="pl-2">
<BinaryOutcomeLabel outcome={bet.outcome as 'YES' | 'NO'} />
</div>
</td>
<td>{formatMoney(bet.amount - filledAmount)}</td>
<td>{formatPercent(bet.limitProb)}</td>
<td>
<button
className="btn btn-xs btn-outline my-auto normal-case"
onClick={onCancel}
>
Cancel
</button>
</td>
</tr>
)
}

View File

@ -7,6 +7,7 @@ import {
listenForUnfilledBets,
withoutAnteBets,
} from 'web/lib/firebase/bets'
import { LimitBet } from 'common/bet'
export const useBets = (contractId: string) => {
const [bets, setBets] = useState<Bet[] | undefined>()
@ -39,7 +40,7 @@ export const useRecentBets = () => {
}
export const useUnfilledBets = (contractId: string) => {
const [unfilledBets, setUnfilledBets] = useState<Bet[] | undefined>()
const [unfilledBets, setUnfilledBets] = useState<LimitBet[] | undefined>()
useEffect(
() => listenForUnfilledBets(contractId, setUnfilledBets),
[contractId]

View File

@ -8,7 +8,7 @@ import {
import { uniq } from 'lodash'
import { db } from './init'
import { Bet } from 'common/bet'
import { Bet, LimitBet } from 'common/bet'
import { Contract } from 'common/contract'
import { getValues, listenForValues } from './utils'
import { getContractFromId } from './contracts'
@ -124,7 +124,7 @@ export function listenForUserContractBets(
export function listenForUnfilledBets(
contractId: string,
setBets: (bets: Bet[]) => void
setBets: (bets: LimitBet[]) => void
) {
const betsQuery = query(
collection(db, 'contracts', contractId, 'bets'),
@ -132,7 +132,7 @@ export function listenForUnfilledBets(
where('isFilled', '==', false),
where('isCancelled', '==', false)
)
return listenForValues<Bet>(betsQuery, (bets) => {
return listenForValues<LimitBet>(betsQuery, (bets) => {
bets.sort((bet1, bet2) => bet1.createdTime - bet2.createdTime)
setBets(bets)
})

View File

@ -38,13 +38,14 @@ import { FeedComment } from 'web/components/feed/feed-comments'
import { FeedBet } from 'web/components/feed/feed-bets'
import { useIsIframe } from 'web/hooks/use-is-iframe'
import ContractEmbedPage from '../embed/[username]/[contractSlug]'
import { useBets } from 'web/hooks/use-bets'
import { useBets, useUnfilledBets } from 'web/hooks/use-bets'
import { CPMMBinaryContract } from 'common/contract'
import { AlertBox } from 'web/components/alert-box'
import { useTracking } from 'web/hooks/use-tracking'
import { CommentTipMap, useTipTxns } from 'web/hooks/use-tip-txns'
import { useRouter } from 'next/router'
import { useLiquidity } from 'web/hooks/use-liquidity'
import { OpenBets } from 'web/components/open-bets'
export const getStaticProps = fromPropz(getStaticPropz)
export async function getStaticPropz(props: {
@ -128,6 +129,9 @@ export function ContractPageContent(
const tips = useTipTxns(contract.id)
const user = useUser()
const unfilledBets = useUnfilledBets(contract.id) ?? []
const yourUnfilledBets = unfilledBets.filter((bet) => bet.userId === user?.id)
const { width, height } = useWindowSize()
const [showConfetti, setShowConfetti] = useState(false)
@ -217,6 +221,10 @@ export function ContractPageContent(
<ContractOverview contract={contract} bets={bets} />
{yourUnfilledBets.length > 0 && (
<OpenBets className="mb-4 xl:hidden" bets={yourUnfilledBets} />
)}
{isNumeric && (
<AlertBox
title="Warning"
@ -415,4 +423,3 @@ const getOpenGraphProps = (contract: Contract) => {
description,
}
}