From f8601af45c06a4628d5d5e42c84e3f09971d4942 Mon Sep 17 00:00:00 2001 From: Sinclair Chen Date: Tue, 17 May 2022 10:31:19 -0700 Subject: [PATCH] Bet embed (#204) * Add bet buttons to embed - Make only title link to market - Prevent avatar / username from being clicked on * refactor: remove extra elem, de-indent * adjust embed info row styles * make bet panel smaller * make sell panel smaller --- web/components/bet-panel.tsx | 3 +- web/components/bet-row.tsx | 8 +- web/components/contract/contract-details.tsx | 95 ++++++++++--------- web/components/sell-button.tsx | 6 +- web/components/sell-modal.tsx | 14 ++- web/pages/embed/[username]/[contractSlug].tsx | 28 ++++-- 6 files changed, 90 insertions(+), 64 deletions(-) diff --git a/web/components/bet-panel.tsx b/web/components/bet-panel.tsx index 06e09e73..8796f842 100644 --- a/web/components/bet-panel.tsx +++ b/web/components/bet-panel.tsx @@ -151,8 +151,7 @@ export function BetPanelSwitcher(props: { className?: string btnClassName?: string + betPanelClassName?: string }) { - const { className, btnClassName, contract } = props + const { className, btnClassName, betPanelClassName, contract } = props const [open, setOpen] = useState(false) const [betChoice, setBetChoice] = useState<'YES' | 'NO' | undefined>( undefined @@ -31,7 +32,7 @@ export default function BetRow(props: { return ( <> <YesNoSelector - className={clsx('mt-2 justify-end', className)} + className={clsx('justify-end', className)} btnClassName={clsx('btn-sm w-24', btnClassName)} onSelect={(choice) => { setOpen(true) @@ -40,6 +41,7 @@ export default function BetRow(props: { replaceNoButton={ yesFloorShares > 0 ? ( <SellButton + panelClassName={betPanelClassName} contract={contract} user={user} sharesOutcome={'YES'} @@ -50,6 +52,7 @@ export default function BetRow(props: { replaceYesButton={ noFloorShares > 0 ? ( <SellButton + panelClassName={betPanelClassName} contract={contract} user={user} sharesOutcome={'NO'} @@ -60,6 +63,7 @@ export default function BetRow(props: { /> <Modal open={open} setOpen={setOpen}> <BetPanelSwitcher + className={betPanelClassName} contract={contract} title={contract.question} selected={betChoice} diff --git a/web/components/contract/contract-details.tsx b/web/components/contract/contract-details.tsx index 17b44795..bd37e5e3 100644 --- a/web/components/contract/contract-details.tsx +++ b/web/components/contract/contract-details.tsx @@ -93,72 +93,73 @@ export function ContractDetails(props: { contract: Contract bets: Bet[] isCreator?: boolean - hideShareButtons?: boolean + disabled?: boolean }) { - const { contract, bets, isCreator, hideShareButtons } = props + const { contract, bets, isCreator, disabled } = props const { closeTime, creatorName, creatorUsername } = contract const { volumeLabel, createdDate, resolvedDate } = contractMetrics(contract) return ( - <Col className="gap-2 text-sm text-gray-500 sm:flex-row sm:flex-wrap"> - <Row className="flex-1 flex-wrap items-center gap-x-4 gap-y-3"> - <Row className="items-center gap-2"> - <Avatar - username={creatorUsername} - avatarUrl={contract.creatorAvatarUrl} - size={6} - /> + <Row className="flex-1 flex-wrap items-center gap-x-4 gap-y-2 text-sm text-gray-500"> + <Row className="items-center gap-2"> + <Avatar + username={creatorUsername} + avatarUrl={contract.creatorAvatarUrl} + noLink={disabled} + size={6} + /> + {disabled ? ( + creatorName + ) : ( <UserLink className="whitespace-nowrap" name={creatorName} username={creatorUsername} /> - </Row> + )} + </Row> - {(!!closeTime || !!resolvedDate) && ( - <Row className="items-center gap-1"> - <ClockIcon className="h-5 w-5" /> + {(!!closeTime || !!resolvedDate) && ( + <Row className="items-center gap-1"> + <ClockIcon className="h-5 w-5" /> - {/* <DateTimeTooltip text="Market created:" time={contract.createdTime}> + {/* <DateTimeTooltip text="Market created:" time={contract.createdTime}> {createdDate} </DateTimeTooltip> */} - {resolvedDate && contract.resolutionTime ? ( - <> - {/* {' - '} */} - <DateTimeTooltip - text="Market resolved:" - time={contract.resolutionTime} - > - {resolvedDate} - </DateTimeTooltip> - </> - ) : null} + {resolvedDate && contract.resolutionTime ? ( + <> + {/* {' - '} */} + <DateTimeTooltip + text="Market resolved:" + time={contract.resolutionTime} + > + {resolvedDate} + </DateTimeTooltip> + </> + ) : null} - {!resolvedDate && closeTime && ( - <> - {/* {' - '}{' '} */} - <EditableCloseDate - closeTime={closeTime} - contract={contract} - isCreator={isCreator ?? false} - /> - </> - )} - </Row> - )} - - <Row className="items-center gap-1"> - <DatabaseIcon className="h-5 w-5" /> - - <div className="whitespace-nowrap">{volumeLabel}</div> + {!resolvedDate && closeTime && ( + <> + {/* {' - '}{' '} */} + <EditableCloseDate + closeTime={closeTime} + contract={contract} + isCreator={isCreator ?? false} + /> + </> + )} </Row> + )} - {!hideShareButtons && ( - <ContractInfoDialog contract={contract} bets={bets} /> - )} + <Row className="items-center gap-1"> + <DatabaseIcon className="h-5 w-5" /> + + <div className="whitespace-nowrap">{volumeLabel}</div> </Row> - </Col> + + {!disabled && <ContractInfoDialog contract={contract} bets={bets} />} + </Row> ) } diff --git a/web/components/sell-button.tsx b/web/components/sell-button.tsx index 5e71bd77..17c8db3e 100644 --- a/web/components/sell-button.tsx +++ b/web/components/sell-button.tsx @@ -11,8 +11,9 @@ export function SellButton(props: { user: User | null | undefined sharesOutcome: 'YES' | 'NO' | undefined shares: number + panelClassName?: string }) { - const { contract, user, sharesOutcome, shares } = props + const { contract, user, sharesOutcome, shares, panelClassName } = props const userBets = useUserContractBets(user?.id, contract.id) const [showSellModal, setShowSellModal] = useState(false) const { mechanism } = contract @@ -24,7 +25,7 @@ export function SellButton(props: { className={clsx( 'btn-sm w-24 gap-1', // from the yes-no-selector: - 'flex inline-flex flex-row items-center justify-center rounded-3xl border-2 p-2', + 'inline-flex items-center justify-center rounded-3xl border-2 p-2', sharesOutcome === 'NO' ? 'hover:bg-primary-focus border-primary hover:border-primary-focus text-primary hover:text-white' : 'border-red-400 text-red-500 hover:border-red-500 hover:bg-red-500 hover:text-white' @@ -38,6 +39,7 @@ export function SellButton(props: { </div> {showSellModal && ( <SellSharesModal + className={panelClassName} contract={contract as FullContract<CPMM, Binary>} user={user} userBets={userBets ?? []} diff --git a/web/components/sell-modal.tsx b/web/components/sell-modal.tsx index 28282766..3e620e24 100644 --- a/web/components/sell-modal.tsx +++ b/web/components/sell-modal.tsx @@ -7,8 +7,10 @@ import { Title } from './title' import { formatWithCommas } from 'common/util/format' import { OutcomeLabel } from './outcome-label' import { SellPanel } from './bet-panel' +import clsx from 'clsx' export function SellSharesModal(props: { + className?: string contract: FullContract<CPMM, Binary> userBets: Bet[] shares: number @@ -16,11 +18,19 @@ export function SellSharesModal(props: { user: User setOpen: (open: boolean) => void }) { - const { contract, shares, sharesOutcome, userBets, user, setOpen } = props + const { + className, + contract, + shares, + sharesOutcome, + userBets, + user, + setOpen, + } = props return ( <Modal open={true} setOpen={setOpen}> - <Col className="rounded-md bg-white px-8 py-6"> + <Col className={clsx('rounded-md bg-white px-8 py-6', className)}> <Title className="!mt-0" text={'Sell shares'} /> <div className="mb-6"> diff --git a/web/pages/embed/[username]/[contractSlug].tsx b/web/pages/embed/[username]/[contractSlug].tsx index 7792a633..a1d64c36 100644 --- a/web/pages/embed/[username]/[contractSlug].tsx +++ b/web/pages/embed/[username]/[contractSlug].tsx @@ -1,7 +1,14 @@ import { Bet } from 'common/bet' -import { Contract, DPM, FreeResponse, FullContract } from 'common/contract' +import { + BinaryContract, + Contract, + DPM, + FreeResponse, + FullContract, +} from 'common/contract' import { DOMAIN } from 'common/envs/constants' import { AnswersGraph } from 'web/components/answers/answers-graph' +import BetRow from 'web/components/bet-row' import { BinaryResolutionOrChance, FreeResponseResolutionOrChance, @@ -92,13 +99,8 @@ function ContractEmbed(props: { contract: Contract; bets: Bet[] }) { return ( <Col className="w-full flex-1 bg-white"> <div className="relative flex flex-col pt-2" ref={setElem}> - <SiteLink - className="absolute top-0 left-0 z-20 h-full w-full" - href={href} - /> - <div className="px-3 text-xl text-indigo-700 md:text-2xl"> - <Linkify text={question} /> + <SiteLink href={href}>{question}</SiteLink> </div> <Spacer h={3} /> @@ -108,10 +110,18 @@ function ContractEmbed(props: { contract: Contract; bets: Bet[] }) { contract={contract} bets={bets} isCreator={false} - hideShareButtons + disabled /> - {isBinary && <BinaryResolutionOrChance contract={contract} />} + {isBinary && ( + <Row className="items-center gap-4"> + <BetRow + contract={contract as BinaryContract} + betPanelClassName="scale-75" + /> + <BinaryResolutionOrChance contract={contract} /> + </Row> + )} {outcomeType === 'FREE_RESPONSE' && resolution && ( <FreeResponseResolutionOrChance