Duplicate a question from '...' screen (#622)

* Duplicate a question from '...' screen

* Remove unused code
This commit is contained in:
Austin Chen 2022-07-05 16:26:58 -07:00 committed by GitHub
parent 3a6d28e2c2
commit cb25a7752d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 102 additions and 32 deletions

View File

@ -21,6 +21,7 @@ import { Title } from '../title'
import { TweetButton } from '../tweet-button'
import { InfoTooltip } from '../info-tooltip'
import { TagsInput } from 'web/components/tags-input'
import { DuplicateContractButton } from '../copy-contract-button'
export const contractDetailsButtonClassName =
'group flex items-center rounded-md px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-100 text-gray-400 hover:text-gray-500'
@ -71,6 +72,7 @@ export function ContractInfoDialog(props: { contract: Contract; bets: Bet[] }) {
tweetText={getTweetText(contract, false)}
/>
<ShareEmbedButton contract={contract} toastClassName={'-left-20'} />
<DuplicateContractButton contract={contract} />
</Row>
<div />

View File

@ -0,0 +1,54 @@
import { DuplicateIcon } from '@heroicons/react/outline'
import clsx from 'clsx'
import { Contract } from 'common/contract'
import { getMappedValue } from 'common/pseudo-numeric'
import { trackCallback } from 'web/lib/service/analytics'
export function DuplicateContractButton(props: {
contract: Contract
className?: string
}) {
const { contract, className } = props
return (
<a
className={clsx('btn btn-xs flex-nowrap normal-case', className)}
style={{
backgroundColor: 'white',
border: '2px solid #a78bfa',
// violet-400
color: '#a78bfa',
}}
href={duplicateContractHref(contract)}
onClick={trackCallback('duplicate market')}
target="_blank"
>
<DuplicateIcon className="mr-1.5 h-4 w-4" aria-hidden="true" />
<div>Duplicate</div>
</a>
)
}
// Pass along the Uri to create a new contract
function duplicateContractHref(contract: Contract) {
const params = {
q: contract.question,
closeTime: contract.closeTime || 0,
description: contract.description,
outcomeType: contract.outcomeType,
} as Record<string, any>
if (contract.outcomeType === 'PSEUDO_NUMERIC') {
params.min = contract.min
params.max = contract.max
params.isLogScale = contract.isLogScale
params.initValue = getMappedValue(contract)(contract.initialProbability)
}
return (
`/create?` +
Object.entries(params)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&')
)
}

View File

@ -28,14 +28,32 @@ import { GroupSelector } from 'web/components/groups/group-selector'
import { CATEGORIES } from 'common/categories'
import { User } from 'common/user'
export default function Create() {
const [question, setQuestion] = useState('')
// get query params:
const router = useRouter()
const { groupId } = router.query as { groupId: string }
useTracking('view create page')
const creator = useUser()
type NewQuestionParams = {
groupId?: string
q: string
type: string
description: string
closeTime: string
outcomeType: string
// Params for PSEUDO_NUMERIC outcomeType
min?: string
max?: string
isLogScale?: string
initValue?: string
}
export default function Create() {
useTracking('view create page')
const router = useRouter()
const params = router.query as NewQuestionParams
// TODO: Not sure why Question is pulled out as its own component;
// Maybe merge into newContract and then we don't need useEffect here.
const [question, setQuestion] = useState('')
useEffect(() => {
setQuestion(params.q ?? '')
}, [params.q])
const creator = useUser()
useEffect(() => {
if (creator === null) router.push('/')
}, [creator, router])
@ -65,11 +83,7 @@ export default function Create() {
</div>
</form>
<Spacer h={6} />
<NewContract
question={question}
groupId={groupId}
creator={creator}
/>
<NewContract question={question} params={params} creator={creator} />
</div>
</div>
</Page>
@ -80,20 +94,21 @@ export default function Create() {
export function NewContract(props: {
creator: User
question: string
groupId?: string
params?: NewQuestionParams
}) {
const { creator, question, groupId } = props
const [outcomeType, setOutcomeType] = useState<outcomeType>('BINARY')
const { creator, question, params } = props
const { groupId, initValue } = params ?? {}
const [outcomeType, setOutcomeType] = useState<outcomeType>(
(params?.outcomeType as outcomeType) ?? 'BINARY'
)
const [initialProb] = useState(50)
const [minString, setMinString] = useState('')
const [maxString, setMaxString] = useState('')
const [isLogScale, setIsLogScale] = useState(false)
const [initialValueString, setInitialValueString] = useState('')
const [minString, setMinString] = useState(params?.min ?? '')
const [maxString, setMaxString] = useState(params?.max ?? '')
const [isLogScale, setIsLogScale] = useState<boolean>(!!params?.isLogScale)
const [initialValueString, setInitialValueString] = useState(initValue)
const [description, setDescription] = useState('')
// const [tagText, setTagText] = useState<string>(tag ?? '')
// const tags = parseWordsAsTags(tagText)
const [description, setDescription] = useState(params?.description ?? '')
useEffect(() => {
if (groupId && creator)
getGroup(groupId).then((group) => {
@ -105,18 +120,17 @@ export function NewContract(props: {
}, [creator, groupId])
const [ante, _setAnte] = useState(FIXED_ANTE)
// useEffect(() => {
// if (ante === null && creator) {
// const initialAnte = creator.balance < 100 ? MINIMUM_ANTE : 100
// setAnte(initialAnte)
// }
// }, [ante, creator])
// const [anteError, setAnteError] = useState<string | undefined>()
// If params.closeTime is set, extract out the specified date and time
// By default, close the market a week from today
const weekFromToday = dayjs().add(7, 'day').format('YYYY-MM-DD')
const [closeDate, setCloseDate] = useState<undefined | string>(weekFromToday)
const [closeHoursMinutes, setCloseHoursMinutes] = useState<string>('23:59')
const timeInMs = Number(params?.closeTime ?? 0)
const initDate = timeInMs
? dayjs(timeInMs).format('YYYY-MM-DD')
: weekFromToday
const initTime = timeInMs ? dayjs(timeInMs).format('HH:mm') : '23:59'
const [closeDate, setCloseDate] = useState<undefined | string>(initDate)
const [closeHoursMinutes, setCloseHoursMinutes] = useState<string>(initTime)
const [marketInfoText, setMarketInfoText] = useState('')
const [isSubmitting, setIsSubmitting] = useState(false)
const [selectedGroup, setSelectedGroup] = useState<Group | undefined>(