Some UI for showing answers

This commit is contained in:
James Grugett 2022-02-13 22:38:37 -06:00
parent 893016a7c3
commit 467effa5ca
4 changed files with 102 additions and 43 deletions

View File

@ -7,6 +7,12 @@ import { Contract } from '../../common/contract'
import { AmountInput } from './amount-input' import { AmountInput } from './amount-input'
import { Col } from './layout/col' import { Col } from './layout/col'
import { createAnswer } from '../lib/firebase/api-call' import { createAnswer } from '../lib/firebase/api-call'
import { Row } from './layout/row'
import { Avatar } from './avatar'
import { SiteLink } from './site-link'
import { DateTimeTooltip } from './datetime-tooltip'
import dayjs from 'dayjs'
import { BuyButton } from './yes-no-selector'
export function AnswersPanel(props: { export function AnswersPanel(props: {
contract: Contract<'MULTI'> contract: Contract<'MULTI'>
@ -15,11 +21,48 @@ export function AnswersPanel(props: {
const { contract, answers } = props const { contract, answers } = props
return ( return (
<Col> <Col className="gap-4">
<CreateAnswerInput contract={contract} />
{answers.map((answer) => ( {answers.map((answer) => (
<div>{answer.text}</div> <AnswerItem key={answer.id} answer={answer} contract={contract} />
))} ))}
<CreateAnswerInput contract={contract} />
</Col>
)
}
function AnswerItem(props: { answer: Answer; contract: Contract<'MULTI'> }) {
const { answer, contract } = props
const { username, avatarUrl, name, createdTime } = answer
const createdDate = dayjs(createdTime).format('MMM D')
return (
<Col className="p-2 sm:flex-row">
<Col className="gap-2 flex-1">
<div>{answer.text}</div>
<Row className="text-gray-500 text-sm gap-2 items-center">
<SiteLink className="relative" href={`/${username}`}>
<Row className="items-center gap-2">
<Avatar avatarUrl={avatarUrl} size={6} />
<div className="truncate">{name}</div>
</Row>
</SiteLink>
<div className=""></div>
<div className="whitespace-nowrap">
<DateTimeTooltip text="" time={contract.createdTime}>
{createdDate}
</DateTimeTooltip>
</div>
</Row>
</Col>
<BuyButton
className="justify-end self-end flex-initial"
onClick={() => {}}
/>
</Col> </Col>
) )
} }
@ -55,40 +98,40 @@ function CreateAnswerInput(props: { contract: Contract<'MULTI'> }) {
} }
return ( return (
<Col className="gap-4"> <Col className="gap-4 mt-2">
<div className="text-xl text-indigo-700">Add your answer</div> <Col className="sm:flex-row gap-8">
<Textarea <Col className="flex-1 gap-2">
value={text} <div className="text-gray-500 text-sm mb-1">Add your answer</div>
onChange={(e) => setText(e.target.value)} <Textarea
className="textarea textarea-bordered w-full" value={text}
placeholder="Type your answer..." onChange={(e) => setText(e.target.value)}
rows={1} className="textarea textarea-bordered w-full"
maxLength={10000} placeholder="Type your answer..."
/> rows={1}
<Col className="gap-2 justify-between self-end sm:flex-row"> maxLength={10000}
{text && ( />
<Col className="gap-2"> <button
<div className="text-gray-500 text-sm">Bet amount</div> className={clsx(
<AmountInput 'btn btn-sm self-end mt-2',
amount={betAmount} canSubmit ? 'btn-outline' : 'btn-disabled'
onChange={setBetAmount} )}
error={amountError} disabled={!canSubmit}
setError={setAmountError} onClick={submitAnswer}
minimumAmount={10} >
disabled={isSubmitting} Submit answer & bet
/> </button>
</Col> </Col>
)} <Col className={clsx('gap-2', text ? 'visible' : 'invisible')}>
<button <div className="text-gray-500 text-sm">Bet amount</div>
className={clsx( <AmountInput
'btn btn-sm self-start', amount={betAmount}
canSubmit ? 'btn-outline' : 'btn-disabled' onChange={setBetAmount}
)} error={amountError}
disabled={!canSubmit} setError={setAmountError}
onClick={submitAnswer} minimumAmount={10}
> disabled={isSubmitting}
Submit answer />
</button> </Col>
</Col> </Col>
</Col> </Col>
) )

View File

@ -28,9 +28,10 @@ export const ContractOverview = (props: {
bets: Bet[] bets: Bet[]
comments: Comment[] comments: Comment[]
folds: Fold[] folds: Fold[]
children?: any
className?: string className?: string
}) => { }) => {
const { contract, bets, comments, folds, className } = props const { contract, bets, comments, folds, children, className } = props
const { question, resolution, creatorId, outcomeType } = contract const { question, resolution, creatorId, outcomeType } = contract
const user = useUser() const user = useUser()
@ -85,6 +86,8 @@ export const ContractOverview = (props: {
{isBinary && <ContractProbGraph contract={contract} bets={bets} />} {isBinary && <ContractProbGraph contract={contract} bets={bets} />}
{children}
<Row className="mt-6 ml-4 hidden items-center justify-between gap-4 sm:flex"> <Row className="mt-6 ml-4 hidden items-center justify-between gap-4 sm:flex">
{folds.length === 0 ? ( {folds.length === 0 ? (
<TagsInput className={clsx('mx-4')} contract={contract} /> <TagsInput className={clsx('mx-4')} contract={contract} />

View File

@ -120,6 +120,15 @@ export function FundsSelector(props: {
) )
} }
export function BuyButton(props: { className?: string; onClick?: () => void }) {
const { className, onClick } = props
return (
<Button className={className} onClick={onClick} color="green">
Buy
</Button>
)
}
function Button(props: { function Button(props: {
className?: string className?: string
onClick?: () => void onClick?: () => void
@ -132,7 +141,7 @@ function Button(props: {
<button <button
type="button" type="button"
className={clsx( className={clsx(
'inline-flex flex-1 items-center justify-center rounded-md border border-transparent px-8 py-3 text-sm font-medium shadow-sm', 'inline-flex flex-1 items-center justify-center rounded-md border border-transparent px-8 py-3 font-medium shadow-sm',
color === 'green' && 'btn-primary text-white', color === 'green' && 'btn-primary text-white',
color === 'red' && 'bg-red-400 text-white hover:bg-red-500', color === 'red' && 'bg-red-400 text-white hover:bg-red-500',
color === 'yellow' && 'bg-yellow-400 text-white hover:bg-yellow-500', color === 'yellow' && 'bg-yellow-400 text-white hover:bg-yellow-500',

View File

@ -119,11 +119,15 @@ export default function ContractPage(props: {
bets={bets ?? []} bets={bets ?? []}
comments={comments ?? []} comments={comments ?? []}
folds={folds} folds={folds}
/> >
{contract.outcomes === 'FREE_ANSWER' && (
<AnswersPanel
contract={contract as any}
answers={props.answers}
/>
)}
</ContractOverview>
{contract.outcomes === 'FREE_ANSWER' && (
<AnswersPanel contract={contract as any} answers={props.answers} />
)}
<BetsSection contract={contract} user={user ?? null} bets={bets} /> <BetsSection contract={contract} user={user ?? null} bets={bets} />
</div> </div>