Add UI for resolution panel!
This commit is contained in:
parent
7e08a68799
commit
0d56ad603e
81
web/components/resolution-panel.tsx
Normal file
81
web/components/resolution-panel.tsx
Normal 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>
|
||||
)
|
||||
}
|
|
@ -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(' ')
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user