Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Calculate collectible price in dutch sell #385

Merged
merged 13 commits into from
May 17, 2019
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ REACT_APP_LOGGER_ID='0x-launch-kit-frontend'
REACT_APP_THEME_NAME='DEFAULT_THEME'
REACT_APP_ENABLE_NO_METAMASK_PROMPT='true'
REACT_APP_COLLECTIBLES_SOURCE='opensea'
REACT_APP_COLLECTIBLE_NAME='Cryptokitties'
REACT_APP_COLLECTIBLE_NAME='CryptoKitties'
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"0x.js": "^6.0.8",
"0x.js": "^6.0.9",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"@0x/connect": "^5.0.8",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: This library also had a release, should we update it?

"@0x/web3-wrapper": "^6.0.6",
"connected-react-router": "^6.2.2",
Expand Down
5 changes: 3 additions & 2 deletions src/components/erc721/collectibles/collectibles_card_list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import styled from 'styled-components';

import { themeBreakPoints } from '../../../themes/commons';
import { getCollectiblePrice } from '../../../util/collectibles';
import { Collectible } from '../../../util/types';

import { CollectibleAssetContainer } from './collectible_details';
Expand Down Expand Up @@ -43,8 +44,8 @@ export const CollectiblesCardList = (props: Props) => {
<CollectiblesListOverflow>
<CollectiblesList>
{collectibles.map((item, index) => {
const { name, image, color, order, tokenId } = item;
const price = order ? order.takerAssetAmount : null;
const { name, image, color, tokenId } = item;
const price = getCollectiblePrice(item);
return (
<CollectibleAssetContainer
color={color}
Expand Down
15 changes: 10 additions & 5 deletions src/components/erc721/marketplace/collectible_buy_sell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import React from 'react';
import { connect } from 'react-redux';
import styled from 'styled-components';

import { ETH_DECIMALS } from '../../../common/constants';
import { cancelOrderCollectible, selectCollectible } from '../../../store/collectibles/actions';
import { getCollectibleById, getEthAccount } from '../../../store/selectors';
import { startBuyCollectibleSteps } from '../../../store/ui/actions';
import { themeDimensions } from '../../../themes/commons';
import { getCollectiblePrice } from '../../../util/collectibles';
import { getEndDateStringFromTimeInSeconds } from '../../../util/time_utils';
import { tokenAmountInUnits } from '../../../util/tokens';
import { Collectible, StoreState } from '../../../util/types';

import { TradeButton } from './trade_button';
Expand Down Expand Up @@ -106,9 +109,7 @@ class CollectibleBuySell extends React.Component<Props> {
return null;
}
const { color, image, order } = collectible;

const price = order ? order.takerAssetAmount : null;

const price = getCollectiblePrice(collectible);
const expDate =
order && order.expirationTimeSeconds
? getEndDateStringFromTimeInSeconds(order.expirationTimeSeconds)
Expand All @@ -127,10 +128,14 @@ class CollectibleBuySell extends React.Component<Props> {
/>
{expDate ? (
<CollectibleText>
{timeSVG()} {expDate}
{timeSVG()} Ends {expDate}
</CollectibleText>
) : null}
{price && <CollectibleText textAlign="center">Last price: Ξ {price.toString()}</CollectibleText>}
{price && (
<CollectibleText textAlign="center">
Last price: Ξ {tokenAmountInUnits(price, ETH_DECIMALS)}
</CollectibleText>
)}
</BuySellWrapper>
);
};
Expand Down
117 changes: 8 additions & 109 deletions src/components/erc721/marketplace/collectible_description.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import React from 'react';
import { connect } from 'react-redux';
import styled from 'styled-components';

import { COLLECTIBLE_NAME } from '../../../common/constants';
import { getCollectibleById, getEthAccount } from '../../../store/selectors';
import { themeBreakPoints } from '../../../themes/commons';
import { truncateAddress } from '../../../util/number_utils';
import { convertTimeInSecondsToDaysAndHours } from '../../../util/time_utils';
import { Collectible, StoreState } from '../../../util/types';
import { Card } from '../../common/card';
import { OutsideUrlIcon } from '../../common/icons/outside_url_icon';
import { CustomTD, Table, TBody, TR } from '../../common/table';

import { DutchAuctionPriceChartCard } from './dutch_auction_price_chart_card';

const CollectibleDescriptionWrapper = styled.div``;

const CustomTDStyled = styled(CustomTD)`
Expand Down Expand Up @@ -57,7 +58,7 @@ const CollectibleDescriptionTypeImage = styled.span<{ backgroundImage: string }>
width: 16px;
`;

const CollectibleDescriptionInnerTitle = styled.h4`
export const CollectibleDescriptionInnerTitle = styled.h4`
color: ${props => props.theme.componentsTheme.cardTitleColor};
font-size: 14px;
font-weight: 500;
Expand Down Expand Up @@ -99,72 +100,6 @@ const CollectibleOwnerText = styled.p`
margin: 0;
`;

const PriceChartContainer = styled.div`
display: flex;
justify-content: space-between;
flex-direction: column;

@media (min-width: ${themeBreakPoints.xl}) {
flex-direction: row;
}
`;

const PriceChartPriceAndTime = styled.div`
margin-bottom: 25px;
max-width: 150px;
padding-right: 15px;
padding-top: 25px;

@media (min-width: ${themeBreakPoints.xl}) {
margin-bottom: 0;
}
`;

const PriceChartTitle = styled.h5`
color: ${props => props.theme.componentsTheme.cardTitleColor};
font-size: 14px;
font-weight: 400;
line-height: 1.2;
margin: 0 0 6px;
`;

const PriceChartValue = styled.p`
color: #00ae99;
font-size: 14px;
line-height: 1.2;
margin: 0 0 35px;

&:last-child {
margin-bottom: 0;
}
`;

const PriceChartValueNeutral = styled(PriceChartValue)`
color: ${props => props.theme.componentsTheme.cardTitleColor};
`;

const PriceChartGraphWrapper = styled.div`
flex-grow: 1;
padding-bottom: 15px;

@media (min-width: ${themeBreakPoints.xl}) {
max-width: 365px;
}
`;

const PriceChartGraph = styled.div`
background-color: #f5f5f5;
height: 148px;
margin: 0 0 15px;
width: 100%;
`;

const PriceChartGraphValues = styled.div`
align-items: center;
display: flex;
justify-content: space-between;
`;

const TransactionContainerTableWrapper = styled.div`
overflow-x: auto;
width: 100%;
Expand Down Expand Up @@ -203,20 +138,11 @@ const CollectibleDescription = (props: Props) => {
return null;
}

const { currentOwner, description, order, name, assetUrl } = collectible;
const emptyPlaceholder = '----';
const price = order ? order.takerAssetAmount : null;
const { currentOwner, description, name, assetUrl } = collectible;
const tableTitlesStyling = { fontWeight: '500', color: '#0036f4' };
const typeImage = 'https://placeimg.com/32/32/any';
const ownerImage = 'https://placeimg.com/50/50/any';

let timeRemaining = '';

if (order && order.expirationTimeSeconds) {
const daysAndHours = convertTimeInSecondsToDaysAndHours(order.expirationTimeSeconds);
timeRemaining = `${daysAndHours.days} Days ${daysAndHours.hours} Hrs`;
}

const doesBelongToCurrentUser = currentOwner.toLowerCase() === ethAccount.toLowerCase();

return (
Expand All @@ -226,7 +152,7 @@ const CollectibleDescription = (props: Props) => {
<CollectibleDescriptionTitle>{name}</CollectibleDescriptionTitle>
<CollectibleDescriptionType href={assetUrl} target="_blank">
<CollectibleDescriptionTypeImage backgroundImage={typeImage} />
<CollectibleDescriptionTypeText>CryptoKitties</CollectibleDescriptionTypeText>
<CollectibleDescriptionTypeText>{COLLECTIBLE_NAME}</CollectibleDescriptionTypeText>
{OutsideUrlIcon()}
</CollectibleDescriptionType>
</CollectibleDescriptionTitleWrapper>
Expand All @@ -242,41 +168,14 @@ const CollectibleDescription = (props: Props) => {
<CollectibleOwnerWrapper>
<CollectibleOwnerImage backgroundImage={ownerImage} />
<CollectibleOwnerText>
${truncateAddress(currentOwner)}
{truncateAddress(currentOwner)}
{doesBelongToCurrentUser && ' (you)'}
</CollectibleOwnerText>
</CollectibleOwnerWrapper>
</>
) : null}
</Card>
<Card>
<CollectibleDescriptionInnerTitle>Price Chart</CollectibleDescriptionInnerTitle>
<PriceChartContainer>
<PriceChartPriceAndTime>
<PriceChartTitle>Current Price</PriceChartTitle>
<PriceChartValue>
{price ? <span>{price.toString()} ETH</span> : emptyPlaceholder}
</PriceChartValue>
<PriceChartTitle>Time Remaining</PriceChartTitle>
<PriceChartValue>
{timeRemaining ? <span>{timeRemaining}</span> : emptyPlaceholder}
</PriceChartValue>
</PriceChartPriceAndTime>
<PriceChartGraphWrapper>
<PriceChartGraph />
<PriceChartGraphValues>
<div>
<PriceChartTitle>Start Price</PriceChartTitle>
<PriceChartValueNeutral>5.00 ETH</PriceChartValueNeutral>
</div>
<div>
<PriceChartTitle>End Price</PriceChartTitle>
<PriceChartValueNeutral>3.00 ETH</PriceChartValueNeutral>
</div>
</PriceChartGraphValues>
</PriceChartGraphWrapper>
</PriceChartContainer>
</Card>
<DutchAuctionPriceChartCard collectible={collectible} />
<Card>
<CollectibleDescriptionInnerTitle>Transaction history</CollectibleDescriptionInnerTitle>
<TransactionContainerTableWrapper>
Expand Down
127 changes: 127 additions & 0 deletions src/components/erc721/marketplace/dutch_auction_price_chart_card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import { BigNumber } from '0x.js';
import React from 'react';
import styled from 'styled-components';

import { ETH_DECIMALS } from '../../../common/constants';
import { themeBreakPoints } from '../../../themes/commons';
import { getCollectiblePrice } from '../../../util/collectibles';
import { getDutchAuctionData, isDutchAuction } from '../../../util/orders';
import { convertTimeInSecondsToDaysAndHours } from '../../../util/time_utils';
import { tokenAmountInUnits } from '../../../util/tokens';
import { Collectible } from '../../../util/types';
import { Card } from '../../common/card';

import { CollectibleDescriptionInnerTitle } from './collectible_description';

const PriceChartContainer = styled.div`
display: flex;
justify-content: space-between;
flex-direction: column;

@media (min-width: ${themeBreakPoints.xl}) {
flex-direction: row;
}
`;

const PriceChartPriceAndTime = styled.div`
margin-bottom: 25px;
max-width: 150px;
padding-right: 15px;
padding-top: 25px;

@media (min-width: ${themeBreakPoints.xl}) {
margin-bottom: 0;
}
`;

export const PriceChartTitle = styled.h5`
color: ${props => props.theme.componentsTheme.cardTitleColor};
font-size: 14px;
font-weight: 400;
line-height: 1.2;
margin: 0 0 6px;
`;

export const PriceChartValue = styled.p`
color: #00ae99;
font-size: 14px;
line-height: 1.2;
margin: 0 0 35px;

&:last-child {
margin-bottom: 0;
}
`;

const PriceChartValueNeutral = styled(PriceChartValue)`
color: ${props => props.theme.componentsTheme.cardTitleColor};
`;

const PriceChartGraphWrapper = styled.div`
flex-grow: 1;
padding-bottom: 15px;

@media (min-width: ${themeBreakPoints.xl}) {
max-width: 365px;
}
`;

const PriceChartGraph = styled.div`
background-color: #f5f5f5;
height: 148px;
margin: 0 0 15px;
width: 100%;
`;

const PriceChartGraphValues = styled.div`
align-items: center;
display: flex;
justify-content: space-between;
`;

interface Props {
collectible: Collectible;
}

export const DutchAuctionPriceChartCard = (props: Props) => {
const { collectible } = props;
const { order } = collectible;
if (order === null || !isDutchAuction(order)) {
return null;
}

const { makerAssetData, expirationTimeSeconds } = order;
const { beginAmount, beginTimeSeconds } = getDutchAuctionData(makerAssetData);
const price = getCollectiblePrice(collectible) as BigNumber;
const { days, hours } = convertTimeInSecondsToDaysAndHours(expirationTimeSeconds.minus(beginTimeSeconds));
return (
<Card>
<CollectibleDescriptionInnerTitle>Price Chart</CollectibleDescriptionInnerTitle>
<PriceChartContainer>
<PriceChartPriceAndTime>
<PriceChartTitle>Current Price</PriceChartTitle>
<PriceChartValue>{tokenAmountInUnits(price, ETH_DECIMALS)} ETH</PriceChartValue>
<PriceChartTitle>Time Remaining</PriceChartTitle>
<PriceChartValue>{`${days} Days ${hours} Hrs`}</PriceChartValue>
</PriceChartPriceAndTime>
<PriceChartGraphWrapper>
<PriceChartGraph />
<PriceChartGraphValues>
<div>
<PriceChartTitle>Start Price</PriceChartTitle>
<PriceChartValueNeutral>
{tokenAmountInUnits(beginAmount, ETH_DECIMALS)} ETH
</PriceChartValueNeutral>
</div>
<div>
<PriceChartTitle>End Price</PriceChartTitle>
<PriceChartValueNeutral>
{tokenAmountInUnits(order.takerAssetAmount, ETH_DECIMALS)} ETH
</PriceChartValueNeutral>
</div>
</PriceChartGraphValues>
</PriceChartGraphWrapper>
</PriceChartContainer>
</Card>
);
};
Loading