From 2728bf6a5cc01931fe98ca4c2e064354fddb3cb3 Mon Sep 17 00:00:00 2001 From: Benyamin Date: Wed, 13 Sep 2023 12:47:20 +0330 Subject: [PATCH 1/2] Add TransactionHistory --- package.json | 1 + public/assets/locales/en/translation.json | 74 +++++--- public/assets/locales/fa/translation.json | 38 +++-- src/index.js | 3 +- .../components/APIKeyCard/APIKeyCard.js | 2 - .../components/CreateAPIKey/CreateAPIKey.js | 25 ++- .../Content/components/Wallet/Wallet.js | 3 + .../components/Deposit/Deposit.js | 14 +- .../Deposit/components/Address/Address.js | 11 +- .../DepositWithdrawTx/DepositWithdrawTx.js | 3 - .../DepositWithdrawTxTables.js | 2 - .../DepositWithdrawTx.module.css | 87 ++++++++++ .../TransactionHistory/TransactionHistory.js | 159 ++++++++++++++++++ .../TransactionHistoryTable.js | 50 ++++++ src/queries/hooks/useTransactionHistory.js | 23 +++ yarn.lock | 31 ++++ 16 files changed, 444 insertions(+), 82 deletions(-) create mode 100644 src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/DepositWithdrawTx.module.css create mode 100644 src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/TransactionHistory.js create mode 100644 src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/components/TransactionHistoryTable/TransactionHistoryTable.js create mode 100644 src/queries/hooks/useTransactionHistory.js diff --git a/package.json b/package.json index b2bd7530..298f1393 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "react-dropzone": "^11.3.1", "react-hot-toast": "^2.4.1", "react-i18next": "^12.2.2", + "react-multi-date-picker": "^4.3.1", "react-number-format": "^4.9.3", "react-qr-code": "^2.0.11", "react-redux": "^8.0.5", diff --git a/public/assets/locales/en/translation.json b/public/assets/locales/en/translation.json index c4e776f1..71e3cee7 100644 --- a/public/assets/locales/en/translation.json +++ b/public/assets/locales/en/translation.json @@ -1,8 +1,8 @@ { "title": "OPEX", - "signIn":"Sign In", + "signIn": "Sign In", "signUp": "Sign Up", - "signOut":"Sign Out", + "signOut": "Sign Out", "date": "Date", "time": "Time", "volume": "Volume", @@ -15,11 +15,10 @@ "max": "Max", "buy": "Buy", "sell": "Sell", - "all": "All", "orderType": "Order Type", - "status" : "Status", - "pleaseLogin" : "Please Log In!", - "comingSoon" : "Coming Soon!", + "status": "Status", + "pleaseLogin": "Please Log In!", + "comingSoon": "Coming Soon!", "deposit": "Deposit", "withdrawal": "Withdrawal", "transfer": "Transfer", @@ -28,6 +27,12 @@ "commission": "Commission", "nextStep": "Next Step", "prevStep": "Prev Step", + "next": "next", + "all": "all", + "prev": "prev", + "ask": "ask", + "bid": "bid", + "to": "to", "submit": "Submit", "username": "Username", "password": "Password", @@ -48,17 +53,17 @@ "improperMobileView ": "Not optimized for mobile view.", "home": "Home", "country": { - "iran" : "I. R. IRAN", - "germany" : "Germany", + "iran": "I. R. IRAN", + "germany": "Germany", "uk": "United Kingdom", - "turkey" : "Turkey" + "turkey": "Turkey" }, "currency": { - "IRT" : "IRT", - "Euro" : "Euro", - "USD" : "USD", - "BTC" : "BTC", - "ETH" : "ETH", + "IRT": "IRT", + "Euro": "Euro", + "USD": "USD", + "BTC": "BTC", + "ETH": "ETH", "USDT": "USDT", "TBTC": "TBTC", "TETH": "TETH", @@ -119,8 +124,8 @@ "LIMIT_MAKER": "Limit Maker" }, "header": { - "lastPrice" : "Last Price", - "availableBalance" : "Available Balance", + "lastPrice": "Last Price", + "availableBalance": "Available Balance", "free": "Available", "locked": "Locked", "inWithdrawalProcess": "Pending Withdrawal", @@ -165,12 +170,12 @@ }, "TimeZone": { "THR": "Asia / Tehran / UTC+3:30", - "UTC" : "UTC" + "UTC": "UTC" }, "orders": { "title": "Order", - "minOrder": "Minimum allowed order is {{min}} {{currency}}", - "maxOrder": "Maximum allowed order is {{max}} {{currency}}", + "minOrder": "Minimum allowed order is {{min}} {{currency}}", + "maxOrder": "Maximum allowed order is {{max}} {{currency}}", "divisibility": "Divisibility !", "notEnoughBalance": "Insufficient Balance ", "availableAmount": "Available Amount", @@ -227,6 +232,20 @@ "showZeroBalance": "Do not show zero balance.", "estimateAlert": "The equivalent amount is calculated based on the highest buy offer" }, + "TransactionHistory": { + "coin": "Coins", + "category": "Categories", + "size": "Per page" + }, + "TransactionCategory": { + "DEPOSIT": "Deposit", + "FEE": "Fee", + "TRADE": "Trade", + "WITHDRAW": "Withdraw", + "ORDER_CANCEL": "Cancel Order", + "ORDER_CREATE": "Create Order", + "ORDER_FINALIZED": "Finalized Order" + }, "DepositWithdraw": { "title": "Deposit / Withdraw", "success": "The Address is copied.", @@ -266,7 +285,7 @@ }, "IPGErrorCode": { "13003": "You are not allowed to pay.", - "13004":"You have an unpaid request.", + "13004": "You have an unpaid request.", "13005": "Request locked.", "13007": "Unknown Error" }, @@ -598,9 +617,9 @@ }, "Footer": { "darkMode": "Dark Mode", - "aboutUs" : "About Us", - "contactUS" : "Contact Us", - "blog" : "Blog", + "aboutUs": "About Us", + "contactUS": "Contact Us", + "blog": "Blog", "guide": "Guide", "rules": "Rules", "api": "API", @@ -618,10 +637,10 @@ "tooManyFiles": "Uploading more than one photo is not allowed!", "errorMsgDefault": "Uploaded photo is not valid!" }, - "errorPage" : { - "needKYC" : "Access denied for KYC status", - "reload" : "Try Again", - "errorText" : "Server connection error" + "errorPage": { + "needKYC": "Access denied for KYC status", + "reload": "Try Again", + "errorText": "Server connection error" }, "aboutUs": { "title": "About US", @@ -663,7 +682,6 @@ "p8": "", "p9": "", "text4": "" - }, "transferFees": { "title": "Transfer Fees", diff --git a/public/assets/locales/fa/translation.json b/public/assets/locales/fa/translation.json index d6437674..f291d1e4 100644 --- a/public/assets/locales/fa/translation.json +++ b/public/assets/locales/fa/translation.json @@ -15,7 +15,6 @@ "max": "حداکثر", "buy": "خرید", "sell": "فروش", - "all": "همه", "orderType": "نوع سفارش", "status": "وضعیت", "pleaseLogin": "لطفاً وارد شوید!", @@ -28,6 +27,12 @@ "commission": "کارمزد", "nextStep": "گام بعدی", "prevStep": "گام قبلی", + "next": "بعدی", + "all": "همه موارد", + "prev": "قبلی", + "ask": "فروش", + "bid": "خرید", + "to": "تا", "submit": "ثبت", "username": "نام کاربری", "password": "رمز ورود", @@ -48,10 +53,10 @@ "improperMobileView ": "فعلاً برای موبایل بهینه نشده است.", "home": "صفحه اصلی", "country": { - "iran" : "جمهوری اسلامی ایران", - "germany" : "آلمان", + "iran": "جمهوری اسلامی ایران", + "germany": "آلمان", "uk": "انگلستان", - "turkey" : "ترکیه" + "turkey": "ترکیه" }, "currency": { "IRT": "تومان", @@ -165,7 +170,7 @@ }, "TimeZone": { "THR": "آسیا / تهران / UTC+3:30", - "UTC" : 0 + "UTC": 0 }, "orders": { "title": "سفارش", @@ -227,6 +232,20 @@ "showZeroBalance": "عدم نمایش موجودی صفر", "estimateAlert": "مبلغ دارایی معادل براساس بالاترین پیشنهاد خرید محاسبه شده" }, + "TransactionHistory": { + "coin" : "ارز", + "category" : "نوع تراکنش", + "size" : "تعداد" + }, + "TransactionCategory": { + "DEPOSIT" : "واریز", + "FEE" : "کارمزد", + "TRADE" : "معامله", + "WITHDRAW" : "برداشت", + "ORDER_CANCEL" : "لغو سفارش", + "ORDER_CREATE" : "ثبت سفارش", + "ORDER_FINALIZED" : "اتمام سفارش" + }, "DepositWithdraw": { "title": "واریز/برداشت", "success": "آدرس کپی شد", @@ -618,10 +637,10 @@ "tooManyFiles": "آپلود بیشتر از یک عکس مجاز نیست!", "errorMsgDefault": "عکس آپلود شده معتبر نیست!" }, - "errorPage" : { - "needKYC" : "دسترسی این بخش فقط برای کاربران احراز هویت شده مجاز است!", - "reload" : "تلاش مجدد", - "errorText" : "خطا در ارتباط با سرور" + "errorPage": { + "needKYC": "دسترسی این بخش فقط برای کاربران احراز هویت شده مجاز است!", + "reload": "تلاش مجدد", + "errorText": "خطا در ارتباط با سرور" }, "aboutUs": { "title": "درباره ما", @@ -663,7 +682,6 @@ "p8": "", "p9": "", "text4": "" - }, "transferFees": { "title": "کارمزد انتقال", diff --git a/src/index.js b/src/index.js index 992cd82f..bab32783 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,7 @@ import React from "react"; import {createRoot} from 'react-dom/client'; import "./i18n/i18n"; import {Provider} from "react-redux"; -import {createStore, applyMiddleware, combineReducers, compose} from "redux"; +import {applyMiddleware, combineReducers, compose, createStore} from "redux"; import createSagaMiddleware from "redux-saga"; import globalReducer from "./store/reducers/globalReducer"; import "normalize.css"; @@ -14,7 +14,6 @@ import Main from "./main/main"; import setupAxios from "./setup/axios/setupAxios"; import axios from "axios"; import exchangeReducer from "./store/reducers/exchangeReducer"; -import {StyleRoot} from "radium"; import {QueryClient, QueryClientProvider} from '@tanstack/react-query'; import {ReactQueryDevtools} from '@tanstack/react-query-devtools' import 'react-tooltip/dist/react-tooltip.css'; diff --git a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Settings/components/APIKey/components/APIKeyList/components/APIKeyCard/APIKeyCard.js b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Settings/components/APIKey/components/APIKeyList/components/APIKeyCard/APIKeyCard.js index 4b460603..1afa408b 100644 --- a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Settings/components/APIKey/components/APIKeyList/components/APIKeyCard/APIKeyCard.js +++ b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Settings/components/APIKey/components/APIKeyList/components/APIKeyCard/APIKeyCard.js @@ -92,8 +92,6 @@ const APIKeyCard = ({data}) => { } const copyToClipboard = (value, e) => { - - console.log("v" , value) e.preventDefault(); navigator.clipboard.writeText(value) toast.success(t('APIKey.copied')); diff --git a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Settings/components/APIKey/components/CreateAPIKey/CreateAPIKey.js b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Settings/components/APIKey/components/CreateAPIKey/CreateAPIKey.js index 094580de..ad94017a 100644 --- a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Settings/components/APIKey/components/CreateAPIKey/CreateAPIKey.js +++ b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Settings/components/APIKey/components/CreateAPIKey/CreateAPIKey.js @@ -1,6 +1,6 @@ import React, {useState} from 'react'; import classes from "./CreateAPIKey.module.css"; -import {Trans, useTranslation} from "react-i18next"; +import {useTranslation} from "react-i18next"; import TextInput from "../../../../../../../../../../../../components/TextInput/TextInput"; import {images} from "../../../../../../../../../../../../assets/images"; import Button from "../../../../../../../../../../../../components/Button/Button"; @@ -24,8 +24,6 @@ const CreateAPIKey = () => { expiration: {value: "", error: []}, }); - console.log("setApikeyResult", apiKeyResult) - const dates = [ {value: "ONE_MONTH", label: t('APIKey.ONE_MONTH')}, {value: "THREE_MONTHS", label: t('APIKey.THREE_MONTHS')}, @@ -38,13 +36,13 @@ const CreateAPIKey = () => { if (isLoading) return if (apiKey.label.value === "") { - return setApiKey({...apiKey, label : { ...apiKey.label, error: [t('APIKey.emptyLabel')]}}) + return setApiKey({...apiKey, label: {...apiKey.label, error: [t('APIKey.emptyLabel')]}}) } setIsLoading(true) const apiKeyData = { label: apiKey.label.value.length <= 0 ? null : apiKey.label.value, - expiration: apiKey.expiration.value.length <= 0 ? null : apiKey.expiration.value , + expiration: apiKey.expiration.value.length <= 0 ? null : apiKey.expiration.value, allowedIPs: apiKey.allowedIPs.value.length <= 0 ? null : apiKey.allowedIPs.value } createAPIKey(apiKeyData).then((res) => { @@ -56,14 +54,10 @@ const CreateAPIKey = () => { expiration: {value: "", error: []}, }) }).catch((error) => { - - console.log("e" , error.response.data.code) - if (error.response.data.code === 7007) { return toast.error(t('APIKey.reachedLimit')); } - - toast.error(t('error')); + toast.error(t('error')); }).finally(() => setIsLoading(false)) } @@ -73,7 +67,6 @@ const CreateAPIKey = () => { return t('submit') } - return ( <>
@@ -107,7 +100,10 @@ const CreateAPIKey = () => { options={dates} onchange={(e) => setApiKey({...apiKey, expiration: {value: e.value, error: []}})} alerts={apiKey.expiration.error} - value={apiKey.expiration.value && {value: apiKey.expiration.value , label: t('APIKey.'+apiKey.expiration.value)}} + value={apiKey.expiration.value && { + value: apiKey.expiration.value, + label: t('APIKey.' + apiKey.expiration.value) + }} />
@@ -118,7 +114,10 @@ const CreateAPIKey = () => { ltr={true} lead={t('APIKey.allowedIPs')} type="text" - onchange={(e) => setApiKey({...apiKey, allowedIPs: {value: e.target.value, error: []}})} + onchange={(e) => setApiKey({ + ...apiKey, + allowedIPs: {value: e.target.value, error: []} + })} alerts={apiKey.allowedIPs.error} /> diff --git a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/Wallet.js b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/Wallet.js index 224c779b..2f5e93ac 100644 --- a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/Wallet.js +++ b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/Wallet.js @@ -5,6 +5,7 @@ import classes from "./components/DepositWithdrawTx/DepositWithdrawTx.module.css import {useTranslation} from "react-i18next"; import {useParams} from "react-router-dom"; import IRTTx from "./components/DepositWithdrawTx/components/IRTTx/IRTTx"; +import TransactionHistory from "./components/TransactionHistory/TransactionHistory"; const Wallet = () => { @@ -15,6 +16,8 @@ const Wallet = () => {
+
+
diff --git a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdraw/components/Deposit/Deposit.js b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdraw/components/Deposit/Deposit.js index 9ed8ac85..696e850f 100644 --- a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdraw/components/Deposit/Deposit.js +++ b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdraw/components/Deposit/Deposit.js @@ -1,16 +1,12 @@ import React, {useEffect, useRef, useState} from "react"; import classes from "../../DepositWithdraw.module.css"; import TextInput from "../../../../../../../../../../../../components/TextInput/TextInput"; -import Icon from "../../../../../../../../../../../../components/Icon/Icon"; import {useParams} from "react-router-dom"; -import {Trans, useTranslation} from "react-i18next"; -import QRCode from "react-qr-code"; -import {toast} from "react-hot-toast"; +import {useTranslation} from "react-i18next"; import Error from "../../../../../../../../../../../../components/Error/Error"; import Loading from "../../../../../../../../../../../../components/Loading/Loading"; -import {useGetCurrencyInfo, useGetDepositAddress} from "../../../../../../../../../../../../queries"; +import {useGetCurrencyInfo} from "../../../../../../../../../../../../queries"; import IRTDeposit from "./components/IRT/IRTDeposit"; -import {BN} from "../../../../../../../../../../../../utils/utils"; import Address from "./components/Address/Address"; const Deposit = () => { @@ -28,8 +24,6 @@ const Deposit = () => { }, [id]); - - useEffect(() => { if (id !== "IRT") { refetchCI() @@ -41,8 +35,6 @@ const Deposit = () => { if (CILoading) return if (CIError) return - console.log("currencyInfo?.chains[networkName.value].network", currencyInfo?.chains[networkName?.value]?.network) - return (
{ { currencyInfo &&
} - -
) } diff --git a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdraw/components/Deposit/components/Address/Address.js b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdraw/components/Deposit/components/Address/Address.js index 32921443..3ec5b9e7 100644 --- a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdraw/components/Deposit/components/Address/Address.js +++ b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdraw/components/Deposit/components/Address/Address.js @@ -1,26 +1,17 @@ import React, {useEffect, useRef} from 'react'; -import className from '../../../../DepositWithdraw.module.css' +import classes from '../../../../DepositWithdraw.module.css' import {useParams} from "react-router-dom"; import {Trans, useTranslation} from "react-i18next"; import {toast} from "react-hot-toast"; import {useGetDepositAddress} from "../../../../../../../../../../../../../../queries"; -import Loading from "../../../../../../../../../../../../../../components/Loading/Loading"; -import Error from "../../../../../../../../../../../../../../components/Error/Error"; import Icon from "../../../../../../../../../../../../../../components/Icon/Icon"; -import classes from "../../../../DepositWithdraw.module.css"; import TextInput from "../../../../../../../../../../../../../../components/TextInput/TextInput"; import QRCode from "react-qr-code"; const Address = ({network}) => { - - console.log("network", network) - const {id} = useParams(); const {t} = useTranslation(); const addressRef = useRef(null); - - - const copyToClipboard = () => { addressRef.current.select(); document.execCommand("copy"); diff --git a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdrawTx/DepositWithdrawTx.js b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdrawTx/DepositWithdrawTx.js index 670ee5d6..08cc8753 100644 --- a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdrawTx/DepositWithdrawTx.js +++ b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdrawTx/DepositWithdrawTx.js @@ -15,9 +15,6 @@ const DepositWithdrawTx = () => { const {data: deposit, isLoading: depositIsLoading, error: depositError} = useDepositTxs(id); const {data: withdraw, isLoading: withdrawIsLoading, error: withdrawError} = useWithdrawTxs(id); - console.log("deposit", deposit) - console.log("withdraw", withdraw) - useLayoutEffect(() => { if (!deposit || !withdraw) { return diff --git a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdrawTx/components/DepositWithdrawTxTables/DepositWithdrawTxTables.js b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdrawTx/components/DepositWithdrawTxTables/DepositWithdrawTxTables.js index 3af6a511..d1544715 100644 --- a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdrawTx/components/DepositWithdrawTxTables/DepositWithdrawTxTables.js +++ b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/DepositWithdrawTx/components/DepositWithdrawTxTables/DepositWithdrawTxTables.js @@ -18,8 +18,6 @@ const DepositWithdrawTxTables = ({txs, id}) => { />); } - console.log("txs", txs.hasOwnProperty('withdrawOrderId')) - const txStatus = (status) => { switch (status) { case 0: diff --git a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/DepositWithdrawTx.module.css b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/DepositWithdrawTx.module.css new file mode 100644 index 00000000..236f2c15 --- /dev/null +++ b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/DepositWithdrawTx.module.css @@ -0,0 +1,87 @@ +.container { + height: 60vh; + border-radius: 9px; +} +.iconBG { + vertical-align: middle; + border-radius: 50vw; +} +.close { + max-height: 0; + overflow: hidden; + transition: max-height 0.3s; + opacity: 0; + line-height: 0; + visibility: collapse; +} +.open { + max-height: 2vh; + transition: max-height 0.6s; +} +.filterInput { + width: 100%; + margin-left: 0.5vw; +} +.filterInput :global(.after) { + width: 20%; +} +.address { + width: 200%; +} +.address :global(.lead) { + width: 25%; +} +.address :global(input) { + width: 75% !important; +} +.button { + width: 100%; + height: 4.5vh; + border: none; + border-radius: 7px; + font-size: 0.8vw; + color: #f2f2f2; + bottom: 0; + margin: 0 1vw; +} +.button.submit { + background-color: var(--darkGreen); +} +.button.reset { + background-color: var(--darkRed); +} +.button.return { + background-color: var(--orange); +} +.thisButton{ + padding: 1vh 2vw; + height: inherit !important; +} + +.thisButton.pay { + background-color: var(--darkGreen); +} +.thisButton.cancel { + background-color: var(--darkRed); +} + +.filterBox { + display: flex; + margin: 4vh 1vw; +} +.btnBox { + display: flex; + margin: 4vh 1vw; +} +.inputTitle { + padding: 0 1vw; + align-items: center; + display: flex; + height: 5vh; +} +.safariFlexSize :global(.accordion-header) { + flex: 22; +} +.safariFlexSize :global(.accordion-body) { + flex: 77; +} diff --git a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/TransactionHistory.js b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/TransactionHistory.js new file mode 100644 index 00000000..83427e7b --- /dev/null +++ b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/TransactionHistory.js @@ -0,0 +1,159 @@ +import React, {useState} from "react"; +import {useTranslation} from "react-i18next"; +import Loading from "../../../../../../../../../../components/Loading/Loading"; +import Error from "../../../../../../../../../../components/Error/Error"; +import {useTransactionHistory} from "../../../../../../../../../../queries/hooks/useTransactionHistory"; +import {useSelector} from "react-redux"; +import TransactionHistoryTable from "./components/TransactionHistoryTable/TransactionHistoryTable"; +import TextInput from "../../../../../../../../../../components/TextInput/TextInput"; +import classes from "../DepositWithdraw/DepositWithdraw.module.css"; +import Button from "../../../../../../../../../../components/Button/Button"; +import moment from "moment-jalaali"; +import DatePicker from "react-multi-date-picker"; +import persian from "react-date-object/calendars/persian" +import persian_fa from "react-date-object/locales/persian_fa" +import i18n from "../../../../../../../../../../i18n/i18n"; + +const TransactionHistory = () => { + const {t} = useTranslation(); + const user_id = useSelector((state) => state.auth.id) + const coins = useSelector((state) => state.exchange.assets) + const [query, setQuery] = useState({ + "coin": null, // optional + "category": null, // optional [DEPOSIT, FEE, TRADE, WITHDRAW, ORDER_CANCEL, ORDER_CREATE, ORDER_FINALIZED] + "startTime": moment().subtract(1, 'months').startOf("day").valueOf(), + "endTime": moment().endOf("day").valueOf(), + "limit": 10, + "offset": 0 + }); + + const {data, isLoading, error} = useTransactionHistory(user_id, query); + const pagination = { + page: (query.offset / query.limit) + 1, + isLastPage: data?.length < query.limit + } + + const categories = ['DEPOSIT', 'FEE', 'TRADE', 'WITHDRAW', 'ORDER_CANCEL', 'ORDER_CREATE', 'ORDER_FINALIZED']; + + const coinsOptions = [{value: null, label: t('all')}] + const categoryOptions = [{value: null, label: t('all')}] + const size = [10, 20, 30, 40, 50] + + categories.forEach((o) => { + categoryOptions.push({value: o, label: t('TransactionCategory.' + o)}) + }) + + coins.forEach((o) => { + coinsOptions.push({value: o, label: o}) + }) + + if (isLoading) return + if (error) return + + //if (data.length === 0) return
{t("noTx")}
+ const pageSizeHandler = (e) => { + setQuery({ + ...query, + limit: e.value, + offset: 0 + }) + } + + const nextPage = () => { + setQuery({ + ...query, + offset: query.offset + query.limit + }) + } + const prevPage = () => { + setQuery({ + ...query, + offset: query.offset - query.limit + }) + } + const startDateHandler = (dateRange) => { + if (dateRange.length === 2) { + setQuery({ + ...query, + startTime: moment.unix(dateRange[0].toUnix()).startOf("day").valueOf(), + endTime: moment.unix(dateRange[1].toUnix()).endOf("day").valueOf() + }) + } + } + + return <> +
+ setQuery({...query, coin: e.value})} + customClass={`width-64 ${classes.thisInput}`} + /> + setQuery({...query, category: e.value})} + customClass={`width-64 ${classes.thisInput}`} + /> + { + return {label: s, value: s} + })} + lead={t('TransactionHistory.size')} + type="select" + value={{ + value: query?.limit, + label: query?.limit, + }} + onchange={pageSizeHandler} + customClass={`width-64 ${classes.thisInput}`} + /> + + } + dateSeparator={" " + t('to') + " "} + range + /> + +
+
+ +
+ +}; + +export default TransactionHistory; \ No newline at end of file diff --git a/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/components/TransactionHistoryTable/TransactionHistoryTable.js b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/components/TransactionHistoryTable/TransactionHistoryTable.js new file mode 100644 index 00000000..080d6ff1 --- /dev/null +++ b/src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/components/TransactionHistoryTable/TransactionHistoryTable.js @@ -0,0 +1,50 @@ +import React, {Fragment, useState} from "react"; +import moment from "moment-jalaali"; +import {Trans, useTranslation} from "react-i18next"; +import {toast} from "react-hot-toast"; +import Date from "../../../../../../../../../../../../components/Date/Date"; + +const TransactionHistoryTable = ({txs}) => { + const [openItem, setOpenItem] = useState(false); + const {t} = useTranslation(); + + const copyAddressToClipboard = (value) => { + navigator.clipboard.writeText(value) + toast.success(); + } + + return + + + + + + + + + + + + {txs.map((tr, index) => ( + + + + + + + + + + + + ))} + +
{t("date")}{t("time")}{t("DepositWithdrawTx.transactionType")}{t("DepositWithdrawTx.network")}{t("volume")}{t("status")}{t("details")}
{moment(tr.date).format("HH:mm:ss")}{t('TransactionCategory.'+tr.category)}{tr.currency}{tr.amount}{tr?.additionalData?.ask && t('ask')} {tr?.additionalData?.bid && t('bid')}{tr?.additionalData?.remainedQuantity}
+} + +export default TransactionHistoryTable; \ No newline at end of file diff --git a/src/queries/hooks/useTransactionHistory.js b/src/queries/hooks/useTransactionHistory.js new file mode 100644 index 00000000..ca61f464 --- /dev/null +++ b/src/queries/hooks/useTransactionHistory.js @@ -0,0 +1,23 @@ +import {useQuery} from "@tanstack/react-query"; +import axios from "axios"; + +export const useTransactionHistory = (user_id, query) => { + + return useQuery( + ['allTxHistory', user_id, query.coin, query.category, query.endTime, query.startTime, query.limit, query.offset], + () => getWithdrawTxsFunc(user_id, query), + { + retry: 1, + staleTime: 5000, + refetchInterval: 10000, + }); +} + +const getWithdrawTxsFunc = async (user_id, query) => { + const {data} = await getTransactionHistory(user_id, query) + return data; +} + +const getTransactionHistory = (user_id, query) => { + return axios.post(`/wallet/transaction/${user_id}`, query) +} diff --git a/yarn.lock b/yarn.lock index a2d9f9f5..7fde28af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10751,6 +10751,7 @@ __metadata: react-dropzone: ^11.3.1 react-hot-toast: ^2.4.1 react-i18next: ^12.2.2 + react-multi-date-picker: ^4.3.1 react-number-format: ^4.9.3 react-qr-code: ^2.0.11 react-redux: ^8.0.5 @@ -12202,6 +12203,13 @@ __metadata: languageName: node linkType: hard +"react-date-object@npm:^2.1.5": + version: 2.1.7 + resolution: "react-date-object@npm:2.1.7" + checksum: f8e16484a16a56251697b52cb6c78c2aaa89ba33694c5f2032a967a68b70446cdb6ff9f4357e6e2a7ad50d48f1518f7b1b49ed7ca111542a8a32902c080a3c8a + languageName: node + linkType: hard + "react-dev-utils@npm:^12.0.1": version: 12.0.1 resolution: "react-dev-utils@npm:12.0.1" @@ -12271,6 +12279,16 @@ __metadata: languageName: node linkType: hard +"react-element-popper@npm:^2.1.6": + version: 2.1.6 + resolution: "react-element-popper@npm:2.1.6" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 0140c2f78ea5b4ef92d2711ca66d96513403ffab62063cd3bdfee662d5424ceaf50f08a74da3a5e370b3160b1e345d144afa834f90bea5e06fa23c1682660ac4 + languageName: node + linkType: hard + "react-error-overlay@npm:^6.0.11": version: 6.0.11 resolution: "react-error-overlay@npm:6.0.11" @@ -12329,6 +12347,19 @@ __metadata: languageName: node linkType: hard +"react-multi-date-picker@npm:^4.3.1": + version: 4.3.1 + resolution: "react-multi-date-picker@npm:4.3.1" + dependencies: + react-date-object: ^2.1.5 + react-element-popper: ^2.1.6 + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 1b8352c355dd68be256f503cf02ab1ac059b8479a1bccea1ddfe180e93a028421ad9989bccac58798b2cddf985828f53fe7535e44a395b4c31143886de2c14e0 + languageName: node + linkType: hard + "react-number-format@npm:^4.9.3": version: 4.9.3 resolution: "react-number-format@npm:4.9.3" From 2734ecf2c07635a309f419e8c052ba8d600dc36c Mon Sep 17 00:00:00 2001 From: Hossein Date: Mon, 25 Sep 2023 19:41:38 +0330 Subject: [PATCH 2/2] #171: Fix tx history --- public/assets/locales/en/translation.json | 24 +- public/assets/locales/fa/translation.json | 19 +- src/components/TextInput/TextInput.js | 50 ++++ src/components/TextInput/TextInput.module.css | 98 ++++++-- src/index.css | 9 +- .../UserPanel/Sections/Content/Content.js | 11 +- .../PersonalProfileStep.js | 1 + .../PersonalProfile/PersonalProfile.js | 1 + .../TechnicalChart/TechnicalChart.js | 38 +-- .../TransactionHistory/TransactionHistory.js | 226 ++++++++++++++++++ .../TransactionHistory.module.css | 31 +++ .../TransactionHistoryTable.js | 134 +++++++++++ .../TransactionHistoryTable.module.css | 6 + .../Content/components/Wallet/Wallet.js | 3 - .../DepositWithdrawTx.module.css | 87 ------- .../TransactionHistory/TransactionHistory.js | 159 ------------ .../TransactionHistoryTable.js | 50 ---- .../Pages/UserPanel/Sections/Header/Header.js | 5 +- .../UserPanel/Sections/MainMenu/MainMenu.js | 17 ++ src/main/Browser/Pages/UserPanel/UserPanel.js | 19 +- src/main/Browser/Routes/routes.js | 5 + 21 files changed, 611 insertions(+), 382 deletions(-) create mode 100644 src/main/Browser/Pages/UserPanel/Sections/Content/components/TransactionHistory/TransactionHistory.js create mode 100644 src/main/Browser/Pages/UserPanel/Sections/Content/components/TransactionHistory/TransactionHistory.module.css create mode 100644 src/main/Browser/Pages/UserPanel/Sections/Content/components/TransactionHistory/components/TransactionHistoryTable/TransactionHistoryTable.js create mode 100644 src/main/Browser/Pages/UserPanel/Sections/Content/components/TransactionHistory/components/TransactionHistoryTable/TransactionHistoryTable.module.css delete mode 100644 src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/DepositWithdrawTx.module.css delete mode 100644 src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/TransactionHistory.js delete mode 100644 src/main/Browser/Pages/UserPanel/Sections/Content/components/Wallet/components/TransactionHistory/components/TransactionHistoryTable/TransactionHistoryTable.js diff --git a/public/assets/locales/en/translation.json b/public/assets/locales/en/translation.json index 71e3cee7..3689d744 100644 --- a/public/assets/locales/en/translation.json +++ b/public/assets/locales/en/translation.json @@ -49,14 +49,21 @@ "noTx": "There is no transaction!", "close": "Close", "unit": "Unit", + "from": "from", + "row": "Row", + "until": "until", + "withPrice": "with price", + "description": "Description", + "first": "First", "offline": "Check your connection!", - "improperMobileView ": "Not optimized for mobile view.", + "improperMobileView": "Not optimized for mobile view.", "home": "Home", "country": { - "iran": "I. R. IRAN", + "iran": "IRAN", "germany": "Germany", "uk": "United Kingdom", - "turkey": "Turkey" + "turkey": "Turkey", + "uzbekistan": "Uzbekistan" }, "currency": { "IRT": "IRT", @@ -149,6 +156,9 @@ "technical": { "title": "Technical" }, + "txHistory": { + "title": "Transactions History" + }, "messages": { "title": "Messages" }, @@ -158,7 +168,8 @@ "Languages": { "Persian": "فارسی", "English": "English", - "Arabic": "عربي" + "Arabic": "عربي", + "Uzbek": "Oʻzbekcha" }, "Theme": { "Light": "Light", @@ -176,7 +187,7 @@ "title": "Order", "minOrder": "Minimum allowed order is {{min}} {{currency}}", "maxOrder": "Maximum allowed order is {{max}} {{currency}}", - "divisibility": "Divisibility !", + "divisibility": "The entered value must be divisible by {{mod}} !", "notEnoughBalance": "Insufficient Balance ", "availableAmount": "Available Amount", "bestOffer": "Best Offer", @@ -235,7 +246,8 @@ "TransactionHistory": { "coin": "Coins", "category": "Categories", - "size": "Per page" + "size": "Per page", + "period" : "Period" }, "TransactionCategory": { "DEPOSIT": "Deposit", diff --git a/public/assets/locales/fa/translation.json b/public/assets/locales/fa/translation.json index f291d1e4..e3d3997d 100644 --- a/public/assets/locales/fa/translation.json +++ b/public/assets/locales/fa/translation.json @@ -49,14 +49,21 @@ "noTx": "تراکنشی وجود ندارد.", "close": "بستن", "unit": "واحد", + "from": "از", + "row": "ردیف", + "until": "تا", + "withPrice": "با قیمت", + "description": "توضیحات", + "first": "ابتدا", "offline": "اتصال اینترنت را بررسی کنید!", - "improperMobileView ": "فعلاً برای موبایل بهینه نشده است.", + "improperMobileView": "فعلاً برای موبایل بهینه نشده است.", "home": "صفحه اصلی", "country": { - "iran": "جمهوری اسلامی ایران", + "iran": "ایران", "germany": "آلمان", "uk": "انگلستان", - "turkey": "ترکیه" + "turkey": "ترکیه", + "uzbekistan": "ازبکستان" }, "currency": { "IRT": "تومان", @@ -149,6 +156,9 @@ "technical": { "title": "تکنیکال" }, + "txHistory": { + "title": "تاریخچه تراکنش‌ ها" + }, "messages": { "title": "پیام ها" }, @@ -235,7 +245,8 @@ "TransactionHistory": { "coin" : "ارز", "category" : "نوع تراکنش", - "size" : "تعداد" + "size" : "تعداد", + "period" : "بازه زمانی" }, "TransactionCategory": { "DEPOSIT" : "واریز", diff --git a/src/components/TextInput/TextInput.js b/src/components/TextInput/TextInput.js index 85fb48b0..70133167 100644 --- a/src/components/TextInput/TextInput.js +++ b/src/components/TextInput/TextInput.js @@ -2,6 +2,12 @@ import React from "react"; import Icon from "../Icon/Icon"; import Select from "react-select"; import classes from "./TextInput.module.css"; +import i18n from "../../i18n/i18n"; +import persian_fa from "react-date-object/locales/persian_fa"; +import persian from "react-date-object/calendars/persian"; +import DatePicker from "react-multi-date-picker"; +import "react-multi-date-picker/styles/backgrounds/bg-dark.css" +import {useSelector} from "react-redux"; const TextInput = (props) => { const { @@ -17,9 +23,25 @@ const TextInput = (props) => { max, ltr, info, + datePicker, ...other } = props + const isDark = useSelector((state) => state.global.isDark) + + + const optionClassHandler = (state) => { + let className = classes.selectOptions + if (state.isFocused) { + className = className + " " + classes.isFocused + } + if (state.isSelected) { + className = className + " " + classes.isSelected + } + console.log("className", className) + return className; + } + let leadSection = null let afterSection = null let alertSection = null @@ -29,6 +51,7 @@ const TextInput = (props) => { readOnly={readOnly} onChange={onchange} max={max} + className={`${classes.input}`} style={{direction: ltr && 'ltr'}} {...other} /> @@ -37,8 +60,14 @@ const TextInput = (props) => { leadSection = {lead} } + if ( select ){ inputSection =