made contract details buttons use IconButton

This commit is contained in:
ingawei 2022-10-12 23:04:39 -07:00
parent c72d6c5df5
commit ead4a6431b
5 changed files with 184 additions and 193 deletions

View File

@ -19,11 +19,12 @@ import ShortToggle from '../widgets/short-toggle'
import { DuplicateContractButton } from '../duplicate-contract-button' import { DuplicateContractButton } from '../duplicate-contract-button'
import { Row } from '../layout/row' import { Row } from '../layout/row'
import { BETTORS, User } from 'common/user' import { BETTORS, User } from 'common/user'
import { Button } from '../button' import { IconButton } from '../button'
import { AddLiquidityButton } from './add-liquidity-button' import { AddLiquidityButton } from './add-liquidity-button'
import { Tooltip } from '../tooltip'
export const contractDetailsButtonClassName = // export const contractDetailsButtonClassName =
'group flex items-center rounded-md px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-100 text-gray-400 hover:text-gray-500' // 'group flex items-center rounded-md px-3 py-2 text-sm font-medium cursor-pointer hover:bg-gray-100 text-gray-400 hover:text-gray-500'
export function ContractInfoDialog(props: { export function ContractInfoDialog(props: {
contract: Contract contract: Contract
@ -84,171 +85,173 @@ export function ContractInfoDialog(props: {
return ( return (
<> <>
<Button <Tooltip text="Market details" placement="bottom" noTap noFade>
size="sm" <IconButton
color="gray-white" size="2xs"
className={clsx(contractDetailsButtonClassName, className)} className={clsx(className)}
onClick={() => setOpen(true)} onClick={() => setOpen(true)}
> >
<DotsHorizontalIcon <DotsHorizontalIcon
className={clsx('h-5 w-5 flex-shrink-0')} className={clsx('h-5 w-5 flex-shrink-0')}
aria-hidden="true" aria-hidden="true"
/> />
</Button> </IconButton>
<Modal open={open} setOpen={setOpen}> <Modal open={open} setOpen={setOpen}>
<Col className="gap-4 rounded bg-white p-6"> <Col className="gap-4 rounded bg-white p-6">
<Title className="!mt-0 !mb-0" text="This Market" /> <Title className="!mt-0 !mb-0" text="This Market" />
<table className="table-compact table-zebra table w-full text-gray-500"> <table className="table-compact table-zebra table w-full text-gray-500">
<tbody> <tbody>
<tr>
<td>Type</td>
<td>{typeDisplay}</td>
</tr>
<tr>
<td>Payout</td>
<td className="flex gap-1">
{mechanism === 'cpmm-1' ? (
<>
Fixed{' '}
<InfoTooltip text="Each YES share is worth M$1 if YES wins." />
</>
) : (
<>
Parimutuel{' '}
<InfoTooltip text="Each share is a fraction of the pool. " />
</>
)}
</td>
</tr>
<tr>
<td>Market created</td>
<td>{formatTime(createdTime)}</td>
</tr>
{closeTime && (
<tr> <tr>
<td>Market close{closeTime > Date.now() ? 's' : 'd'}</td> <td>Type</td>
<td>{formatTime(closeTime)}</td> <td>{typeDisplay}</td>
</tr> </tr>
)}
{resolutionTime && (
<tr> <tr>
<td>Market resolved</td> <td>Payout</td>
<td>{formatTime(resolutionTime)}</td> <td className="flex gap-1">
</tr> {mechanism === 'cpmm-1' ? (
)} <>
Fixed{' '}
<tr> <InfoTooltip text="Each YES share is worth M$1 if YES wins." />
<td> </>
<span className="mr-1">Volume</span> ) : (
<InfoTooltip text="Total amount bought or sold" /> <>
</td> Parimutuel{' '}
<td>{formatMoney(contract.volume)}</td> <InfoTooltip text="Each share is a fraction of the pool. " />
</tr> </>
)}
<tr>
<td>{capitalize(BETTORS)}</td>
<td>{uniqueBettorCount ?? '0'}</td>
</tr>
<tr>
<td>
<Row>
<span className="mr-1">Elasticity</span>
<InfoTooltip
text={
mechanism === 'cpmm-1'
? 'Probability change between a M$50 bet on YES and NO'
: 'Probability change from a M$100 bet'
}
/>
</Row>
</td>
<td>{formatPercent(elasticity)}</td>
</tr>
<tr>
<td>Liquidity subsidies</td>
<td>
{mechanism === 'cpmm-1'
? formatMoney(contract.totalLiquidity)
: formatMoney(100)}
</td>
</tr>
<tr>
<td>Pool</td>
<td>
{mechanism === 'cpmm-1' && outcomeType === 'BINARY'
? `${Math.round(pool.YES)} YES, ${Math.round(pool.NO)} NO`
: mechanism === 'cpmm-1' && outcomeType === 'PSEUDO_NUMERIC'
? `${Math.round(pool.YES)} HIGHER, ${Math.round(
pool.NO
)} LOWER`
: contractPool(contract)}
</td>
</tr>
{/* Show a path to Firebase if user is an admin, or we're on localhost */}
{(isAdmin || isDev) && (
<tr>
<td>[ADMIN] Firestore</td>
<td>
<SiteLink href={firestoreConsolePath(id)}>
Console link
</SiteLink>
</td> </td>
</tr> </tr>
)}
{isAdmin && (
<tr>
<td>[ADMIN] Featured</td>
<td>
<ShortToggle
on={featured}
setOn={setFeatured}
onChange={onFeaturedToggle}
/>
</td>
</tr>
)}
{user && (
<tr>
<td>{isAdmin ? '[ADMIN]' : ''} Unlisted</td>
<td>
<ShortToggle
disabled={
isUnlisted
? !(isAdmin || (isCreator && wasUnlistedByCreator))
: !(isCreator || isAdmin)
}
on={contract.visibility === 'unlisted'}
setOn={(b) =>
updateContract(id, {
visibility: b ? 'unlisted' : 'public',
unlistedById: b ? user.id : '',
})
}
/>
</td>
</tr>
)}
</tbody>
</table>
<Row className="flex-wrap"> <tr>
{mechanism === 'cpmm-1' && ( <td>Market created</td>
<AddLiquidityButton contract={contract} className="mr-2" /> <td>{formatTime(createdTime)}</td>
)} </tr>
<DuplicateContractButton contract={contract} />
</Row> {closeTime && (
</Col> <tr>
</Modal> <td>Market close{closeTime > Date.now() ? 's' : 'd'}</td>
<td>{formatTime(closeTime)}</td>
</tr>
)}
{resolutionTime && (
<tr>
<td>Market resolved</td>
<td>{formatTime(resolutionTime)}</td>
</tr>
)}
<tr>
<td>
<span className="mr-1">Volume</span>
<InfoTooltip text="Total amount bought or sold" />
</td>
<td>{formatMoney(contract.volume)}</td>
</tr>
<tr>
<td>{capitalize(BETTORS)}</td>
<td>{uniqueBettorCount ?? '0'}</td>
</tr>
<tr>
<td>
<Row>
<span className="mr-1">Elasticity</span>
<InfoTooltip
text={
mechanism === 'cpmm-1'
? 'Probability change between a M$50 bet on YES and NO'
: 'Probability change from a M$100 bet'
}
/>
</Row>
</td>
<td>{formatPercent(elasticity)}</td>
</tr>
<tr>
<td>Liquidity subsidies</td>
<td>
{mechanism === 'cpmm-1'
? formatMoney(contract.totalLiquidity)
: formatMoney(100)}
</td>
</tr>
<tr>
<td>Pool</td>
<td>
{mechanism === 'cpmm-1' && outcomeType === 'BINARY'
? `${Math.round(pool.YES)} YES, ${Math.round(pool.NO)} NO`
: mechanism === 'cpmm-1' &&
outcomeType === 'PSEUDO_NUMERIC'
? `${Math.round(pool.YES)} HIGHER, ${Math.round(
pool.NO
)} LOWER`
: contractPool(contract)}
</td>
</tr>
{/* Show a path to Firebase if user is an admin, or we're on localhost */}
{(isAdmin || isDev) && (
<tr>
<td>[ADMIN] Firestore</td>
<td>
<SiteLink href={firestoreConsolePath(id)}>
Console link
</SiteLink>
</td>
</tr>
)}
{isAdmin && (
<tr>
<td>[ADMIN] Featured</td>
<td>
<ShortToggle
on={featured}
setOn={setFeatured}
onChange={onFeaturedToggle}
/>
</td>
</tr>
)}
{user && (
<tr>
<td>{isAdmin ? '[ADMIN]' : ''} Unlisted</td>
<td>
<ShortToggle
disabled={
isUnlisted
? !(isAdmin || (isCreator && wasUnlistedByCreator))
: !(isCreator || isAdmin)
}
on={contract.visibility === 'unlisted'}
setOn={(b) =>
updateContract(id, {
visibility: b ? 'unlisted' : 'public',
unlistedById: b ? user.id : '',
})
}
/>
</td>
</tr>
)}
</tbody>
</table>
<Row className="flex-wrap">
{mechanism === 'cpmm-1' && (
<AddLiquidityButton contract={contract} className="mr-2" />
)}
<DuplicateContractButton contract={contract} />
</Row>
</Col>
</Modal>
</Tooltip>
</> </>
) )
} }

View File

@ -2,7 +2,7 @@ import { ShareIcon } from '@heroicons/react/outline'
import { Row } from '../layout/row' import { Row } from '../layout/row'
import { Contract } from 'web/lib/firebase/contracts' import { Contract } from 'web/lib/firebase/contracts'
import React, { useState } from 'react' import React, { useState } from 'react'
import { Button } from 'web/components/button' import { IconButton } from 'web/components/button'
import { useUser } from 'web/hooks/use-user' import { useUser } from 'web/hooks/use-user'
import { ShareModal } from './share-modal' import { ShareModal } from './share-modal'
import { FollowMarketButton } from 'web/components/follow-market-button' import { FollowMarketButton } from 'web/components/follow-market-button'
@ -16,15 +16,14 @@ export function ExtraContractActionsRow(props: { contract: Contract }) {
const [isShareOpen, setShareOpen] = useState(false) const [isShareOpen, setShareOpen] = useState(false)
return ( return (
<Row> <Row className="gap-1">
<FollowMarketButton contract={contract} user={user} /> <FollowMarketButton contract={contract} user={user} />
<LikeMarketButton contract={contract} user={user} /> <LikeMarketButton contract={contract} user={user} />
<Tooltip text="Share" placement="bottom" noTap noFade> <Tooltip text="Share" placement="bottom" noTap noFade>
<Button <IconButton
size="sm" size="2xs"
color="gray-white"
className={'flex'} className={'flex'}
onClick={() => setShareOpen(true)} onClick={() => setShareOpen(true)}
> >
@ -35,7 +34,7 @@ export function ExtraContractActionsRow(props: { contract: Contract }) {
contract={contract} contract={contract}
user={user} user={user}
/> />
</Button> </IconButton>
</Tooltip> </Tooltip>
<ContractInfoDialog contract={contract} user={user} /> <ContractInfoDialog contract={contract} user={user} />

View File

@ -13,8 +13,7 @@ export function TipButton(props: {
isCompact?: boolean isCompact?: boolean
disabled?: boolean disabled?: boolean
}) { }) {
const { tipAmount, totalTipped, userTipped, isCompact, onClick, disabled } = const { tipAmount, totalTipped, userTipped, onClick, disabled } = props
props
const tipDisplay = shortFormatNumber(Math.ceil(totalTipped / 10)) const tipDisplay = shortFormatNumber(Math.ceil(totalTipped / 10))
@ -35,6 +34,7 @@ export function TipButton(props: {
onClick={onClick} onClick={onClick}
disabled={disabled} disabled={disabled}
className={clsx( className={clsx(
'px-2 py-1 text-xs', //2xs button
'text-greyscale-6 transition-transform hover:text-indigo-600 disabled:cursor-not-allowed', 'text-greyscale-6 transition-transform hover:text-indigo-600 disabled:cursor-not-allowed',
!disabled ? 'hover:rotate-12' : '' !disabled ? 'hover:rotate-12' : ''
)} )}
@ -43,20 +43,20 @@ export function TipButton(props: {
> >
<Col className={clsx('relative', disabled ? 'opacity-30' : '')}> <Col className={clsx('relative', disabled ? 'opacity-30' : '')}>
<TipJar <TipJar
size={16} size={18}
color={hover || userTipped ? '#4f46e5' : '#66667C'} color={userTipped || (hover && !disabled) ? '#4f46e5' : '#66667C'}
fill={userTipped ? '#4f46e5' : 'none'} fill={userTipped ? '#4f46e5' : 'none'}
/> />
<div <div
className={clsx( className={clsx(
' absolute top-[3px] text-[0.5rem]', ' absolute top-[2px] text-[0.5rem]',
userTipped ? 'text-white' : '', userTipped ? 'text-white' : '',
tipDisplay.length === 1 tipDisplay.length === 1
? 'left-[6px]' ? 'left-[7px]'
: tipDisplay.length === 2 : tipDisplay.length === 2
? 'left-[3.5px]' ? 'left-[4.5px]'
: tipDisplay.length > 2 : tipDisplay.length > 2
? 'left-[3px] top-[5px] text-[0.35rem]' ? 'left-[4px] top-[2.5px] text-[0.35rem]'
: '' : ''
)} )}
> >

View File

@ -178,14 +178,10 @@ export function CommentActions(props: {
}) { }) {
const { onReplyClick, comment, showTip, myTip, totalTip, contract } = props const { onReplyClick, comment, showTip, myTip, totalTip, contract } = props
return ( return (
<Row className="grow justify-end gap-2"> <Row className="grow justify-end">
{onReplyClick && ( {onReplyClick && (
<IconButton <IconButton size={'xs'} onClick={() => onReplyClick(comment)}>
size={'xs'} <ReplyIcon className="h-5 w-5" />
className={clsx('mt-0 mb-1 max-w-xs')}
onClick={() => onReplyClick(comment)}
>
<ReplyIcon className="h-4 w-4" />
</IconButton> </IconButton>
)} )}
{showTip && ( {showTip && (

View File

@ -1,4 +1,4 @@
import { Button } from 'web/components/button' import { IconButton } from 'web/components/button'
import { import {
Contract, Contract,
followContract, followContract,
@ -33,9 +33,8 @@ export const FollowMarketButton = (props: {
noTap noTap
noFade noFade
> >
<Button <IconButton
size={'sm'} size="2xs"
color={'gray-white'}
onClick={async () => { onClick={async () => {
if (!user) return firebaseLogin() if (!user) return firebaseLogin()
if (followers?.includes(user.id)) { if (followers?.includes(user.id)) {
@ -65,18 +64,12 @@ export const FollowMarketButton = (props: {
> >
{watching ? ( {watching ? (
<Col className={'items-center gap-x-2 sm:flex-row'}> <Col className={'items-center gap-x-2 sm:flex-row'}>
<EyeOffIcon <EyeOffIcon className={clsx('h-5 w-5')} aria-hidden="true" />
className={clsx('h-5 w-5 sm:h-6 sm:w-6')}
aria-hidden="true"
/>
{/* Unwatch */} {/* Unwatch */}
</Col> </Col>
) : ( ) : (
<Col className={'items-center gap-x-2 sm:flex-row'}> <Col className={'items-center gap-x-2 sm:flex-row'}>
<EyeIcon <EyeIcon className={clsx('h-5 w-5')} aria-hidden="true" />
className={clsx('h-5 w-5 sm:h-6 sm:w-6')}
aria-hidden="true"
/>
{/* Watch */} {/* Watch */}
</Col> </Col>
)} )}
@ -87,7 +80,7 @@ export const FollowMarketButton = (props: {
followers?.includes(user?.id ?? 'nope') ? 'watched' : 'unwatched' followers?.includes(user?.id ?? 'nope') ? 'watched' : 'unwatched'
} a question!`} } a question!`}
/> />
</Button> </IconButton>
</Tooltip> </Tooltip>
) )
} }