Editable interface for auto resolution
This commit is contained in:
parent
4de86d5b08
commit
57493fae1a
|
@ -95,6 +95,7 @@ export type Numeric = {
|
||||||
resolutionValue?: number
|
resolutionValue?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type contractField = keyof Contract
|
||||||
export type outcomeType = 'BINARY' | 'MULTI' | 'FREE_RESPONSE' | 'NUMERIC'
|
export type outcomeType = 'BINARY' | 'MULTI' | 'FREE_RESPONSE' | 'NUMERIC'
|
||||||
export type resolution = 'YES' | 'NO' | 'MKT' | 'CANCEL'
|
export type resolution = 'YES' | 'NO' | 'MKT' | 'CANCEL'
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,8 @@ import {
|
||||||
ClockIcon,
|
ClockIcon,
|
||||||
DatabaseIcon,
|
DatabaseIcon,
|
||||||
PencilIcon,
|
PencilIcon,
|
||||||
CurrencyDollarIcon,
|
|
||||||
TrendingUpIcon,
|
TrendingUpIcon,
|
||||||
StarIcon,
|
|
||||||
} from '@heroicons/react/outline'
|
} from '@heroicons/react/outline'
|
||||||
import { StarIcon as SolidStarIcon } from '@heroicons/react/solid'
|
|
||||||
import { Row } from '../layout/row'
|
import { Row } from '../layout/row'
|
||||||
import { formatMoney } from 'common/util/format'
|
import { formatMoney } from 'common/util/format'
|
||||||
import { UserLink } from '../user-page'
|
import { UserLink } from '../user-page'
|
||||||
|
@ -17,7 +14,6 @@ import {
|
||||||
contractPool,
|
contractPool,
|
||||||
updateContract,
|
updateContract,
|
||||||
} from 'web/lib/firebase/contracts'
|
} from 'web/lib/firebase/contracts'
|
||||||
import { Col } from '../layout/col'
|
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { DateTimeTooltip } from '../datetime-tooltip'
|
import { DateTimeTooltip } from '../datetime-tooltip'
|
||||||
import { fromNow } from 'web/lib/util/time'
|
import { fromNow } from 'web/lib/util/time'
|
||||||
|
@ -170,7 +166,7 @@ export function ContractDetails(props: {
|
||||||
<div className="whitespace-nowrap">{volumeLabel}</div>
|
<div className="whitespace-nowrap">{volumeLabel}</div>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
{!disabled && <ContractInfoDialog contract={contract} bets={bets} />}
|
{!disabled && <ContractInfoDialog contract={contract} bets={bets} isCreator={isCreator ?? false}/>}
|
||||||
</Row>
|
</Row>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -194,7 +190,7 @@ export function contractTextDetails(contract: Contract) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function EditableCloseDate(props: {
|
export function EditableCloseDate(props: {
|
||||||
closeTime: number
|
closeTime: number
|
||||||
contract: Contract
|
contract: Contract
|
||||||
isCreator: boolean
|
isCreator: boolean
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
import { DotsHorizontalIcon } from '@heroicons/react/outline'
|
import { DotsHorizontalIcon, PencilIcon } from '@heroicons/react/outline'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { uniqBy, sum } from 'lodash'
|
import { uniqBy } from 'lodash'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { Bet } from 'common/bet'
|
import { Bet } from 'common/bet'
|
||||||
|
|
||||||
import { Contract } from 'common/contract'
|
import { Contract, contractField } from 'common/contract'
|
||||||
import { formatMoney } from 'common/util/format'
|
import { formatMoney } from 'common/util/format'
|
||||||
import {
|
import {
|
||||||
contractMetrics,
|
|
||||||
contractPath,
|
contractPath,
|
||||||
contractPool,
|
contractPool,
|
||||||
getBinaryProbPercent,
|
getBinaryProbPercent,
|
||||||
|
updateContract,
|
||||||
} from 'web/lib/firebase/contracts'
|
} from 'web/lib/firebase/contracts'
|
||||||
import { AddLiquidityPanel } from '../add-liquidity-panel'
|
import { AddLiquidityPanel } from '../add-liquidity-panel'
|
||||||
import { CopyLinkButton } from '../copy-link-button'
|
import { CopyLinkButton } from '../copy-link-button'
|
||||||
|
@ -23,13 +23,13 @@ import { TagsInput } from '../tags-input'
|
||||||
import { Title } from '../title'
|
import { Title } from '../title'
|
||||||
import { TweetButton } from '../tweet-button'
|
import { TweetButton } from '../tweet-button'
|
||||||
|
|
||||||
export function ContractInfoDialog(props: { contract: Contract; bets: Bet[] }) {
|
const formatTime = (dt: number) => dayjs(dt).format('MMM DD, YYYY hh:mm a z')
|
||||||
const { contract, bets } = props
|
|
||||||
|
export function ContractInfoDialog(props: { contract: Contract; bets: Bet[]; isCreator: boolean }) {
|
||||||
|
const { contract, bets, isCreator } = props
|
||||||
|
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
|
|
||||||
const formatTime = (dt: number) => dayjs(dt).format('MMM DD, YYYY hh:mm a z')
|
|
||||||
|
|
||||||
const { createdTime, closeTime, resolutionTime, autoResolutionTime, autoResolution } = contract
|
const { createdTime, closeTime, resolutionTime, autoResolutionTime, autoResolution } = contract
|
||||||
const tradersCount = uniqBy(bets, 'userId').length
|
const tradersCount = uniqBy(bets, 'userId').length
|
||||||
|
|
||||||
|
@ -85,11 +85,21 @@ export function ContractInfoDialog(props: { contract: Contract; bets: Bet[] }) {
|
||||||
<>
|
<>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Automatic resolution</td>
|
<td>Automatic resolution</td>
|
||||||
<td>{formatTime(autoResolutionTime)}</td>
|
<EditableTime
|
||||||
|
time={autoResolutionTime}
|
||||||
|
contract={contract}
|
||||||
|
isCreator={isCreator}
|
||||||
|
dateType='autoResolutionTime'
|
||||||
|
/>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Default resolution</td>
|
<td>Default resolution</td>
|
||||||
<td>{autoResolution}</td>
|
<EditableString
|
||||||
|
value={autoResolution}
|
||||||
|
contract={contract}
|
||||||
|
isCreator={isCreator}
|
||||||
|
dateType='autoResolution'
|
||||||
|
/>
|
||||||
</tr>
|
</tr>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -161,3 +171,106 @@ const getTweetText = (contract: Contract, isCreator: boolean) => {
|
||||||
|
|
||||||
return `${tweetQuestion}\n\n${tweetDescription}\n\n${url}`
|
return `${tweetQuestion}\n\n${tweetDescription}\n\n${url}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function EditableTime(props: {
|
||||||
|
time: number
|
||||||
|
contract: Contract
|
||||||
|
isCreator: boolean
|
||||||
|
dateType: contractField
|
||||||
|
}) {
|
||||||
|
const { time, contract, isCreator, dateType } = props
|
||||||
|
|
||||||
|
const [isEditing, setIsEditing] = useState(false)
|
||||||
|
const [timeString, setTimeString] = useState(time && formatTime(time))
|
||||||
|
const onSave = () => {
|
||||||
|
const newTime = dayjs(timeString).valueOf()
|
||||||
|
if (newTime === time) setIsEditing(false)
|
||||||
|
else if (newTime > (contract.closeTime ?? Date.now)) {
|
||||||
|
updateContract(contract.id, {
|
||||||
|
[dateType]: newTime
|
||||||
|
})
|
||||||
|
setIsEditing(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<td>
|
||||||
|
{isEditing ? (
|
||||||
|
<div className="form-control mr-1 items-start">
|
||||||
|
<input
|
||||||
|
type="datetime-local"
|
||||||
|
className="input input-xs"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
onChange={(e) => setTimeString(e.target.value || '')}
|
||||||
|
min={contract.closeTime}
|
||||||
|
value={timeString}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="form-control mr-1 items-start">{timeString}</div>
|
||||||
|
)}
|
||||||
|
{isCreator &&
|
||||||
|
(isEditing ? (
|
||||||
|
<button className="btn btn-xs btn-ghost" onClick={onSave}>
|
||||||
|
Done
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button className="btn btn-xs btn-ghost"
|
||||||
|
onClick={() => setIsEditing(true)}
|
||||||
|
>
|
||||||
|
<PencilIcon className="mr-2 inline h-4 w-4" /> Edit
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function EditableString(props: {
|
||||||
|
value: string
|
||||||
|
contract: Contract
|
||||||
|
isCreator: boolean
|
||||||
|
dateType: contractField
|
||||||
|
}) {
|
||||||
|
const { value, contract, isCreator, dateType } = props
|
||||||
|
|
||||||
|
const [isEditing, setIsEditing] = useState(false)
|
||||||
|
const [newValue, setTimeString] = useState(value)
|
||||||
|
const onSave = () => {
|
||||||
|
if (newValue === value) setIsEditing(false)
|
||||||
|
else {
|
||||||
|
updateContract(contract.id, {
|
||||||
|
[dateType]: newValue
|
||||||
|
})
|
||||||
|
setIsEditing(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<td>
|
||||||
|
{isEditing ? (
|
||||||
|
<input
|
||||||
|
style={{ maxWidth: 50 }}
|
||||||
|
className="input input-xs resize-none"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
onChange={(e) => setTimeString(e.target.value || '')}
|
||||||
|
min={contract.closeTime}
|
||||||
|
value={newValue}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<>{newValue}</>
|
||||||
|
)}
|
||||||
|
{isCreator &&
|
||||||
|
(isEditing ? (
|
||||||
|
<button className="btn btn-xs btn-ghost" onClick={onSave}>
|
||||||
|
Done
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button className="btn btn-xs btn-ghost"
|
||||||
|
onClick={() => setIsEditing(true)}
|
||||||
|
>
|
||||||
|
<PencilIcon className="mr-2 inline h-4 w-4" /> Edit
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user