commit
769c34648f
18 changed files with 326 additions and 80 deletions
99
.github/workflows/codeql.yml
vendored
Normal file
99
.github/workflows/codeql.yml
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL Advanced"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: '21 18 * * 6'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze (${{ matrix.language }})
|
||||
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||
# - https://gh.io/supported-runners-and-hardware-resources
|
||||
# - https://gh.io/using-larger-runners (GitHub.com only)
|
||||
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
permissions:
|
||||
# required for all workflows
|
||||
security-events: write
|
||||
|
||||
# required to fetch internal or private CodeQL packs
|
||||
packages: read
|
||||
|
||||
# only required for workflows in private repositories
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- language: javascript-typescript
|
||||
build-mode: none
|
||||
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
|
||||
# Use `c-cpp` to analyze code written in C, C++ or both
|
||||
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
|
||||
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
||||
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
|
||||
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
|
||||
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
|
||||
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Add any setup steps before running the `github/codeql-action/init` action.
|
||||
# This includes steps like installing compilers or runtimes (`actions/setup-node`
|
||||
# or others). This is typically only required for manual builds.
|
||||
# - name: Setup runtime (example)
|
||||
# uses: actions/setup-example@v1
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
# If the analyze step fails for one of the languages you are analyzing with
|
||||
# "We were unable to automatically build your code", modify the matrix above
|
||||
# to set the build mode to "manual" for that language. Then modify this step
|
||||
# to build your code.
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
- name: Run manual build steps
|
||||
if: matrix.build-mode == 'manual'
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'If you are using a "manual" build mode for one or more of the' \
|
||||
'languages you are analyzing, replace this with the commands to build' \
|
||||
'your code, for example:'
|
||||
echo ' make bootstrap'
|
||||
echo ' make release'
|
||||
exit 1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
15
package-lock.json
generated
15
package-lock.json
generated
|
|
@ -23,6 +23,7 @@
|
|||
"next": "^13.2.4",
|
||||
"next-themes": "^0.2.1",
|
||||
"node-fetch": "^3.3.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"react": "18.2.0",
|
||||
"react-apexcharts": "^1.5.0",
|
||||
"react-dom": "18.2.0",
|
||||
|
|
@ -42,6 +43,7 @@
|
|||
"@types/big.js": "^6.2.0",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/pg": "^8.10.2",
|
||||
"@types/react": "18.2.16",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
|
|
@ -4214,6 +4216,13 @@
|
|||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/nprogress": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/nprogress/-/nprogress-0.2.3.tgz",
|
||||
"integrity": "sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/pg": {
|
||||
"version": "8.15.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.4.tgz",
|
||||
|
|
@ -9876,6 +9885,12 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/nprogress": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz",
|
||||
"integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nth-check": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
"next": "^13.2.4",
|
||||
"next-themes": "^0.2.1",
|
||||
"node-fetch": "^3.3.1",
|
||||
"nprogress": "^0.2.0",
|
||||
"react": "18.2.0",
|
||||
"react-apexcharts": "^1.5.0",
|
||||
"react-dom": "18.2.0",
|
||||
|
|
@ -54,6 +55,7 @@
|
|||
"@types/big.js": "^6.2.0",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/pg": "^8.10.2",
|
||||
"@types/react": "18.2.16",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
|
|
|
|||
|
|
@ -72,7 +72,9 @@ export default function OrderNotification({
|
|||
</div>
|
||||
<div className={styles['dex__order-notification_delimiter']} />
|
||||
<div className={styles['dex__order-notification_details']}>
|
||||
<Link href={pairLink}>Details</Link>
|
||||
<Link href={pairLink} onClick={onCloseClick}>
|
||||
Details
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { useEffect, useState, useRef, useMemo } from 'react';
|
||||
import { useEffect, useState, useRef, useMemo, useLayoutEffect } from 'react';
|
||||
import useAdvancedTheme from '@/hook/useTheme';
|
||||
import ReactECharts from 'echarts-for-react';
|
||||
import type CandleChartProps from '@/interfaces/props/pages/dex/trading/CandleChartProps/CandleChartProps';
|
||||
|
|
@ -18,7 +18,6 @@ import {
|
|||
function CandleChart(props: CandleChartProps) {
|
||||
const { theme } = useAdvancedTheme();
|
||||
const chartRef = useRef<ReactECharts>(null);
|
||||
|
||||
const [candles, setCandles] = useState<ResultCandle[]>([]);
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
|
||||
|
|
@ -148,6 +147,12 @@ function CandleChart(props: CandleChartProps) {
|
|||
};
|
||||
}, [candles, props.period, theme]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
requestAnimationFrame(() => {
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={styles.chart}>
|
||||
{/* Header */}
|
||||
|
|
@ -179,14 +184,16 @@ function CandleChart(props: CandleChartProps) {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<ReactECharts
|
||||
ref={chartRef}
|
||||
option={option}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
opts={{ devicePixelRatio: 2 }}
|
||||
lazyUpdate
|
||||
notMerge
|
||||
/>
|
||||
<div className={styles.chart__body}>
|
||||
<ReactECharts
|
||||
ref={chartRef}
|
||||
option={option}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
opts={{ devicePixelRatio: 2 }}
|
||||
lazyUpdate
|
||||
notMerge
|
||||
/>
|
||||
</div>
|
||||
|
||||
{!candles.length && isLoaded && (
|
||||
<h1 className={styles.chart__lowVolume}>[ Low volume ]</h1>
|
||||
|
|
|
|||
|
|
@ -40,10 +40,19 @@
|
|||
}
|
||||
}
|
||||
|
||||
> canvas {
|
||||
&__body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: crosshair;
|
||||
|
||||
div,
|
||||
canvas {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
canvas {
|
||||
cursor: crosshair;
|
||||
}
|
||||
}
|
||||
|
||||
&__lowVolume {
|
||||
|
|
@ -63,4 +72,4 @@
|
|||
font-size: 36px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -78,48 +78,29 @@
|
|||
&__body {
|
||||
tr {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
position: relative !important;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--table-tr-hover-color);
|
||||
}
|
||||
|
||||
&.buy {
|
||||
td {
|
||||
&:last-child {
|
||||
&::before {
|
||||
background-color: var(--dex-buy-percentage);
|
||||
}
|
||||
}
|
||||
}
|
||||
background: linear-gradient(
|
||||
to left,
|
||||
var(--dex-buy-percentage) var(--precentage),
|
||||
transparent var(--precentage)
|
||||
);
|
||||
}
|
||||
|
||||
&.sell {
|
||||
td {
|
||||
&:last-child {
|
||||
&::before {
|
||||
background-color: var(--dex-sell-percentage);
|
||||
}
|
||||
}
|
||||
}
|
||||
background: linear-gradient(
|
||||
to left,
|
||||
var(--dex-sell-percentage) var(--precentage),
|
||||
transparent var(--precentage)
|
||||
);
|
||||
}
|
||||
|
||||
td {
|
||||
position: static !important;
|
||||
|
||||
&:last-child {
|
||||
&::before {
|
||||
content: '';
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: var(--precentage);
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
p,
|
||||
span {
|
||||
position: relative;
|
||||
|
|
@ -199,6 +180,7 @@
|
|||
padding: 10px;
|
||||
transform: translateX(-50%);
|
||||
background-color: var(--dex-tooltip-bg);
|
||||
transition: none !important;
|
||||
|
||||
&__arrow {
|
||||
border-top: 1px solid var(--dex-tooltip-border-color);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import PeriodState from '@/interfaces/states/pages/dex/trading/InputPanelItem/PeriodState';
|
||||
import SelectValue from '@/interfaces/states/pages/dex/trading/InputPanelItem/SelectValue';
|
||||
|
||||
export const API_URL = process.env.NEXT_PUBLIC_API_URL;
|
||||
|
||||
export const periods: PeriodState[] = [
|
||||
// { name: '1s', code: '1sec' },
|
||||
{ name: '1m', code: '1min' },
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
getTrades,
|
||||
} from '@/utils/methods';
|
||||
import useUpdateUser from '@/hook/useUpdateUser';
|
||||
import { Dispatch, SetStateAction, useContext, useEffect, useState } from 'react';
|
||||
import { Dispatch, SetStateAction, useContext, useEffect, useRef, useState } from 'react';
|
||||
import CandleRow from '@/interfaces/common/CandleRow';
|
||||
import { PageOrderData } from '@/interfaces/responses/orders/GetOrdersPageRes';
|
||||
import { Trade } from '@/interfaces/responses/trades/GetTradeRes';
|
||||
|
|
@ -45,9 +45,12 @@ export function useTradingData({
|
|||
const { state } = useContext(Store);
|
||||
const fetchUser = useUpdateUser();
|
||||
const router = useRouter();
|
||||
const [candlesLoaded, setCandlesLoaded] = useState(false);
|
||||
const [ordersLoading, setOrdersLoading] = useState(true);
|
||||
const [tradesLoading, setTradesLoading] = useState(true);
|
||||
const isFirstLoad = useRef(true);
|
||||
const prevPeriod = useRef<string | null>(null);
|
||||
|
||||
const [candlesLoaded, setCandlesLoaded] = useState(true);
|
||||
const [ordersLoading, setOrdersLoading] = useState(false);
|
||||
const [tradesLoading, setTradesLoading] = useState(false);
|
||||
const pairId = typeof router.query.id === 'string' ? router.query.id : '';
|
||||
const loggedIn = !!state.wallet?.connected;
|
||||
|
||||
|
|
@ -108,17 +111,37 @@ export function useTradingData({
|
|||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isFirstLoad.current) {
|
||||
isFirstLoad.current = false;
|
||||
|
||||
setOrdersLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchPairStats();
|
||||
getPairData();
|
||||
updateOrders();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!prevPeriod.current) {
|
||||
prevPeriod.current = periodsState.code;
|
||||
return;
|
||||
}
|
||||
|
||||
if (prevPeriod.current === periodsState.code) return;
|
||||
|
||||
prevPeriod.current = periodsState.code;
|
||||
fetchCandles();
|
||||
}, [periodsState]);
|
||||
}, [periodsState.code]);
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (isFirstLoad.current) {
|
||||
setTradesLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await fetchTrades();
|
||||
})();
|
||||
}, [pairId]);
|
||||
|
|
|
|||
13
src/interfaces/props/pages/dex/trading/TradingProps.ts
Normal file
13
src/interfaces/props/pages/dex/trading/TradingProps.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import CandleRow from '@/interfaces/common/CandleRow';
|
||||
import PairData from '@/interfaces/common/PairData';
|
||||
import { PageOrderData } from '@/interfaces/responses/orders/GetOrdersPageRes';
|
||||
import { PairStats } from '@/interfaces/responses/orders/GetPairStatsRes';
|
||||
import { Trade } from '@/interfaces/responses/trades/GetTradeRes';
|
||||
|
||||
export interface TradingProps {
|
||||
initialPair: PairData | null;
|
||||
initialStats: PairStats | null;
|
||||
initialOrders: PageOrderData[];
|
||||
initialTrades: Trade[];
|
||||
initialCandles: CandleRow[];
|
||||
}
|
||||
|
|
@ -7,8 +7,29 @@ import NextApp, { AppContext, AppProps } from 'next/app';
|
|||
import { ThemeProvider } from 'next-themes';
|
||||
import GetConfigRes, { GetConfigResData } from '@/interfaces/responses/config/GetConfigRes';
|
||||
import inter from '@/utils/font';
|
||||
import { API_URL } from '@/constants';
|
||||
import NProgress from 'nprogress';
|
||||
import { Router } from 'next/router';
|
||||
import PageHandler from './PageHandler';
|
||||
import NotificationPopups from './NotificationPopups';
|
||||
import 'nprogress/nprogress.css';
|
||||
|
||||
NProgress.configure({
|
||||
showSpinner: false,
|
||||
trickleSpeed: 200,
|
||||
});
|
||||
|
||||
Router.events.on('routeChangeStart', () => {
|
||||
NProgress.start();
|
||||
});
|
||||
|
||||
Router.events.on('routeChangeComplete', () => {
|
||||
NProgress.done();
|
||||
});
|
||||
|
||||
Router.events.on('routeChangeError', () => {
|
||||
NProgress.done();
|
||||
});
|
||||
|
||||
function App(data: AppProps & { config?: GetConfigResData }) {
|
||||
const { Component, pageProps } = data;
|
||||
|
|
@ -63,7 +84,7 @@ App.getInitialProps = async (context: AppContext) => {
|
|||
try {
|
||||
const pageProps = await NextApp.getInitialProps(context);
|
||||
|
||||
const configRes = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/config`, {
|
||||
const configRes = await fetch(`${API_URL}/api/config`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
|
|
|
|||
|
|
@ -14,16 +14,19 @@ import { useInView } from 'react-intersection-observer';
|
|||
import Preloader from '@/components/UI/Preloader/Preloader';
|
||||
import { PairSortOption } from '@/interfaces/enum/pair';
|
||||
import PairsTable from '@/components/default/PairsTable/PairsTable';
|
||||
import axios from 'axios';
|
||||
import { API_URL } from '@/constants';
|
||||
import DexHeader from './DexHeader/DexHeader';
|
||||
import PairsList from './pairs/PairsList/PairsList';
|
||||
|
||||
function Dex() {
|
||||
function Dex({ initialPairs }: { initialPairs: PairData[] }) {
|
||||
const fetchIdRef = useRef<string>(nanoid());
|
||||
const bottomInView = useRef<boolean>(false);
|
||||
const isFirstLoad = useRef(true);
|
||||
|
||||
const [pairInputState, setPairInputState] = useState('');
|
||||
const [pairs, setPairs] = useState<PairData[]>([]);
|
||||
const [allLoaded, setLoadedState] = useState(false);
|
||||
const [pairs, setPairs] = useState<PairData[]>(initialPairs);
|
||||
const [allLoaded, setLoadedState] = useState(initialPairs.length > 0);
|
||||
const [pagesAmount, setPagesAmount] = useState<number>();
|
||||
const [pageLoading, setPageLoading] = useState(false);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
|
|
@ -36,7 +39,7 @@ function Dex() {
|
|||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window !== undefined) {
|
||||
if (typeof window !== 'undefined') {
|
||||
const currentState = localStorage.getItem('all_pairs') ?? '';
|
||||
|
||||
if (currentState === '' || currentState === 'true') {
|
||||
|
|
@ -66,14 +69,14 @@ function Dex() {
|
|||
async function fetchPairs() {
|
||||
const initial = currentPage === 1;
|
||||
|
||||
if (initial) {
|
||||
setLoadedState(false);
|
||||
setPageLoading(false);
|
||||
} else {
|
||||
setPageLoading(true);
|
||||
setLoadedState(true);
|
||||
if (initial && initialPairs.length > 0 && isFirstLoad.current) {
|
||||
isFirstLoad.current = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!initial) {
|
||||
setPageLoading(true);
|
||||
}
|
||||
const newFetchId = nanoid();
|
||||
fetchIdRef.current = newFetchId;
|
||||
const result = await getPairsPage(currentPage, pairInputState, whitelistedOnly, sortOption);
|
||||
|
|
@ -162,4 +165,14 @@ function Dex() {
|
|||
);
|
||||
}
|
||||
|
||||
export async function getServerSideProps() {
|
||||
const result = await getPairsPage(1, '', true, PairSortOption.VOLUME_HIGH_TO_LOW);
|
||||
|
||||
return {
|
||||
props: {
|
||||
initialPairs: result.success ? result.data : [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default Dex;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,14 @@ import Footer from '@/components/default/Footer/Footer';
|
|||
import Header from '@/components/default/Header/Header';
|
||||
import HorizontalSelect from '@/components/UI/HorizontalSelect/HorizontalSelect';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { cancelOrder } from '@/utils/methods';
|
||||
import {
|
||||
cancelOrder,
|
||||
getCandles,
|
||||
getOrdersPage,
|
||||
getPair,
|
||||
getPairStats,
|
||||
getTrades,
|
||||
} from '@/utils/methods';
|
||||
import ContentPreloader from '@/components/UI/ContentPreloader/ContentPreloader';
|
||||
import Alert from '@/components/UI/Alert/Alert';
|
||||
import PeriodState from '@/interfaces/states/pages/dex/trading/InputPanelItem/PeriodState';
|
||||
|
|
@ -30,24 +37,33 @@ import useMatrixAddresses from '@/hook/useMatrixAddresses';
|
|||
import takeOrderClick from '@/utils/takeOrderClick';
|
||||
import useUpdateUser from '@/hook/useUpdateUser';
|
||||
import { GuideProvider } from '@/store/guide-provider';
|
||||
import { GetServerSidePropsContext } from 'next';
|
||||
import { TradingProps } from '@/interfaces/props/pages/dex/trading/TradingProps';
|
||||
|
||||
function Trading() {
|
||||
function Trading({
|
||||
initialOrders,
|
||||
initialPair,
|
||||
initialStats,
|
||||
initialTrades,
|
||||
initialCandles,
|
||||
}: TradingProps) {
|
||||
const { alertState, alertSubtitle, setAlertState } = useAlert();
|
||||
const { elementRef: orderListRef, scrollToElement: scrollToOrdersList } =
|
||||
useScroll<HTMLDivElement>();
|
||||
const { elementRef: orderFormRef, scrollToElement: scrollToOrderForm } =
|
||||
useScroll<HTMLDivElement>();
|
||||
|
||||
const [pairData, setPairData] = useState<PairData | null>(initialPair);
|
||||
const [pairStats, setPairStats] = useState<PairStats | null>(initialStats);
|
||||
const [ordersHistory, setOrdersHistory] = useState<PageOrderData[]>(initialOrders);
|
||||
const [candles, setCandles] = useState<CandleRow[]>(initialCandles);
|
||||
const [trades, setTrades] = useState<Trade[]>(initialTrades);
|
||||
|
||||
const fetchUser = useUpdateUser();
|
||||
const [ordersHistory, setOrdersHistory] = useState<PageOrderData[]>([]);
|
||||
const [userOrders, setUserOrders] = useState<OrderRow[]>([]);
|
||||
const [periodsState, setPeriodsState] = useState<PeriodState>(periods[4]);
|
||||
const [pairData, setPairData] = useState<PairData | null>(null);
|
||||
const [candles, setCandles] = useState<CandleRow[]>([]);
|
||||
const [trades, setTrades] = useState<Trade[]>([]);
|
||||
const [myOrdersLoading, setMyOrdersLoading] = useState(true);
|
||||
const [ordersBuySell, setOrdersBuySell] = useState(buySellValues[0]);
|
||||
const [pairStats, setPairStats] = useState<PairStats | null>(null);
|
||||
const [applyTips, setApplyTips] = useState<ApplyTip[]>([]);
|
||||
const matrixAddresses = useMatrixAddresses(ordersHistory);
|
||||
const [orderFormType, setOrderFormType] = useState(buySellValues[1]);
|
||||
|
|
@ -243,4 +259,26 @@ function Trading() {
|
|||
);
|
||||
}
|
||||
|
||||
export async function getServerSideProps(ctx: GetServerSidePropsContext) {
|
||||
const pairId = ctx.params?.id as string;
|
||||
|
||||
const [pairRes, statsRes, ordersRes, tradesRes, candlesRes] = await Promise.all([
|
||||
getPair(pairId),
|
||||
getPairStats(pairId),
|
||||
getOrdersPage(pairId),
|
||||
getTrades(pairId),
|
||||
getCandles(pairId, '1h'),
|
||||
]);
|
||||
|
||||
return {
|
||||
props: {
|
||||
initialPair: pairRes.success ? pairRes.data : null,
|
||||
initialStats: statsRes.success ? statsRes.data : null,
|
||||
initialOrders: ordersRes.success ? ordersRes.data : [],
|
||||
initialTrades: tradesRes.success ? tradesRes.data : [],
|
||||
initialCandles: candlesRes.success ? candlesRes.data : [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default Trading;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ import { GetServerSideProps } from 'next';
|
|||
|
||||
import { findPairID } from '@/utils/methods';
|
||||
import styles from '@/styles/404.module.scss';
|
||||
|
||||
const API_URL = process.env.NEXT_PUBLIC_API_URL;
|
||||
import { API_URL } from '@/constants';
|
||||
|
||||
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||
const { first, second } = context.query;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
|
||||
@media screen and (max-width: 1024px) {
|
||||
.trading__top {
|
||||
|
||||
&_trades,
|
||||
&_form {
|
||||
max-width: 100%;
|
||||
|
|
@ -89,4 +90,4 @@
|
|||
.trading__top {
|
||||
height: 370px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ main {
|
|||
padding: 80px 100px;
|
||||
|
||||
&.with-separators {
|
||||
> * {
|
||||
>* {
|
||||
padding: 40px 0;
|
||||
border-bottom: 1px solid var(--delimiter-color);
|
||||
|
||||
|
|
@ -115,7 +115,7 @@ h6 {
|
|||
}
|
||||
|
||||
h1,
|
||||
h1 > * {
|
||||
h1>* {
|
||||
color: var(--font-main-color);
|
||||
font-size: 48px;
|
||||
}
|
||||
|
|
@ -174,8 +174,9 @@ svg {
|
|||
}
|
||||
|
||||
@media screen and (max-width: 700px) {
|
||||
|
||||
h1,
|
||||
h1 > * {
|
||||
h1>* {
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
|
@ -276,3 +277,17 @@ svg {
|
|||
background-color: #1f8feb !important;
|
||||
}
|
||||
}
|
||||
|
||||
#nprogress {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#nprogress .bar {
|
||||
background: #1f8feb;
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
}
|
||||
|
|
@ -24,6 +24,10 @@ import GetChatChunkRes from '@/interfaces/responses/chats/GetChatChunkRes';
|
|||
import axios from 'axios';
|
||||
import GetPairsPagesAmountRes from '@/interfaces/responses/dex/GetPairsPagesAmountRes';
|
||||
import { PairSortOption } from '@/interfaces/enum/pair';
|
||||
import { API_URL } from '@/constants';
|
||||
|
||||
const isServer = typeof window === 'undefined';
|
||||
const baseUrl = isServer ? API_URL : '';
|
||||
|
||||
export async function getUser(): Promise<ErrorRes | GetUserRes> {
|
||||
return axios
|
||||
|
|
@ -185,7 +189,7 @@ export async function getPairsPage(
|
|||
sortOption: PairSortOption,
|
||||
): Promise<ErrorRes | GetPairsPageRes> {
|
||||
return axios
|
||||
.post('/api/dex/get-pairs-page', {
|
||||
.post(`${baseUrl}/api/dex/get-pairs-page`, {
|
||||
page,
|
||||
searchText,
|
||||
whitelistedOnly,
|
||||
|
|
@ -208,7 +212,7 @@ export async function getPairsPagesAmount(
|
|||
|
||||
export async function getPair(id: string): Promise<ErrorRes | GetPairRes> {
|
||||
return axios
|
||||
.post('/api/dex/get-pair', {
|
||||
.post(`${baseUrl}/api/dex/get-pair`, {
|
||||
id,
|
||||
})
|
||||
.then((res) => res.data);
|
||||
|
|
@ -227,7 +231,7 @@ export async function createOrder(
|
|||
|
||||
export async function getOrdersPage(pairId: string): Promise<ErrorRes | GetOrdersPageRes> {
|
||||
return axios
|
||||
.post('/api/orders/get-page', {
|
||||
.post(`${baseUrl}/api/orders/get-page`, {
|
||||
pairId,
|
||||
})
|
||||
.then((res) => res.data);
|
||||
|
|
@ -273,7 +277,7 @@ export async function getCandles(
|
|||
period: Period,
|
||||
): Promise<ErrorRes | GetCandlesRes> {
|
||||
return axios
|
||||
.post('/api/orders/get-candles', {
|
||||
.post(`${baseUrl}/api/orders/get-candles`, {
|
||||
pairId,
|
||||
period,
|
||||
})
|
||||
|
|
@ -290,7 +294,7 @@ export async function getChartOrders(pairId: string): Promise<ErrorRes | GetChar
|
|||
|
||||
export async function getPairStats(pairId: string): Promise<ErrorRes | GetPairStatsRes> {
|
||||
return axios
|
||||
.post('/api/orders/get-pair-stats', {
|
||||
.post(`${baseUrl}/api/orders/get-pair-stats`, {
|
||||
pairId,
|
||||
})
|
||||
.then((res) => res.data);
|
||||
|
|
@ -331,7 +335,7 @@ export async function getChatChunk(
|
|||
|
||||
export async function getTrades(pairId: string) {
|
||||
return axios
|
||||
.post(`/api/orders/get-trades`, {
|
||||
.post(`${baseUrl}/api/orders/get-trades`, {
|
||||
pairId,
|
||||
})
|
||||
.then((res) => res.data);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { API_URL } from '@/constants';
|
||||
import { io } from 'socket.io-client';
|
||||
|
||||
const SOCKET_URL = process.env.NEXT_PUBLIC_API_URL as string;
|
||||
const SOCKET_URL = API_URL as string;
|
||||
|
||||
const socket = io(SOCKET_URL, {
|
||||
transports: ['websocket'],
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue