Show error after modal

- Show balance if insufficient funds
- Clear error from amount input if amount deleted entirely
This commit is contained in:
Sinclair Chen 2022-08-18 14:18:13 -07:00
parent 94a225615f
commit b49999c077
3 changed files with 60 additions and 42 deletions

View File

@ -113,6 +113,8 @@ export function BuyAmountInput(props: {
} else { } else {
setError(undefined) setError(undefined)
} }
} else {
setError(undefined)
} }
} }

View File

@ -14,14 +14,18 @@ import { useUnfilledBets } from 'web/hooks/use-bets'
import { useUser } from 'web/hooks/use-user' import { useUser } from 'web/hooks/use-user'
import { SignUpPrompt } from './sign-up-prompt' import { SignUpPrompt } from './sign-up-prompt'
import { getCpmmProbability } from 'common/calculate-cpmm' import { getCpmmProbability } from 'common/calculate-cpmm'
import { Col } from './layout/col'
import { XIcon } from '@heroicons/react/solid'
import { formatMoney } from 'common/util/format'
// adapted from bet-panel.ts // adapted from bet-panel.ts
export function BetInline(props: { export function BetInline(props: {
contract: CPMMBinaryContract | PseudoNumericContract contract: CPMMBinaryContract | PseudoNumericContract
className?: string className?: string
setProbAfter: (probAfter: number) => void setProbAfter: (probAfter: number) => void
onClose: () => void
}) { }) {
const { contract, className, setProbAfter: setResult } = props const { contract, className, setProbAfter, onClose } = props
const user = useUser() const user = useUser()
@ -40,7 +44,7 @@ export function BetInline(props: {
unfilledBets unfilledBets
) )
const resultProb = getCpmmProbability(newPool, newP) const resultProb = getCpmmProbability(newPool, newP)
useEffect(() => setResult(resultProb), [resultProb]) useEffect(() => setProbAfter(resultProb), [resultProb])
const submitBet = useMutation( const submitBet = useMutation(
() => placeBet({ outcome, amount, contractId: contract.id }), () => placeBet({ outcome, amount, contractId: contract.id }),
@ -64,41 +68,53 @@ export function BetInline(props: {
const betDisabled = submitBet.isLoading || submitBet.isError || !amount const betDisabled = submitBet.isLoading || submitBet.isError || !amount
return ( return (
<Row className={clsx('h-8 items-stretch justify-center gap-3', className)}> <Col className={clsx('items-center', className)}>
<div className="text-xl">Bet</div> <Row className="h-12 items-stretch gap-3 rounded bg-indigo-200 py-2 px-3">
<YesNoSelector <div className="text-xl">Bet</div>
className="space-x-0" <YesNoSelector
btnClassName="rounded-none first:rounded-l-2xl last:rounded-r-2xl" className="space-x-0"
selected={outcome} btnClassName="rounded-none first:rounded-l-2xl last:rounded-r-2xl"
onSelect={setOutcome} selected={outcome}
isPseudoNumeric={isPseudoNumeric} onSelect={setOutcome}
/> isPseudoNumeric={isPseudoNumeric}
<BuyAmountInput />
className="-mb-4" <BuyAmountInput
inputClassName={clsx( className="-mb-4"
'input-sm w-[100px] !text-base', inputClassName={clsx(
error && 'input-error' 'input-sm w-[100px] !text-base',
error && 'input-error'
)}
amount={amount}
onChange={setAmount}
error="" // handle error ourselves
setError={setError}
/>
{user && (
<Button
color={({ YES: 'green', NO: 'red' } as const)[outcome]}
size="xs"
disabled={betDisabled}
onClick={() => submitBet.mutate()}
>
{submitBet.isLoading
? 'Submitting'
: submitBet.isSuccess
? 'Success!'
: 'Submit'}
</Button>
)} )}
amount={amount} <SignUpPrompt size="xs" />
onChange={setAmount} <button onClick={onClose}>
error="" // handle error ourselves <XIcon className="ml-1 h-6 w-6" />
setError={setError} </button>
/> </Row>
{user && ( {error && (
<Button <div className="text-error my-1 text-sm">
color={({ YES: 'green', NO: 'red' } as const)[outcome]} {error}{' '}
size="xs" {error === 'Insufficient balance' &&
disabled={betDisabled} `(${formatMoney(user?.balance ?? 0)})`}
onClick={() => submitBet.mutate()} </div>
>
{submitBet.isLoading
? 'Submitting'
: submitBet.isSuccess
? 'Success!'
: 'Submit'}
</Button>
)} )}
<SignUpPrompt size="xs" /> </Col>
</Row>
) )
} }

View File

@ -149,12 +149,12 @@ export function ContractEmbed(props: { contract: Contract; bets: Bet[] }) {
</div> </div>
{(isBinary || isPseudoNumeric) && betPanelOpen && ( {(isBinary || isPseudoNumeric) && betPanelOpen && (
<Row className="mb-2 items-center justify-center gap-4 self-center rounded bg-indigo-200 py-2 px-3"> <BetInline
<BetInline contract={contract as any} setProbAfter={setProbAfter}/> contract={contract as any}
<button onClick={() => setBetPanelOpen(false)}> setProbAfter={setProbAfter}
<XIcon className="h-6 w-6" /> onClose={() => setBetPanelOpen(false)}
</button> className="self-center"
</Row> />
)} )}
<div className="mx-1 mb-2 min-h-0 flex-1" ref={setElem}> <div className="mx-1 mb-2 min-h-0 flex-1" ref={setElem}>