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) => {