import clsx from 'clsx'
import dayjs from 'dayjs'
import Link from 'next/link'
import { useState } from 'react'
import { AmountInput } from '../components/amount-input'
import { InfoTooltip } from '../components/info-tooltip'
import { Col } from '../components/layout/col'
import { Row } from '../components/layout/row'
import { Spacer } from '../components/layout/spacer'
import { Linkify } from '../components/linkify'
import { Page } from '../components/page'
import { Title } from '../components/title'
import { useUser } from '../hooks/use-user'
import { createContract } from '../lib/firebase/api-call'
import {
contractMetrics,
Contract,
contractPath,
} from '../lib/firebase/contracts'
type Prediction = {
question: string
description: string
initialProb: number
createdUrl?: string
}
function toPrediction(contract: Contract): Prediction {
const { startProb } = contractMetrics(contract)
return {
question: contract.question,
description: contract.description,
initialProb: startProb * 100,
createdUrl: contractPath(contract),
}
}
function PredictionRow(props: { prediction: Prediction }) {
const { prediction } = props
return (
{prediction.description}
{/* Initial probability */}
{prediction.initialProb.toFixed(0)}%
chance
{/* Current probability; hidden for now */}
{/*
{prediction.initialProb}%
chance
*/}
)
}
function PredictionList(props: { predictions: Prediction[] }) {
const { predictions } = props
return (
{predictions.map((prediction) =>
prediction.createdUrl ? (
) : (
)
)}
)
}
const TEST_VALUE = `1. Biden approval rating (as per 538) is greater than 50%: 80%
2. Court packing is clearly going to happen (new justices don't have to be appointed by end of year): 5%
3. Yang is New York mayor: 80%
4. Newsom recalled as CA governor: 5%
5. At least $250 million in damage from BLM protests this year: 30%
6. Significant capital gains tax hike (above 30% for highest bracket): 20%`
export default function MakePredictions() {
const user = useUser()
const [predictionsString, setPredictionsString] = useState('')
const [description, setDescription] = useState('')
const [isSubmitting, setIsSubmitting] = useState(false)
const [createdContracts, setCreatedContracts] = useState([])
const [ante, setAnte] = useState(100)
const [anteError, setAnteError] = useState()
// By default, close the market a week from today
const weekFromToday = dayjs().add(7, 'day').format('YYYY-MM-DDT23:59')
const [closeDate, setCloseDate] = useState(weekFromToday)
const closeTime = closeDate ? dayjs(closeDate).valueOf() : undefined
const bulkPlaceholder = `e.g.
${TEST_VALUE}
...
`
const predictions: Prediction[] = []
// Parse bulkContracts, then run createContract for each
const lines = predictionsString ? predictionsString.split('\n') : []
for (const line of lines) {
// Parse line with regex
const matches = line.match(/^(.*):\s*(\d+)%\s*$/) || ['', '', '']
const [_, question, prob] = matches
if (!question || !prob) {
console.error('Invalid prediction: ', line)
continue
}
predictions.push({
question,
description,
initialProb: parseInt(prob),
})
}
async function createContracts() {
if (!user) {
// TODO: Convey error with snackbar/toast
console.error('You need to be signed in!')
return
}
setIsSubmitting(true)
for (const prediction of predictions) {
const contract = await createContract({
question: prediction.question,
description: prediction.description,
initialProb: prediction.initialProb,
ante,
closeTime,
}).then((r) => (r.data as any).contract)
setCreatedContracts((prev) => [...prev, contract])
}
setPredictionsString('')
setIsSubmitting(false)
}
return (
{createdContracts.length > 0 && (
<>
>
)}
)
}
// Given a date string like '2022-04-02',
// return the time just before midnight on that date (in the user's local time), as millis since epoch
function dateToMillis(date: string) {
return dayjs(date)
.set('hour', 23)
.set('minute', 59)
.set('second', 59)
.valueOf()
}