List created predictions
This commit is contained in:
parent
b8ffaf0145
commit
030cf36a21
|
@ -51,11 +51,14 @@ export function compute(contract: Contract) {
|
||||||
const volume = pool.YES + pool.NO - startPool.YES - startPool.NO
|
const volume = pool.YES + pool.NO - startPool.YES - startPool.NO
|
||||||
const prob = pool.YES ** 2 / (pool.YES ** 2 + pool.NO ** 2)
|
const prob = pool.YES ** 2 / (pool.YES ** 2 + pool.NO ** 2)
|
||||||
const probPercent = Math.round(prob * 100) + '%'
|
const probPercent = Math.round(prob * 100) + '%'
|
||||||
|
const startProb =
|
||||||
|
startPool.YES ** 2 / (startPool.YES ** 2 + startPool.NO ** 2)
|
||||||
|
const startProbPercent = Math.round(startProb * 100) + '%'
|
||||||
const createdDate = dayjs(createdTime).format('MMM D')
|
const createdDate = dayjs(createdTime).format('MMM D')
|
||||||
const resolvedDate = isResolved
|
const resolvedDate = isResolved
|
||||||
? dayjs(resolutionTime).format('MMM D')
|
? dayjs(resolutionTime).format('MMM D')
|
||||||
: undefined
|
: undefined
|
||||||
return { volume, probPercent, createdDate, resolvedDate }
|
return { volume, probPercent, startProb, createdDate, resolvedDate }
|
||||||
}
|
}
|
||||||
|
|
||||||
const db = getFirestore(app)
|
const db = getFirestore(app)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import clsx from 'clsx'
|
||||||
|
import Link from 'next/link'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { Col } from '../components/layout/col'
|
import { Col } from '../components/layout/col'
|
||||||
import { Row } from '../components/layout/row'
|
import { Row } from '../components/layout/row'
|
||||||
|
@ -6,12 +8,24 @@ import { Linkify } from '../components/linkify'
|
||||||
import { Page } from '../components/page'
|
import { Page } from '../components/page'
|
||||||
import { Title } from '../components/title'
|
import { Title } from '../components/title'
|
||||||
import { useUser } from '../hooks/use-user'
|
import { useUser } from '../hooks/use-user'
|
||||||
|
import { compute, Contract, path } from '../lib/firebase/contracts'
|
||||||
import { createContract } from '../lib/service/create-contract'
|
import { createContract } from '../lib/service/create-contract'
|
||||||
|
|
||||||
type Prediction = {
|
type Prediction = {
|
||||||
question: string
|
question: string
|
||||||
description: string
|
description: string
|
||||||
initalProb: number
|
initialProb: number
|
||||||
|
createdUrl?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
function toPrediction(contract: Contract): Prediction {
|
||||||
|
const { startProb } = compute(contract)
|
||||||
|
return {
|
||||||
|
question: contract.question,
|
||||||
|
description: contract.description,
|
||||||
|
initialProb: startProb * 100,
|
||||||
|
createdUrl: path(contract),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function PredictionRow(props: { prediction: Prediction }) {
|
function PredictionRow(props: { prediction: Prediction }) {
|
||||||
|
@ -28,7 +42,8 @@ function PredictionRow(props: { prediction: Prediction }) {
|
||||||
<div className="ml-auto">
|
<div className="ml-auto">
|
||||||
<div className="text-3xl">
|
<div className="text-3xl">
|
||||||
<div className="text-primary">
|
<div className="text-primary">
|
||||||
{prediction.initalProb}%<div className="text-lg">chance</div>
|
{prediction.initialProb.toFixed(0)}%
|
||||||
|
<div className="text-lg">chance</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -36,7 +51,7 @@ function PredictionRow(props: { prediction: Prediction }) {
|
||||||
{/* <div>
|
{/* <div>
|
||||||
<div className="text-3xl">
|
<div className="text-3xl">
|
||||||
<div className="text-primary">
|
<div className="text-primary">
|
||||||
{prediction.initalProb}%<div className="text-lg">chance</div>
|
{prediction.initialProb}%<div className="text-lg">chance</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div> */}
|
</div> */}
|
||||||
|
@ -48,9 +63,20 @@ function PredictionList(props: { predictions: Prediction[] }) {
|
||||||
const { predictions } = props
|
const { predictions } = props
|
||||||
return (
|
return (
|
||||||
<Col className="divide-gray-300 divide-y border-gray-300 border rounded-md">
|
<Col className="divide-gray-300 divide-y border-gray-300 border rounded-md">
|
||||||
{predictions.map((prediction) => (
|
{predictions.map((prediction) =>
|
||||||
<PredictionRow key={prediction.question} prediction={prediction} />
|
prediction.createdUrl ? (
|
||||||
))}
|
<Link href={prediction.createdUrl}>
|
||||||
|
<a>
|
||||||
|
<PredictionRow
|
||||||
|
key={prediction.question}
|
||||||
|
prediction={prediction}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<PredictionRow key={prediction.question} prediction={prediction} />
|
||||||
|
)
|
||||||
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -64,8 +90,10 @@ const TEST_VALUE = `1. Biden approval rating (as per 538) is greater than 50%: 8
|
||||||
|
|
||||||
export default function MakePredictions() {
|
export default function MakePredictions() {
|
||||||
const user = useUser()
|
const user = useUser()
|
||||||
const [predictionsString, setBulkContracts] = useState('')
|
const [predictionsString, setPredictionsString] = useState('')
|
||||||
const [description, setDescription] = useState('')
|
const [description, setDescription] = useState('')
|
||||||
|
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||||
|
const [createdContracts, setCreatedContracts] = useState<Contract[]>([])
|
||||||
|
|
||||||
const bulkPlaceholder = `e.g.
|
const bulkPlaceholder = `e.g.
|
||||||
${TEST_VALUE}
|
${TEST_VALUE}
|
||||||
|
@ -75,13 +103,13 @@ ${TEST_VALUE}
|
||||||
const predictions: Prediction[] = []
|
const predictions: Prediction[] = []
|
||||||
|
|
||||||
// Parse bulkContracts, then run createContract for each
|
// Parse bulkContracts, then run createContract for each
|
||||||
const lines = predictionsString.split('\n')
|
const lines = predictionsString ? predictionsString.split('\n') : []
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
// Parse line with regex
|
// Parse line with regex
|
||||||
const matches = line.match(/^(.*):\s*(\d+)%\s*$/) || ['', '', '']
|
const matches = line.match(/^(.*):\s*(\d+)%\s*$/) || ['', '', '']
|
||||||
const [_, question, prob] = matches
|
const [_, question, prob] = matches
|
||||||
|
|
||||||
if (!user || !question || !prob) {
|
if (!question || !prob) {
|
||||||
console.error('Invalid prediction: ', line)
|
console.error('Invalid prediction: ', line)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -89,7 +117,7 @@ ${TEST_VALUE}
|
||||||
predictions.push({
|
predictions.push({
|
||||||
question,
|
question,
|
||||||
description,
|
description,
|
||||||
initalProb: parseInt(prob),
|
initialProb: parseInt(prob),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,16 +127,18 @@ ${TEST_VALUE}
|
||||||
console.error('You need to be signed in!')
|
console.error('You need to be signed in!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
setIsSubmitting(true)
|
||||||
for (const prediction of predictions) {
|
for (const prediction of predictions) {
|
||||||
await createContract(
|
const contract = await createContract(
|
||||||
prediction.question,
|
prediction.question,
|
||||||
prediction.description,
|
prediction.description,
|
||||||
prediction.initalProb,
|
prediction.initialProb,
|
||||||
user
|
user
|
||||||
)
|
)
|
||||||
// TODO: Convey success in the UI
|
setCreatedContracts((prev) => [...prev, contract])
|
||||||
console.log('Created contract: ', prediction.question)
|
|
||||||
}
|
}
|
||||||
|
setPredictionsString('')
|
||||||
|
setIsSubmitting(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -125,7 +155,7 @@ ${TEST_VALUE}
|
||||||
className="textarea h-60 textarea-bordered"
|
className="textarea h-60 textarea-bordered"
|
||||||
placeholder={bulkPlaceholder}
|
placeholder={bulkPlaceholder}
|
||||||
value={predictionsString}
|
value={predictionsString}
|
||||||
onChange={(e) => setBulkContracts(e.target.value || '')}
|
onChange={(e) => setPredictionsString(e.target.value || '')}
|
||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -161,8 +191,10 @@ ${TEST_VALUE}
|
||||||
<div className="flex justify-end my-4">
|
<div className="flex justify-end my-4">
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="btn btn-primary"
|
className={clsx('btn btn-primary', {
|
||||||
disabled={predictions.length === 0}
|
loading: isSubmitting,
|
||||||
|
})}
|
||||||
|
disabled={predictions.length === 0 || isSubmitting}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
createContracts()
|
createContracts()
|
||||||
|
@ -172,6 +204,16 @@ ${TEST_VALUE}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{createdContracts.length > 0 && (
|
||||||
|
<>
|
||||||
|
<Spacer h={16} />
|
||||||
|
<Title text="Created Predictions" />
|
||||||
|
<div className="w-full bg-gray-100 rounded-lg shadow-xl px-6 py-4">
|
||||||
|
<PredictionList predictions={createdContracts.map(toPrediction)} />
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Page>
|
</Page>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user