Getting basic functionality working
This commit is contained in:
parent
ee6b463f94
commit
3d772a8a9b
|
@ -1,8 +1,9 @@
|
|||
import { useState } from 'react'
|
||||
import clsx from 'clsx'
|
||||
|
||||
import { SimpleBetPanel } from './bet-panel'
|
||||
import { BetPanel, BuyPanel, SimpleBetPanel } from './bet-panel'
|
||||
import { CPMMBinaryContract, PseudoNumericContract } from 'common/contract'
|
||||
import { getBinaryBetStats, getBinaryCpmmBetInfo } from 'common/new-bet'
|
||||
import { Modal } from './layout/modal'
|
||||
import { useUser } from 'web/hooks/use-user'
|
||||
import { useUserContractBets } from 'web/hooks/use-user-bets'
|
||||
|
@ -17,6 +18,13 @@ import { User } from 'web/lib/firebase/users'
|
|||
import { SellRow } from './sell-row'
|
||||
import { PlayMoneyDisclaimer } from './play-money-disclaimer'
|
||||
import { Row } from './layout/row'
|
||||
import { useUnfilledBets } from 'web/hooks/use-bets'
|
||||
import { Bet } from 'common/bet'
|
||||
import { getProbability } from 'common/calculate'
|
||||
import { useFocus } from 'web/hooks/use-focus'
|
||||
import { isAndroid, isIOS } from 'web/lib/util/device'
|
||||
import { APIError, placeBet } from 'web/lib/firebase/api'
|
||||
import { track } from '@amplitude/analytics-browser'
|
||||
|
||||
/** Button that opens BetPanel in a new modal */
|
||||
export default function BetButton(props: {
|
||||
|
@ -105,44 +113,72 @@ export function SignedInBinaryMobileBetting(props: {
|
|||
contract: CPMMBinaryContract
|
||||
user: User
|
||||
}) {
|
||||
enum betChoiceState {
|
||||
YES = 'yes',
|
||||
NO = 'no',
|
||||
NEITHER = 'neither',
|
||||
}
|
||||
const { contract, user } = props
|
||||
const [betChoice, setBetChoice] = useState<betChoiceState>(
|
||||
betChoiceState.NEITHER
|
||||
const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>(
|
||||
undefined
|
||||
)
|
||||
const unfilledBets = useUnfilledBets(contract.id) ?? []
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* GET BACK TO THIS BUT GAH DAMN IT'S UGLY */}
|
||||
{/* <SellRow
|
||||
contract={contract}
|
||||
user={user}
|
||||
className={'rounded-t-md bg-gray-100 px-4 py-5'}
|
||||
/> */}
|
||||
<Row className="w-full">
|
||||
<button
|
||||
className={clsx(
|
||||
'w-1/2 rounded-full border-2 border-emerald-500 py-2',
|
||||
betChoice == betChoiceState.YES
|
||||
? 'bg-emerald-500 text-white'
|
||||
: betChoice == betChoiceState.NO
|
||||
? 'border-greyscale-4 text-greyscale-4 bg-white'
|
||||
: 'bg-white text-emerald-500'
|
||||
)}
|
||||
onClick={() => {
|
||||
if (betChoice == betChoiceState.YES) {
|
||||
setBetChoice(betChoiceState.NEITHER)
|
||||
} else {
|
||||
setBetChoice(betChoiceState.YES)
|
||||
}
|
||||
}}
|
||||
>
|
||||
YES
|
||||
</button>
|
||||
</Row>
|
||||
<Col className="w-full gap-2 px-1">
|
||||
{/* <SellRow
|
||||
contract={contract}
|
||||
user={user}
|
||||
className={'rounded-t-md bg-gray-100 px-4 py-5'}
|
||||
/> */}
|
||||
{/* <Row className="w-full justify-between gap-4">
|
||||
<button
|
||||
className={clsx(
|
||||
'w-1/2 rounded-full border-2 py-2',
|
||||
betChoice === 'YES'
|
||||
? 'border-teal-500 bg-teal-500 text-white'
|
||||
: betChoice === 'NO'
|
||||
? 'border-greyscale-3 text-greyscale-3 bg-white'
|
||||
: 'border-teal-500 bg-white text-teal-500'
|
||||
)}
|
||||
onClick={() => {
|
||||
if (betChoice === 'YES') {
|
||||
setBetChoice(undefined)
|
||||
} else {
|
||||
setBetChoice('YES')
|
||||
}
|
||||
}}
|
||||
>
|
||||
YES
|
||||
</button>
|
||||
<button
|
||||
className={clsx(
|
||||
'w-1/2 rounded-full border-2 py-2',
|
||||
betChoice === 'NO'
|
||||
? 'border-red-500 bg-red-500 text-white'
|
||||
: betChoice === 'YES'
|
||||
? 'border-greyscale-3 text-greyscale-3 bg-white'
|
||||
: 'border-red-500 bg-white text-red-500'
|
||||
)}
|
||||
onClick={() => {
|
||||
if (betChoice === 'NO') {
|
||||
setBetChoice(undefined)
|
||||
} else {
|
||||
setBetChoice('NO')
|
||||
}
|
||||
}}
|
||||
>
|
||||
NO
|
||||
</button>
|
||||
</Row> */}
|
||||
<Col>
|
||||
<BuyPanel
|
||||
hidden={false}
|
||||
contract={contract}
|
||||
user={user}
|
||||
unfilledBets={unfilledBets}
|
||||
selected={betChoice}
|
||||
mobileView={true}
|
||||
// onBuySuccess={onBetSuccess}>
|
||||
/>
|
||||
</Col>
|
||||
</Col>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -162,15 +162,24 @@ export function SimpleBetPanel(props: {
|
|||
)
|
||||
}
|
||||
|
||||
function BuyPanel(props: {
|
||||
export function BuyPanel(props: {
|
||||
contract: CPMMBinaryContract | PseudoNumericContract
|
||||
user: User | null | undefined
|
||||
unfilledBets: Bet[]
|
||||
hidden: boolean
|
||||
selected?: 'YES' | 'NO'
|
||||
onBuySuccess?: () => void
|
||||
mobileView?: boolean
|
||||
}) {
|
||||
const { contract, user, unfilledBets, hidden, selected, onBuySuccess } = props
|
||||
const {
|
||||
contract,
|
||||
user,
|
||||
unfilledBets,
|
||||
hidden,
|
||||
selected,
|
||||
onBuySuccess,
|
||||
mobileView,
|
||||
} = props
|
||||
|
||||
const initialProb = getProbability(contract)
|
||||
const isPseudoNumeric = contract.outcomeType === 'PSEUDO_NUMERIC'
|
||||
|
@ -192,6 +201,19 @@ function BuyPanel(props: {
|
|||
}
|
||||
}
|
||||
|
||||
function mobileOnBetChoice(choice: 'YES' | 'NO' | undefined) {
|
||||
if (outcome === choice) {
|
||||
setOutcome(undefined)
|
||||
} else {
|
||||
setOutcome(choice)
|
||||
}
|
||||
setWasSubmitted(false)
|
||||
|
||||
if (!isIOS() && !isAndroid()) {
|
||||
focusAmountInput()
|
||||
}
|
||||
}
|
||||
|
||||
function onBetChange(newAmount: number | undefined) {
|
||||
setWasSubmitted(false)
|
||||
setBetAmount(newAmount)
|
||||
|
@ -281,92 +303,119 @@ function BuyPanel(props: {
|
|||
|
||||
return (
|
||||
<Col className={hidden ? 'hidden' : ''}>
|
||||
<div className="my-3 text-left text-sm text-gray-500">
|
||||
{isPseudoNumeric ? 'Direction' : 'Outcome'}
|
||||
</div>
|
||||
<YesNoSelector
|
||||
className="mb-4"
|
||||
btnClassName="flex-1"
|
||||
selected={outcome}
|
||||
onSelect={(choice) => onBetChoice(choice)}
|
||||
isPseudoNumeric={isPseudoNumeric}
|
||||
/>
|
||||
|
||||
<Row className="my-3 justify-between text-left text-sm text-gray-500">
|
||||
Amount
|
||||
<span className={'xl:hidden'}>
|
||||
Balance: {formatMoney(user?.balance ?? 0)}
|
||||
</span>
|
||||
</Row>
|
||||
|
||||
<BuyAmountInput
|
||||
inputClassName="w-full max-w-none"
|
||||
amount={betAmount}
|
||||
onChange={onBetChange}
|
||||
error={error}
|
||||
setError={setError}
|
||||
disabled={isSubmitting}
|
||||
inputRef={inputRef}
|
||||
showSliderOnMobile
|
||||
/>
|
||||
|
||||
<Col className="mt-3 w-full gap-3">
|
||||
<Row className="items-center justify-between text-sm">
|
||||
<div className="text-gray-500">
|
||||
{isPseudoNumeric ? 'Estimated value' : 'Probability'}
|
||||
{!mobileView && (
|
||||
<>
|
||||
<div className="my-3 text-left text-sm text-gray-500">
|
||||
{isPseudoNumeric ? 'Direction' : 'Outcome'}
|
||||
</div>
|
||||
{probStayedSame ? (
|
||||
<div>{format(initialProb)}</div>
|
||||
) : (
|
||||
<div>
|
||||
{format(initialProb)}
|
||||
<span className="mx-2">→</span>
|
||||
{format(resultProb)}
|
||||
</div>
|
||||
)}
|
||||
</Row>
|
||||
|
||||
<Row className="items-center justify-between gap-2 text-sm">
|
||||
<Row className="flex-nowrap items-center gap-2 whitespace-nowrap text-gray-500">
|
||||
<div>
|
||||
{isPseudoNumeric ? (
|
||||
'Max payout'
|
||||
) : (
|
||||
<>
|
||||
Payout if <BinaryOutcomeLabel outcome={outcome ?? 'YES'} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Row>
|
||||
<div>
|
||||
<span className="mr-2 whitespace-nowrap">
|
||||
{formatMoney(currentPayout)}
|
||||
</span>
|
||||
(+{currentReturnPercent})
|
||||
</div>
|
||||
</Row>
|
||||
</Col>
|
||||
|
||||
<Spacer h={8} />
|
||||
|
||||
{user && (
|
||||
<WarningConfirmationButton
|
||||
warning={warning}
|
||||
onSubmit={submitBet}
|
||||
isSubmitting={isSubmitting}
|
||||
disabled={!!betDisabled}
|
||||
openModalButtonClass={clsx(
|
||||
'btn mb-2 flex-1',
|
||||
betDisabled
|
||||
? 'btn-disabled'
|
||||
: outcome === 'YES'
|
||||
? 'btn-primary'
|
||||
: 'border-none bg-red-400 hover:bg-red-500'
|
||||
)}
|
||||
/>
|
||||
<YesNoSelector
|
||||
className="mb-4"
|
||||
btnClassName="flex-1"
|
||||
selected={outcome}
|
||||
onSelect={(choice) => onBetChoice(choice)}
|
||||
isPseudoNumeric={isPseudoNumeric}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{mobileView && (
|
||||
<>
|
||||
<YesNoSelector
|
||||
className="mb-4"
|
||||
btnClassName="flex-1"
|
||||
selected={outcome}
|
||||
onSelect={(choice) => mobileOnBetChoice(choice)}
|
||||
isPseudoNumeric={isPseudoNumeric}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{wasSubmitted && <div className="mt-4">Trade submitted!</div>}
|
||||
<Col
|
||||
className={clsx(
|
||||
mobileView
|
||||
? outcome === 'NO'
|
||||
? 'bg-red-50'
|
||||
: outcome === 'YES'
|
||||
? 'bg-teal-50'
|
||||
: 'hidden'
|
||||
: 'bg-white'
|
||||
)}
|
||||
>
|
||||
<Row className="my-3 justify-between text-left text-sm text-gray-500">
|
||||
Amount
|
||||
{/* <span className={'xl:hidden'}>
|
||||
Balance: {formatMoney(user?.balance ?? 0)}
|
||||
</span> */}
|
||||
</Row>
|
||||
|
||||
<BuyAmountInput
|
||||
inputClassName="w-full max-w-none"
|
||||
amount={betAmount}
|
||||
onChange={onBetChange}
|
||||
error={error}
|
||||
setError={setError}
|
||||
disabled={isSubmitting}
|
||||
inputRef={inputRef}
|
||||
showSliderOnMobile
|
||||
/>
|
||||
|
||||
<Col className="mt-3 w-full gap-3">
|
||||
<Row className="items-center justify-between text-sm">
|
||||
<div className="text-gray-500">
|
||||
{isPseudoNumeric ? 'Estimated value' : 'Probability'}
|
||||
</div>
|
||||
{probStayedSame ? (
|
||||
<div>{format(initialProb)}</div>
|
||||
) : (
|
||||
<div>
|
||||
{format(initialProb)}
|
||||
<span className="mx-2">→</span>
|
||||
{format(resultProb)}
|
||||
</div>
|
||||
)}
|
||||
</Row>
|
||||
|
||||
<Row className="items-center justify-between gap-2 text-sm">
|
||||
<Row className="flex-nowrap items-center gap-2 whitespace-nowrap text-gray-500">
|
||||
<div>
|
||||
{isPseudoNumeric ? (
|
||||
'Max payout'
|
||||
) : (
|
||||
<>
|
||||
Payout if <BinaryOutcomeLabel outcome={outcome ?? 'YES'} />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Row>
|
||||
<div>
|
||||
<span className="mr-2 whitespace-nowrap">
|
||||
{formatMoney(currentPayout)}
|
||||
</span>
|
||||
(+{currentReturnPercent})
|
||||
</div>
|
||||
</Row>
|
||||
</Col>
|
||||
|
||||
<Spacer h={8} />
|
||||
|
||||
{user && (
|
||||
<WarningConfirmationButton
|
||||
warning={warning}
|
||||
onSubmit={submitBet}
|
||||
isSubmitting={isSubmitting}
|
||||
disabled={!!betDisabled}
|
||||
openModalButtonClass={clsx(
|
||||
'btn mb-2 flex-1',
|
||||
betDisabled
|
||||
? 'btn-disabled'
|
||||
: outcome === 'YES'
|
||||
? 'btn-primary'
|
||||
: 'border-none bg-red-400 hover:bg-red-500'
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
|
||||
{wasSubmitted && <div className="mt-4">Trade submitted!</div>}
|
||||
</Col>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -35,10 +35,11 @@ export function YesNoSelector(props: {
|
|||
<button
|
||||
className={clsx(
|
||||
commonClassNames,
|
||||
'hover:bg-primary-focus border-primary hover:border-primary-focus hover:text-white',
|
||||
selected == 'YES'
|
||||
? 'bg-primary text-white'
|
||||
: 'text-primary bg-white',
|
||||
? 'border-teal-500 bg-teal-500 text-white'
|
||||
: selected == 'NO'
|
||||
? 'border-greyscale-3 text-greyscale-3 bg-white'
|
||||
: 'border-teal-500 bg-white text-teal-500 hover:bg-teal-50',
|
||||
btnClassName
|
||||
)}
|
||||
onClick={() => onSelect('YES')}
|
||||
|
@ -52,10 +53,11 @@ export function YesNoSelector(props: {
|
|||
<button
|
||||
className={clsx(
|
||||
commonClassNames,
|
||||
'border-red-400 hover:border-red-500 hover:bg-red-500 hover:text-white',
|
||||
selected == 'NO'
|
||||
? 'bg-red-400 text-white'
|
||||
: 'bg-white text-red-400',
|
||||
? 'border-red-500 bg-red-500 text-white'
|
||||
: selected == 'YES'
|
||||
? 'border-greyscale-3 text-greyscale-3 bg-white'
|
||||
: 'border-red-500 bg-white text-red-500 hover:bg-red-50',
|
||||
btnClassName
|
||||
)}
|
||||
onClick={() => onSelect('NO')}
|
||||
|
|
Loading…
Reference in New Issue
Block a user