Resolve answer UI
This commit is contained in:
parent
fbdc6eacad
commit
0a178a7519
|
@ -14,7 +14,7 @@ import { Avatar } from './avatar'
|
|||
import { SiteLink } from './site-link'
|
||||
import { DateTimeTooltip } from './datetime-tooltip'
|
||||
import dayjs from 'dayjs'
|
||||
import { BuyButton } from './yes-no-selector'
|
||||
import { BuyButton, ChooseCancelSelector } from './yes-no-selector'
|
||||
import { Spacer } from './layout/spacer'
|
||||
import {
|
||||
formatMoney,
|
||||
|
@ -32,6 +32,7 @@ import {
|
|||
import { firebaseLogin } from '../lib/firebase/users'
|
||||
import { Bet } from '../../common/bet'
|
||||
import { useAnswers } from '../hooks/use-answers'
|
||||
import { ResolveConfirmationButton } from './confirmation-button'
|
||||
|
||||
export function AnswersPanel(props: {
|
||||
contract: Contract<'MULTI'>
|
||||
|
@ -45,18 +46,49 @@ export function AnswersPanel(props: {
|
|||
(answer) => -1 * getOutcomeProbability(contract.totalShares, answer.id)
|
||||
)
|
||||
|
||||
const user = useUser()
|
||||
|
||||
const [resolveOption, setResolveOption] = useState<
|
||||
'CHOOSE' | 'CANCEL' | undefined
|
||||
>()
|
||||
const [answerChoice, setAnswerChoice] = useState<string | undefined>()
|
||||
|
||||
return (
|
||||
<Col className="gap-3">
|
||||
{sortedAnswers.map((answer) => (
|
||||
<AnswerItem key={answer.id} answer={answer} contract={contract} />
|
||||
<AnswerItem
|
||||
key={answer.id}
|
||||
answer={answer}
|
||||
contract={contract}
|
||||
showChoice={resolveOption === 'CHOOSE'}
|
||||
isChosen={answer.id === answerChoice}
|
||||
onChoose={() => setAnswerChoice(answer.id)}
|
||||
/>
|
||||
))}
|
||||
|
||||
<CreateAnswerInput contract={contract} />
|
||||
|
||||
{user?.id === contract.creatorId && (
|
||||
<AnswerResolvePanel
|
||||
contract={contract}
|
||||
resolveOption={resolveOption}
|
||||
setResolveOption={setResolveOption}
|
||||
answer={answerChoice}
|
||||
clearAnswerChoice={() => setAnswerChoice(undefined)}
|
||||
/>
|
||||
)}
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
||||
function AnswerItem(props: { answer: Answer; contract: Contract<'MULTI'> }) {
|
||||
const { answer, contract } = props
|
||||
function AnswerItem(props: {
|
||||
answer: Answer
|
||||
contract: Contract<'MULTI'>
|
||||
showChoice: boolean
|
||||
isChosen: boolean
|
||||
onChoose: () => void
|
||||
}) {
|
||||
const { answer, contract, showChoice, isChosen, onChoose } = props
|
||||
const { username, avatarUrl, name, createdTime, number, text } = answer
|
||||
|
||||
const createdDate = dayjs(createdTime).format('MMM D')
|
||||
|
@ -99,12 +131,28 @@ function AnswerItem(props: { answer: Answer; contract: Contract<'MULTI'> }) {
|
|||
) : (
|
||||
<Row className="self-end sm:self-start items-center gap-4">
|
||||
<div className="text-2xl text-green-500">{probPercent}</div>
|
||||
<BuyButton
|
||||
className="justify-end self-end flex-initial btn-md !px-8"
|
||||
onClick={() => {
|
||||
setIsBetting(true)
|
||||
}}
|
||||
/>
|
||||
{showChoice ? (
|
||||
<div className="form-control py-1">
|
||||
<label className="cursor-pointer label gap-2">
|
||||
<span className="label-text">Choose this answer</span>
|
||||
<input
|
||||
className={clsx('radio', isChosen && '!bg-green-500')}
|
||||
type="radio"
|
||||
name="opt"
|
||||
checked={isChosen}
|
||||
onChange={onChoose}
|
||||
value={answer.id}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
) : (
|
||||
<BuyButton
|
||||
className="justify-end self-end flex-initial btn-md !px-8"
|
||||
onClick={() => {
|
||||
setIsBetting(true)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Row>
|
||||
)}
|
||||
</Col>
|
||||
|
@ -327,3 +375,64 @@ function CreateAnswerInput(props: { contract: Contract<'MULTI'> }) {
|
|||
</Col>
|
||||
)
|
||||
}
|
||||
|
||||
function AnswerResolvePanel(props: {
|
||||
contract: Contract<'MULTI'>
|
||||
resolveOption: 'CHOOSE' | 'CANCEL' | undefined
|
||||
setResolveOption: (option: 'CHOOSE' | 'CANCEL' | undefined) => void
|
||||
answer: string | undefined
|
||||
clearAnswerChoice: () => void
|
||||
}) {
|
||||
const {
|
||||
contract,
|
||||
resolveOption,
|
||||
setResolveOption,
|
||||
answer,
|
||||
clearAnswerChoice,
|
||||
} = props
|
||||
|
||||
const resolutionButtonClass =
|
||||
resolveOption === 'CANCEL'
|
||||
? 'bg-yellow-400 hover:bg-yellow-500'
|
||||
: resolveOption === 'CHOOSE' && answer
|
||||
? 'btn-primary'
|
||||
: 'btn-disabled'
|
||||
|
||||
return (
|
||||
<Col className="gap-4 p-4 bg-gray-50 rounded">
|
||||
<div>Resolve your market</div>
|
||||
<Col className="sm:flex-row sm:items-center gap-2">
|
||||
<ChooseCancelSelector
|
||||
className="!flex-row flex-wrap 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)
|
||||
clearAnswerChoice()
|
||||
}}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
)}
|
||||
<ResolveConfirmationButton
|
||||
onResolve={() => {}}
|
||||
isSubmitting={false}
|
||||
openModelButtonClass={resolutionButtonClass}
|
||||
submitButtonClass={resolutionButtonClass}
|
||||
/>
|
||||
</Row>
|
||||
</Col>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -51,3 +51,36 @@ export function ConfirmationButton(props: {
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export function ResolveConfirmationButton(props: {
|
||||
onResolve: () => void
|
||||
isSubmitting: boolean
|
||||
openModelButtonClass?: string
|
||||
submitButtonClass?: string
|
||||
}) {
|
||||
const { onResolve, isSubmitting, openModelButtonClass, submitButtonClass } =
|
||||
props
|
||||
return (
|
||||
<ConfirmationButton
|
||||
id="resolution-modal"
|
||||
openModelBtn={{
|
||||
className: clsx(
|
||||
'border-none self-start',
|
||||
openModelButtonClass,
|
||||
isSubmitting && 'btn-disabled loading'
|
||||
),
|
||||
label: 'Resolve',
|
||||
}}
|
||||
cancelBtn={{
|
||||
label: 'Back',
|
||||
}}
|
||||
submitBtn={{
|
||||
label: 'Resolve',
|
||||
className: clsx('border-none', submitButtonClass),
|
||||
}}
|
||||
onSubmit={onResolve}
|
||||
>
|
||||
<p>Are you sure you want to resolve this market?</p>
|
||||
</ConfirmationButton>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -27,5 +27,5 @@ export function ProbLabel() {
|
|||
}
|
||||
|
||||
export function AnswerNumberLabel(props: { number: string }) {
|
||||
return <span className="text-blue-400">#{props.number}</span>
|
||||
return <span className="text-primary">#{props.number}</span>
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import { Title } from './title'
|
|||
import { User } from '../lib/firebase/users'
|
||||
import { YesNoCancelSelector } from './yes-no-selector'
|
||||
import { Spacer } from './layout/spacer'
|
||||
import { ConfirmationButton as ConfirmationButton } from './confirmation-button'
|
||||
import { ResolveConfirmationButton } from './confirmation-button'
|
||||
import { resolveMarket } from '../lib/firebase/api-call'
|
||||
import { ProbabilitySelector } from './probability-selector'
|
||||
import { getProbability } from '../../common/calculate'
|
||||
|
@ -114,27 +114,12 @@ export function ResolutionPanel(props: {
|
|||
|
||||
{!!error && <div className="text-red-500">{error}</div>}
|
||||
|
||||
<ConfirmationButton
|
||||
id="resolution-modal"
|
||||
openModelBtn={{
|
||||
className: clsx(
|
||||
'border-none self-start mt-2 w-full',
|
||||
submitButtonClass,
|
||||
isSubmitting && 'btn-disabled loading'
|
||||
),
|
||||
label: 'Resolve',
|
||||
}}
|
||||
cancelBtn={{
|
||||
label: 'Back',
|
||||
}}
|
||||
submitBtn={{
|
||||
label: 'Resolve',
|
||||
className: submitButtonClass,
|
||||
}}
|
||||
onSubmit={resolve}
|
||||
>
|
||||
<p>Are you sure you want to resolve this market?</p>
|
||||
</ConfirmationButton>
|
||||
<ResolveConfirmationButton
|
||||
onResolve={resolve}
|
||||
isSubmitting={isSubmitting}
|
||||
openModelButtonClass={clsx('w-full mt-2', submitButtonClass)}
|
||||
submitButtonClass={submitButtonClass}
|
||||
/>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -90,6 +90,37 @@ export function YesNoCancelSelector(props: {
|
|||
)
|
||||
}
|
||||
|
||||
export function ChooseCancelSelector(props: {
|
||||
selected: 'CHOOSE' | 'CANCEL' | undefined
|
||||
onSelect: (selected: 'CHOOSE' | 'CANCEL') => void
|
||||
className?: string
|
||||
btnClassName?: string
|
||||
}) {
|
||||
const { selected, onSelect, className } = props
|
||||
|
||||
const btnClassName = clsx('px-6 flex-1', props.btnClassName)
|
||||
|
||||
return (
|
||||
<Col className={clsx('gap-2', className)}>
|
||||
<Button
|
||||
color={selected === 'CHOOSE' ? 'green' : 'gray'}
|
||||
onClick={() => onSelect('CHOOSE')}
|
||||
className={clsx('whitespace-nowrap', btnClassName)}
|
||||
>
|
||||
Choose an answer
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
color={selected === 'CANCEL' ? 'yellow' : 'gray'}
|
||||
onClick={() => onSelect('CANCEL')}
|
||||
className={clsx(btnClassName, '')}
|
||||
>
|
||||
N/A
|
||||
</Button>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
|
||||
const fundAmounts = [500, 1000, 2500, 10000]
|
||||
|
||||
export function FundsSelector(props: {
|
||||
|
@ -121,7 +152,7 @@ export function BuyButton(props: { className?: string; onClick?: () => void }) {
|
|||
const { className, onClick } = props
|
||||
return (
|
||||
<Button className={className} onClick={onClick} color="green">
|
||||
Buy
|
||||
BUY
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user