From 57493fae1a985d74e2b68154e48e9af8cf7069e0 Mon Sep 17 00:00:00 2001 From: Milli Date: Wed, 1 Jun 2022 02:20:38 +0200 Subject: [PATCH] Editable interface for auto resolution --- common/contract.ts | 1 + web/components/contract/contract-details.tsx | 8 +- .../contract/contract-info-dialog.tsx | 133 ++++++++++++++++-- 3 files changed, 126 insertions(+), 16 deletions(-) diff --git a/common/contract.ts b/common/contract.ts index a21dccb1..410a15a9 100644 --- a/common/contract.ts +++ b/common/contract.ts @@ -95,6 +95,7 @@ export type Numeric = { resolutionValue?: number } +export type contractField = keyof Contract export type outcomeType = 'BINARY' | 'MULTI' | 'FREE_RESPONSE' | 'NUMERIC' export type resolution = 'YES' | 'NO' | 'MKT' | 'CANCEL' diff --git a/web/components/contract/contract-details.tsx b/web/components/contract/contract-details.tsx index 36916774..d1706520 100644 --- a/web/components/contract/contract-details.tsx +++ b/web/components/contract/contract-details.tsx @@ -3,11 +3,8 @@ import { ClockIcon, DatabaseIcon, PencilIcon, - CurrencyDollarIcon, TrendingUpIcon, - StarIcon, } from '@heroicons/react/outline' -import { StarIcon as SolidStarIcon } from '@heroicons/react/solid' import { Row } from '../layout/row' import { formatMoney } from 'common/util/format' import { UserLink } from '../user-page' @@ -17,7 +14,6 @@ import { contractPool, updateContract, } from 'web/lib/firebase/contracts' -import { Col } from '../layout/col' import dayjs from 'dayjs' import { DateTimeTooltip } from '../datetime-tooltip' import { fromNow } from 'web/lib/util/time' @@ -170,7 +166,7 @@ export function ContractDetails(props: {
{volumeLabel}
- {!disabled && } + {!disabled && } ) } @@ -194,7 +190,7 @@ export function contractTextDetails(contract: Contract) { ) } -function EditableCloseDate(props: { +export function EditableCloseDate(props: { closeTime: number contract: Contract isCreator: boolean diff --git a/web/components/contract/contract-info-dialog.tsx b/web/components/contract/contract-info-dialog.tsx index f5eabf27..bfa7b0cc 100644 --- a/web/components/contract/contract-info-dialog.tsx +++ b/web/components/contract/contract-info-dialog.tsx @@ -1,17 +1,17 @@ -import { DotsHorizontalIcon } from '@heroicons/react/outline' +import { DotsHorizontalIcon, PencilIcon } from '@heroicons/react/outline' import clsx from 'clsx' import dayjs from 'dayjs' -import { uniqBy, sum } from 'lodash' +import { uniqBy } from 'lodash' import { useState } from 'react' import { Bet } from 'common/bet' -import { Contract } from 'common/contract' +import { Contract, contractField } from 'common/contract' import { formatMoney } from 'common/util/format' import { - contractMetrics, contractPath, contractPool, getBinaryProbPercent, + updateContract, } from 'web/lib/firebase/contracts' import { AddLiquidityPanel } from '../add-liquidity-panel' import { CopyLinkButton } from '../copy-link-button' @@ -23,13 +23,13 @@ import { TagsInput } from '../tags-input' import { Title } from '../title' import { TweetButton } from '../tweet-button' -export function ContractInfoDialog(props: { contract: Contract; bets: Bet[] }) { - const { contract, bets } = props +const formatTime = (dt: number) => dayjs(dt).format('MMM DD, YYYY hh:mm a z') + +export function ContractInfoDialog(props: { contract: Contract; bets: Bet[]; isCreator: boolean }) { + const { contract, bets, isCreator } = props 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 tradersCount = uniqBy(bets, 'userId').length @@ -85,11 +85,21 @@ export function ContractInfoDialog(props: { contract: Contract; bets: Bet[] }) { <> Automatic resolution - {formatTime(autoResolutionTime)} + Default resolution - {autoResolution} + )} @@ -161,3 +171,106 @@ const getTweetText = (contract: Contract, isCreator: boolean) => { 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 ( + + {isEditing ? ( +
+ e.stopPropagation()} + onChange={(e) => setTimeString(e.target.value || '')} + min={contract.closeTime} + value={timeString} + /> +
+ ) : ( +
{timeString}
+ )} + {isCreator && + (isEditing ? ( + + ) : ( + + ))} + + ) +} + +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 ( + + {isEditing ? ( + e.stopPropagation()} + onChange={(e) => setTimeString(e.target.value || '')} + min={contract.closeTime} + value={newValue} + /> + ) : ( + <>{newValue} + )} + {isCreator && + (isEditing ? ( + + ) : ( + + ))} + + ) +}