trade-frontend/src/pages/dex/orders/index.tsx
2026-01-17 15:50:06 +05:00

277 lines
6.8 KiB
TypeScript

import styles from '@/styles/Orders.module.scss';
import Header from '@/components/default/Header/Header';
import PageTitle from '@/components/default/PageTitle/PageTitle';
import HorizontalSelect from '@/components/UI/HorizontalSelect/HorizontalSelect';
import { useEffect, useState } from 'react';
import Dropdown from '@/components/UI/Dropdown/Dropdown';
import DateRangeSelector from '@/components/UI/DateRangeSelector/DateRangeSelector';
import Button from '@/components/UI/Button/Button';
import { cancelOrder, getUserOrders } from '@/utils/methods';
import Alert from '@/components/UI/Alert/Alert';
import AlertType from '@/interfaces/common/AlertType';
import { UserOrderData } from '@/interfaces/responses/orders/GetUserOrdersRes';
import PairValue from '@/interfaces/props/pages/dex/orders/PairValue';
import DateState from '@/interfaces/common/DateState';
import useUpdateUser from '@/hook/useUpdateUser';
import { Footer } from '@/zano_ui/src';
import OrdersTable from './OrdersTable/OrdersTable';
function Orders() {
const fetchUser = useUpdateUser();
const ordersCategories = [
{
name: 'Active orders',
code: 'active-orders',
},
{
name: 'Finished',
code: 'history',
},
];
const buySellValues = [
{
name: 'Buy & Sell',
},
{
name: 'Buy',
},
{
name: 'Sell',
},
];
const [pairsValues, setPairsValues] = useState<PairValue[]>([{ name: 'All pairs', code: '' }]);
const [pairDropdownValue, setPairDropdownState] = useState(pairsValues[0]);
const [buyDropdownValue, setBuyDropdownState] = useState(buySellValues[0]);
const [categoryState, setCategoryState] = useState(ordersCategories[0]);
const [alertState, setAlertState] = useState<AlertType>(null);
const [alertSubtitle, setAlertSubtitle] = useState<string>('');
const [dateRange, setDateRange] = useState<DateState>({
first: null,
last: null,
});
const [orders, setOrders] = useState<UserOrderData[]>([]);
useEffect(() => {
async function getOrders() {
setAlertState('loading');
setAlertSubtitle('Loading orders data...');
const result = await getUserOrders();
if (!result.success) {
setAlertState('error');
setAlertSubtitle('Error loading orders data');
await new Promise((resolve) => setTimeout(resolve, 2000));
setAlertState(null);
setAlertSubtitle('');
return;
}
fetchUser();
setOrders(result.data);
function getPairsFromOrders(orders: UserOrderData[]) {
const pairs = [
{
code: '',
name: 'All pairs',
},
];
for (let i = 0; i < orders.length; i++) {
const pair = {
name: `${orders[i].first_currency.name}/${orders[i].second_currency.name}`,
code: orders[i].pair_id,
};
if (!pairs.find((e) => e.code === pair.code)) pairs.push(pair);
}
return pairs;
}
const pairs = getPairsFromOrders(result.data);
setPairsValues(pairs);
setPairDropdownState(pairs[0]);
setAlertState(null);
setAlertSubtitle('');
const { success, data } = await getUserOrders();
if (success) {
setOrders(data);
}
}
getOrders();
}, []);
function buySellFilter(e: UserOrderData) {
if (buyDropdownValue.name === 'Buy & Sell') return true;
if (buyDropdownValue.name === 'Buy') return e.type === 'buy';
if (buyDropdownValue.name === 'Sell') return e.type === 'sell';
}
function pairFilter(e: UserOrderData) {
if (!pairDropdownValue) return true;
return !pairDropdownValue.code || e.pair_id === pairDropdownValue.code;
}
function dateFilter(e: UserOrderData) {
if (!dateRange.first || !dateRange.last) return true;
const firstDate = new Date(dateRange.first);
const lastDate = new Date(dateRange.last);
const timestamp = parseInt(e.timestamp, 10);
firstDate.setHours(0, 0, 0, 0);
lastDate.setHours(24, 0, 0, 0);
if (!dateRange.first && !dateRange.last) return true;
if (dateRange.first && !dateRange.last) return timestamp >= firstDate.getTime();
if (!dateRange.first && dateRange.last) return timestamp <= lastDate.getTime();
return timestamp >= firstDate.getTime() && timestamp <= lastDate.getTime();
}
function categoryFilter(e: UserOrderData) {
if (categoryState.code === 'active-orders') {
return e.status === 'active';
}
return e.status === 'finished';
}
const activeOrders = orders.filter((e) => e.status === 'active');
async function cancelAllOrders() {
setAlertState('loading');
setAlertSubtitle('Canceling all orders...');
// const results = await Promise.allSettled(
// activeOrders.map(async (e) => {
// await cancelOrder(e.id);
// }),
// );
const results = await (async () => {
const res = [];
for (const order of activeOrders) {
res.push(await cancelOrder(order.id).catch(() => null));
}
return res;
})();
if (results.some((e) => e === null)) {
setAlertState('error');
setAlertSubtitle('Some of the orders were not canceled');
} else {
setAlertState('success');
setAlertSubtitle('All orders canceled');
}
setTimeout(() => {
setAlertState(null);
setAlertSubtitle('');
}, 2000);
const { success, data } = await getUserOrders();
if (success) {
setOrders(data);
}
}
return (
<>
<Header />
<main className={styles.main}>
<PageTitle>
<div className={styles.orders__title}>
<h1>My Trade Orders</h1>
<p>Check all the offers you have</p>
</div>
</PageTitle>
<div className={styles.orders__content}>
<div className={styles.orders__nav}>
<HorizontalSelect
body={ordersCategories}
value={categoryState}
setValue={setCategoryState}
isTab
/>
<div className={styles.orders__filters_wrapper}>
<div className={styles.orders__filters}>
<Dropdown
maxItems={5}
className={styles.orders__pair__filter}
selfContained
withSearch
value={pairDropdownValue || {}}
setValue={(e) => {
setPairDropdownState(e);
}}
body={pairsValues}
/>
<Dropdown
className={styles.orders__buy_sell__filter}
selfContained
value={buyDropdownValue}
setValue={(e) => {
setBuyDropdownState(e);
}}
body={buySellValues}
/>
<DateRangeSelector value={dateRange} setValue={setDateRange} />
</div>
<Button transparent onClick={cancelAllOrders}>
Cancel all orders
</Button>
</div>
</div>
<OrdersTable
value={orders
.filter(buySellFilter)
.filter(pairFilter)
.filter(dateFilter)
.filter(categoryFilter)}
setAlertState={setAlertState}
setAlertSubtitle={setAlertSubtitle}
setOrders={setOrders}
category={categoryState.code}
/>
</div>
{alertState && (
<Alert
type={alertState}
subtitle={alertSubtitle || ''}
close={() => setAlertState(null)}
/>
)}
</main>
<Footer />
</>
);
}
export default Orders;