Advanced metrics for bet panel

This commit is contained in:
jahooma 2022-01-05 12:23:44 -06:00
parent 3302cbddbd
commit 5eaf50612d
3 changed files with 118 additions and 75 deletions

View File

@ -0,0 +1,35 @@
import clsx from 'clsx'
import { useState } from 'react'
export function AdvancedPanel(props: { children: any }) {
const { children } = props
const [collapsed, setCollapsed] = useState(true)
return (
<div
tabIndex={0}
className={clsx(
'cursor-pointer relative collapse collapse-arrow',
collapsed ? 'collapse-close' : 'collapse-open'
)}
>
<div onClick={() => setCollapsed((collapsed) => !collapsed)}>
<div className="mt-4 mr-6 text-sm text-gray-400 text-right">
Advanced
</div>
<div
className="collapse-title p-0 absolute w-0 h-0 min-h-0"
style={{
top: -2,
right: -15,
color: '#9ca3af' /* gray-400 */,
}}
/>
</div>
<div className="collapse-content !p-0 m-0 !bg-transparent">
{children}
</div>
</div>
)
}

View File

@ -8,14 +8,22 @@ import { Col } from './layout/col'
import { Row } from './layout/row' import { Row } from './layout/row'
import { Spacer } from './layout/spacer' import { Spacer } from './layout/spacer'
import { YesNoSelector } from './yes-no-selector' import { YesNoSelector } from './yes-no-selector'
import { formatMoney, formatPercent } from '../lib/util/format' import {
formatMoney,
formatPercent,
formatWithCommas,
} from '../lib/util/format'
import { Title } from './title' import { Title } from './title'
import { import {
getProbability, getProbability,
calculateShares, calculateShares,
getProbabilityAfterBet, getProbabilityAfterBet,
calculatePayout,
} from '../lib/calculate' } from '../lib/calculate'
import { firebaseLogin } from '../lib/firebase/users' import { firebaseLogin } from '../lib/firebase/users'
import { OutcomeLabel } from './outcome-label'
import { AdvancedPanel } from './advanced-panel'
import { Bet } from '../lib/firebase/bets'
export function BetPanel(props: { contract: Contract; className?: string }) { export function BetPanel(props: { contract: Contract; className?: string }) {
const { contract, className } = props const { contract, className } = props
@ -151,6 +159,29 @@ export function BetPanel(props: { contract: Contract; className?: string }) {
{formatMoney(estimatedWinnings)} &nbsp; (+{estimatedReturnPercent}) {formatMoney(estimatedWinnings)} &nbsp; (+{estimatedReturnPercent})
</div> </div>
<AdvancedPanel>
<div className="mt-2 mb-1 text-sm text-gray-400">
<OutcomeLabel outcome={betChoice} /> shares
</div>
<div>
{formatWithCommas(shares)} of{' '}
{formatWithCommas(shares + contract.totalShares[betChoice])}
</div>
<div className="mt-2 mb-1 text-sm text-gray-400">
Current payout if <OutcomeLabel outcome={betChoice} />
</div>
<div>
{formatMoney(
calculatePayout(
contract,
{ outcome: betChoice, amount: betAmount ?? 0, shares } as Bet,
betChoice
)
)}
</div>
</AdvancedPanel>
<Spacer h={6} /> <Spacer h={6} />
{user ? ( {user ? (

View File

@ -11,6 +11,7 @@ import { useUser } from '../hooks/use-user'
import { Contract, path } from '../lib/firebase/contracts' import { Contract, path } from '../lib/firebase/contracts'
import { Page } from '../components/page' import { Page } from '../components/page'
import { formatMoney } from '../lib/util/format' import { formatMoney } from '../lib/util/format'
import { AdvancedPanel } from '../components/advanced-panel'
// Allow user to create a new contract // Allow user to create a new contract
export default function NewContract() { export default function NewContract() {
@ -29,7 +30,6 @@ export default function NewContract() {
const [closeDate, setCloseDate] = useState('') const [closeDate, setCloseDate] = useState('')
const [isSubmitting, setIsSubmitting] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false)
const [collapsed, setCollapsed] = useState(true)
const closeTime = dateToMillis(closeDate) || undefined const closeTime = dateToMillis(closeDate) || undefined
// We'd like this to look like "Apr 2, 2022, 23:59:59 PM PT" but timezones are hard with dayjs // We'd like this to look like "Apr 2, 2022, 23:59:59 PM PT" but timezones are hard with dayjs
@ -141,82 +141,59 @@ export default function NewContract() {
/> />
</div> </div>
{/* Collapsible "Advanced" section */} <AdvancedPanel>
<div <div className="form-control mb-1">
tabIndex={0} <label className="label">
className={clsx( <span className="label-text">Subsidize your market</span>
'cursor-pointer relative collapse collapse-arrow', </label>
collapsed ? 'collapse-close' : 'collapse-open'
)} <label className="input-group">
> <span className="text-sm bg-gray-200">M$</span>
<div onClick={() => setCollapsed((collapsed) => !collapsed)}> <input
<div className="mt-4 mr-6 text-sm text-gray-400 text-right"> className={clsx(
Advanced 'input input-bordered',
anteError && 'input-error'
)}
type="text"
placeholder="0"
maxLength={9}
value={ante ?? ''}
disabled={isSubmitting}
onChange={(e) => onAnteChange(e.target.value)}
/>
</label>
<div className="mt-3 mb-1 text-sm text-gray-400">
Remaining balance
</div> </div>
<div <div>
className="collapse-title p-0 absolute w-0 h-0 min-h-0" {formatMoney(remainingBalance > 0 ? remainingBalance : 0)}
style={{ </div>
top: -2, </div>
right: -15,
color: '#9ca3af' /* gray-400 */, <Spacer h={4} />
}}
<div className="form-control">
<label className="label">
<span className="label-text">Close date (optional)</span>
</label>
<input
type="date"
className="input input-bordered"
onClick={(e) => e.stopPropagation()}
onChange={(e) => setCloseDate(e.target.value || '')}
min={new Date().toISOString().split('T')[0]}
disabled={isSubmitting}
value={closeDate}
/> />
</div> </div>
<label>
<div className="collapse-content !p-0 m-0 !bg-transparent"> <span className="label-text text-gray-400 ml-2">
<div className="form-control mb-1"> No new trades will be allowed after{' '}
<label className="label"> {closeDate ? formattedCloseTime : 'this time'}
<span className="label-text">Subsidize your market</span> </span>
</label> </label>
</AdvancedPanel>
<label className="input-group">
<span className="text-sm bg-gray-200">M$</span>
<input
className={clsx(
'input input-bordered',
anteError && 'input-error'
)}
type="text"
placeholder="0"
maxLength={9}
value={ante ?? ''}
disabled={isSubmitting}
onChange={(e) => onAnteChange(e.target.value)}
/>
</label>
<div className="mt-3 mb-1 text-sm text-gray-400">
Remaining balance
</div>
<div>
{formatMoney(remainingBalance > 0 ? remainingBalance : 0)}
</div>
</div>
<Spacer h={4} />
<div className="form-control">
<label className="label">
<span className="label-text">Close date (optional)</span>
</label>
<input
type="date"
className="input input-bordered"
onClick={(e) => e.stopPropagation()}
onChange={(e) => setCloseDate(e.target.value || '')}
min={new Date().toISOString().split('T')[0]}
disabled={isSubmitting}
value={closeDate}
/>
</div>
<label>
<span className="label-text text-gray-400 ml-2">
No new trades will be allowed after{' '}
{closeDate ? formattedCloseTime : 'this time'}
</span>
</label>
</div>
</div>
<Spacer h={4} /> <Spacer h={4} />