diff --git a/server/api/swagger/swagger.js b/server/api/swagger/swagger.js
index 7aa39ffc94..56e2d80bad 100644
--- a/server/api/swagger/swagger.js
+++ b/server/api/swagger/swagger.js
@@ -4,7 +4,7 @@ const definition = {
swagger: '2.0',
info: {
title: 'HollaEx Kit',
- version: '2.13.1'
+ version: '2.13.2'
},
host: 'api.hollaex.com',
basePath: '/v2',
diff --git a/server/package.json b/server/package.json
index c5280c0e23..838942ba4e 100644
--- a/server/package.json
+++ b/server/package.json
@@ -1,5 +1,5 @@
{
- "version": "2.13.1",
+ "version": "2.13.2",
"private": false,
"description": "HollaEx Kit",
"keywords": [
diff --git a/server/utils/hollaex-tools-lib/tools/order.js b/server/utils/hollaex-tools-lib/tools/order.js
index d1b481d22a..9ecf11167f 100644
--- a/server/utils/hollaex-tools-lib/tools/order.js
+++ b/server/utils/hollaex-tools-lib/tools/order.js
@@ -259,16 +259,6 @@ const getUserQuickTrade = async (spending_currency, spending_amount, receiving_a
if (spending_amount != null) responseObj.receiving_amount = priceValues.targetAmount;
else if (receiving_amount != null) responseObj.spending_amount = priceValues.sourceAmount;
- //Check if the estimated price is 50% greater than the last trade
- const lastTrades = await getPublicTrades(symbol);
- if (Array.isArray(lastTrades[symbol]) && lastTrades[symbol].length > 0) {
- const lastPrice = new BigNumber(lastTrades[symbol][0].price).multipliedBy(1.50).toNumber();
-
- if (priceValues.estimatedPrice > lastPrice) {
- throw new Error(QUICK_TRADE_ORDER_CURRENT_PRICE_ERROR);
- }
- }
-
let user_id = null;
if (bearerToken) {
const auth = await verifyBearerTokenPromise(bearerToken, ip);
diff --git a/server/utils/hollaex-tools-lib/tools/p2p.js b/server/utils/hollaex-tools-lib/tools/p2p.js
index 5074cda368..8470ef6eb6 100644
--- a/server/utils/hollaex-tools-lib/tools/p2p.js
+++ b/server/utils/hollaex-tools-lib/tools/p2p.js
@@ -571,7 +571,7 @@ const createP2PTransaction = async (data) => {
data.user_status = 'pending';
data.merchant_status = 'pending';
data.transaction_status = 'active';
- data.transaction_duration = 30;
+ data.transaction_duration = Number(p2pConfig?.transaction_duration || 30);
data.transaction_id = uuid();
data.merchant_id = side === 'buy' ? user_id : merchant_id;
data.user_id = side === 'buy' ? merchant_id : user_id;
diff --git a/server/utils/orderbook.js b/server/utils/orderbook.js
index 20c480787f..a6cae9f46b 100644
--- a/server/utils/orderbook.js
+++ b/server/utils/orderbook.js
@@ -1,7 +1,10 @@
'use strict';
-const { getOrderbook, getKitPairsConfig } = require('./hollaex-tools-lib/tools/common');
+const { getOrderbook, getOrderbooks, getKitPairsConfig } = require('./hollaex-tools-lib/tools/common');
const math = require('mathjs');
const BigNumber = require('bignumber.js');
+const { client } = require('./hollaex-tools-lib/tools/database/redis')
+
+
const sumQuantities = (orders) =>
orders.reduce((total, [, size]) => math.add(total, size), 0);
@@ -52,8 +55,15 @@ const estimatedQuickTradePriceSelector = ({ pairsOrders, pair, side, size, isFir
}
const setPriceEssentials = async (priceEssentials, opts) => {
- const pairsOrders = await getOrderbook(priceEssentials.pair, opts);
+ let pairsOrders = await client.getAsync(`orderbooks`);
+
+ if (!pairsOrders) {
+ pairsOrders = await getOrderbooks(opts);
+ await client.setexAsync(`orderbooks`, 30, JSON.stringify(pairsOrders));
+ } else {
+ pairsOrders = JSON.parse(pairsOrders);
+ };
const pair = priceEssentials.pair;
const side = priceEssentials.side;
const isSourceChanged = priceEssentials.isSourceChanged;
diff --git a/version b/version
index 94f15e9cc3..0e83a9a9c4 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-2.13.1
+2.13.2
diff --git a/web/package.json b/web/package.json
index e8d2546003..d01bb80bc1 100644
--- a/web/package.json
+++ b/web/package.json
@@ -1,6 +1,6 @@
{
"name": "hollaex-kit",
- "version": "2.13.1",
+ "version": "2.13.2",
"private": true,
"dependencies": {
"@ant-design/compatible": "1.0.5",
diff --git a/web/src/components/AppBar/AccountTab.js b/web/src/components/AppBar/AccountTab.js
index 44c1d6ca2d..956e2d2a14 100644
--- a/web/src/components/AppBar/AccountTab.js
+++ b/web/src/components/AppBar/AccountTab.js
@@ -13,6 +13,7 @@ import withConfig from 'components/ConfigProvider/withConfig';
import { Image, EditWrapper } from 'components';
import { isLoggedIn, removeToken } from 'utils/token';
import { setSecurityTab, setSettingsTab } from 'actions/appActions';
+import { renderConfirmSignout } from './Utils';
const AccountTab = ({
config_level,
@@ -105,6 +106,7 @@ const AccountList = ({
}) => {
const [isHelpResources, setIsHelpResources] = useState(false);
const [currPath, setCurrpath] = useState('/summary');
+ const [isLogout, setIsLogout] = useState(false);
useEffect(() => {
const getCurrPage = window.location.pathname;
@@ -186,7 +188,7 @@ const AccountList = ({
const onHandleRoutes = (value = '/', title = '') => {
const selectedTab = {
'LOGIN.HELP': () => setIsHelpResources(true),
- 'ACCOUNTS.TAB_SIGNOUT': () => removeToken(),
+ 'ACCOUNTS.TAB_SIGNOUT': () => setIsLogout(true),
'ACCOUNTS.TAB_SECURITY': () => setSecurityTab(0),
'MORE_OPTIONS_LABEL.ICONS.API': () => setSecurityTab(2),
'USER_SETTINGS.TITLE_LANGUAGE': () => setSettingsTab(2),
@@ -217,6 +219,16 @@ const AccountList = ({
? Icons[`LEVEL_ACCOUNT_ICON_${verification_level}`]
: Icons['LEVEL_ACCOUNT_ICON_4'];
+ const onHandlelogout = () => {
+ setIsLogout(false);
+ removeToken();
+ return browserHistory?.push('/login');
+ };
+
+ const onHandleclose = () => {
+ setIsLogout(false);
+ };
+
return (
{isHelpResources && renderHelpResource()}
@@ -238,6 +250,8 @@ const AccountList = ({
({user?.email})
+ {isLogout &&
+ renderConfirmSignout(isLogout, onHandleclose, onHandlelogout)}
{accountOptions?.map((options) => {
return (
options?.isDisplay && (
diff --git a/web/src/components/AppBar/DesktopSearch.js b/web/src/components/AppBar/DesktopSearch.js
new file mode 100644
index 0000000000..acc6d2c2e5
--- /dev/null
+++ b/web/src/components/AppBar/DesktopSearch.js
@@ -0,0 +1,23 @@
+import React from 'react';
+import STRINGS from 'config/localizedStrings';
+import EditWrapper from 'components/EditWrapper';
+import MobileBarMoreOptions from 'containers/App/MobileBarMoreOptions';
+
+const DesktopSearch = () => {
+ return (
+
+
+
+
+ {STRINGS['DESKTOP_ULTIMATE_SEARCH.SEARCH_DESCRIPTION']}
+
+
+
+
+
+
+
+ );
+};
+
+export default DesktopSearch;
diff --git a/web/src/components/AppBar/Utils.js b/web/src/components/AppBar/Utils.js
index 6e2328512c..0f14b8a20d 100644
--- a/web/src/components/AppBar/Utils.js
+++ b/web/src/components/AppBar/Utils.js
@@ -351,3 +351,37 @@ export const ReconnectPopup = ({ isDisplayPopup, onHandleClose }) => {
);
};
+
+export const renderConfirmSignout = (
+ isVisible,
+ onHandleclose,
+ onHandlelogout
+) => {
+ return (
+
+ );
+};
diff --git a/web/src/components/AppBar/_AppBar.scss b/web/src/components/AppBar/_AppBar.scss
index d92598bd2e..5305c08585 100644
--- a/web/src/components/AppBar/_AppBar.scss
+++ b/web/src/components/AppBar/_AppBar.scss
@@ -87,6 +87,12 @@ $app-menu-width: calc(100vw - 40rem);
}
}
}
+ .active-menu {
+ color: $base_top-bar-navigation_text;
+ border-top: 4px solid $link;
+ height: 100%;
+ opacity: 1;
+ }
}
.app_bar-quicktrade-container {
@@ -517,6 +523,11 @@ $app-menu-width: calc(100vw - 40rem);
cursor: pointer;
font-size: 11px;
}
+
+ .app-bar-search-icon {
+ padding: 2%;
+ font-size: 16px;
+ }
}
.capitalize {
text-transform: capitalize;
@@ -1530,3 +1541,171 @@ $app-menu-width: calc(100vw - 40rem);
}
}
}
+
+.dynamic-search-description {
+ font-size: 12px;
+}
+
+.desktop-search-wrapper {
+ .search-description-container {
+ margin: 3% 0;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ .search-description {
+ .edit-wrapper__container {
+ font-size: 24px;
+ }
+ }
+ .dynamic-search-container {
+ width: 100%;
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ .desktop-search-more-option {
+ width: 90%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ .search-field {
+ width: 90%;
+ margin-top: 2%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ .ant-input-affix-wrapper {
+ width: 80%;
+ height: 4rem;
+ background-color: transparent;
+ border: 1px solid $colors-notifications-blue;
+ }
+ .ant-input {
+ border: none;
+ color: $colors-main-black;
+ background-color: transparent;
+ padding: 3%;
+ }
+ .ant-input:hover {
+ border: none;
+ }
+ .ant-input-affix-wrapper:hover {
+ border: 2px solid $colors-notifications-blue;
+ box-shadow: none;
+ }
+ .ant-input-suffix {
+ svg {
+ font-size: 20px;
+ path {
+ fill: $colors-black;
+ }
+ }
+ }
+ .search-icon-container {
+ margin-left: 1%;
+ background-color: $colors-notifications-blue;
+ padding: 1.5%;
+ border-radius: 5px;
+ .search-icon {
+ font-size: 30px;
+ svg {
+ path {
+ fill: #ffffff;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .options-container {
+ margin: 3% 0;
+ width: 100%;
+ .popular-option-container {
+ .options-field {
+ width: 60% !important;
+ }
+ }
+ .other-option-container {
+ margin-top: 5%;
+ }
+
+ .hot-options-container {
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ .hot-function-title {
+ font-size: 16px;
+ }
+ .search-result {
+ font-family: 'Open Sans';
+ }
+ .options-field {
+ width: 90%;
+ margin-top: 3%;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: center;
+ gap: 2%;
+ .plugins-icon {
+ svg {
+ path {
+ fill: $colors-main-black;
+ }
+ }
+ }
+ .icon-field {
+ min-width: 14%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 2%;
+ .hot-icon {
+ position: relative;
+ bottom: 15px;
+ svg {
+ width: 1.2rem;
+ path {
+ fill: $colors-notification-pending !important;
+ }
+ }
+ }
+ .icon-logo {
+ width: 25px;
+ path {
+ fill: $colors-main-black;
+ }
+ }
+ }
+ .image-wrapper {
+ .icon-logo {
+ position: relative;
+ left: 10px;
+ }
+ .assets-icon {
+ position: relative;
+ bottom: 15px;
+ }
+ }
+ .icon-field:hover {
+ cursor: pointer;
+ background-color: $app-sidebar-background;
+ border-radius: 5px;
+ }
+ }
+ }
+ }
+ }
+ }
+ .crypto-link {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+ .blue-link:hover {
+ cursor: pointer;
+ }
+ }
+}
diff --git a/web/src/components/AppBar/index.js b/web/src/components/AppBar/index.js
index de71f3ea4e..7768f76659 100644
--- a/web/src/components/AppBar/index.js
+++ b/web/src/components/AppBar/index.js
@@ -4,6 +4,7 @@ import { bindActionCreators } from 'redux';
import classnames from 'classnames';
import { Link } from 'react-router';
import { isMobile } from 'react-device-detect';
+import { SearchOutlined } from '@ant-design/icons';
import { DEFAULT_URL } from 'config/constants';
import { MobileBarWrapper, EditWrapper, ButtonLink, Image } from 'components';
import { isLoggedIn } from 'utils/token';
@@ -238,8 +239,8 @@ class AppBar extends Component {
constants: { valid_languages } = {},
constants = {},
children,
- // activePath,
- // onMenuChange,
+ activePath,
+ onMenuChange,
// menuItems,
router,
isHome,
@@ -365,6 +366,16 @@ class AppBar extends Component {
verificationPending={verificationPending}
/>
+ onMenuChange('/details')}
+ >
+
+
)}
diff --git a/web/src/config/lang/en.json b/web/src/config/lang/en.json
index d1b992edc3..83029cc60e 100644
--- a/web/src/config/lang/en.json
+++ b/web/src/config/lang/en.json
@@ -2062,7 +2062,7 @@
"TRANSFER_DETAILS": "TRANSFER DETAILS",
"PAYMENT_INSTRUCTIONS": "Here's the selected payment method, transfer money to seller. After you've successfully transferred the money please click confirm below to notify the seller",
"PAYMENT_ACCOUNT": "Below is the payment account and method that is shared with the buyer.",
- "EXPECTED_TIME": "Expected time until funds are release: 30 minutes",
+ "EXPECTED_TIME": "Expected time until funds are release: {0} minutes",
"PAYMENT_TIME": "Please make the payment in the time provided above.",
"ORDER_CANCELLED": "The order will otherwise be cancelled",
"AUTO_RESPONSE_LIMIT": "Auto response text must be no longer than 240 characters",
@@ -2177,6 +2177,7 @@
"TERMS_CONDITIONS": "Terms and conditions",
"PAYMENT_TIME_LIMIT_LABEL": "Payment time limit: {0}",
"30_MINUTES": "30 Minutes",
+ "MINUTES_TEXT": "{0} minutes",
"AMOUNT_SEND_RELEASE": "(Amount of crypto you'll sell and release)",
"MINUTES": "minutes",
"EDIT_UPPERCASE": "EDIT",
@@ -2543,5 +2544,32 @@
"HELP_DESC": "Get help. Support contact",
"TRANSACTION_DESC": "Review all trades, deposits & withdrawals",
"ONRAMPER_DESC": "Use Onramper to buy and sell crypto"
+ },
+ "DESKTOP_ULTIMATE_SEARCH": {
+ "SEARCH_DESCRIPTION": "Find Functions, Coins, and More",
+ "SEARCH_PLACEHOILDER": "Input page name, functions, coins, features or other keyword",
+ "POPULAR_FUNCTION": "Popular functions",
+ "SEARCH_RESULT": "Search results ({0})",
+ "PROFIT_LOSS_INFO_TEXT": "Wallet profit and loss, Asset % breakdown",
+ "FEES_INFO_TEXT": "Trading fees for account level tiers",
+ "WITHDRAWAL_INFO_TEXT": "Withdrawal limits for account level tiers",
+ "WALLET_INFO_TEXT": "View all your assets and thier balances",
+ "P2P_INFO_TEXT": "Direct user peer-to-peer trading",
+ "ACCOUNT_INFO_TEXT": "Account trading volume information",
+ "ASSET_INFO_TEXT": "Asset price list",
+ "SECURITY_2FA_INFO_TEXT": "Otp two-factor authentication security",
+ "LOGIN_INFO_TEXT": "Historical record of all login on your account",
+ "SESSIONS_INFO_TEXT": "Check currently active logged in sessions",
+ "BANK_INFO_TEXT": "Your banking or payment information",
+ "AUDIO_INFO_TEXT": "Audio sound effects.Trading feedback",
+ "INTERFACE_INFO_TEXT": "User interface customizations, Color theme",
+ "NOTIFICATION_INFO_TEXT": "Alert and notification, pop ups etc.",
+ "CHAT_INFO_TEXT": "Chat settings",
+ "EMAIL_INFO_TEXT": "Email associated with your account",
+ "PHONE_INFO_TEXT": "Phone number associated with your account",
+ "CRYPTO_PRICES": "Looking for crypto prices?",
+ "PRICE_LINK": "Visit price link here.",
+ "BUY_TEXT": "BUY {0}",
+ "DEPOSIT_TEXT": "Deposit {0}"
}
}
diff --git a/web/src/containers/Admin/AdminFinancials/action.js b/web/src/containers/Admin/AdminFinancials/action.js
index 8ecf3d9440..cefe230945 100644
--- a/web/src/containers/Admin/AdminFinancials/action.js
+++ b/web/src/containers/Admin/AdminFinancials/action.js
@@ -185,3 +185,21 @@ export const deleteTransactionLimit = (values) => {
data: values,
});
};
+
+export const setAutoPaymentDetail = (values) => {
+ const options = {
+ method: 'POST',
+ body: JSON.stringify(values),
+ };
+
+ return requestDashAuthenticated('/dash/user/auto-payment', options);
+};
+
+export const removeAutoPayment = (values) => {
+ const options = {
+ method: 'DELETE',
+ body: JSON.stringify(values),
+ };
+
+ return requestDashAuthenticated('/dash/user/auto-payment', options);
+};
diff --git a/web/src/containers/Admin/Billing/Billing.scss b/web/src/containers/Admin/Billing/Billing.scss
index 39bb260e26..0ac70f6907 100644
--- a/web/src/containers/Admin/Billing/Billing.scss
+++ b/web/src/containers/Admin/Billing/Billing.scss
@@ -190,9 +190,34 @@
padding: 0rem 3rem 0rem 2.5rem !important;
}
+ .billing-button-container {
+ justify-content: space-between !important;
+ align-items: center;
+ padding: 0 3%;
+ .button-wrapper {
+ min-width: 65%;
+ display: flex;
+ align-items: center;
+ justify-content: flex-start;
+ gap: 4%;
+ .custom-line {
+ width: 2px;
+ height: 20px;
+ background-color: #ffffff;
+ }
+ .check-icon {
+ svg {
+ path {
+ fill: var(--specials_checks-okay-done);
+ }
+ }
+ }
+ }
+ }
+
.button-container {
display: flex;
- justify-content: flex-end;
+ // justify-content: flex-end;
background-color: #040e6d;
border-bottom-left-radius: 1rem;
border-bottom-right-radius: 1rem;
@@ -201,7 +226,8 @@
color: #ffffff;
text-decoration: underline;
cursor: pointer;
- margin: 1rem 16rem 0rem 0rem;
+ // margin: 1rem 16rem 0rem 0rem;
+ width: max-content;
}
.paid-btn {
@@ -1132,3 +1158,177 @@
cursor: not-allowed;
}
}
+
+.auto-payment-billing-popup-wrapper {
+ .ant-modal-body {
+ background-color: #27339d;
+ color: #ffffff;
+ font-size: 12px;
+ .auto-payment-billing-popup-container {
+ .title {
+ font-size: 20px !important;
+ }
+
+ .payment-description {
+ margin-top: 2%;
+ }
+
+ .account-details {
+ margin-top: 3%;
+ display: flex;
+ flex-direction: column;
+ .payment-email-input-wrapper {
+ .payment-email-address {
+ width: 60%;
+ font-size: 12px;
+ }
+ .edit-btn:hover {
+ cursor: pointer;
+ }
+ }
+ }
+ .asset-wrapper {
+ display: flex;
+ gap: 2%;
+ align-items: center;
+ .asset-icon {
+ width: 32px;
+ height: 32px;
+ border-radius: 25px;
+ font-size: 10px;
+ color: #cccccc;
+ background-color: #178700;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ }
+ .error-field {
+ color: #ffff00;
+ padding: 2% 0;
+ display: flex;
+ gap: 1%;
+ align-items: center;
+ font-weight: bold;
+ margin-left: 8%;
+ }
+ .warning-description {
+ width: 85%;
+ margin-top: 2%;
+ background-color: var(--admin_panel_content_background);
+ padding: 2%;
+ display: flex;
+ align-items: center;
+ .message {
+ font-size: 10px;
+ }
+ .warning-icon {
+ svg {
+ width: 2rem;
+ height: 1.5rem;
+ path {
+ fill: #ffffff;
+ }
+ }
+ }
+ }
+ .auto-payment-popup-button-wrapper {
+ margin-top: 5%;
+ display: flex;
+ gap: 5%;
+ .green-btn {
+ width: 50%;
+ background-color: #288500 !important;
+ color: #ffffff !important;
+ border: none;
+ }
+ .inactive-btn {
+ opacity: 0.5;
+ }
+ }
+ }
+ }
+ .ant-modal-close {
+ color: #ffffff;
+ }
+}
+
+.confirm-payment-billing-popup-wrapper {
+ top: 5%;
+ .confirm-payment-billing-popup-container {
+ .details-description {
+ color: #cccccc;
+ }
+ .cloud-card {
+ font-size: 14px;
+ padding: 2% 0 4% 0;
+ border-bottom: 2px solid #a8a8b1;
+ .card-wrapper {
+ margin-top: 2%;
+ background-size: contain;
+ background-position: right;
+ background-repeat: no-repeat;
+ padding: 5% 0;
+ background-color: var(--admin_panel_content_background);
+ border-radius: 5px;
+ .diy-background,
+ .cloud-background {
+ padding: 0 0 0 2%;
+ width: 18%;
+ }
+ .cloud-card-details {
+ align-items: center;
+ gap: 3%;
+ .cloud-type,
+ .white-text,
+ .basic-plan {
+ margin-bottom: unset !important;
+ font-size: 13px !important;
+ }
+ .white-text,
+ .cloud-type {
+ font-weight: bold;
+ }
+ .cloud-type {
+ margin-left: 3%;
+ }
+ .cloud-type,
+ .basic-plan {
+ color: #a8a8b1 !important;
+ }
+ }
+ }
+ }
+ .fund-source-details,
+ .payment-interval,
+ .next-payment-date,
+ .payment-amount {
+ padding: 1% 0;
+ .payment-title {
+ font-size: 14px !important;
+ }
+ .description-text {
+ font-size: 12px;
+ color: #cccccc;
+ }
+ }
+ }
+}
+
+.edit-payment-billing-popup-wrapper {
+ .edit-payment-popup-container {
+ .input-field {
+ display: flex;
+ align-items: flex-start;
+ gap: 2%;
+ .ant-input {
+ width: 3%;
+ position: relative;
+ top: 2px;
+ }
+ }
+ .auto-payment-popup-button-wrapper {
+ margin-top: 20% !important;
+ }
+ }
+}
diff --git a/web/src/containers/Admin/Billing/generalContent.js b/web/src/containers/Admin/Billing/generalContent.js
index 8b162b88a8..691caf1adc 100644
--- a/web/src/containers/Admin/Billing/generalContent.js
+++ b/web/src/containers/Admin/Billing/generalContent.js
@@ -1,4 +1,4 @@
-import React, { Fragment, useEffect, useState } from 'react';
+import React, { Fragment, useEffect, useRef, useState } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import { ReactSVG } from 'react-svg';
@@ -25,6 +25,7 @@ import {
CopyOutlined,
CheckCircleFilled,
ExclamationCircleFilled,
+ ExclamationCircleOutlined,
} from '@ant-design/icons';
import isEmpty from 'lodash.isempty';
@@ -70,6 +71,12 @@ import {
pendingPayOption,
} from './utils';
import './Billing.scss';
+import { getFormattedDate } from 'utils/string';
+import {
+ removeAutoPayment,
+ setAutoPaymentDetail,
+} from '../AdminFinancials/action';
+import { requestUsers } from '../Trades/actions';
const { Option } = Select;
const TabPane = Tabs.TabPane;
@@ -105,13 +112,12 @@ const GeneralContent = ({
const balance = user?.balance;
const dashToken = localStorage.getItem(DASH_TOKEN_KEY);
const isPluginDataAvail = !isEmpty(pluginData);
+ const month = dashExchange.period !== 'year';
const [modalWidth, setModalWidth] = useState('85rem');
const [OpenPlanModal, setOpenPlanModal] = useState(isPluginDataAvail);
const [isLoading, setIsLoading] = useState(false);
- const [isMonthly, setIsMonthly] = useState(
- dashExchange.period !== 'year' ? true : false
- );
+ const [isMonthly, setIsMonthly] = useState(month);
const [invoiceData, setinvoiceData] = useState([]);
const [currentInvoice, setCurrentInvoice] = useState({});
const [activateInvoiceData, setActivateInvoiceData] = useState({});
@@ -127,6 +133,18 @@ const GeneralContent = ({
const [selectedPendingItem, setSelectedPendingItem] = useState({});
const [cryptoPayType, setCryptoPay] = useState('');
const [activeKey, setActiveKey] = useState('1');
+ const [isAutoPayment, setIsAutoPayment] = useState(false);
+ const [isConfirmAutoPayment, setIsConfirmAutoPayment] = useState(false);
+ const [isEditAutoPayment, setIsEditAutoPayment] = useState(false);
+ const [isEditDetail, setIsEditDetail] = useState(true);
+ const [isRemovePayment, setIsRemovePayment] = useState(false);
+ const [isConfirmRemovePayment, setIsConfirmRemovePayment] = useState(false);
+ const [userData, setUserData] = useState([]);
+ const [selectedEmailData, setSelectedEmailData] = useState(
+ userData[0]?.email || ''
+ );
+
+ const selectRef = useRef(null);
const planPriceData = priceData[selectedType];
@@ -207,6 +225,30 @@ const GeneralContent = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedType]);
+ const getAllUserData = async (params = {}, emailChange = false) => {
+ try {
+ const res = await requestUsers(params);
+ if (res && res.data) {
+ const userData = res.data.map((user) => ({
+ label: user.email,
+ value: user.id,
+ }));
+ setSelectedEmailData(userData);
+ setUserData(res.data);
+ }
+ } catch (error) {
+ console.error('error', error);
+ }
+ };
+
+ const searchUser = (searchText) => {
+ getAllUserData({ search: searchText });
+ };
+
+ const searchUserById = (userId) => {
+ getAllUserData({ id: userId });
+ };
+
const getExplorePlugin = async () => {
try {
const res = await requestPlugins();
@@ -598,6 +640,81 @@ const GeneralContent = ({
setHideBreadcrumb(false);
};
+ const renderCardDetails = () => {
+ return (
+
+
+
+
+
+
+
+ {exchangeCardKey !== 'diy' && (
+
Cloud:
+ )}
+
+ {selectedType === 'diy'
+ ? 'Do-It-Yourself'
+ : selectedType === 'fiat'
+ ? 'Enterprise'
+ : selectedType}
+
+
+
+
+ {selectedPlanData[selectedType]?.description}
+
+
+
+
+ );
+ };
+
+ const onHandleAutoPayment = () => {
+ if (dashExchange?.auto_payment_id) {
+ setIsEditAutoPayment(true);
+ } else {
+ setIsAutoPayment(true);
+ }
+ searchUserById(1);
+ };
+
const renderCard = () => {
const isPaid =
dashExchange.is_paid && moment().isBefore(moment(dashExchange.expiry));
@@ -611,74 +728,34 @@ const GeneralContent = ({
) : (
<>
+ {renderCardDetails()}
-
-
-
-
-
-
- {exchangeCardKey !== 'diy' && (
-
Cloud:
- )}
-
- {selectedType === 'diy'
- ? 'Do-It-Yourself'
- : selectedType === 'fiat'
- ? 'Enterprise'
- : selectedType}
-
+
+
+ {isPaid && (
+
+ View last bill
-
-
- {selectedPlanData[selectedType]?.description}
-
+ )}
+
+ {dashExchange?.auto_payment_id ? (
+ onHandleAutoPayment()}>
+ {' '}
+ Auto Payment Set
+
+ ) : (
+ onHandleAutoPayment()}
+ >
+ Auto Payment Bill
+
+ )}
-
-
-
-
- {isPaid && (
-
- View last bill
-
- )}
{displayP2pModel && (
@@ -494,6 +510,28 @@ const P2PSettings = ({ coins, pairs, p2p_config, features, constants }) => {
);
})}
+
+
+ Transaction Duration
+
+
+ Select the max duration for transaction expiration(in minutes)
+
+
)}
@@ -901,6 +939,32 @@ const P2PSettings = ({ coins, pairs, p2p_config, features, constants }) => {
+
+
+
+
Duration for transaction expiration
+
{transactionDuration} Minutes
+
+
{
+ setStep(0);
+ }}
+ style={{ cursor: 'pointer' }}
+ >
+ EDIT
+
+
+
+
{
merchant_fee: merchantFee,
user_fee: userFee,
source_account: sourceAccount,
+ transaction_duration: transactionDuration,
},
},
});
@@ -1163,6 +1228,9 @@ const P2PSettings = ({ coins, pairs, p2p_config, features, constants }) => {
setSelectedPaymentMethods(result?.bank_payment_methods);
setMerchantFee(result?.merchant_fee);
setUserFee(result?.user_fee);
+ setTransactionDuration(
+ result?.transaction_duration || 30
+ );
setSourceAccount(result?.source_account);
setP2pConfig(result);
});
diff --git a/web/src/containers/Admin/User/AboutData.js b/web/src/containers/Admin/User/AboutData.js
index 8c51428e1e..35c8e810c0 100644
--- a/web/src/containers/Admin/User/AboutData.js
+++ b/web/src/containers/Admin/User/AboutData.js
@@ -634,7 +634,7 @@ const AboutData = ({
return (
-
+
{userData.activated ? (
diff --git a/web/src/containers/Admin/User/UserContent.js b/web/src/containers/Admin/User/UserContent.js
index 93b305922f..c50a779fac 100644
--- a/web/src/containers/Admin/User/UserContent.js
+++ b/web/src/containers/Admin/User/UserContent.js
@@ -230,13 +230,13 @@ class UserContent extends Component {
deleteUser(postValues)
.then((res) => {
refreshData({ ...postValues, activated: false });
- this.setState({ showDeleteModal: false });
})
.catch((err) => {
const _error =
err.data && err.data.message ? err.data.message : err.message;
message.error(_error);
});
+ this.setState({ showDeleteModal: false });
};
openVerifyEmailModal = () => {
@@ -505,7 +505,7 @@ class UserContent extends Component {
/>
this.setState({ showRecoverModal: false })}
+ onCancel={() => this.setState({ showDeleteModal: false })}
onConfirm={this.handleDeleteUser}
userData={userInformation}
/>
diff --git a/web/src/containers/App/App.js b/web/src/containers/App/App.js
index d0ee8c3f4e..b9b3905444 100644
--- a/web/src/containers/App/App.js
+++ b/web/src/containers/App/App.js
@@ -72,6 +72,7 @@ import GetSocketState from './GetSocketState';
import withEdit from 'components/EditProvider/withEdit';
import withConfig from 'components/ConfigProvider/withConfig';
import { ETHEREUM_EVENTS } from 'actions/stakingActions';
+import { renderConfirmSignout } from 'components/AppBar/Utils';
class App extends Component {
state = {
@@ -91,6 +92,7 @@ class App extends Component {
isTradeTab: false,
isProTrade: false,
isQuickTrade: false,
+ isLogout: false,
};
ordersQueued = [];
limitTimeOut = null;
@@ -319,7 +321,7 @@ class App extends Component {
switch (path) {
case 'logout':
- this.logout();
+ this.setState({ isLogout: true });
break;
case 'help':
this.props.openHelpfulResourcesForm();
@@ -677,6 +679,15 @@ class App extends Component {
browserHistory.push(path);
};
+ onHandleClose = () => {
+ this.setState({ isLogout: false });
+ };
+
+ onHandleLogout = () => {
+ this.onHandleClose();
+ this.logout();
+ };
+
render() {
const {
symbol,
@@ -887,6 +898,12 @@ class App extends Component {
)} */}
+ {this.state.isLogout &&
+ renderConfirmSignout(
+ this.state.isLogout,
+ this.onHandleClose,
+ this.onHandleLogout
+ )}