diff --git a/web/components/contract/contract-card.tsx b/web/components/contract/contract-card.tsx
index 3aa0869c..7578e9c5 100644
--- a/web/components/contract/contract-card.tsx
+++ b/web/components/contract/contract-card.tsx
@@ -33,6 +33,10 @@ import { AvatarDetails, MiscDetails } from './contract-details'
import { getExpectedValue, getValueFromBucket } from 'common/calculate-dpm'
import TriangleFillIcon from 'web/lib/icons/triangle-fill-icon'
import TriangleDownFillIcon from 'web/lib/icons/triangle-down-fill-icon'
+import toast from 'react-hot-toast'
+import { CheckIcon, XIcon } from '@heroicons/react/solid'
+import { useEffect, useState } from 'react'
+import { APIError, placeBet } from 'web/lib/firebase/api-call'
// Return a number from 0 to 1 for this contract
// Resolved contracts are set to 1, for coloring purposes (even if NO)
@@ -93,6 +97,53 @@ export function ContractCard(props: {
const color = getColor(contract)
const marketClosed = (contract.closeTime || Infinity) < Date.now()
+ // TODO: switch to useContract after you place a bet on it
+
+ function betToast(outcome: string) {
+ let canceled = false
+ const toastId = toast.custom(
+ ,
+ {
+ duration: 3000,
+ }
+ )
+
+ function onToastCancel() {
+ toast.remove(toastId)
+ canceled = true
+ }
+
+ function onToastFinish() {
+ if (canceled) return
+ console.log('Finishing toast')
+ toast.remove(toastId)
+ placeBet({
+ amount: 10,
+ outcome,
+ contractId: contract.id,
+ })
+ .then((r) => {
+ // Success
+ console.log('placed bet. Result:', r)
+ toast.success('Bet placed!', { duration: 1000 })
+ })
+ .catch((e) => {
+ // Failure
+ if (e instanceof APIError) {
+ toast.error(e.toString(), { duration: 1000 })
+ } else {
+ console.error(e)
+ toast.error('Could not place bet')
+ }
+ })
+ }
+ }
+
return (
{
- console.log('success')
- }}
+ onClick={() => betToast('YES')}
>
{formatMoney(20)}
@@ -188,7 +237,7 @@ export function ContractCard(props: {
{}}
+ onClick={() => betToast('NO')}
>
{contract.createdTime % 3 == 2 ? (
)
}
+
+function BetToast(props: {
+ outcome: string
+ seconds: number
+ onToastFinish: () => void
+ onToastCancel: () => void
+}) {
+ const { outcome, seconds, onToastFinish, onToastCancel } = props
+
+ // Track the number of seconds left, starting with durationMs
+ const [secondsLeft, setSecondsLeft] = useState(seconds)
+ console.log('renderings using', secondsLeft)
+
+ // Update the secondsLeft state every second
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setSecondsLeft((seconds) => seconds - 1)
+ }, 1000)
+ return () => clearInterval(interval)
+ }, [])
+
+ if (secondsLeft <= 0) {
+ console.log('finishing')
+ onToastFinish()
+ // return null
+ }
+
+ return (
+
+
+
+
+
+ Betting M$10 on {outcome} in {secondsLeft}s
+
+
+
+ {/*
+
+
*/}
+
+
+
+ )
+}