277 lines
6.8 KiB
TypeScript
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;
|