2022-02-20 22:25:58 +00:00
|
|
|
import clsx from 'clsx'
|
2022-06-29 23:47:06 +00:00
|
|
|
import { sum } from 'lodash'
|
2022-09-19 13:31:04 +00:00
|
|
|
import { useEffect, useState } from 'react'
|
2022-02-20 22:25:58 +00:00
|
|
|
|
2022-07-28 02:40:33 +00:00
|
|
|
import { FreeResponseContract, MultipleChoiceContract } from 'common/contract'
|
2022-02-20 22:25:58 +00:00
|
|
|
import { Col } from '../layout/col'
|
2022-07-10 22:03:15 +00:00
|
|
|
import { APIError, resolveMarket } from 'web/lib/firebase/api'
|
2022-02-20 22:25:58 +00:00
|
|
|
import { Row } from '../layout/row'
|
|
|
|
import { ChooseCancelSelector } from '../yes-no-selector'
|
|
|
|
import { ResolveConfirmationButton } from '../confirmation-button'
|
2022-05-09 13:04:36 +00:00
|
|
|
import { removeUndefinedProps } from 'common/util/object'
|
2022-09-19 13:31:04 +00:00
|
|
|
import { BETTOR, PAST_BETS } from 'common/user'
|
2022-02-20 22:25:58 +00:00
|
|
|
|
|
|
|
export function AnswerResolvePanel(props: {
|
2022-09-15 03:28:40 +00:00
|
|
|
isAdmin: boolean
|
|
|
|
isCreator: boolean
|
2022-07-28 02:40:33 +00:00
|
|
|
contract: FreeResponseContract | MultipleChoiceContract
|
2022-02-20 22:25:58 +00:00
|
|
|
resolveOption: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined
|
|
|
|
setResolveOption: (
|
|
|
|
option: 'CHOOSE' | 'CHOOSE_MULTIPLE' | 'CANCEL' | undefined
|
|
|
|
) => void
|
|
|
|
chosenAnswers: { [answerId: string]: number }
|
|
|
|
}) {
|
2022-09-15 03:28:40 +00:00
|
|
|
const {
|
|
|
|
contract,
|
|
|
|
resolveOption,
|
|
|
|
setResolveOption,
|
|
|
|
chosenAnswers,
|
|
|
|
isAdmin,
|
|
|
|
isCreator,
|
|
|
|
} = props
|
2022-02-20 22:25:58 +00:00
|
|
|
const answers = Object.keys(chosenAnswers)
|
|
|
|
|
|
|
|
const [isSubmitting, setIsSubmitting] = useState(false)
|
|
|
|
const [error, setError] = useState<string | undefined>(undefined)
|
2022-09-19 13:31:04 +00:00
|
|
|
const [warning, setWarning] = useState<string | undefined>(undefined)
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (resolveOption === 'CANCEL') {
|
|
|
|
setWarning(
|
|
|
|
`All ${PAST_BETS} will be returned. Unique ${BETTOR} bonuses will be
|
|
|
|
withdrawn from your account.`
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
setWarning(undefined)
|
|
|
|
}
|
|
|
|
}, [resolveOption])
|
2022-02-20 22:25:58 +00:00
|
|
|
|
|
|
|
const onResolve = async () => {
|
|
|
|
if (resolveOption === 'CHOOSE' && answers.length !== 1) return
|
|
|
|
if (resolveOption === 'CHOOSE_MULTIPLE' && answers.length < 2) return
|
|
|
|
|
|
|
|
setIsSubmitting(true)
|
|
|
|
|
2022-05-22 08:36:05 +00:00
|
|
|
const totalProb = sum(Object.values(chosenAnswers))
|
2022-06-29 23:47:06 +00:00
|
|
|
const resolutions = Object.entries(chosenAnswers).map(([i, p]) => {
|
|
|
|
return { answer: parseInt(i), pct: (100 * p) / totalProb }
|
|
|
|
})
|
2022-02-20 22:25:58 +00:00
|
|
|
|
|
|
|
const resolutionProps = removeUndefinedProps({
|
|
|
|
outcome:
|
|
|
|
resolveOption === 'CHOOSE'
|
2022-06-29 23:47:06 +00:00
|
|
|
? parseInt(answers[0])
|
2022-02-20 22:25:58 +00:00
|
|
|
: resolveOption === 'CHOOSE_MULTIPLE'
|
|
|
|
? 'MKT'
|
|
|
|
: 'CANCEL',
|
|
|
|
resolutions:
|
2022-06-29 23:47:06 +00:00
|
|
|
resolveOption === 'CHOOSE_MULTIPLE' ? resolutions : undefined,
|
2022-02-20 22:25:58 +00:00
|
|
|
contractId: contract.id,
|
|
|
|
})
|
|
|
|
|
2022-06-29 23:47:06 +00:00
|
|
|
try {
|
|
|
|
const result = await resolveMarket(resolutionProps)
|
|
|
|
console.log('resolved', resolutionProps, 'result:', result)
|
|
|
|
} catch (e) {
|
|
|
|
if (e instanceof APIError) {
|
|
|
|
setError(e.toString())
|
|
|
|
} else {
|
|
|
|
console.error(e)
|
|
|
|
setError('Error resolving market')
|
|
|
|
}
|
2022-02-20 22:25:58 +00:00
|
|
|
}
|
2022-06-29 23:47:06 +00:00
|
|
|
|
2022-02-20 22:25:58 +00:00
|
|
|
setResolveOption(undefined)
|
|
|
|
setIsSubmitting(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
2022-04-18 23:02:40 +00:00
|
|
|
<Col className="gap-4 rounded">
|
2022-09-15 03:28:40 +00:00
|
|
|
<Row className="justify-between">
|
|
|
|
<div>Resolve your market</div>
|
|
|
|
{isAdmin && !isCreator && (
|
|
|
|
<span className="rounded bg-red-200 p-1 text-xs text-red-600">
|
|
|
|
ADMIN
|
|
|
|
</span>
|
|
|
|
)}
|
|
|
|
</Row>
|
2022-03-03 09:09:32 +00:00
|
|
|
<Col className="gap-4 sm:flex-row sm:items-center">
|
2022-02-20 22:25:58 +00:00
|
|
|
<ChooseCancelSelector
|
|
|
|
className="sm:!flex-row sm:items-center"
|
|
|
|
selected={resolveOption}
|
|
|
|
onSelect={setResolveOption}
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Row
|
|
|
|
className={clsx(
|
|
|
|
'flex-1 items-center',
|
|
|
|
resolveOption ? 'justify-between' : 'justify-end'
|
|
|
|
)}
|
|
|
|
>
|
|
|
|
{resolveOption && (
|
|
|
|
<button
|
|
|
|
className="btn btn-ghost"
|
|
|
|
onClick={() => {
|
|
|
|
setResolveOption(undefined)
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
Clear
|
|
|
|
</button>
|
|
|
|
)}
|
2022-09-30 05:41:22 +00:00
|
|
|
|
2022-02-20 22:25:58 +00:00
|
|
|
<ResolveConfirmationButton
|
2022-09-30 05:41:22 +00:00
|
|
|
color={
|
|
|
|
resolveOption === 'CANCEL'
|
|
|
|
? 'yellow'
|
|
|
|
: resolveOption === 'CHOOSE' && answers.length
|
|
|
|
? 'green'
|
|
|
|
: resolveOption === 'CHOOSE_MULTIPLE' &&
|
|
|
|
answers.length > 1 &&
|
|
|
|
answers.every((answer) => chosenAnswers[answer] > 0)
|
|
|
|
? 'blue'
|
|
|
|
: 'indigo'
|
|
|
|
}
|
|
|
|
disabled={
|
|
|
|
!resolveOption ||
|
|
|
|
(resolveOption === 'CHOOSE' && !answers.length) ||
|
|
|
|
(resolveOption === 'CHOOSE_MULTIPLE' &&
|
|
|
|
(!(answers.length > 1) ||
|
|
|
|
!answers.every((answer) => chosenAnswers[answer] > 0)))
|
|
|
|
}
|
2022-02-20 22:25:58 +00:00
|
|
|
onResolve={onResolve}
|
|
|
|
isSubmitting={isSubmitting}
|
|
|
|
/>
|
|
|
|
</Row>
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
{!!error && <div className="text-red-500">{error}</div>}
|
2022-09-19 13:31:04 +00:00
|
|
|
{!!warning && <div className="text-warning">{warning}</div>}
|
2022-02-20 22:25:58 +00:00
|
|
|
</Col>
|
|
|
|
)
|
|
|
|
}
|