Replace the popup with a YES/NO selector
This commit is contained in:
parent
54d15dede2
commit
82fa464e58
|
@ -30,17 +30,18 @@ export function BetPanel(props: {
|
|||
contract: Contract
|
||||
className?: string
|
||||
title?: string
|
||||
selected?: 'YES' | 'NO'
|
||||
}) {
|
||||
useEffect(() => {
|
||||
// warm up cloud function
|
||||
placeBet({}).catch()
|
||||
}, [])
|
||||
|
||||
const { contract, className, title } = props
|
||||
const { contract, className, title, selected } = props
|
||||
|
||||
const user = useUser()
|
||||
|
||||
const [betChoice, setBetChoice] = useState<'YES' | 'NO'>('YES')
|
||||
const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>(selected)
|
||||
const [betAmount, setBetAmount] = useState<number | undefined>(undefined)
|
||||
|
||||
const [error, setError] = useState<string | undefined>()
|
||||
|
@ -92,14 +93,14 @@ export function BetPanel(props: {
|
|||
|
||||
const resultProb = getProbabilityAfterBet(
|
||||
contract.totalShares,
|
||||
betChoice,
|
||||
betChoice || 'YES',
|
||||
betAmount ?? 0
|
||||
)
|
||||
|
||||
const shares = calculateShares(
|
||||
contract.totalShares,
|
||||
betAmount ?? 0,
|
||||
betChoice
|
||||
betChoice || 'YES'
|
||||
)
|
||||
|
||||
const currentPayout = betAmount
|
||||
|
@ -112,12 +113,16 @@ export function BetPanel(props: {
|
|||
|
||||
const currentReturn = betAmount ? (currentPayout - betAmount) / betAmount : 0
|
||||
const currentReturnPercent = (currentReturn * 100).toFixed() + '%'
|
||||
const panelTitle = title ?? `Buy ${betChoice || 'shares'}`
|
||||
|
||||
return (
|
||||
<Col
|
||||
className={clsx('bg-gray-100 shadow-md px-8 py-6 rounded-md', className)}
|
||||
>
|
||||
<Title className="mt-0 text-neutral" text={title ?? `Buy ${betChoice}`} />
|
||||
<Title
|
||||
className={clsx('!mt-0 text-neutral', title ? '!text-xl' : '')}
|
||||
text={panelTitle}
|
||||
/>
|
||||
|
||||
<div className="mt-2 mb-1 text-sm text-gray-500">Outcome</div>
|
||||
<YesNoSelector
|
||||
|
@ -145,22 +150,27 @@ export function BetPanel(props: {
|
|||
<div>{formatPercent(resultProb)}</div>
|
||||
</Row>
|
||||
|
||||
<Row className="mt-2 mb-1 items-center gap-2 text-sm text-gray-500">
|
||||
Payout if <OutcomeLabel outcome={betChoice} />
|
||||
<InfoTooltip
|
||||
text={`Current payout for ${formatWithCommas(
|
||||
shares
|
||||
)} / ${formatWithCommas(
|
||||
shares +
|
||||
contract.totalShares[betChoice] -
|
||||
contract.phantomShares[betChoice]
|
||||
)} ${betChoice} shares`}
|
||||
/>
|
||||
</Row>
|
||||
<div>
|
||||
{formatMoney(currentPayout)}
|
||||
<span>(+{currentReturnPercent})</span>
|
||||
</div>
|
||||
{betChoice && (
|
||||
<>
|
||||
<Spacer h={4} />
|
||||
<Row className="mt-2 mb-1 items-center gap-2 text-sm text-gray-500">
|
||||
Payout if <OutcomeLabel outcome={betChoice} />
|
||||
<InfoTooltip
|
||||
text={`Current payout for ${formatWithCommas(
|
||||
shares
|
||||
)} / ${formatWithCommas(
|
||||
shares +
|
||||
contract.totalShares[betChoice] -
|
||||
contract.phantomShares[betChoice]
|
||||
)} ${betChoice} shares`}
|
||||
/>
|
||||
</Row>
|
||||
<div>
|
||||
{formatMoney(currentPayout)}
|
||||
<span>(+{currentReturnPercent})</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
<Spacer h={6} />
|
||||
|
||||
|
|
|
@ -1,30 +1,46 @@
|
|||
/* This example requires Tailwind CSS v2.0+ */
|
||||
import { Fragment, useState } from 'react'
|
||||
import { Dialog, Transition } from '@headlessui/react'
|
||||
import { CheckIcon } from '@heroicons/react/outline'
|
||||
import { Contract } from '../lib/firebase/contracts'
|
||||
import { BetPanel } from './bet-panel'
|
||||
import { Row } from './layout/row'
|
||||
import { YesNoSelector } from './yes-no-selector'
|
||||
|
||||
// Inline version of a bet panel. Opens BetPanel in a new modal.
|
||||
// TODO: Hide when not appropriate
|
||||
// TODO: Autofocus the bet amount input
|
||||
export default function BetRow(props: { contract: Contract }) {
|
||||
// Button to open the modal
|
||||
const [open, setOpen] = useState(false)
|
||||
const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>(
|
||||
undefined
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className="flex items-center justify-center w-full h-full p-2 text-white bg-blue-500 hover:bg-blue-700 rounded-lg"
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
Trade
|
||||
</button>
|
||||
<Modal open={open} setOpen={setOpen}>
|
||||
<BetPanel contract={props.contract} title={props.contract.question} />
|
||||
</Modal>
|
||||
<div className="-mt-4 text-xl pb-6 -mx-4 -mb-6">
|
||||
<Row className="items-center gap-2 justify-center">
|
||||
Buy
|
||||
<YesNoSelector
|
||||
className="w-72"
|
||||
onSelect={(choice) => {
|
||||
setOpen(true)
|
||||
setBetChoice(choice)
|
||||
}}
|
||||
/>
|
||||
</Row>
|
||||
<Modal open={open} setOpen={setOpen}>
|
||||
<BetPanel
|
||||
contract={props.contract}
|
||||
title={props.contract.question}
|
||||
selected={betChoice}
|
||||
/>
|
||||
</Modal>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
// From https://tailwindui.com/components/application-ui/overlays/modals
|
||||
export function Modal(props: {
|
||||
children: React.ReactNode
|
||||
open: boolean
|
||||
|
|
|
@ -5,7 +5,7 @@ import { Col } from './layout/col'
|
|||
import { Row } from './layout/row'
|
||||
|
||||
export function YesNoSelector(props: {
|
||||
selected: 'YES' | 'NO'
|
||||
selected?: 'YES' | 'NO'
|
||||
onSelect: (selected: 'YES' | 'NO') => void
|
||||
className?: string
|
||||
}) {
|
||||
|
@ -13,19 +13,28 @@ export function YesNoSelector(props: {
|
|||
|
||||
return (
|
||||
<Row className={clsx('space-x-3', className)}>
|
||||
<Button
|
||||
color={selected === 'YES' ? 'green' : 'gray'}
|
||||
<button
|
||||
className={clsx(
|
||||
'flex-1 inline-flex justify-center items-center p-2 hover:bg-primary-focus hover:text-white rounded-lg border-primary hover:border-primary-focus border-2',
|
||||
selected == 'YES'
|
||||
? 'bg-primary text-white'
|
||||
: 'bg-transparent text-primary'
|
||||
)}
|
||||
onClick={() => onSelect('YES')}
|
||||
>
|
||||
YES
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
color={selected === 'NO' ? 'red' : 'gray'}
|
||||
</button>
|
||||
<button
|
||||
className={clsx(
|
||||
'flex-1 inline-flex justify-center items-center p-2 hover:bg-red-500 hover:text-white rounded-lg border-red-400 hover:border-red-500 border-2',
|
||||
selected == 'NO'
|
||||
? 'bg-red-400 text-white'
|
||||
: 'bg-transparent text-red-400'
|
||||
)}
|
||||
onClick={() => onSelect('NO')}
|
||||
>
|
||||
NO
|
||||
</Button>
|
||||
</button>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user