3b953a7c21
* Prototype range limit order UI * Conditionally show YES or NO max payout * Range bet executes both bets immediately. * Validate lowLimitProb < highLimitProb * Show error if low limit is higher than high limit * Update range order UI * Revert "Validate lowLimitProb < highLimitProb" This reverts commitc261fc2743
. * Revert "Range bet executes both bets immediately." This reverts commit30b95d75d9
. * Buy panel only non-limit orders * Bet choice => outcome * More iterating on range UI * betChoice => outcome * Lighten placeholder text
95 lines
2.6 KiB
TypeScript
95 lines
2.6 KiB
TypeScript
import clsx from 'clsx'
|
|
import { CPMMBinaryContract, PseudoNumericContract } from 'common/contract'
|
|
import { getPseudoProbability } from 'common/pseudo-numeric'
|
|
import { BucketInput } from './bucket-input'
|
|
import { Col } from './layout/col'
|
|
import { Spacer } from './layout/spacer'
|
|
|
|
export function ProbabilityInput(props: {
|
|
prob: number | undefined
|
|
onChange: (newProb: number | undefined) => void
|
|
disabled?: boolean
|
|
placeholder?: string
|
|
className?: string
|
|
inputClassName?: string
|
|
}) {
|
|
const { prob, onChange, disabled, placeholder, className, inputClassName } =
|
|
props
|
|
|
|
const onProbChange = (str: string) => {
|
|
let prob = parseInt(str.replace(/\D/g, ''))
|
|
const isInvalid = !str || isNaN(prob)
|
|
if (prob.toString().length > 2) {
|
|
if (prob === 100) prob = 99
|
|
else if (prob < 1) prob = 1
|
|
else prob = +prob.toString().slice(-2)
|
|
}
|
|
onChange(isInvalid ? undefined : prob)
|
|
}
|
|
|
|
return (
|
|
<Col className={className}>
|
|
<label className="input-group">
|
|
<input
|
|
className={clsx(
|
|
'input input-bordered max-w-[200px] text-lg placeholder:text-gray-400',
|
|
inputClassName
|
|
)}
|
|
type="number"
|
|
max={99}
|
|
min={1}
|
|
pattern="[0-9]*"
|
|
inputMode="numeric"
|
|
placeholder={placeholder ?? '0'}
|
|
maxLength={2}
|
|
value={prob ?? ''}
|
|
disabled={disabled}
|
|
onChange={(e) => onProbChange(e.target.value)}
|
|
/>
|
|
<span className="bg-gray-200 text-sm">%</span>
|
|
</label>
|
|
<Spacer h={4} />
|
|
</Col>
|
|
)
|
|
}
|
|
|
|
export function ProbabilityOrNumericInput(props: {
|
|
contract: CPMMBinaryContract | PseudoNumericContract
|
|
prob: number | undefined
|
|
setProb: (prob: number | undefined) => void
|
|
isSubmitting: boolean
|
|
placeholder?: string
|
|
}) {
|
|
const { contract, prob, setProb, isSubmitting, placeholder } = props
|
|
const isPseudoNumeric = contract.outcomeType === 'PSEUDO_NUMERIC'
|
|
|
|
return isPseudoNumeric ? (
|
|
<BucketInput
|
|
contract={contract}
|
|
onBucketChange={(value) =>
|
|
setProb(
|
|
value === undefined
|
|
? undefined
|
|
: 100 *
|
|
getPseudoProbability(
|
|
value,
|
|
contract.min,
|
|
contract.max,
|
|
contract.isLogScale
|
|
)
|
|
)
|
|
}
|
|
isSubmitting={isSubmitting}
|
|
placeholder={placeholder}
|
|
/>
|
|
) : (
|
|
<ProbabilityInput
|
|
inputClassName="w-full max-w-none"
|
|
prob={prob}
|
|
onChange={setProb}
|
|
disabled={isSubmitting}
|
|
placeholder={placeholder}
|
|
/>
|
|
)
|
|
}
|