import { DotsHorizontalIcon } from '@heroicons/react/outline' import clsx from 'clsx' import dayjs from 'dayjs' import { useState } from 'react' import { capitalize } from 'lodash' import { Contract } from 'common/contract' import { formatMoney, formatPercent } from 'common/util/format' import { contractPool, updateContract } from 'web/lib/firebase/contracts' import { Col } from '../layout/col' import { Modal } from '../layout/modal' import { Title } from '../title' import { InfoTooltip } from '../info-tooltip' import { useAdmin, useDev } from 'web/hooks/use-admin' import { SiteLink } from '../site-link' import { firestoreConsolePath } from 'common/envs/constants' import { deleteField } from 'firebase/firestore' import ShortToggle from '../widgets/short-toggle' import { DuplicateContractButton } from '../duplicate-contract-button' import { Row } from '../layout/row' import { BETTORS, User } from 'common/user' import { IconButton } from '../button' import { AddLiquidityButton } from './add-liquidity-button' import { Tooltip } from '../tooltip' import { Table } from '../table' export function ContractInfoDialog(props: { contract: Contract user: User | null | undefined className?: string }) { const { contract, className, user } = props const [open, setOpen] = useState(false) const [featured, setFeatured] = useState( (contract?.featuredOnHomeRank ?? 0) > 0 ) const isDev = useDev() const isAdmin = useAdmin() const isCreator = user?.id === contract.creatorId const isUnlisted = contract.visibility === 'unlisted' const wasUnlistedByCreator = contract.unlistedById ? contract.unlistedById === contract.creatorId : false const formatTime = (dt: number) => dayjs(dt).format('MMM DD, YYYY hh:mm a') const { createdTime, closeTime, resolutionTime, uniqueBettorCount, mechanism, outcomeType, id, elasticity, pool, } = contract const typeDisplay = outcomeType === 'BINARY' ? 'YES / NO' : outcomeType === 'FREE_RESPONSE' ? 'Free response' : outcomeType === 'MULTIPLE_CHOICE' ? 'Multiple choice' : 'Numeric' const onFeaturedToggle = async (enabled: boolean) => { if ( enabled && (contract.featuredOnHomeRank === 0 || !contract?.featuredOnHomeRank) ) { await updateContract(id, { featuredOnHomeRank: 1 }) setFeatured(true) } else if (!enabled && (contract?.featuredOnHomeRank ?? 0) > 0) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore await updateContract(id, { featuredOnHomeRank: deleteField() }) setFeatured(false) } } return ( <> setOpen(true)} > <Table> <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> <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> </> ) }