Skip to content

Commit

Permalink
feat: show market status and winning outcome on cardbet
Browse files Browse the repository at this point in the history
  • Loading branch information
berteotti committed Oct 29, 2024
1 parent a729c53 commit 75e94ae
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 43 deletions.
13 changes: 3 additions & 10 deletions app/(main)/markets/Bet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,20 @@ import {
ButtonLink,
Icon,
Tag,
TagProps,
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@swapr/ui';
import { Market } from '@/entities';
import { FixedProductMarketMaker } from '@/queries/omen';
import { Swapbox } from '@/app/components';
import { KLEROS_URL, REALITY_QUESTION_URL } from '@/constants';
import { KLEROS_URL, OUTCOME_TAG_COLORS_SCHEME, REALITY_QUESTION_URL } from '@/constants';
import { PropsWithChildren } from 'react';

interface BetProps {
fixedProductMarketMaker: FixedProductMarketMaker;
}

const tagSchemeColors: Record<number, TagProps['colorScheme']> = {
0: 'success',
1: 'danger',
[Market.INVALID_ANSWER]: 'quaternary',
};

export const Bet = ({ fixedProductMarketMaker }: BetProps) => {
const marketModel = new Market(fixedProductMarketMaker);

Expand Down Expand Up @@ -82,7 +75,7 @@ export const Bet = ({ fixedProductMarketMaker }: BetProps) => {
<span>Current winner outcome is</span>
<Tag
className="w-fit uppercase"
colorScheme={tagSchemeColors[marketModel.currentAnswer]}
colorScheme={OUTCOME_TAG_COLORS_SCHEME[marketModel.currentAnswer]}
>
{marketModel.currentAnswer === Market.INVALID_ANSWER
? 'Invalid'
Expand Down Expand Up @@ -123,7 +116,7 @@ export const Bet = ({ fixedProductMarketMaker }: BetProps) => {
<div className="flex items-center space-x-2">
<Tag
className="w-fit uppercase"
colorScheme={tagSchemeColors[winnerOutcome.index]}
colorScheme={OUTCOME_TAG_COLORS_SCHEME[winnerOutcome.index]}
>
{winnerOutcome.name}
</Tag>
Expand Down
12 changes: 5 additions & 7 deletions app/(main)/markets/MarketActivity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,13 @@ import {
getMarketTradesAndTransactions,
} from '@/queries/omen';
import { formatDateTimeWithYear, formatEtherWithFixedDecimals, timeAgo } from '@/utils';
import { Button, Icon, Tag, TagColorSchemeProp } from '@swapr/ui';
import { Button, Icon, Tag } from '@swapr/ui';
import { Outcome } from '@/entities';

import { Skeleton, TokenLogo, UserAvatarWithAddress } from '@/app/components';
import { getAIAgents } from '@/queries/dune';
import { Address } from 'viem';

const TAG_COLOR_SCHEMES: { 0: TagColorSchemeProp; 1: TagColorSchemeProp } = {
0: 'success',
1: 'danger',
};
import { OUTCOME_TAG_COLORS_SCHEME } from '@/constants';

const txTypeHumanWords: Record<TransactionType, string[]> = {
[TransactionType.Add]: ['added', 'to'],
Expand Down Expand Up @@ -215,7 +211,9 @@ const TradeRow = ({ activity, isAIAgent }: TradeRowProps) => {
)}
<Tag
size="xs"
colorScheme={outcome ? TAG_COLOR_SCHEMES[outcome.index as 0 | 1] : 'quaternary'}
colorScheme={
outcome ? OUTCOME_TAG_COLORS_SCHEME[outcome.index as 0 | 1] : 'quaternary'
}
className="w-fit space-x-1 text-sm uppercase"
>
<p>{formatEtherWithFixedDecimals(activity.outcomeTokensTraded)}</p>
Expand Down
68 changes: 46 additions & 22 deletions app/components/CardBet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { MarketThumbnail } from './MarketThumbnail';
import { Skeleton } from './Skeleton';
import { formatEtherWithFixedDecimals, formatValueWithFixedDecimals } from '@/utils';
import { useTx } from '@/context';
import { OUTCOME_TAG_COLORS_SCHEME } from '@/constants';

interface CardBetProps extends PropsWithChildren {
userBets: UserBets;
Expand Down Expand Up @@ -55,7 +56,7 @@ export const CardBet = ({ userBets, children }: CardBetProps) => {
const isLoser = market.isLoser(outcomeIndex);

const getResultAmountString = (): string => {
if (!market.isClosed) return 'Potential win';
if (!market.isClosed || !market.isAnswerFinal) return 'Potential win';
if (isWinner) return 'Won';
if (market.isAnswerInvalid) return 'Receive';

Expand All @@ -68,7 +69,7 @@ export const CardBet = ({ userBets, children }: CardBetProps) => {
outcomeIndex
);

if (!market.isClosed || isWinner)
if (!market.isClosed || isWinner || !market.isAnswerFinal)
return formatValueWithFixedDecimals(outcomeBalance, 2);

if (market.isAnswerInvalid)
Expand All @@ -85,46 +86,69 @@ export const CardBet = ({ userBets, children }: CardBetProps) => {
className={cx(
'w-full bg-gradient-to-b from-[#F1F1F1] dark:from-[#131313]',
isWinner && 'from-[#F2f2F2] to-[#d0ffd6] dark:from-[#131313] dark:to-[#11301F]',
isLoser && 'from-[#F2f2F2] to-[#f4cbc4] dark:from-[#131313] dark:to-[#301111]'
isLoser
? market.isAnswerInvalid
? ''
: 'from-[#F2f2F2] to-[#f4cbc4] dark:from-[#131313] dark:to-[#301111]'
: ''
)}
>
<Link key={market.fpmm.id} href={`markets?id=${market.fpmm.id}`} className="block">
<section className="flex h-[144px] flex-col justify-between space-y-4 p-4">
<section className="flex min-h-[144px] flex-col space-y-4 p-4">
<div className="flex items-center justify-between">
<div className="flex space-x-2">
<Tag colorScheme="quaternary" size="sm" className="capitalize">
{market.fpmm.category}
</Tag>
<div className="flex items-center space-x-2">
<Tag colorScheme="quaternary" size="sm" className="capitalize">
{market.fpmm.category}
</Tag>
<Tag colorScheme="success" size="sm">
{position.getOutcome()}
{market.getMarketStatus()}
</Tag>
<p className="text-sm text-text-low-em">
{remainingTime(market.closingDate)}
</p>
</div>
<p className="text-sm text-text-low-em">
{remainingTime(market.closingDate)}
</p>
</div>
<div className="flex space-x-4">
<div className="flex space-x-4 py-2">
<MarketThumbnail
width={40}
height={40}
className="size-[40px] rounded-8"
marketId={market.fpmm.id}
/>
<div className="text-normal h-[80px] flex-1 overflow-y-auto font-semibold text-text-high-em md:text-xl">
{market.fpmm.title}
<div className="space-y-2">
<div className="flex-1 overflow-y-auto text-md font-semibold text-text-high-em md:text-xl">
{market.fpmm.title}
</div>
{market.isClosed && (
<div className="flex space-x-2">
<p className="text-text-med-em">Answer:</p>
{market.currentAnswer !== null && (
<Tag colorScheme={OUTCOME_TAG_COLORS_SCHEME[market.currentAnswer]}>
{market.getCurrentAnswerOutcome()?.name}
</Tag>
)}
</div>
)}
</div>
</div>
</section>
</Link>
<section className="flex items-center border-t border-outline-base-em px-4 py-2 md:h-[48px] md:py-0">
<section className="flex items-center border-t border-outline-base-em p-4 md:h-[48px]">
<div className="flex w-full items-center justify-between space-x-4">
<div className="flex flex-col items-start space-y-0.5 md:flex-row md:items-center md:space-x-3">
<div className="flex flex-col items-start gap-2 md:flex-row md:items-center md:gap-4">
<div className="flex items-center space-x-1">
<p className="text-sm font-semibold text-text-med-em">Bet amount:</p>
<p className="flex items-center space-x-1 text-sm font-semibold text-text-high-em">
<p>{formatEtherWithFixedDecimals(collateralAmountSpent, 2)}</p>
<TokenLogo address={market.fpmm.collateralToken} className="size-3" />
</p>
<p className="text-sm font-semibold text-text-med-em">Bet:</p>{' '}
<div className="flex items-center space-x-1.5">
<Tag
colorScheme={position.getOutcomeIndex() === 0 ? 'success' : 'danger'}
>
{position.getOutcome()}
</Tag>
<p className="flex items-center space-x-1 text-sm font-semibold text-text-high-em">
<p>{formatEtherWithFixedDecimals(collateralAmountSpent, 2)}</p>
<TokenLogo address={market.fpmm.collateralToken} className="size-3" />
</p>
</div>
</div>
<div className="flex items-center space-x-1">
<p className="text-sm font-semibold text-text-med-em">
Expand Down
9 changes: 8 additions & 1 deletion constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Token } from '@/entities';
import { Market, Token } from '@/entities';
import { TagProps } from '@swapr/ui';

export const AI_AGENTS_ALLOWLIST = [
'0x89c5cc945dd550bcffb72fe42bff002429f46fec',
Expand Down Expand Up @@ -76,3 +77,9 @@ export const DISCORD_URL =
process.env.NEXT_PUBLIC_DISCORD_URL || 'https://discord.com/invite/QFkNsjTkzD';
export const GITHUB_URL =
process.env.NEXT_PUBLIC_GITHUB_URL || 'https://github.com/SwaprHQ/presagio';

export const OUTCOME_TAG_COLORS_SCHEME: Record<number, TagProps['colorScheme']> = {
0: 'success',
1: 'danger',
[Market.INVALID_ANSWER]: 'quaternary',
};
22 changes: 19 additions & 3 deletions entities/markets/market.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ export class Market {
this.fpmm = fpmm;
this.closingDate = new Date(+fpmm.openingTimestamp * 1000);
this.isAnswerFinal =
!!fpmm.resolutionTimestamp ||
fpmm.answerFinalizedTimestamp < nowTimestamp;
!!fpmm.resolutionTimestamp || fpmm.answerFinalizedTimestamp < nowTimestamp;

this.currentAnswer = fpmm.question?.currentAnswer
? fpmm.question.currentAnswer === INVALID_ANSWER_HEX
Expand Down Expand Up @@ -56,6 +55,7 @@ export class Market {
fpmm.id,
fpmm.outcomeTokenMarginalPrices?.[1]
),
new Outcome(-1, 'Invalid', fpmm.id),
];
}

Expand All @@ -68,8 +68,24 @@ export class Market {
}

getWinnerOutcome() {
return this.isClosed && this.answer !== null && this.answer !== Market.INVALID_ANSWER
return this.isClosed && this.answer !== null && !this.isAnswerInvalid
? this.outcomes[this.answer]
: null;
}

getCurrentAnswerOutcome() {
return this.currentAnswer !== null
? this.outcomes.at(this.currentAnswer) || null
: null;
}

getMarketStatus() {
if (this.isAnswerInvalid) return 'invalid market';

if (!this.isAnswerFinal && this.isClosed) return 'finalizing';

if (this.isClosed) return 'closed';

return 'open';
}
}

0 comments on commit 75e94ae

Please sign in to comment.