Prettier everything

(Hopefully for the last time)
This commit is contained in:
Austin Chen 2021-12-13 23:30:09 -08:00
parent 6995802272
commit d4bb419478
11 changed files with 100 additions and 70 deletions

View File

@ -51,7 +51,9 @@ export const ContractOverview = (props: {
<Spacer h={12} />
<div className="text-gray-600 whitespace-pre-line">{contract.description}</div>
<div className="text-gray-600 whitespace-pre-line">
{contract.description}
</div>
</Col>
)
}

View File

@ -2,19 +2,23 @@ import dayjs from 'dayjs'
import Link from 'next/link'
import { useEffect, useState } from 'react'
import { useUser } from '../hooks/use-user'
import { Contract, deleteContract, listContracts } from '../lib/firebase/contracts'
import {
Contract,
deleteContract,
listContracts,
} from '../lib/firebase/contracts'
function ContractCard(props: { contract: Contract }) {
const { contract } = props
// only show delete button if there's not bets
const showDelete = contract.pot.YES === contract.seedAmounts.YES
&& contract.pot.NO === contract.seedAmounts.NO
const showDelete =
contract.pot.YES === contract.seedAmounts.YES &&
contract.pot.NO === contract.seedAmounts.NO
const [isDeleted, setIsDeleted] = useState(false) // temporary fix until we stream changes
if (isDeleted)
return <></>
if (isDeleted) return <></>
return (
<li>
@ -40,10 +44,10 @@ function ContractCard(props: { contract: Contract }) {
</time>
</p>
{showDelete &&
{showDelete && (
<button
className="btn btn-xs btn-error btn-outline ml-2"
onClick={async e => {
onClick={async (e) => {
e.preventDefault()
await deleteContract(contract.id)
setIsDeleted(true)
@ -51,7 +55,7 @@ function ContractCard(props: { contract: Contract }) {
>
Delete
</button>
}
)}
</div>
</div>
</div>

View File

@ -34,11 +34,15 @@ function SignInLink(props: { darkBackground?: boolean }) {
{user ? (
<>
<Link href="/contract">
<a className={clsx('text-base font-medium', themeClasses)}>Create a market</a>
<a className={clsx('text-base font-medium', themeClasses)}>
Create a market
</a>
</Link>
<Link href="/account">
<a className={clsx('text-base font-medium', themeClasses)}>{user.name}</a>
<a className={clsx('text-base font-medium', themeClasses)}>
{user.name}
</a>
</Link>
</>
) : showLogin ? (
@ -70,7 +74,10 @@ export function Header(props: { darkBackground?: boolean }) {
<Link href="/">
<a className="flex flex-row items-center align-items-center h-6 sm:h-10">
<div className="inline-block mr-3">
<img className="h-6 sm:h-10 w-6 sm:w-10" src="/logo-icon.svg" />
<img
className="h-6 sm:h-10 w-6 sm:w-10"
src="/logo-icon.svg"
/>
</div>
<span
className={clsx(

View File

@ -18,8 +18,8 @@ export const Hero = () => {
</div>
</h1>
<p className="mt-3 text-base text-gray-300 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
Better forecasting through play-money prediction
markets for you and your community
Better forecasting through play-money prediction markets for
you and your community
</p>
<div className="mt-10 sm:mt-12">
<ConvertKitEmailForm />

View File

@ -31,10 +31,10 @@ export function ResolutionPanel(props: {
outcome === 'YES'
? 'btn-primary'
: outcome === 'NO'
? 'bg-red-400 hover:bg-red-500'
: outcome === 'CANCEL'
? 'bg-yellow-400 hover:bg-yellow-500'
: 'btn-disabled'
? 'bg-red-400 hover:bg-red-500'
: outcome === 'CANCEL'
? 'bg-yellow-400 hover:bg-yellow-500'
: 'btn-disabled'
return (
<Col

View File

@ -4,49 +4,53 @@ import { randomString } from '../util/random-string'
import { slugify } from '../util/slugify'
// consider moving to cloud function for security
export async function createContract(question: string, description: string, initialProb: number, creator: User) {
const slug = slugify(question).substr(0, 35)
export async function createContract(
question: string,
description: string,
initialProb: number,
creator: User
) {
const slug = slugify(question).substr(0, 35)
const preexistingContract = await getContract(slug)
const preexistingContract = await getContract(slug)
const contractId = preexistingContract
? slug + '-' + randomString()
: slug
const contractId = preexistingContract ? slug + '-' + randomString() : slug
const { seedYes, seedNo } = calcSeedBets(initialProb)
const { seedYes, seedNo } = calcSeedBets(initialProb)
const contract: Contract = {
id: contractId,
outcomeType: 'BINARY',
const contract: Contract = {
id: contractId,
outcomeType: 'BINARY',
creatorId: creator.id,
creatorName: creator.name,
creatorId: creator.id,
creatorName: creator.name,
question: question.trim(),
description: description.trim(),
question: question.trim(),
description: description.trim(),
seedAmounts: { YES: seedYes, NO: seedNo },
pot: { YES: seedYes, NO: seedNo },
isResolved: false,
seedAmounts: { YES: seedYes, NO: seedNo },
pot: { YES: seedYes, NO: seedNo },
isResolved: false,
// TODO: Set create time to Firestore timestamp
createdTime: Date.now(),
lastUpdatedTime: Date.now(),
}
// TODO: Set create time to Firestore timestamp
createdTime: Date.now(),
lastUpdatedTime: Date.now(),
}
await setContract(contract)
await setContract(contract)
return contract
return contract
}
export function calcSeedBets(initialProb: number, initialCapital = 1000) {
const p = initialProb / 100.0
const p = initialProb / 100.0
const seedYes = p === 0.5
? p * initialCapital
: -(initialCapital * (-p + Math.sqrt((-1 + p) * -p))) / (-1 + 2 * p)
const seedYes =
p === 0.5
? p * initialCapital
: -(initialCapital * (-p + Math.sqrt((-1 + p) * -p))) / (-1 + 2 * p)
const seedNo = initialCapital - seedYes
const seedNo = initialCapital - seedYes
return { seedYes, seedNo }
return { seedYes, seedNo }
}

View File

@ -20,13 +20,17 @@ function makeWeights(bids: Bid[]) {
// First pass: calculate all the weights
for (const { yesBid, noBid } of bids) {
const yesWeight = yesBid * Math.pow(noPot, 2) / (Math.pow(yesPot, 2) + yesBid * yesPot) || 0
const noWeight = noBid * Math.pow(yesPot, 2) / (Math.pow(noPot, 2) + noBid * noPot) || 0
const yesWeight =
(yesBid * Math.pow(noPot, 2)) / (Math.pow(yesPot, 2) + yesBid * yesPot) ||
0
const noWeight =
(noBid * Math.pow(yesPot, 2)) / (Math.pow(noPot, 2) + noBid * noPot) || 0
// Note: Need to calculate weights BEFORE updating pot
yesPot += yesBid
noPot += noBid
const prob = Math.pow(yesPot, 2) / (Math.pow(yesPot, 2) + Math.pow(noPot, 2))
const prob =
Math.pow(yesPot, 2) / (Math.pow(yesPot, 2) + Math.pow(noPot, 2))
weights.push({
yesBid,

View File

@ -1,2 +1 @@
export const randomString = () => Math.random().toString(16).substr(2, 14)
export const randomString = () => Math.random().toString(16).substr(2, 14)

View File

@ -1,11 +1,10 @@
export const slugify = (text: any, separator = '-'): string => {
return text
.toString()
.normalize('NFD') // split an accented letter in the base letter and the acent
.replace(/[\u0300-\u036f]/g, '') // remove all previously split accents
.toLowerCase()
.trim()
.replace(/[^a-z0-9 ]/g, '') // remove all chars not letters, numbers and spaces (to be replaced)
.replace(/\s+/g, separator)
}
return text
.toString()
.normalize('NFD') // split an accented letter in the base letter and the acent
.replace(/[\u0300-\u036f]/g, '') // remove all previously split accents
.toLowerCase()
.trim()
.replace(/[^a-z0-9 ]/g, '') // remove all chars not letters, numbers and spaces (to be replaced)
.replace(/\s+/g, separator)
}

View File

@ -11,7 +11,12 @@ function UserCard(props: { user: User }) {
<Row className="card glass lg:card-side shadow-xl hover:shadow-xl text-neutral-content bg-green-600 hover:bg-green-600 transition-all max-w-sm mx-auto my-12">
<div className="p-4">
{user?.avatarUrl && (
<img src={user.avatarUrl} className="rounded-lg shadow-lg" width={96} height={96} />
<img
src={user.avatarUrl}
className="rounded-lg shadow-lg"
width={96}
height={96}
/>
)}
</div>
<div className="max-w-md card-body">

View File

@ -8,7 +8,6 @@ import { Title } from '../../components/title'
import { useUser } from '../../hooks/use-user'
import { createContract } from '../../lib/service/create-contract'
// Allow user to create a new contract
export default function NewContract() {
const creator = useUser()
@ -24,7 +23,12 @@ export default function NewContract() {
setIsSubmitting(true)
const contract = await createContract(question, description, initialProb, creator)
const contract = await createContract(
question,
description,
initialProb,
creator
)
await router.push(`contract/${contract.id}`)
}
@ -51,7 +55,7 @@ export default function NewContract() {
placeholder="e.g. Will the FDA approve Paxlovid before Jun 2nd, 2022?"
className="input"
value={question}
onChange={e => setQuestion(e.target.value || '')}
onChange={(e) => setQuestion(e.target.value || '')}
/>
</div>
@ -66,7 +70,7 @@ export default function NewContract() {
className="textarea h-24 textarea-bordered"
placeholder={descriptionPlaceholder}
value={description}
onChange={e => setDescription(e.target.value || '')}
onChange={(e) => setDescription(e.target.value || '')}
></textarea>
</div>
@ -74,7 +78,9 @@ export default function NewContract() {
<div className="form-control">
<label className="label">
<span className="label-text">Initial probability: {initialProb}%</span>
<span className="label-text">
Initial probability: {initialProb}%
</span>
</label>
<input
@ -82,7 +88,7 @@ export default function NewContract() {
min="1"
max={99}
value={initialProb}
onChange={e => setInitialProb(parseInt(e.target.value))}
onChange={(e) => setInitialProb(parseInt(e.target.value))}
/>
</div>