Small ux tweaks for signed out market page

This commit is contained in:
Ian Philips 2022-08-24 16:41:46 -06:00
parent 5bf135760e
commit b6e636cbc0
5 changed files with 105 additions and 49 deletions

View File

@ -5,6 +5,7 @@ import { formatMoney } from 'common/util/format'
import { Col } from './layout/col' import { Col } from './layout/col'
import { SiteLink } from './site-link' import { SiteLink } from './site-link'
import { ENV_CONFIG } from 'common/envs/constants' import { ENV_CONFIG } from 'common/envs/constants'
import { useWindowSize } from 'web/hooks/use-window-size'
export function AmountInput(props: { export function AmountInput(props: {
amount: number | undefined amount: number | undefined
@ -33,7 +34,8 @@ export function AmountInput(props: {
const isInvalid = !str || isNaN(amount) const isInvalid = !str || isNaN(amount)
onChange(isInvalid ? undefined : amount) onChange(isInvalid ? undefined : amount)
} }
const { width } = useWindowSize()
const isMobile = (width ?? 0) < 768
return ( return (
<Col className={className}> <Col className={className}>
<label className="input-group mb-4"> <label className="input-group mb-4">
@ -50,6 +52,7 @@ export function AmountInput(props: {
inputMode="numeric" inputMode="numeric"
placeholder="0" placeholder="0"
maxLength={6} maxLength={6}
autoFocus={!isMobile}
value={amount ?? ''} value={amount ?? ''}
disabled={disabled} disabled={disabled}
onChange={(e) => onAmountChange(e.target.value)} onChange={(e) => onAmountChange(e.target.value)}

View File

@ -8,6 +8,8 @@ import { useUser } from 'web/hooks/use-user'
import { useUserContractBets } from 'web/hooks/use-user-bets' import { useUserContractBets } from 'web/hooks/use-user-bets'
import { useSaveBinaryShares } from './use-save-binary-shares' import { useSaveBinaryShares } from './use-save-binary-shares'
import { Col } from './layout/col' import { Col } from './layout/col'
import { Button } from 'web/components/button'
import { firebaseLogin } from 'web/lib/firebase/users'
/** Button that opens BetPanel in a new modal */ /** Button that opens BetPanel in a new modal */
export default function BetButton(props: { export default function BetButton(props: {
@ -30,23 +32,27 @@ export default function BetButton(props: {
return ( return (
<> <>
<Col className={clsx('items-center', className)}> <Col className={clsx('items-center', className)}>
<button <Button
className={clsx( size={'lg'}
'btn btn-lg btn-outline my-auto inline-flex h-10 min-h-0 w-24', className={clsx('my-auto inline-flex min-w-[75px] ', btnClassName)}
btnClassName onClick={() => {
)} !user ? firebaseLogin() : setOpen(true)
onClick={() => setOpen(true)} }}
> >
Bet {user ? 'Bet' : 'Sign up to Bet'}
</button> </Button>
{user && (
<div className={'mt-1 w-24 text-center text-sm text-gray-500'}> <div className={'mt-1 w-24 text-center text-sm text-gray-500'}>
{hasYesShares {hasYesShares
? `(${Math.floor(yesShares)} ${isPseudoNumeric ? 'HIGHER' : 'YES'})` ? `(${Math.floor(yesShares)} ${
isPseudoNumeric ? 'HIGHER' : 'YES'
})`
: hasNoShares : hasNoShares
? `(${Math.floor(noShares)} ${isPseudoNumeric ? 'LOWER' : 'NO'})` ? `(${Math.floor(noShares)} ${isPseudoNumeric ? 'LOWER' : 'NO'})`
: ''} : ''}
</div> </div>
)}
</Col> </Col>
<Modal open={open} setOpen={setOpen}> <Modal open={open} setOpen={setOpen}>

View File

@ -1,7 +1,9 @@
import { import {
ClockIcon, ClockIcon,
DatabaseIcon, DatabaseIcon,
LinkIcon,
PencilIcon, PencilIcon,
ShareIcon,
TrendingUpIcon, TrendingUpIcon,
UserGroupIcon, UserGroupIcon,
} from '@heroicons/react/outline' } from '@heroicons/react/outline'
@ -9,7 +11,11 @@ import {
import { Row } from '../layout/row' import { Row } from '../layout/row'
import { formatMoney } from 'common/util/format' import { formatMoney } from 'common/util/format'
import { UserLink } from '../user-page' import { UserLink } from '../user-page'
import { Contract, updateContract } from 'web/lib/firebase/contracts' import {
Contract,
contractPath,
updateContract,
} from 'web/lib/firebase/contracts'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { DateTimeTooltip } from '../datetime-tooltip' import { DateTimeTooltip } from '../datetime-tooltip'
import { fromNow } from 'web/lib/util/time' import { fromNow } from 'web/lib/util/time'
@ -32,6 +38,11 @@ import { groupPath } from 'web/lib/firebase/groups'
import { insertContent } from '../editor/utils' import { insertContent } from '../editor/utils'
import clsx from 'clsx' import clsx from 'clsx'
import { contractMetrics } from 'common/contract-details' import { contractMetrics } from 'common/contract-details'
import { User } from 'common/user'
import { copyToClipboard } from 'web/lib/util/copy'
import toast from 'react-hot-toast'
import { track } from 'web/lib/service/analytics'
import { ENV_CONFIG } from 'common/envs/constants'
export type ShowTime = 'resolve-date' | 'close-date' export type ShowTime = 'resolve-date' | 'close-date'
@ -134,6 +145,7 @@ export function AbbrContractDetails(props: {
export function ContractDetails(props: { export function ContractDetails(props: {
contract: Contract contract: Contract
bets: Bet[] bets: Bet[]
user: User | null | undefined
isCreator?: boolean isCreator?: boolean
disabled?: boolean disabled?: boolean
}) { }) {
@ -146,7 +158,11 @@ export function ContractDetails(props: {
groupLinks?.sort((a, b) => a.createdTime - b.createdTime)[0] ?? null groupLinks?.sort((a, b) => a.createdTime - b.createdTime)[0] ?? null
const user = useUser() const user = useUser()
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const shareUrl = `https://${ENV_CONFIG.domain}${contractPath(contract)}${
user?.username && contract.creatorUsername !== user?.username
? '?referrer=' + user?.username
: ''
}`
const groupInfo = ( const groupInfo = (
<Row> <Row>
<UserGroupIcon className="mx-1 inline h-5 w-5 shrink-0" /> <UserGroupIcon className="mx-1 inline h-5 w-5 shrink-0" />
@ -157,7 +173,7 @@ export function ContractDetails(props: {
) )
return ( return (
<Row className="flex-1 flex-wrap items-center gap-x-4 gap-y-2 text-sm text-gray-500"> <Row className="flex-1 flex-wrap items-center gap-2 text-sm text-gray-500 md:gap-x-4 md:gap-y-2">
<Row className="items-center gap-2"> <Row className="items-center gap-2">
<Avatar <Avatar
username={creatorUsername} username={creatorUsername}
@ -179,6 +195,8 @@ export function ContractDetails(props: {
<Row> <Row>
{disabled ? ( {disabled ? (
groupInfo groupInfo
) : !groupToDisplay && !user ? (
<div />
) : ( ) : (
<Button <Button
size={'xs'} size={'xs'}
@ -203,13 +221,30 @@ export function ContractDetails(props: {
/> />
</Col> </Col>
</Modal> </Modal>
{!user && (
<Row className={'items-center justify-end'}>
<Button
size="xs"
color="gray-white"
className={'flex'}
onClick={() => {
copyToClipboard(shareUrl)
toast('Link copied!', {
icon: <LinkIcon className="mr-2 h-6 w-6" aria-hidden="true" />,
})
track('copy share link')
}}
>
<ShareIcon className={clsx('mr-2 h-5 w-5')} aria-hidden="true" />
Share
</Button>
</Row>
)}
{(!!closeTime || !!resolvedDate) && ( {(!!closeTime || !!resolvedDate) && (
<Row className="items-center gap-1"> <Row className="items-center gap-1">
<ClockIcon className="h-5 w-5" />
{resolvedDate && contract.resolutionTime ? ( {resolvedDate && contract.resolutionTime ? (
<> <>
<ClockIcon className="h-5 w-5" />
<DateTimeTooltip <DateTimeTooltip
text="Market resolved:" text="Market resolved:"
time={dayjs(contract.resolutionTime)} time={dayjs(contract.resolutionTime)}
@ -219,8 +254,9 @@ export function ContractDetails(props: {
</> </>
) : null} ) : null}
{!resolvedDate && closeTime && ( {!resolvedDate && closeTime && user && (
<> <>
<ClockIcon className="h-5 w-5" />
<EditableCloseDate <EditableCloseDate
closeTime={closeTime} closeTime={closeTime}
contract={contract} contract={contract}
@ -230,14 +266,15 @@ export function ContractDetails(props: {
)} )}
</Row> </Row>
)} )}
{user && (
<>
<Row className="items-center gap-1"> <Row className="items-center gap-1">
<DatabaseIcon className="h-5 w-5" /> <DatabaseIcon className="h-5 w-5" />
<div className="whitespace-nowrap">{volumeLabel}</div> <div className="whitespace-nowrap">{volumeLabel}</div>
</Row> </Row>
{!disabled && <ContractInfoDialog contract={contract} bets={bets} />} {!disabled && <ContractInfoDialog contract={contract} bets={bets} />}
</>
)}
</Row> </Row>
) )
} }

View File

@ -73,7 +73,14 @@ export const ContractOverview = (props: {
<Row className="items-center justify-between gap-4 xl:hidden"> <Row className="items-center justify-between gap-4 xl:hidden">
<BinaryResolutionOrChance contract={contract} /> <BinaryResolutionOrChance contract={contract} />
{tradingAllowed(contract) && ( {tradingAllowed(contract) && (
<Col>
<BetButton contract={contract as CPMMBinaryContract} /> <BetButton contract={contract as CPMMBinaryContract} />
{!user && (
<div className="text-sm text-gray-500">
(Don't worry, it's play money!)
</div>
)}
</Col>
)} )}
</Row> </Row>
) : isPseudoNumeric ? ( ) : isPseudoNumeric ? (
@ -102,6 +109,7 @@ export const ContractOverview = (props: {
contract={contract} contract={contract}
bets={bets} bets={bets}
isCreator={isCreator} isCreator={isCreator}
user={user}
/> />
</Col> </Col>
<Spacer h={4} /> <Spacer h={4} />

View File

@ -27,6 +27,7 @@ export function ShareRow(props: {
return ( return (
<Row className="mt-2"> <Row className="mt-2">
{user && (
<Button <Button
size="lg" size="lg"
color="gray-white" color="gray-white"
@ -44,6 +45,7 @@ export function ShareRow(props: {
user={user} user={user}
/> />
</Button> </Button>
)}
{showChallenge && ( {showChallenge && (
<Button <Button