Add UI for resolution panel!

This commit is contained in:
jahooma 2021-12-13 18:00:02 -06:00
parent 7e08a68799
commit 0d56ad603e
3 changed files with 141 additions and 24 deletions

View File

@ -0,0 +1,81 @@
import clsx from 'clsx'
import React, { useState } from 'react'
import { Contract } from '../lib/firebase/contracts'
import { Col } from './layout/col'
import { Title } from './title'
import { User } from '../lib/firebase/users'
import { YesNoCancelSelector } from './yes-no-selector'
import { Spacer } from './layout/spacer'
export function ResolutionPanel(props: {
creator: User
contract: Contract
className?: string
}) {
const { creator, contract, className } = props
const [outcome, setOutcome] = useState<'YES' | 'NO' | 'CANCEL' | undefined>()
const resolveDisabled = false
function resolve() {}
return (
<Col
className={clsx(
'bg-gray-200 shadow-xl px-8 py-6 rounded-md w-full md:w-auto',
className
)}
>
<Title className="mt-0" text="Your market" />
<div className="pt-2 pb-1 text-sm text-gray-500">Resolve outcome</div>
<YesNoCancelSelector
className="p-2"
selected={outcome}
onSelect={setOutcome}
/>
<Spacer h={3} />
<div className="text-gray-500 text-sm">
{outcome === 'YES' ? (
<>
Winnings will be paid out to Yes bettors. You earn 1% of the No
bets.
</>
) : outcome === 'NO' ? (
<>
Winnings will be paid out to No bettors. You earn 1% of the Yes
bets.
</>
) : outcome === 'CANCEL' ? (
<>All bets will be returned with no fees.</>
) : (
<>Resolving this market will immediately pay out bettors.</>
)}
</div>
<Spacer h={3} />
<button
className={clsx(
'btn border-none self-start m-2',
resolveDisabled
? 'btn-disabled'
: outcome === 'YES'
? 'btn-primary'
: outcome === 'NO'
? 'bg-red-400 hover:bg-red-500'
: outcome === 'CANCEL'
? 'bg-yellow-400 hover:bg-yellow-500'
: 'btn-disabled'
)}
onClick={resolveDisabled ? undefined : resolve}
>
Resolve
</button>
</Col>
)
}

View File

@ -1,32 +1,64 @@
import clsx from 'clsx'
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
const { selected, onSelect, className } = props
return (
<Row className={className}>
<Row className={clsx('space-x-3', className)}>
<Button
color={selected === 'YES' ? 'green' : 'deemphasized'}
hideFocusRing
color={selected === 'YES' ? 'green' : 'gray'}
onClick={() => onSelect('YES')}
>
{yesLabel ?? 'Yes'}
Yes
</Button>
<Button
color={selected === 'NO' ? 'red' : 'deemphasized'}
hideFocusRing
color={selected === 'NO' ? 'red' : 'gray'}
onClick={() => onSelect('NO')}
className="ml-3"
>
{noLabel ?? 'No'}
No
</Button>
</Row>
)
}
export function YesNoCancelSelector(props: {
selected: 'YES' | 'NO' | 'CANCEL' | undefined
onSelect: (selected: 'YES' | 'NO' | 'CANCEL') => void
className?: string
}) {
const { selected, onSelect, className } = props
return (
<Row className={clsx('space-x-3', className)}>
<Button
color={selected === 'YES' ? 'green' : 'gray'}
onClick={() => onSelect('YES')}
className="px-6"
>
Yes
</Button>
<Button
color={selected === 'NO' ? 'red' : 'gray'}
onClick={() => onSelect('NO')}
className="px-6"
>
No
</Button>
<Button
color={selected === 'CANCEL' ? 'yellow' : 'gray'}
onClick={() => onSelect('CANCEL')}
className="px-6"
>
Cancel
</Button>
</Row>
)
@ -35,22 +67,20 @@ export function YesNoSelector(props: {
function Button(props: {
className?: string
onClick?: () => void
color: 'green' | 'red' | 'deemphasized'
hideFocusRing?: boolean
color: 'green' | 'red' | 'yellow' | 'gray'
children?: any
}) {
const { className, onClick, children, color, hideFocusRing } = props
const { className, onClick, children, color } = props
return (
<button
type="button"
className={classNames(
className={clsx(
'inline-flex items-center px-8 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white',
!hideFocusRing && 'focus:outline-none focus:ring-2 focus:ring-offset-2',
color === 'green' && 'btn-primary',
color === 'red' && 'bg-red-400 hover:bg-red-500 focus:ring-red-400',
color === 'deemphasized' &&
'text-gray-700 bg-gray-300 hover:bg-gray-400 focus:ring-gray-400',
color === 'red' && 'bg-red-400 hover:bg-red-500',
color === 'yellow' && 'bg-yellow-400 hover:bg-yellow-500',
color === 'gray' && 'text-gray-700 bg-gray-300 hover:bg-gray-400',
className
)}
onClick={onClick}
@ -59,7 +89,3 @@ function Button(props: {
</button>
)
}
function classNames(...classes: any[]) {
return classes.filter(Boolean).join(' ')
}

View File

@ -5,8 +5,12 @@ import { Header } from '../../components/header'
import { ContractOverview } from '../../components/contract-overview'
import { BetPanel } from '../../components/bet-panel'
import { Col } from '../../components/layout/col'
import { useUser } from '../../hooks/use-user'
import { ResolutionPanel } from '../../components/resolution-panel'
export default function ContractPage() {
const user = useUser()
const router = useRouter()
const { contractId } = router.query as { contractId: string }
@ -20,6 +24,8 @@ export default function ContractPage() {
return <div>Contract not found...</div>
}
const isCreator = user?.id === contract.creatorId
return (
<div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
<Header />
@ -29,7 +35,11 @@ export default function ContractPage() {
<div className="mt-12 md:mt-0" />
{isCreator ? (
<ResolutionPanel className="self-start" creator={user} contract={contract} />
) : (
<BetPanel className="self-start" contract={contract} />
)}
</Col>
</div>
)