diff --git a/web/components/bet-panel.tsx b/web/components/bet-panel.tsx
new file mode 100644
index 00000000..565a5219
--- /dev/null
+++ b/web/components/bet-panel.tsx
@@ -0,0 +1,52 @@
+import React, { useState } from 'react'
+import { Contract } from '../lib/firebase/contracts'
+import { Col } from './layout/col'
+import { Spacer } from './layout/spacer'
+import { YesNoSelector } from './yes-no-selector'
+
+export function BetPanel(props: { contract: Contract; className?: string }) {
+ const { contract, className } = props
+
+ const [betChoice, setBetChoice] = useState<'YES' | 'NO'>('YES')
+ const [shares, setShares] = useState(0)
+
+ return (
+
+ Pick outcome
+
+
+
+
+ Shares
+
+ setShares(parseInt(e.target.value) || 0)}
+ onFocus={(e) => e.target.select()}
+ />
+
+
+
+
+ Price
+
+ {shares * (betChoice === 'YES' ? 57 : 43)} points
+
+
+
+
+ {shares !== 0 && (
+
+ )}
+
+ )
+}
diff --git a/web/components/contract-overview.tsx b/web/components/contract-overview.tsx
new file mode 100644
index 00000000..543aa98a
--- /dev/null
+++ b/web/components/contract-overview.tsx
@@ -0,0 +1,64 @@
+import React from 'react'
+import { Line } from 'react-chartjs-2'
+import {
+ CategoryScale,
+ Chart,
+ LinearScale,
+ PointElement,
+ LineElement,
+ Title,
+ Tooltip,
+ Legend,
+} from 'chart.js'
+import { Contract } from '../lib/firebase/contracts'
+import { Col } from './layout/col'
+import { Row } from './layout/row'
+import { Spacer } from './layout/spacer'
+
+// Auto import doesn't work for some reason...
+// So we manually register ChartJS components instead:
+Chart.register(
+ CategoryScale,
+ LinearScale,
+ PointElement,
+ LineElement,
+ Title,
+ Tooltip,
+ Legend
+)
+const chartData = {
+ labels: Array.from({ length: 0 }, (_, i) => i + 1),
+ datasets: [
+ {
+ label: 'Implied probability',
+ data: [],
+ borderColor: 'rgb(75, 192, 192)',
+ },
+ ],
+}
+
+export const ContractOverview = (props: { contract: Contract }) => {
+ const { contract } = props
+
+ return (
+
+ {contract.question}
+
+
+ By {contract.creatorName}
+ •
+ Dec 9
+ •
+ 200,000 volume
+
+
+
+
+
+
+
+
+ {contract.description}
+
+ )
+}
diff --git a/web/components/layout/col.tsx b/web/components/layout/col.tsx
new file mode 100644
index 00000000..da71f130
--- /dev/null
+++ b/web/components/layout/col.tsx
@@ -0,0 +1,5 @@
+export function Col(props: { children?: any; className?: string }) {
+ const { children, className } = props
+
+ return {children}
+}
diff --git a/web/components/layout/row.tsx b/web/components/layout/row.tsx
new file mode 100644
index 00000000..4faaeb6c
--- /dev/null
+++ b/web/components/layout/row.tsx
@@ -0,0 +1,5 @@
+export function Row(props: { children?: any; className?: string }) {
+ const { children, className } = props
+
+ return {children}
+}
diff --git a/web/components/layout/spacer.tsx b/web/components/layout/spacer.tsx
new file mode 100644
index 00000000..04a9b0d7
--- /dev/null
+++ b/web/components/layout/spacer.tsx
@@ -0,0 +1,8 @@
+export function Spacer(props: { w?: number; h?: number }) {
+ const { w, h } = props
+
+ const width = w === undefined ? undefined : w * 0.25 + 'rem'
+ const height = h === undefined ? undefined : h * 0.25 + 'rem'
+
+ return
+}
diff --git a/web/components/yes-no-selector.tsx b/web/components/yes-no-selector.tsx
new file mode 100644
index 00000000..632e5b54
--- /dev/null
+++ b/web/components/yes-no-selector.tsx
@@ -0,0 +1,66 @@
+import React from 'react'
+import { Row } from './layout/row'
+
+export function YesNoSelector(props: {
+ selected: 'YES' | 'NO'
+ onSelect: (selected: 'YES' | 'NO') => void
+ yesLabel?: string
+ noLabel?: string
+ className?: string
+}) {
+ const { selected, onSelect, yesLabel, noLabel, className } = props
+
+ return (
+
+
+
+
+
+ )
+}
+
+function Button(props: {
+ className?: string
+ onClick?: () => void
+ color: 'green' | 'red' | 'deemphasized'
+ hideFocusRing?: boolean
+ children?: any
+}) {
+ const { className, onClick, children, color, hideFocusRing } = props
+
+ return (
+
+ )
+}
+
+function classNames(...classes: any[]) {
+ return classes.filter(Boolean).join(' ')
+}
diff --git a/web/lib/firebase/contracts.ts b/web/lib/firebase/contracts.ts
index 42166817..87d49c04 100644
--- a/web/lib/firebase/contracts.ts
+++ b/web/lib/firebase/contracts.ts
@@ -3,7 +3,10 @@ import { db } from './init'
export type Contract = {
id: string
+ creatorId: string
+ creatorName: string
question: string
+ description: string
}
const contractCollection = collection(db, 'contracts')
diff --git a/web/pages/contract/[contractId].tsx b/web/pages/contract/[contractId].tsx
index 4b34715a..610b9959 100644
--- a/web/pages/contract/[contractId].tsx
+++ b/web/pages/contract/[contractId].tsx
@@ -1,27 +1,36 @@
+import React from 'react'
import { useRouter } from 'next/router'
import { useContract } from '../../hooks/use-contract'
-import { useUser } from '../../hooks/use-user'
+import { Header } from '../../components/header'
+import { Row } from '../../components/layout/row'
+import { ContractOverview } from '../../components/contract-overview'
+import { BetPanel } from '../../components/bet-panel'
export default function ContractPage() {
- const user = useUser()
-
const router = useRouter()
const { contractId } = router.query as { contractId: string }
const contract = useContract(contractId)
if (contract === 'loading') {
- return Loading...
+ return
}
- if (contract === null) {
+ if (!contract) {
return Contract not found...
}
return (
-
-
{contract.id}
-
{contract.question}
+
)
}
diff --git a/web/pages/simulator/index.tsx b/web/pages/simulator/index.tsx
index 6e562bbc..5f57f49d 100644
--- a/web/pages/simulator/index.tsx
+++ b/web/pages/simulator/index.tsx
@@ -199,6 +199,7 @@ function NewBidTable(props: {
type="number"
placeholder="0"
className="input input-bordered"
+ style={{ maxWidth: 100 }}
value={newBid}
onChange={(e) => setNewBid(parseInt(e.target.value) || 0)}
onKeyUp={(e) => {