Don’t show negative values in feed for sales

This commit is contained in:
mantikoros 2022-01-17 21:36:33 -06:00
parent 6625983bb7
commit e6d467764d
2 changed files with 79 additions and 30 deletions

View File

@ -1,5 +1,6 @@
// From https://tailwindui.com/components/application-ui/lists/feeds // From https://tailwindui.com/components/application-ui/lists/feeds
import { useState } from 'react' import { useState } from 'react'
import _ from 'lodash'
import { import {
BanIcon, BanIcon,
ChatAltIcon, ChatAltIcon,
@ -10,11 +11,11 @@ import {
UsersIcon, UsersIcon,
XIcon, XIcon,
} from '@heroicons/react/solid' } from '@heroicons/react/solid'
import { useBets } from '../hooks/use-bets'
import { Bet, withoutAnteBets } from '../lib/firebase/bets'
import { Comment, mapCommentsByBetId } from '../lib/firebase/comments'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime' import relativeTime from 'dayjs/plugin/relativeTime'
dayjs.extend(relativeTime)
import { OutcomeLabel } from './outcome-label' import { OutcomeLabel } from './outcome-label'
import { import {
contractMetrics, contractMetrics,
@ -33,11 +34,18 @@ import { SiteLink } from './site-link'
import { Col } from './layout/col' import { Col } from './layout/col'
import { UserLink } from './user-page' import { UserLink } from './user-page'
import { DateTimeTooltip } from './datetime-tooltip' import { DateTimeTooltip } from './datetime-tooltip'
dayjs.extend(relativeTime) import { useBets } from '../hooks/use-bets'
import { Bet, withoutAnteBets } from '../lib/firebase/bets'
import { Comment, mapCommentsByBetId } from '../lib/firebase/comments'
import { JoinSpans } from './join-spans'
function FeedComment(props: { activityItem: any }) { function FeedComment(props: { activityItem: any }) {
const { activityItem } = props const { activityItem } = props
const { person, text, amount, outcome, createdTime } = activityItem const { person, text, amount, outcome, createdTime } = activityItem
const bought = amount >= 0 ? 'bought' : 'sold'
const money = formatMoney(Math.abs(amount))
return ( return (
<> <>
<SiteLink className="relative" href={`/${person.username}`}> <SiteLink className="relative" href={`/${person.username}`}>
@ -59,7 +67,7 @@ function FeedComment(props: { activityItem: any }) {
username={person.username} username={person.username}
name={person.name} name={person.name}
/>{' '} />{' '}
placed {formatMoney(amount)} on <OutcomeLabel outcome={outcome} />{' '} {bought} {money} of <OutcomeLabel outcome={outcome} />{' '}
<Timestamp time={createdTime} /> <Timestamp time={createdTime} />
</p> </p>
</div> </div>
@ -97,6 +105,10 @@ function FeedBet(props: { activityItem: any }) {
if (!user || !comment) return if (!user || !comment) return
await createComment(contractId, id, comment, user) await createComment(contractId, id, comment, user)
} }
const bought = amount >= 0 ? 'bought' : 'sold'
const money = formatMoney(Math.abs(amount))
return ( return (
<> <>
<div> <div>
@ -108,9 +120,8 @@ function FeedBet(props: { activityItem: any }) {
</div> </div>
<div className="min-w-0 flex-1 py-1.5"> <div className="min-w-0 flex-1 py-1.5">
<div className="text-sm text-gray-500"> <div className="text-sm text-gray-500">
<span>{isCreator ? 'You' : 'A trader'}</span> placed{' '} <span>{isCreator ? 'You' : 'A trader'}</span> {bought} {money} of{' '}
{formatMoney(amount)} on <OutcomeLabel outcome={outcome} />{' '} <OutcomeLabel outcome={outcome} /> <Timestamp time={createdTime} />
<Timestamp time={createdTime} />
{canComment && ( {canComment && (
// Allow user to comment in an textarea if they are the creator // Allow user to comment in an textarea if they are the creator
<div className="mt-2"> <div className="mt-2">
@ -452,44 +463,51 @@ function groupBets(
return items as ActivityItem[] return items as ActivityItem[]
} }
function BetGroupSpan(props: { bets: Bet[]; outcome: 'YES' | 'NO' }) {
const { bets, outcome } = props
const numberTraders = _.uniqBy(bets, (b) => b.userId).length
const [buys, sells] = _.partition(bets, (bet) => bet.amount >= 0)
const buyTotal = _.sumBy(buys, (b) => b.amount)
const sellTotal = _.sumBy(sells, (b) => -b.amount)
return (
<span>
{numberTraders} {numberTraders > 1 ? 'traders' : 'trader'}{' '}
<JoinSpans>
{buyTotal > 0 && <>bought {formatMoney(buyTotal)} </>}
{sellTotal > 0 && <>sold {formatMoney(sellTotal)} </>}
</JoinSpans>
of <OutcomeLabel outcome={outcome} />
</span>
)
}
// TODO: Make this expandable to show all grouped bets? // TODO: Make this expandable to show all grouped bets?
function FeedBetGroup(props: { activityItem: any }) { function FeedBetGroup(props: { activityItem: any }) {
const { activityItem } = props const { activityItem } = props
const bets: Bet[] = activityItem.bets const bets: Bet[] = activityItem.bets
const yesAmount = bets const [yesBets, noBets] = _.partition(bets, (bet) => bet.outcome === 'YES')
.filter((b) => b.outcome == 'YES')
.reduce((acc, bet) => acc + bet.amount, 0)
const yesSpan = yesAmount ? (
<span>
{formatMoney(yesAmount)} on <OutcomeLabel outcome={'YES'} />
</span>
) : null
const noAmount = bets
.filter((b) => b.outcome == 'NO')
.reduce((acc, bet) => acc + bet.amount, 0)
const noSpan = noAmount ? (
<span>
{formatMoney(noAmount)} on <OutcomeLabel outcome={'NO'} />
</span>
) : null
const traderCount = bets.length
const createdTime = bets[0].createdTime const createdTime = bets[0].createdTime
return ( return (
<> <>
<div> <div>
<div className="relative px-1"> <div className="relative px-1">
<div className="h-8 w-8 bg-gray-200 rounded-full ring-8 ring-gray-50 flex items-center justify-center"> <div className="h-10 w-10 bg-gray-200 rounded-full ring-8 ring-gray-50 flex items-center justify-center">
<UsersIcon className="h-5 w-5 text-gray-500" aria-hidden="true" /> <UsersIcon className="h-6 w-6 text-gray-500" aria-hidden="true" />
</div> </div>
</div> </div>
</div> </div>
<div className="min-w-0 flex-1 py-1.5"> <div className="min-w-0 flex-1 py-1.5">
<div className="text-sm text-gray-500"> <div className="text-sm text-gray-500">
<span>{traderCount} traders</span> placed {yesSpan} {yesBets.length > 0 && <BetGroupSpan outcome="YES" bets={yesBets} />}
{yesAmount && noAmount ? ' and ' : ''} {yesBets.length > 0 && noBets.length > 0 && <br />}
{noSpan} <Timestamp time={createdTime} /> {noBets.length > 0 && <BetGroupSpan outcome="NO" bets={noBets} />}
<Timestamp time={createdTime} />
</div> </div>
</div> </div>
</> </>

View File

@ -0,0 +1,31 @@
export const JoinSpans = (props: {
children: any[]
separator?: JSX.Element | string
}) => {
const { separator } = props
const children = props.children.filter((x) => !!x)
if (children.length === 0) return <></>
if (children.length === 1) return children[0]
if (children.length === 2)
return (
<>
{children[0]} and {children[1]}
</>
)
const head = children.slice(0, -1).map((child) => (
<>
{child}
{separator || ','}{' '}
</>
))
const tail = children[children.length - 1]
return (
<>
{head}and {tail}
</>
)
}