Skip to content

Commit

Permalink
Winning outcomes (#10523)
Browse files Browse the repository at this point in the history
* added winning outcome displays to the market cards

* added winning outcome label to the market view page
  • Loading branch information
JohnDanz authored Feb 3, 2021
1 parent 2d6c1b5 commit f7e92e8
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,50 @@
}
}

.WinningOutcomeLabel {
.SimpleBorder;

border: @size-1 solid var(--color-brand);
display: flex;
flex-flow: column nowrap;
width: 100%;
min-width: 100%;
min-height: @size-86;
height: @size-86;
max-height: @size-86;
justify-content: center;
padding: @size-16;


@media @breakpoint-mobile-tablet {
margin-bottom: @size-24;
}

> span {
align-items: center;
display: flex;
flex-flow: row nowrap;
white-space: nowrap;

&:first-of-type {
.text-16;

color: var(--simple-secondary-text);
margin-bottom: @size-8;
}

&:last-of-type {
.text-20-semi-bold;

color: var(--simple-primary-text);

> svg {
margin-left: @size-8;
}
}
}
}

.CategoryIcon,
.CategoryLabel {
.RoundedLabel;
Expand Down
13 changes: 12 additions & 1 deletion packages/augur-simplified/src/modules/market/market-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ import {
getMarketEndtimeDate,
} from '../../utils/date-utils';
import { getCurrentAmms } from '../stores/app-status-hooks';
import { getWinningOutcome } from '../markets/markets-view';
import { ConfirmedCheck } from '../common/icons';

const WinningOutcomeLabel = ({ winningOutcome }) => (
<span className={Styles.WinningOutcomeLabel}>
<span>Winning Outcome</span>
<span>{winningOutcome.name}{ConfirmedCheck}</span>
</span>
);

const getDetails = (market) => {
const rawInfo = market?.extraInfoRaw || '{}';
Expand Down Expand Up @@ -87,7 +96,8 @@ const MarketView = ({ defaultMarket = null }) => {
if (!market) return <div className={Styles.MarketView} />;
const details = getDetails(market);
const currentAMMs = getCurrentAmms(market, markets);
const { reportingState } = market;
const { reportingState, outcomes } = market;
const winningOutcomes = getWinningOutcome(amm?.ammOutcomes, outcomes);
return (
<div className={Styles.MarketView}>
<section>
Expand All @@ -100,6 +110,7 @@ const MarketView = ({ defaultMarket = null }) => {
<CurrencyLabel name={amm?.cash?.name} />
</div>
<h1>{market.description}</h1>
{winningOutcomes.length > 0 && <WinningOutcomeLabel winningOutcome={winningOutcomes[0]} />}
<ul className={Styles.StatsRow}>
<li>
<span>24hr Volume</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,40 @@
}

.OutcomesTable {
.SimpleBorder;

border-radius: @size-8;
display: flex;
flex-direction: column;

> div {
padding: @size-10 @size-16;
display: flex;

&:first-of-type {
.SimpleBorder;

&:not(:last-of-type) {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}

&.WinningOutcome {
border: @size-1 solid var(--color-brand);
}
}

&:last-of-type {
.SimpleBorder;

&:not(:first-of-type) {
border-top-left-radius: 0;
border-top-right-radius: 0;
}

&.WinningOutcome {
border: @size-1 solid var(--color-brand);
}
}

> span {
display: flex;
align-items: center;
Expand All @@ -193,12 +218,26 @@
color: var(--simple-primary-text);
}
}
&:not(:first-of-type) {
border-top: @size-1 solid var(--simple-border);
&:not(:first-of-type):not(:last-of-type) {
border-top: 0;
}

&:last-of-type:not(:first-of-type):not(.WinningOutcome) {
border-top: 0;
}
}

&.hasWinner {
> div:nth-last-child(2):not(.WinningOutcome) {
border-bottom: 0;
}
}
}

&.WinningOutcome {
background: var(--color-brand-20);
}

@media @breakpoint-mobile-tablet {
.MarketsView {
padding: @size-16;
Expand Down
92 changes: 74 additions & 18 deletions packages/augur-simplified/src/modules/markets/markets-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
formatDai,
formatPercent,
} from '../../utils/format-number';
import { FilterIcon } from '../common/icons';
import { FilterIcon, ConfirmedCheck } from '../common/icons';
import classNames from 'classnames';
import {
PrimaryButton,
Expand All @@ -24,7 +24,7 @@ import {
} from '../common/buttons';
import { SquareDropdown } from '../common/selection';
import { useAppStatusStore } from '../stores/app-status';
import { AmmExchange, AmmOutcome, MarketInfo } from '../types';
import { AmmExchange, AmmOutcome, MarketInfo, MarketOutcome } from '../types';
import {
SIDEBAR_TYPES,
ALL_CURRENCIES,
Expand All @@ -48,7 +48,7 @@ import {
CREATE,
} from '../constants';
import { sliceByPage, Pagination } from '../common/pagination';
import { TopBanner } from 'modules/common/top-banner';
import { TopBanner } from '../common/top-banner';
import { searchMarkets } from '../apollo/client';
import { SearchInput } from '../common/inputs';

Expand Down Expand Up @@ -76,33 +76,89 @@ const LoadingMarketCard = () => {
);
};

export const outcomesToDisplay = (ammOutcomes: AmmOutcome[]) => {
export const combineOutcomeData = (
ammOutcomes: AmmOutcome[],
marketOutcomes: MarketOutcome[]
) => {
if (!ammOutcomes || ammOutcomes.length === 0) return [];
const invalid = ammOutcomes.slice(0, 1);
const yes = ammOutcomes.slice(2, 3);
const no = ammOutcomes.slice(1, 2);
return invalid.concat(yes).concat(no).concat(ammOutcomes.slice(3));
return marketOutcomes.map((mOutcome, index) => ({
...mOutcome,
...ammOutcomes[index],
}));
};

const OutcomesTable = ({ amm }: { amm: AmmExchange }) => (
<div className={Styles.OutcomesTable}>
{outcomesToDisplay(amm.ammOutcomes)
.filter((outcome) => !outcome.isInvalid)
.map((outcome) => (
<div key={`${outcome.name}-${amm?.marketId}-${outcome.id}`}>
export const getWinningOutcome = (
ammOutcomes: AmmOutcome[],
marketOutcomes: MarketOutcome[]
) => combineOutcomeData(ammOutcomes, marketOutcomes).filter(({ payoutNumerator }) => payoutNumerator !== null && payoutNumerator !== '0');

export const outcomesToDisplay = (
ammOutcomes: AmmOutcome[],
marketOutcomes: MarketOutcome[]
) => {
const combinedData = combineOutcomeData(ammOutcomes, marketOutcomes);
const invalid = combinedData.slice(0, 1);
const yes = combinedData.slice(2, 3);
const no = combinedData.slice(1, 2);
let newOrder = invalid.concat(yes).concat(no).concat(combinedData.slice(3));
if (
newOrder[0].isFinalNumerator &&
newOrder[0].payoutNumerator !== '0' &&
newOrder[0].payoutNumerator !== null
) {
// invalid is winner -- only pass invalid
newOrder = invalid;
} else {
newOrder = newOrder.filter((outcome) => !outcome.isInvalid);
}
return newOrder;
};

const OutcomesTable = ({
amm,
marketOutcomes,
}: {
amm: AmmExchange;
marketOutcomes: MarketOutcome[];
}) => (
<div
className={classNames(Styles.OutcomesTable, {
[Styles.hasWinner]: marketOutcomes[0].isFinalNumerator,
})}
>
{outcomesToDisplay(amm.ammOutcomes, marketOutcomes).map((outcome) => {
const isWinner =
outcome.isFinalNumerator && outcome.payoutNumerator !== '0';
return (
<div
key={`${outcome.name}-${amm?.marketId}-${outcome.id}`}
className={classNames({ [Styles.WinningOutcome]: isWinner })}
>
<span>{outcome.name.toLowerCase()}</span>
<span>
{amm?.liquidity !== '0'
{isWinner
? ConfirmedCheck
: outcome.isFinalNumerator
? ''
: amm?.liquidity !== '0'
? formatCashPrice(outcome.price, amm?.cash?.name).full
: '-'}
</span>
</div>
))}
);
})}
</div>
);

const MarketCard = ({ market }: { market: MarketInfo }) => {
const { categories, description, marketId, amm, reportingState } = market;
const {
categories,
description,
marketId,
amm,
reportingState,
outcomes,
} = market;
const formattedApy = amm?.apy && formatPercent(amm.apy).full;
const {
isLogged,
Expand Down Expand Up @@ -158,7 +214,7 @@ const MarketCard = ({ market }: { market: MarketInfo }) => {
value={formatDai(market.amm?.volumeTotalUSD).full}
/>
<ValueLabel label="APY" value={formattedApy} />
<OutcomesTable amm={amm} />
<OutcomesTable amm={amm} marketOutcomes={outcomes} />
</>
)}
</div>
Expand Down

0 comments on commit f7e92e8

Please sign in to comment.