diff --git a/src/app/components/OrderBook.tsx b/src/app/components/OrderBook.tsx index 0ff3bd01..d0dc3406 100644 --- a/src/app/components/OrderBook.tsx +++ b/src/app/components/OrderBook.tsx @@ -1,9 +1,10 @@ -import { CSSProperties } from "react"; +import { CSSProperties, useState } from "react"; import "../styles/orderbook.css"; import * as utils from "../utils"; import { OrderBookRowProps, orderBookSlice } from "../state/orderBookSlice"; import { useAppDispatch, useAppSelector, useTranslations } from "../hooks"; +import { Calculator } from "services/Calculator"; // For all intents, we can round all numbers to 8 decimals for Dexter. // Alphadex will not accept any numbers with more than 8 decimals @@ -123,7 +124,49 @@ function CurrentPriceRow() { } } +enum OrderBookTabOptions { + ORDER_BOOK = "ORDER_BOOK", + RECENT_TRADES = "RECENT_TRADES", +} + export function OrderBook() { + const t = useTranslations(); + const [currentTab, setCurrentTab] = useState(OrderBookTabOptions.ORDER_BOOK); + + return ( +
+
+ {[ + [t("order_book"), OrderBookTabOptions.ORDER_BOOK], + [t("recent_trades"), OrderBookTabOptions.RECENT_TRADES], + ].map(([title, tab], indx) => { + const isActive = tab === currentTab; + return ( +
setCurrentTab(tab as OrderBookTabOptions)} + > + {title} +
+ ); + })} +
+
+ {currentTab === OrderBookTabOptions.ORDER_BOOK && } + {currentTab === OrderBookTabOptions.RECENT_TRADES && ( + + )} +
+
+ ); +} + +export function OrderBookTab() { const t = useTranslations(); const dispatch = useAppDispatch(); const token1Symbol = useAppSelector( @@ -134,16 +177,15 @@ export function OrderBook() { ); const sells = useAppSelector((state) => state.orderBook.sells); const buys = useAppSelector((state) => state.orderBook.buys); - //const grouping = useAppSelector((state) => state.orderBook.grouping); return ( -
-
-
{t("order_book")}
+
+
+
{t("grouping")} ) => { const grouping = Number(event.target.value); dispatch(orderBookSlice.actions.setGrouping(grouping)); @@ -184,3 +226,72 @@ export function OrderBook() {
); } + +function RecentTradesTab() { + const t = useTranslations(); + const { recentTrades } = useAppSelector((state) => state.orderBook); + const lastTrades = recentTrades.slice(0, 34); + const { token1, token2 } = useAppSelector((state) => state.pairSelector); + return ( +
+ + + + + + + + + + {lastTrades.map((trade, indx) => { + const price = Calculator.divide( + trade.token2Amount, + trade.token1Amount + ); + const time = trade.timestamp.split("T").join(" ").split(":00.")[0]; + const amount = Math.round(trade.token1Amount); + return ( + + ); + })} +
+ {t("price")} +
({token2.symbol}) +
+ {t("amount")}
({token1.symbol}) +
{t("time")}
+
+ ); +} + +function RecentTradeRow({ + price, + side, + time, + amount, +}: { + price: number; + side: string; + time: string; + amount: number; +}) { + return ( + + + {price.toFixed(4)} + + {amount.toLocaleString("en")} + {time} + + ); +} diff --git a/src/app/state/locales/en/trade.json b/src/app/state/locales/en/trade.json index 06281fec..9c8d9c0f 100644 --- a/src/app/state/locales/en/trade.json +++ b/src/app/state/locales/en/trade.json @@ -86,5 +86,7 @@ "cancel_1_order": "Cancel 1 Order", "submitting_batch_cancel": "Submitting batch cancel", "failed_to_cancel_orders": "Failed to cancel orders", - "connect_wallet_to_batch_delete": "Connect wallet to batch delete" + "connect_wallet_to_batch_delete": "Connect wallet to batch delete", + "recent_trades": "Recent Trades", + "time": "Time" } diff --git a/src/app/state/locales/pt/trade.json b/src/app/state/locales/pt/trade.json index 103d8b7a..58fcfc99 100644 --- a/src/app/state/locales/pt/trade.json +++ b/src/app/state/locales/pt/trade.json @@ -86,5 +86,7 @@ "cancel_1_order": "Cancelar 1 Orden", "submitting_batch_cancel": "Enviando cancelamento em lote", "failed_to_cancel_orders": "Falha ao cancelar pedidos", - "connect_wallet_to_batch_delete": "Conectar carteira para exclusão em lote" + "connect_wallet_to_batch_delete": "Conectar carteira para exclusão em lote", + "recent_trades": "Negocia. Recentes", + "time": "Hora" } diff --git a/src/app/state/orderBookSlice.ts b/src/app/state/orderBookSlice.ts index acf42a93..7b48cd6a 100644 --- a/src/app/state/orderBookSlice.ts +++ b/src/app/state/orderBookSlice.ts @@ -24,6 +24,7 @@ export interface OrderBookState { spread: number | null; spreadPercent: number | null; grouping: number | null; + recentTrades: adex.Trade[]; } const initialState: OrderBookState = { @@ -35,6 +36,7 @@ const initialState: OrderBookState = { spread: null, spreadPercent: null, grouping: 0, + recentTrades: [], }; export const MAX_ROWS = 13; @@ -202,6 +204,9 @@ export const orderBookSlice = createSlice({ state.bestSell = bestSell; state.bestBuy = bestBuy; }, + updateRecentTrades(state, action: PayloadAction) { + state.recentTrades = action.payload; + }, }, }); diff --git a/src/app/subscriptions.ts b/src/app/subscriptions.ts index d2821b7e..dd665f57 100644 --- a/src/app/subscriptions.ts +++ b/src/app/subscriptions.ts @@ -118,6 +118,11 @@ export function initializeSubscriptions(store: AppStore) { store.dispatch( rewardSlice.actions.updatePairsList(serializedState.pairsList) ); + store.dispatch( + orderBookSlice.actions.updateRecentTrades( + serializedState.currentPairTrades + ) + ); }) ); }