Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ const SKELETON_LAYOUTS = {
desktop: (data: Dimensions) => createSkeletonLayout(12, data),
};

const ChartSkeletonWrapper = styled(clone(SkeletonWrapper, { skeletonLayouts: SKELETON_LAYOUTS }))`
const OrderbookAndTradesSkeletonWrapper = styled(clone(SkeletonWrapper, { skeletonLayouts: SKELETON_LAYOUTS }))`
background: ${({ theme }) => theme.colors.bgSecondary};
border-radius: 10px;
height: 100%;
min-height: 416px;
`;

export default ChartSkeletonWrapper;
export default OrderbookAndTradesSkeletonWrapper;
55 changes: 55 additions & 0 deletions src/components/TableOrderBook/HistoryOrderBook.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from "react";
import { useTheme } from "@emotion/react";
import styled from "@emotion/styled";

import { SmartFlex } from "@components/SmartFlex";
import { DataArray } from "@components/TableOrderBook/TableOrderBook";
import Text, { TEXT_TYPES } from "@components/Text";

const HistoryOrderBook = ({ data }: { data: DataArray[] }) => {
const theme = useTheme();
return (
<Container className="better-scroll">
{data.map((trade, index) => (
<Row key={"trade" + trade[index]}>
<Text color={trade[3] ? theme.colors.redLight : theme.colors.greenLight} type={TEXT_TYPES.BODY}>
{trade[0]}
</Text>
<TextRightAlign color={theme.colors.textPrimary} type={TEXT_TYPES.BODY}>
{trade[1]}
</TextRightAlign>
<TextRightAlign color={theme.colors.textPrimary} type={TEXT_TYPES.BODY}>
{trade[2]}
</TextRightAlign>
</Row>
))}
</Container>
);
};
export default HistoryOrderBook;

const Container = styled.div`
display: flex;
flex-direction: column;
width: 100%;
box-sizing: border-box;
padding: 5px 12px 8px;
overflow-y: auto;
height: 100%;
`;

const Row = styled(SmartFlex)`
display: grid;
grid-template-columns: repeat(3, 1fr);

height: 16px;

gap: 10px;

align-items: center;
justify-content: space-between;
`;

const TextRightAlign = styled(Text)`
text-align: right !important;
`;
116 changes: 116 additions & 0 deletions src/components/TableOrderBook/SellAndBuy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React from "react";
import { useTheme } from "@emotion/react";
import styled from "@emotion/styled";
import numeral from "numeral";

import { Column } from "@components/Flex";
import { SmartFlex } from "@components/SmartFlex";
import { ConfigProps, DataArray } from "@components/TableOrderBook/TableOrderBook";
import Text, { TEXT_TYPES } from "@components/Text";
import { media } from "@themes/breakpoints";

interface HistoryOrderBookProps {
firstData: DataArray[];
secondData?: DataArray[];
config: ConfigProps;
}
const SellAndBuy = ({ firstData, secondData, config }: HistoryOrderBookProps) => {
const theme = useTheme();

const renderSpread = () => {
let price = config.isSpreadValid ? config.spreadPrice : "-";
price = price === "-" ? price : numeral(price).format(`0.${"0".repeat(config.decimalGroup ?? 0)}a`);
const percent = config.isSpreadValid ? config.spreadPercent : "-";
if (media.mobile) {
return (
<SpreadContainer>
<Text type={TEXT_TYPES.H} primary>
{price}
</Text>
<Text>{`(${percent}%)`}</Text>
</SpreadContainer>
);
}

return (
<SpreadContainer>
<Text type={TEXT_TYPES.SUPPORTING}>SPREAD</Text>
<Text primary>{price}</Text>
<Text>{`(${percent}%) `}</Text>
</SpreadContainer>
);
};

const generateRow = (data: DataArray[]) =>
data.map((trade, index) => (
<Row key={"trade" + trade[index]}>
<Text color={trade[3] ? theme.colors.redLight : theme.colors.greenLight} type={TEXT_TYPES.BODY}>
{trade[0]}
</Text>
<TextRightAlign color={theme.colors.textPrimary} type={TEXT_TYPES.BODY}>
{trade[1]}
</TextRightAlign>
<TextRightAlign color={theme.colors.textPrimary} type={TEXT_TYPES.BODY}>
{trade[2]}
</TextRightAlign>
</Row>
));
return (
<Container>
<OrderBookColumn>
<SmartFlexOrder flexDirection="column-reverse">{generateRow(firstData)}</SmartFlexOrder>
{renderSpread()}
<SmartFlexOrder>{generateRow(secondData ?? [])}</SmartFlexOrder>
</OrderBookColumn>
</Container>
);
};
export default SellAndBuy;

const Container = styled.div`
display: flex;
flex-direction: column;
width: 100%;
box-sizing: border-box;
padding: 5px 12px 8px;
overflow-y: auto;
height: 100%;
`;

const Row = styled(SmartFlex)`
display: grid;
grid-template-columns: repeat(3, 1fr);

height: 16px;

gap: 10px;

align-items: center;
justify-content: space-between;
`;

const TextRightAlign = styled(Text)`
text-align: right !important;
`;

const SmartFlexOrder = styled(SmartFlex)<{ flexDirection?: string }>`
flex-direction: ${({ flexDirection }) => flexDirection ?? "column"};
flex-grow: 1;
width: 100%;
height: 0;
overflow: hidden;
`;

const OrderBookColumn = styled(Column)`
height: 100%;
width: 100%;
`;

const SpreadContainer = styled(SmartFlex)`
padding-left: 12px;
height: 24px;
background: ${({ theme }) => theme.colors.bgPrimary};
align-items: center;
gap: 12px;
width: 100%;
`;
101 changes: 101 additions & 0 deletions src/components/TableOrderBook/TableOrderBook.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from "react";
import styled from "@emotion/styled";

import { Column } from "@components/Flex";
import HistoryOrderBook from "@components/TableOrderBook/HistoryOrderBook";
import SellAndBuy from "@components/TableOrderBook/SellAndBuy";
import Text, { TEXT_TYPES } from "@components/Text";
import { media } from "@themes/breakpoints";

export interface ColumnProps {
title: string;
align: "left" | "center" | "right";
}

export enum SPOT_ORDER_FILTER {
SELL_AND_BUY = 0,
SELL = 1,
BUY = 2,
HISTORY = 3,
}

export type DataArray = [string, string, string, boolean]; // первые 3 это данные, 4 это направление цены

export interface ConfigProps {
orderFilter: SPOT_ORDER_FILTER;
isSpreadValid?: boolean;
spreadPrice?: string;
spreadPercent?: string;
decimalGroup?: number;
}

interface TableOrderBookProps {
column: ColumnProps[];
firstData: DataArray[];
secondData?: DataArray[];
config: ConfigProps;
}
const TableOrderBook = ({ column, firstData, secondData, config }: TableOrderBookProps) => {
const isDataEmpty = firstData.length === 0;
if (isDataEmpty)
return (
<Root alignItems="center" justifyContent="center" mainAxisSize="stretch">
<Text type={TEXT_TYPES.SUPPORTING}>No trades yet</Text>
</Root>
);
const renderOrderBook = () => {
if (config.orderFilter === SPOT_ORDER_FILTER.SELL_AND_BUY) {
return <SellAndBuy config={config} firstData={firstData} secondData={secondData} />;
}
return <HistoryOrderBook data={firstData} />;
};
return (
<Root>
<Header>
{column.map((el) => (
<TextStyled key={el.title} align={el.align} type={TEXT_TYPES.SUPPORTING}>
{el.title}
</TextStyled>
))}
</Header>
{renderOrderBook()}
</Root>
);
};

export default TableOrderBook;

const Root = styled(Column)`
width: 100%;
height: 100%;
`;

const Header = styled.div`
display: grid;
grid-template-columns: repeat(3, 1fr);
width: 100%;
padding: 0 12px;
text-align: center;
height: 26px;
align-items: center;
gap: 10px;

${Text} {
text-align: start;
}

${media.mobile} {
grid-template-columns: 1fr min-content;

${Text}:nth-of-type(2) {
text-align: end;
}
${Text}:nth-of-type(3) {
display: none;
}
}
`;

const TextStyled = styled(Text)<{ align: string }>`
${({ align }) => `text-align: ${align};`};
`;
4 changes: 4 additions & 0 deletions src/entity/PerpPosition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,8 @@ export class PerpPosition {
get isUnrealizedPnlInProfit() {
return this.takerOpenNational.multipliedBy(this.takerPositionSize).multipliedBy(this.markPrice).isPositive();
}

get leverage() {
return "20";
}
}
27 changes: 27 additions & 0 deletions src/screens/PerpScreen/BottomTables/BottomTables.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from "react";
import styled from "@emotion/styled";
import { observer } from "mobx-react";

import { media } from "@themes/breakpoints";

import PerpTable from "./PerpTable";

const BottomTables: React.FC = observer(() => {
return (
<StyledBottomTables>
<PerpTable />
</StyledBottomTables>
);
});

export default BottomTables;

const StyledBottomTables = styled.div`
width: 100%;
border: 1px solid rgba(46, 46, 46, 1);
border-radius: 8px;

${media.mobile} {
flex-grow: 1;
}
`;
Loading