-
+
{
return type === 'individual' ? (
@@ -288,7 +300,15 @@ const LimitsBlock = ({
- {getRows(coins, level, tiers, icons, transaction_limits, type)}
+ {getRows(
+ coins,
+ level,
+ tiers,
+ icons,
+ transaction_limits,
+ type,
+ search
+ )}
diff --git a/web/src/containers/FeesAndLimits/TradingFees.js b/web/src/containers/FeesAndLimits/TradingFees.js
index 119b38b6b8..1e09851c15 100644
--- a/web/src/containers/FeesAndLimits/TradingFees.js
+++ b/web/src/containers/FeesAndLimits/TradingFees.js
@@ -97,6 +97,7 @@ const TradingFees = ({
}
textType="title bold text-align-left"
iconPath={ICONS['FEES_AND_LIMITS_TRADING_FEES']}
+ className="fees-limits-title"
/>
diff --git a/web/src/containers/FeesAndLimits/WithdrawalFees.js b/web/src/containers/FeesAndLimits/WithdrawalFees.js
index cf4a84e364..b6ea4b7fad 100644
--- a/web/src/containers/FeesAndLimits/WithdrawalFees.js
+++ b/web/src/containers/FeesAndLimits/WithdrawalFees.js
@@ -19,6 +19,8 @@ const WithdrawalFees = ({
icons: ICONS,
search,
setSearch,
+ coin_customizations,
+ fiat_fees,
}) => {
const accountData = config_level[selectedLevel] || {};
const description =
@@ -99,6 +101,7 @@ const WithdrawalFees = ({
}
textType="title bold text-align-left"
iconPath={ICONS['FEES_AND_LIMITS_WITHDRAWAL_FEES']}
+ className="fees-limits-title"
/>
@@ -131,6 +134,8 @@ const WithdrawalFees = ({
coins={coins}
level={selectedLevel}
search={search}
+ coin_customizations={coin_customizations}
+ fiat_fees={fiat_fees}
/>
@@ -145,6 +150,8 @@ const mapStateToProps = (state) => {
coins: state.app.coins,
pairs: state.app.pairs,
config_level: state.app.config_level,
+ coin_customizations: state.app.constants.coin_customizations,
+ fiat_fees: state.app.constants.fiat_fees,
options: Object.entries(state.app.config_level).map(([key, { name }]) => ({
value: key,
label: name,
diff --git a/web/src/containers/FeesAndLimits/WithdrawalLimits.js b/web/src/containers/FeesAndLimits/WithdrawalLimits.js
index de5e75e9ca..9adaaab55f 100644
--- a/web/src/containers/FeesAndLimits/WithdrawalLimits.js
+++ b/web/src/containers/FeesAndLimits/WithdrawalLimits.js
@@ -1,6 +1,7 @@
import React from 'react';
import { connect } from 'react-redux';
-import { Select } from 'antd';
+import { Select, Input } from 'antd';
+import { SearchOutlined } from '@ant-design/icons';
import classnames from 'classnames';
import { isMobile } from 'react-device-detect';
import { Image, IconTitle, EditWrapper } from 'components';
@@ -17,6 +18,8 @@ const WithdrawalLimits = ({
setSelectedLevel,
options,
icons: ICONS,
+ search,
+ setSearch,
}) => {
const accountData = config_level[selectedLevel] || {};
const description =
@@ -87,16 +90,35 @@ const WithdrawalLimits = ({
}
textType="title bold text-align-left"
iconPath={ICONS['FEES_AND_LIMITS_WITHDRAWAL_LIMITS']}
+ className="fees-limits-title"
/>
-
+
+
+
+
+ {
+ STRINGS[
+ 'FEES_AND_LIMITS.TABS.WITHDRAWAL_LIMITS.TABLE_2.SUBTITLE'
+ ]
+ }
+
+
+
-
- {
- STRINGS[
- 'FEES_AND_LIMITS.TABS.WITHDRAWAL_LIMITS.TABLE_2.SUBTITLE'
- ]
+ }
+ placeholder={
+ STRINGS['FEES_AND_LIMITS.SEARCH_PLACEHOLDER']
}
-
+ value={search}
+ onChange={({ target: { value } }) => setSearch(value)}
+ style={{
+ width: 200,
+ }}
+ bordered={false}
+ className="kit-divider"
+ />
@@ -107,6 +129,7 @@ const WithdrawalLimits = ({
tiers={config_level}
transaction_limits={transaction_limits}
type={'individual'}
+ search={search}
/>
@@ -120,6 +143,7 @@ const WithdrawalLimits = ({
}
textType="title bold text-align-left"
iconPath={ICONS['FEES_AND_LIMITS_WITHDRAWAL_LIMITS']}
+ className="fees-limits-title"
/>
diff --git a/web/src/containers/FeesAndLimits/index.js b/web/src/containers/FeesAndLimits/index.js
index 497b778d90..16d5b003fe 100644
--- a/web/src/containers/FeesAndLimits/index.js
+++ b/web/src/containers/FeesAndLimits/index.js
@@ -19,7 +19,12 @@ import WithdrawalFees from './WithdrawalFees';
import WithdrawalLimits from './WithdrawalLimits';
import { isLoggedIn } from 'utils/token';
-const Index = ({ config_level, verification_level, router }) => {
+const Index = ({
+ config_level,
+ verification_level,
+ router,
+ selectedAccount,
+}) => {
const [selectedLevel, setSelectedLevel] = useState(
isLoggedIn() ? verification_level?.toString() : Object.keys(config_level)[0]
);
@@ -82,6 +87,10 @@ const Index = ({ config_level, verification_level, router }) => {
updateTabs();
}, [selectedLevel, config_level, search]);
+ useEffect(() => {
+ setSelectedLevel(selectedAccount);
+ }, [selectedAccount]);
+
const renderContent = (tabs, activeTab) =>
tabs[activeTab] && tabs[activeTab].content ? (
tabs[activeTab].content
@@ -89,7 +98,7 @@ const Index = ({ config_level, verification_level, router }) => {
);
- return config_level && Object.keys(config_level).length && selectedLevel ? (
+ return config_level && Object.keys(config_level).length ? (
{!isMobile && (
{
const mapStateToProps = (state) => {
const {
- app: { config_level },
+ app: { config_level, selectedAccount },
} = state;
return {
verification_level: state.user.verification_level,
config_level,
+ selectedAccount,
};
};
diff --git a/web/src/containers/Home/index.js b/web/src/containers/Home/index.js
index d888ec0742..f72795df4f 100644
--- a/web/src/containers/Home/index.js
+++ b/web/src/containers/Home/index.js
@@ -175,8 +175,6 @@ class Home extends Component {
const {
constants: { features: { quick_trade = false } = {} } = {},
isReady,
- pair,
- // sections,
} = this.props;
const sectionsNumber = Object.entries(this.state.sectionData)
@@ -191,7 +189,7 @@ class Home extends Component {
minHeight: this.calculateMinHeight(sectionsNumber),
}}
onClickDemo={
- pair ? this.goTo(`trade/${pair}`) : this.goTo('markets')
+ this.goTo('accounts')
}
onClickTrade={this.goTo('signup')}
/>
diff --git a/web/src/containers/Init/Login.js b/web/src/containers/Init/Login.js
index ae674e4005..0701b9053e 100644
--- a/web/src/containers/Init/Login.js
+++ b/web/src/containers/Init/Login.js
@@ -13,7 +13,6 @@ import {
email,
} from '../../components/AdminForm/validations';
import { STATIC_ICONS } from 'config/icons';
-import { getLanguage } from '../../utils/string';
import { getExchangeInitialized } from '../../utils/initialize';
import { isAdmin } from '../../utils/token';
@@ -54,9 +53,6 @@ const Login = (props) => {
} else {
errMsg = error.message;
}
- setTimeout(() => {
- props.change('LOGIN_FORM', 'captcha', '');
- }, 5000);
message.error(errMsg);
});
}
@@ -98,12 +94,6 @@ const Login = (props) => {
maxLength: "6",
onInput: maxLengthCheck
},
- captcha: {
- type: 'captcha',
- language: getLanguage(),
- theme: props.theme,
- validate: [validateRequired],
- },
}}
onSubmit={handleSubmit}
buttonText={'Proceed'}
diff --git a/web/src/containers/Login/LoginForm.js b/web/src/containers/Login/LoginForm.js
index da9d91c5fe..52cb4842ad 100644
--- a/web/src/containers/Login/LoginForm.js
+++ b/web/src/containers/Login/LoginForm.js
@@ -7,7 +7,6 @@ import {
normalizeEmail,
} from 'components/Form/validations';
import { AuthForm } from 'components';
-import { getLanguage } from 'utils/string';
import STRINGS from 'config/localizedStrings';
export const FORM_NAME = 'LoginForm';
@@ -28,13 +27,7 @@ const Form = (props) => {
fullWidth: true,
label: STRINGS['FORM_FIELDS.PASSWORD_LABEL'],
placeholder: STRINGS['FORM_FIELDS.PASSWORD_PLACEHOLDER'],
- },
- captcha: {
- type: 'captcha',
- language: getLanguage(),
- theme: props.theme,
- validate: [required],
- },
+ }
};
return (
diff --git a/web/src/containers/Login/index.js b/web/src/containers/Login/index.js
index 24a9ecac69..10b5e607de 100644
--- a/web/src/containers/Login/index.js
+++ b/web/src/containers/Login/index.js
@@ -11,7 +11,7 @@ import {
storeLoginResult,
setLogoutMessage,
} from 'actions/authAction';
-import LoginForm, { FORM_NAME } from './LoginForm';
+import LoginForm from './LoginForm';
import { Dialog, OtpForm, IconTitle, Notification } from 'components';
import { NOTIFICATIONS } from 'actions/appActions';
import { errorHandler } from 'components/OtpForm/utils';
@@ -135,9 +135,6 @@ class Login extends Component {
: err.message;
let error = {};
- errorTimeOut = setTimeout(() => {
- this.props.change(FORM_NAME, 'captcha', '');
- }, 5000);
if (_error.toLowerCase().indexOf('otp') > -1) {
this.setState({ values, otpDialogIsOpen: true });
@@ -145,8 +142,6 @@ class Login extends Component {
} else {
if (_error === 'User is not activated') {
error._error = STRINGS['VALIDATIONS.FROZEN_ACCOUNT'];
- } else if (_error.indexOf('captcha') > -1) {
- error._error = STRINGS['VALIDATIONS.CAPTCHA'];
} else {
error._error = _error;
}
diff --git a/web/src/containers/QuickTrade/_QuickTrade.scss b/web/src/containers/QuickTrade/_QuickTrade.scss
index cb4b223c6e..f941452864 100644
--- a/web/src/containers/QuickTrade/_QuickTrade.scss
+++ b/web/src/containers/QuickTrade/_QuickTrade.scss
@@ -131,11 +131,11 @@
}
.extreme-volatility-msg {
- color:#FFAA00;
+ color: #ffaa00;
}
.disclaimer-checkbox span {
- color: #fff;
+ color: $colors-main-black;
opacity: 0.7;
}
diff --git a/web/src/containers/QuickTrade/components/Details.js b/web/src/containers/QuickTrade/components/Details.js
index fa55c759f5..4dce63af65 100644
--- a/web/src/containers/QuickTrade/components/Details.js
+++ b/web/src/containers/QuickTrade/components/Details.js
@@ -112,6 +112,10 @@ const Details = ({
const handleClick = () => {
if (!isNetwork && !brokerUsed) {
router.push(`/trade/${pair}`);
+ } else if (isNetwork && brokerUsed) {
+ router.push(`/quick-trade/${pair}`);
+ } else {
+ router.push(`/prices/coin/${pair.split('-')[0]}`);
}
};
@@ -168,8 +172,8 @@ const Details = ({
@@ -190,7 +194,7 @@ const Details = ({
-
+
{STRINGS['MARKETS_TABLE.LAST_PRICE']}
@@ -226,7 +230,7 @@ const Details = ({
-
+
{
@@ -275,7 +279,7 @@ const Details = ({
{STRINGS['ASSET_INFO']}
{getLink(
- `/assets/coin/${pairBase}`,
+ `/prices/coin/${pairBase}`,
STRINGS.formatString(
STRINGS['QUICK_TRADE_COMPONENT.COIN_INFORMATION'],
coins[pairBase].display_name
diff --git a/web/src/containers/QuickTrade/components/ReviewOrder.js b/web/src/containers/QuickTrade/components/ReviewOrder.js
index 50c8b41864..0f293e3036 100644
--- a/web/src/containers/QuickTrade/components/ReviewOrder.js
+++ b/web/src/containers/QuickTrade/components/ReviewOrder.js
@@ -6,7 +6,6 @@ import classnames from 'classnames';
import { Button } from 'components';
import { Progress } from 'antd';
import { ClockCircleOutlined } from '@ant-design/icons';
-import { RiskyTrade } from './RiskyTrade';
const ReviewOrder = ({
onCloseDialog,
@@ -27,21 +26,6 @@ const ReviewOrder = ({
moment(expiry).diff(moment(time), 'seconds')
);
- const getShowCoinRisky = () => {
- const {is_risky, code} = coins[selectedTarget];
-
- if(is_risky) {
- const localRiskyItems = localStorage.getItem('riskyItems');
- const riskyItems = localRiskyItems ? JSON.parse(localRiskyItems) : {};
- const isNotWarn = !riskyItems[code];
- return isNotWarn;
- }
-
- return false;
- }
-
- const [showRisky, setShowRisky] = useState(getShowCoinRisky());
-
const [isExpired, setIsExpired] = useState(timeToExpiry <= 0);
useEffect(() => {
@@ -58,80 +42,78 @@ const ReviewOrder = ({
return (
- {showRisky ?
:
- (
-
-
-
{STRINGS['CONFIRM_TEXT']}
-
- {STRINGS['QUOTE_CONFIRMATION_MSG_TEXT_1']}
-
-
- {STRINGS['QUOTE_CONFIRMATION_MSG_TEXT_2']}
-
-
-
-
-
- {isExpired ? (
-
-
{STRINGS['QUOTE_CONFIRMATION_EXPIRED_MSG_TEXT_1']}
-
{STRINGS['QUOTE_CONFIRMATION_EXPIRED_MSG_TEXT_2']}
-
- ) : (
- STRINGS.formatString(
- STRINGS['QUOTE_CONFIRMATION_EXPIRY_MSG'],
- timeToExpiry,
- timeToExpiry > 1 ? STRINGS['SECONDS'] : STRINGS['SECOND']
- )
- )}
-
+
+
+
{STRINGS['CONFIRM_TEXT']}
+
+ {STRINGS['QUOTE_CONFIRMATION_MSG_TEXT_1']}
-
-
+
+ {STRINGS['QUOTE_CONFIRMATION_MSG_TEXT_2']}
-
-
+
+
+
+ {isExpired ? (
+
+
{STRINGS['QUOTE_CONFIRMATION_EXPIRED_MSG_TEXT_1']}
+
{STRINGS['QUOTE_CONFIRMATION_EXPIRED_MSG_TEXT_2']}
+
+ ) : (
+ STRINGS.formatString(
+ STRINGS['QUOTE_CONFIRMATION_EXPIRY_MSG'],
+ timeToExpiry,
+ timeToExpiry > 1 ? STRINGS['SECONDS'] : STRINGS['SECOND']
+ )
+ )}
-
- )}
+
+
+
+
+
+
+
+
);
};
diff --git a/web/src/containers/QuickTrade/components/RiskyTrade.js b/web/src/containers/QuickTrade/components/RiskyTrade.js
deleted file mode 100644
index dcc23e0442..0000000000
--- a/web/src/containers/QuickTrade/components/RiskyTrade.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import React, { useState } from 'react';
-import { Button, Coin } from 'components';
-import { Checkbox } from 'antd';
-
-import STRINGS from 'config/localizedStrings';
-import classNames from 'classnames';
-
-export const RiskyTrade = ({ setShowRisky, coinData, onCloseDialog }) => {
- const [enableProceedBtn, setEnableProceedBtn] = useState(false);
- const { icon_id, fullname, display_name, code } = coinData;
-
- const toggleRisk = (e) => {
- setEnableProceedBtn(e.target.checked);
- };
-
- const handleProceedClick = () => {
- localstoreRiskyCoin();
- setShowRisky(false);
- };
-
- const localstoreRiskyCoin = () => {
- const localRiskyItems = localStorage.getItem('riskyItems');
- const riskyItems = localRiskyItems ? JSON.parse(localRiskyItems) : {};
- riskyItems[code] = true;
- localStorage.setItem('riskyItems', JSON.stringify(riskyItems));
- };
-
- return (
-
-
-
-
-
-
- {STRINGS['USER_SETTINGS.RISKY_TRADE_DETECTED']}
-
-
- {STRINGS.formatString(
- STRINGS['RISKY_TRADE_DISCLAIMER.MSG_1'],
- fullname,
- display_name
- )}
-
-
- {STRINGS['RISKY_TRADE_DISCLAIMER.MSG_2']}
-
-
-
- {STRINGS['RISKY_TRADE_DISCLAIMER.MSG_3']}
-
-
-
- {STRINGS['RISKY_TRADE_DISCLAIMER.UNDERSTAND_RISK_MSG']}
-
-
-
-
-
- );
-};
diff --git a/web/src/containers/QuickTrade/components/_Details.scss b/web/src/containers/QuickTrade/components/_Details.scss
index ecc4081432..6c3b6e10aa 100644
--- a/web/src/containers/QuickTrade/components/_Details.scss
+++ b/web/src/containers/QuickTrade/components/_Details.scss
@@ -51,8 +51,7 @@ $colors-white: white;
}
.trade_tabs-container {
margin: 0;
- padding-left: 80px;
- width: 100% !important;
+ width: auto !important;
}
.main-coin-wrapper {
diff --git a/web/src/containers/RequestResetPassword/ResetPasswordForm.js b/web/src/containers/RequestResetPassword/ResetPasswordForm.js
index a53f158141..7f64678783 100644
--- a/web/src/containers/RequestResetPassword/ResetPasswordForm.js
+++ b/web/src/containers/RequestResetPassword/ResetPasswordForm.js
@@ -4,11 +4,9 @@ import {
requiredWithCustomMessage,
email,
normalizeEmail,
- required,
} from 'components/Form/validations';
import { AuthForm } from 'components';
import STRINGS from 'config/localizedStrings';
-import { getLanguage } from 'utils/string';
export const generateFormFields = (theme) => ({
email: {
@@ -21,13 +19,7 @@ export const generateFormFields = (theme) => ({
fullWidth: true,
label: STRINGS['FORM_FIELDS.EMAIL_LABEL'],
placeholder: STRINGS['FORM_FIELDS.EMAIL_PLACEHOLDER'],
- },
- captcha: {
- type: 'captcha',
- language: getLanguage(),
- theme: theme,
- validate: [required],
- },
+ }
});
const Form = (props) => (
diff --git a/web/src/containers/RequestResetPassword/index.js b/web/src/containers/RequestResetPassword/index.js
index 5fccfcc83c..0cf0e80733 100644
--- a/web/src/containers/RequestResetPassword/index.js
+++ b/web/src/containers/RequestResetPassword/index.js
@@ -67,9 +67,6 @@ class RequestResetPassword extends Component {
} else {
errors._error = error.message;
}
- errorTimeOut = setTimeout(() => {
- this.props.change('ResetPasswordForm', 'captcha', '');
- }, 5000);
throw new SubmissionError(errors);
}
});
diff --git a/web/src/containers/Signup/SignupForm.js b/web/src/containers/Signup/SignupForm.js
index 19545627f1..e1bb0cd573 100644
--- a/web/src/containers/Signup/SignupForm.js
+++ b/web/src/containers/Signup/SignupForm.js
@@ -60,12 +60,7 @@ export const generateFormFields = (strings, theme, links = {}) => ({
text={strings['SIGN_UP.TERMS.policy']}
/>
),
- },
- captcha: {
- type: 'captcha',
- theme,
- validate: [required],
- },
+ }
});
const validate = (values) => {
diff --git a/web/src/containers/Signup/index.js b/web/src/containers/Signup/index.js
index 1caa05e16a..b7b8e9d9ac 100644
--- a/web/src/containers/Signup/index.js
+++ b/web/src/containers/Signup/index.js
@@ -114,10 +114,6 @@ class Signup extends Component {
})
.catch((error) => {
const errors = {};
- errorTimeOut = setTimeout(() => {
- this.props.change(FORM_NAME, 'captcha', '');
- }, 5000);
-
if (error.response && error.response.status === 409) {
errors.email = STRINGS['VALIDATIONS.USER_EXIST'];
} else if (error.response) {
diff --git a/web/src/containers/Summary/components/Markets.js b/web/src/containers/Summary/components/Markets.js
index a95bf6848f..4e1257a377 100644
--- a/web/src/containers/Summary/components/Markets.js
+++ b/web/src/containers/Summary/components/Markets.js
@@ -141,7 +141,7 @@ class Markets extends Component {
{STRINGS.formatString(
STRINGS['SUMMARY_MARKETS.VISIT_COIN_INFO_PAGE'],
-
+
{STRINGS['SUMMARY_MARKETS.HERE']}
)}
diff --git a/web/src/containers/Summary/index.js b/web/src/containers/Summary/index.js
index a18b40c936..325e5c6a44 100644
--- a/web/src/containers/Summary/index.js
+++ b/web/src/containers/Summary/index.js
@@ -19,6 +19,7 @@ import {
logoutconfirm,
setNotification,
NOTIFICATIONS,
+ setSelectedAccount,
} from 'actions/appActions';
import {
BASE_CURRENCY,
@@ -88,6 +89,7 @@ class Summary extends Component {
onAccountTypeChange = (type) => {
this.setState({ selectedAccount: type });
+ this.props.setSelectedAccount(type);
};
onUpgradeAccount = () => {
@@ -102,11 +104,13 @@ class Summary extends Component {
currentTradingAccount,
selectedAccount: user.verification_level,
});
+ this.props.setSelectedAccount(user.verification_level);
} else if (!isLoggedIn()) {
const { config_level } = this.props;
this.setState({
selectedAccount: Object.keys(config_level)[0] || 0,
});
+ this.props.setSelectedAccount(Object.keys(config_level)[0] || 0);
}
};
@@ -339,6 +343,7 @@ const mapDispatchToProps = (dispatch) => ({
setNotification: bindActionCreators(setNotification, dispatch),
getUserReferrals: bindActionCreators(getUserReferrals, dispatch),
openContactForm: bindActionCreators(openContactForm, dispatch),
+ setSelectedAccount: bindActionCreators(setSelectedAccount, dispatch),
});
export default connect(
diff --git a/web/src/containers/Trade/Chart.js b/web/src/containers/Trade/Chart.js
index 048eaef2b6..6a1abd1389 100644
--- a/web/src/containers/Trade/Chart.js
+++ b/web/src/containers/Trade/Chart.js
@@ -327,6 +327,7 @@ class TVChartContainer extends React.PureComponent {
tvWidget.chart().createStudy('Moving Average', false, false, [7]);
tvWidget.chart().createStudy('Moving Average', false, false, [25]);
tvWidget.chart().createStudy('Volume', false, false);
+ // tvWidget.chart().createStudy('Keltner Channels', false, false, [{}, 20, 2]);
// tvWidget.chart().createStudy('MACD', false, false, [14, 30, 'close', 9])
}
diff --git a/web/src/containers/Trade/MobileTrade.js b/web/src/containers/Trade/MobileTrade.js
index 86b6cf861b..9b381a84c6 100644
--- a/web/src/containers/Trade/MobileTrade.js
+++ b/web/src/containers/Trade/MobileTrade.js
@@ -12,7 +12,6 @@ const MobileTrade = ({
balance,
onSubmitOrder,
openCheckOrder,
- onRiskyTrade,
settings,
orderbookProps,
symbol,
@@ -41,7 +40,6 @@ const MobileTrade = ({
{
+ return (
+
+ {STRINGS[label]}
+
+ onHandleClick('caretUp', label)} />
+ onHandleClick('caretDown', label)} />
+
+
+ );
+};
+
const generateHeaders = (
pairs = {},
onCancel,
onCancelAll,
ICONS,
- activeOrdersMarket
+ activeOrdersMarket,
+ orders,
+ onHandleClick
) => [
{
stringId: 'PAIR',
@@ -64,14 +79,14 @@ const generateHeaders = (
// },
// },
!isMobile && {
- label: STRINGS['TIME'],
+ label: rendercaret('TIME', onHandleClick),
key: 'created_At',
renderCell: ({ created_at = '' }, key, index) => {
return {getFormatTimestamp(created_at)} ;
},
},
{
- label: STRINGS['PRICE'],
+ label: rendercaret('PRICE', onHandleClick),
key: 'price',
renderCell: ({ price = 0, symbol }, key, index) => {
let pairData = pairs[symbol] || {};
@@ -194,6 +209,25 @@ const ActiveOrders = ({
activeOrdersMarket,
pageSize,
}) => {
+ const [filteredOrders, setFilteredOrders] = useState([...orders]);
+
+ useEffect(() => {
+ setFilteredOrders(orders);
+ }, [orders]);
+
+ const onHandleClick = (type, label) => {
+ const filteredData = filteredOrders.sort((a, b) => {
+ if (label === 'TIME') {
+ return type === 'caretUp'
+ ? new Date(a.created_at) - new Date(b.created_at)
+ : new Date(b.created_at) - new Date(a.created_at);
+ } else {
+ return type === 'caretUp' ? a.price - b.price : b.price - a.price;
+ }
+ });
+ setFilteredOrders((prev) => [...prev, ...filteredData]);
+ };
+
return (
{
- if (risk.popup_warning && isRiskyOrder) {
- order['order_portfolio_percentage'] = risk.order_portfolio_percentage;
- onRiskyTrade(order, () => {
- submit(FORM_NAME);
- });
- } else {
- submit(FORM_NAME);
- }
- });
- } else if (risk.popup_warning && isRiskyOrder) {
- order['order_portfolio_percentage'] = risk.order_portfolio_percentage;
- onRiskyTrade(order, () => {
submit(FORM_NAME);
});
} else {
@@ -727,7 +694,6 @@ const mapStateToProps = (state) => {
bids,
marketPrice,
order_entry_data: state.orderbook.order_entry_data,
- totalAsset: state.asset.totalAsset,
oraclePrices: state.asset.oraclePrices,
estimatedPrice,
};
diff --git a/web/src/containers/Trade/components/OrderEntryReview.js b/web/src/containers/Trade/components/OrderEntryReview.js
index 4cb5e341c3..fffb03b953 100644
--- a/web/src/containers/Trade/components/OrderEntryReview.js
+++ b/web/src/containers/Trade/components/OrderEntryReview.js
@@ -84,7 +84,7 @@ const Review = ({
-
+
{STRINGS.formatString(STRINGS['ABOUT_LINK'], symbol)}
diff --git a/web/src/containers/Trade/index.js b/web/src/containers/Trade/index.js
index 4a1bdd67b5..03405bd5db 100644
--- a/web/src/containers/Trade/index.js
+++ b/web/src/containers/Trade/index.js
@@ -21,7 +21,6 @@ import {
changePair,
setNotification,
NOTIFICATIONS,
- RISKY_ORDER,
setTradeTab,
} from 'actions/appActions';
import { NORMAL_CLOSURE_CODE, isIntentionalClosure } from 'utils/webSocket';
@@ -314,16 +313,6 @@ class Trade extends PureComponent {
});
};
- onRiskyTrade = (order, onConfirm) => {
- const { setNotification, fees, pairData } = this.props;
- setNotification(RISKY_ORDER, {
- order,
- onConfirm,
- fees,
- pairData,
- });
- };
-
onPriceClick = (price) => {
this.props.change(FORM_NAME, 'price', price);
playBackgroundAudioNotification(
@@ -613,7 +602,6 @@ class Trade extends PureComponent {
focusOnSizeInput={this.focusOnSizeInput}
submitOrder={this.onSubmitOrder}
openCheckOrder={this.openCheckOrder}
- onRiskyTrade={this.onRiskyTrade}
symbol={symbol}
balance={balance}
fees={fees}
@@ -767,7 +755,6 @@ class Trade extends PureComponent {
settings={settings}
orderbookReady={orderbookReady}
openCheckOrder={this.openCheckOrder}
- onRiskyTrade={this.onRiskyTrade}
onSubmitOrder={this.onSubmitOrder}
pair={pair}
setPriceRef={this.setPriceRef}
diff --git a/web/src/containers/TradeTabs/components/MarketRow.js b/web/src/containers/TradeTabs/components/MarketRow.js
index c058b9b94d..4a2e78109e 100644
--- a/web/src/containers/TradeTabs/components/MarketRow.js
+++ b/web/src/containers/TradeTabs/components/MarketRow.js
@@ -105,7 +105,10 @@ class MarketRow extends Component {
{ticker.volume > 0 && (
- {volume_native_text}
+ {volume_native_text.split(' ')[0]}
+
+
+ {volume_native_text.split(' ')[1]}
)}
diff --git a/web/src/containers/TradeTabs/index.js b/web/src/containers/TradeTabs/index.js
index 05a57b6786..e2ad95e16b 100644
--- a/web/src/containers/TradeTabs/index.js
+++ b/web/src/containers/TradeTabs/index.js
@@ -175,14 +175,14 @@ class AddTradeTab extends Component {
{!isMobile && (
- {STRINGS['ASSET_INFO_PAGE']}
+ {STRINGS['ASSET_INFO_PAGE']}
{constants &&
constants.features &&
constants.features.quick_trade ? (
- {STRINGS['QUICK_TRADE']}
+ {STRINGS['DIGITAL_ASSETS.QUICK_TRADE']}
) : null}
diff --git a/web/src/containers/TransactionsHistory/index.js b/web/src/containers/TransactionsHistory/index.js
index 0751e8cfcb..1c69fc4dc2 100644
--- a/web/src/containers/TransactionsHistory/index.js
+++ b/web/src/containers/TransactionsHistory/index.js
@@ -48,9 +48,7 @@ import STRINGS from 'config/localizedStrings';
import withConfig from 'components/ConfigProvider/withConfig';
import { STATIC_ICONS } from 'config/icons';
import { Image } from 'hollaex-web-lib';
-import {
- quicktradePairSelector,
-} from 'containers/QuickTrade/components/utils';
+import { quicktradePairSelector } from 'containers/QuickTrade/components/utils';
const GROUP_CLASSES = [...FLEX_CENTER_CLASSES, 'flex-column'];
const transactionTabs = ['trades', 'orders', 'deposits', 'withdrawals'];
@@ -156,7 +154,8 @@ class TransactionsHistory extends Component {
}
if (
JSON.stringify(nextProps.pairs) !== JSON.stringify(pairs) ||
- JSON.stringify(nextProps.quicktradePairs) !== JSON.stringify(quicktradePairs) ||
+ JSON.stringify(nextProps.quicktradePairs) !==
+ JSON.stringify(quicktradePairs) ||
JSON.stringify(nextProps.coins) !== JSON.stringify(coins)
) {
this.generateFilters();
@@ -702,6 +701,7 @@ class TransactionsHistory extends Component {
onCloseDialog={onCloseDialog}
shouldCloseOnOverlayClick={true}
showCloseText={false}
+ className="cancel-withdraw-pop-up"
>
-
+
{STRINGS['CANCEL_WITHDRAWAL_POPUP_CONFIRM']}
diff --git a/web/src/containers/TransactionsHistory/selectors.js b/web/src/containers/TransactionsHistory/selectors.js
index dd809ba357..70b627d6cf 100644
--- a/web/src/containers/TransactionsHistory/selectors.js
+++ b/web/src/containers/TransactionsHistory/selectors.js
@@ -9,7 +9,7 @@ const getWithdrawals = (state) => state.wallet.withdrawals;
const modifyTradesAndOrders = (history, coins) => {
const data = history.data.map((record, index) => {
- const { symbol: pair, fee_coin } = record;
+ const { symbol: pair, fee_coin, quick } = record;
const [pair_base, pair_2] = pair.split('-');
const { display_name: pair_base_display, icon_id } =
coins[pair_base] || DEFAULT_COIN_DATA;
@@ -17,6 +17,7 @@ const modifyTradesAndOrders = (history, coins) => {
const { display_name: fee_coin_display } =
coins[fee_coin || pair_base] || DEFAULT_COIN_DATA;
const display_name = `${pair_base_display}-${pair_2_display}`;
+
return {
...record,
display_name,
@@ -25,6 +26,7 @@ const modifyTradesAndOrders = (history, coins) => {
fee_coin_display,
icon_id,
history_id: index,
+ quick,
};
});
diff --git a/web/src/containers/TransactionsHistory/utils.js b/web/src/containers/TransactionsHistory/utils.js
index 61ae397648..4084d1e463 100644
--- a/web/src/containers/TransactionsHistory/utils.js
+++ b/web/src/containers/TransactionsHistory/utils.js
@@ -3,8 +3,9 @@ import {
InfoCircleTwoTone,
PlusSquareOutlined,
MinusSquareOutlined,
+ ThunderboltFilled,
} from '@ant-design/icons';
-import { notification } from 'antd';
+import { notification, Tooltip } from 'antd';
import classnames from 'classnames';
import mathjs from 'mathjs';
import { isMobile } from 'react-device-detect';
@@ -424,12 +425,22 @@ export const generateTradeHeaders = (
key: 'pair',
exportToCsv: ({ display_name }) => display_name,
className: 'sticky-col',
- renderCell: ({ display_name, icon_id }, key, index) => {
+ renderCell: ({ display_name, icon_id, quick }, key, index) => {
return (
{display_name}
+
+ {quick && (
+
+
+
+ )}
+
);
diff --git a/web/src/containers/UserSecurity/OTP.js b/web/src/containers/UserSecurity/OTP.js
index 676259fc5a..c9e0d37664 100644
--- a/web/src/containers/UserSecurity/OTP.js
+++ b/web/src/containers/UserSecurity/OTP.js
@@ -1,18 +1,48 @@
-import React from 'react';
-import { CheckboxButton, IconTitle, EditWrapper } from 'components';
+import React, { useState, useEffect } from 'react';
import QRCode from 'qrcode.react';
-import OTPForm from './OTPForm';
+import { Button } from 'antd';
+import { CloseCircleOutlined } from '@ant-design/icons';
+import { CheckboxButton, IconTitle, EditWrapper } from 'components';
import STRINGS from 'config/localizedStrings';
import { Image } from 'hollaex-web-lib';
+import { RenderBtn, RenderBackBtn } from './utils_logins';
+import { STATIC_ICONS } from 'config/icons';
-export const renderOTPForm = (
+const OtpFormSteps = ({
secret,
email,
activateOTP,
constants = {},
- ICONS
-) => {
+ ICONS,
+ closeDialog,
+ handleOTPCheckbox,
+ handleUpdateOtp,
+ selectedStep,
+}) => {
+ const [step, setStep] = useState(0);
+ const [otpValue, setOtpValue] = useState();
+ const [errorMsg, setErrorMsg] = useState('');
const app_name = constants.api_name.replace(' ', '').trim() || '';
+
+ useEffect(() => {
+ if (selectedStep) {
+ setStep(selectedStep);
+ handleUpdateOtp(false);
+ }
+ }, [selectedStep, handleUpdateOtp]);
+
+ useEffect(() => {
+ if (otpValue) {
+ setErrorMsg('');
+ }
+ }, [otpValue]);
+
+ const handleOnBlur = () => {
+ if (!otpValue) {
+ setErrorMsg(STRINGS['ACCOUNT_SECURITY.OTP.MANUEL_ERROR_1']);
+ }
+ };
+
return (
-
-
- {string} }
- >
- {STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.MESSAGE_1']}
-
-
-
-
- {STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.MESSAGE_2']}
-
+ {step === 0 && (
+
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.DOWNLOAD_APP']}
+
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.GOOGLE_AUTHENTICATOR']}
+
+
+
+
+
+ window.open(
+ 'https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en&gl=US',
+ '_blank'
+ )
+ }
+ >
+
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.DOWNLOAD_FROM']}
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.GOOGLE_PLAY']}
+
+
+
+
+
+
+ window.open(
+ 'https://apps.apple.com/us/app/google-authenticator/id388497605',
+ '_blank'
+ )
+ }
+ >
+
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.DOWNLOAD_FROM']}
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.APPLE']}
+
+
+
+
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.APP_INFO']}
+
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.DONT_UNINSTALL']}
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.INFO_UNINSTALL']}
+
+
+
-
-
-
+
+
+ {string} }
+ >
+ {STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.MESSAGE_1']}
+
+
+
+
+
+
+
+ {string} }
+ >
+ {STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.MESSAGE_5']}
+
+
+
{secret}
+
+
+ {STRINGS.formatString(
+ STRINGS['ACCOUNT_SECURITY.OTP.NOTE'],
+ STRINGS['ACCOUNT_SECURITY.OTP.MANUEL_DESCRIPTION_2'],
+ STRINGS['ACCOUNT_SECURITY.OTP.MANUEL_DESCRIPTION_3']
+ )}
+
+
+
+
+
-
-
-
- {string} }
- >
- {STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.MESSAGE_5']}
-
-
-
-
- {STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.MESSAGE_3']}
-
-
-
- {STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.MESSAGE_4']}
-
-
-
{secret}
-
-
-
-
{string} }
- >
- {STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.INPUT']}
-
+ )}
+
+ {step === 2 && (
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.MANUEL_DESCRIPTION']}
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.MANUEL_KEY']}
+
+
+
{
+ setOtpValue(e.target.value);
+ }}
+ required
+ onBlur={handleOnBlur}
+ />
+ {errorMsg &&
{errorMsg}
}
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.MANUEL_WARNING']}
+
+
+
+
+
+ {
+ if (!otpValue) {
+ setErrorMsg(STRINGS['ACCOUNT_SECURITY.OTP.MANUEL_ERROR_1']);
+ return;
+ }
+ if (otpValue !== secret) {
+ setErrorMsg(STRINGS['ACCOUNT_SECURITY.OTP.MANUEL_ERROR_2']);
+ return;
+ }
+ handleUpdateOtp(true);
+ handleOTPCheckbox(false);
+ }}
+ className="proceed-btn"
+ >
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.NEXT']}
+
+
+
-
-
+ )}
);
};
+export const renderOTPForm = (
+ secret,
+ email,
+ activateOTP,
+ constants = {},
+ ICONS,
+ closeDialog,
+ handleOTPCheckbox = () => {},
+ handleUpdateOtp = () => {},
+ selectedStep
+) => {
+ return (
+
+ );
+};
+
export const OTP = ({
requestOTP,
data = {},
@@ -89,12 +309,74 @@ export const OTP = ({
icons = {},
}) => (
-
- {!otp_enabled && (
-
-
- {STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.WARNING']}
-
+
+ {!otp_enabled ? (
+
+
+
+ {STRINGS.formatString(
+ STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.WARNING'],
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.STRONGLY_RECOMMEND']}
+ ,
+ STRINGS['ACCOUNT_SECURITY.OTP.CONTENT.WARNING_CONTENT']
+ )}
+
+
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.2FA_DISABLED']}
+
+
+
+
+ {STRINGS.formatString(
+ STRINGS['ACCOUNT_SECURITY.OTP.2FA_CONTENT_ONE'],
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.TITLE']}
+ ,
+ STRINGS['ACCOUNT_SECURITY.OTP.2FA_CONTENT_TWO']
+ )}
+
+
+
+
+ ) : (
+
+ {otp_enabled && (
+
+ )}
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.2FA_DISABLED']}
+
+
+
+
+
+ {STRINGS.formatString(
+ STRINGS['ACCOUNT_SECURITY.OTP.2FA_CONTENT_ONE'],
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.TITLE']}
+ ,
+ STRINGS['ACCOUNT_SECURITY.OTP.2FA_CONTENT_THREE']
+ )}
+
+
+
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.2FA_CONTENT_FOUR']}
+
+
+
)}
@@ -115,15 +397,6 @@ export const OTP = ({
>
{children}
- {otp_enabled && (
-
- )}
);
diff --git a/web/src/containers/UserSecurity/_UserSecurity.scss b/web/src/containers/UserSecurity/_UserSecurity.scss
index 1f25a53672..8d2071b2b4 100644
--- a/web/src/containers/UserSecurity/_UserSecurity.scss
+++ b/web/src/containers/UserSecurity/_UserSecurity.scss
@@ -1,14 +1,15 @@
-.user_security-wrapper {
+.user_security-wrapper,
+.user_security-wrapper-disabled {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
- margin-top: 30px;
padding: 30px;
background-color: $app-sidebar-background;
- > *:not(:last-child) {
- margin-bottom: 2rem;
- }
+}
+
+.user_security-wrapper-disabled {
+ margin-top: 3%;
}
.OTP_Success {
@@ -26,8 +27,128 @@
min-width: 30rem;
width: 30rem;
+ .step-one-title-wrapper {
+ font-family: 'Open Sans';
+ }
+
+ .step-one-pop-up {
+ .store-wrapper {
+ cursor: pointer;
+ padding: 2%;
+ width: 30%;
+ color: #000000;
+ font-size: 10px;
+ border-radius: 10px;
+ border: 1px solid $colors-main-border;
+ background-color: #f5f5f7;
+ .store-icons {
+ width: 25%;
+ }
+ }
+ .download-content-title {
+ font-weight: bold;
+ margin: 2% 0;
+ }
+ .store-icons-wrapper {
+ display: flex;
+ justify-content: space-evenly;
+ margin-bottom: 5%;
+ .play-store-field {
+ cursor: pointer;
+ padding: 2%;
+ width: 100%;
+ height: 50%;
+ color: $colors-main-black;
+ font-size: 12px;
+ border-radius: 10px;
+ background-color: $colors-main-black;
+ }
+ }
+ .app-info {
+ margin-bottom: 5%;
+ }
+ .uninstall-info {
+ color: #ffbb00;
+ font-weight: bold;
+ }
+ }
+
+ .step-one-pop-up,
+ .step-two-pop-up {
+ .note-txt {
+ color: #e59b07;
+ }
+ .otp-border,
+ .otp-border-footer {
+ margin-bottom: 5%;
+ border-bottom: 1px solid $colors-main-border;
+ width: 100%;
+ }
+ .otp-border-footer {
+ width: 25%;
+ }
+ .btn-wrapper {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 8%;
+ .back-btn,
+ .proceed-btn {
+ background-color: $link;
+ border: none;
+ width: 45%;
+ height: 40px;
+ text-align: center;
+ color: $colors-main-black;
+ }
+ }
+ }
+
+ .step-two-pop-up {
+ .btn-wrapper {
+ margin-top: 5% !important;
+ }
+ }
+
+ .step-three-pop-up {
+ .verfication-field {
+ background-color: $app-sidebar-background;
+ border: none;
+ border-bottom: 1px solid $colors-black;
+ border-image: initial;
+ width: 100%;
+ margin-top: 5px;
+ }
+ .warning-text {
+ color: $colors-black;
+ margin-top: 15%;
+ }
+ .btn-wrapper {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 8%;
+ }
+ }
+
+ .step-three-pop-up,
+ .step-four-pop-up {
+ .back-btn,
+ .proceed-btn {
+ background-color: $link;
+ border: none;
+ width: 45%;
+ height: 40px;
+ text-align: center;
+ color: $colors-main-black;
+ }
+ }
+
+ .step-four-pop-up {
+ .back-btn {
+ width: 100%;
+ }
+ }
+
.otp_form-section-wrapper {
- border-top: 1px solid $colors-main-border;
padding: 0.75rem 0;
.otp_form-section-content {
@@ -67,7 +188,7 @@
font-size: $font-size-subhead2;
}
.icon_title-svg {
- @include size(6.5rem);
+ @include size(5.5rem);
svg {
@include size(6.5rem);
}
@@ -240,6 +361,20 @@ $padding-input: 4rem;
}
}
+.otp-field-wrapper {
+ margin-top: 3%;
+ .warning_text {
+ padding: 10px;
+ text-align: center;
+ background-color: $colors-notifications-red;
+ color: $colors-main-black;
+ .improtant-text {
+ font-weight: bold;
+ text-decoration: underline;
+ }
+ }
+}
+
.layout-mobile {
.user_security-wrapper {
.warning_text {
@@ -464,3 +599,10 @@ $padding-input: 4rem;
}
}
}
+
+.errorField {
+ border-color: $colors-notifications-red !important;
+}
+.errorText {
+ color: $colors-notifications-red !important;
+}
diff --git a/web/src/containers/UserSecurity/index.js b/web/src/containers/UserSecurity/index.js
index e2b8eb3a85..8c7242ba0e 100644
--- a/web/src/containers/UserSecurity/index.js
+++ b/web/src/containers/UserSecurity/index.js
@@ -4,7 +4,7 @@ import { bindActionCreators } from 'redux';
import { SubmissionError } from 'redux-form';
import { isMobile } from 'react-device-detect';
import { message } from 'antd';
-import { openContactForm } from 'actions/appActions';
+import { openContactForm, setSelectedStep } from 'actions/appActions';
import {
resetPassword,
otpRequest,
@@ -62,6 +62,8 @@ class UserSecurity extends Component {
freeze: false,
error: '',
updatedPassword: {},
+ isEnableOtpForm: false,
+ otpFormStep: 0,
};
componentDidMount() {
@@ -480,7 +482,7 @@ class UserSecurity extends Component {
onSubmitCancelOTP = (values) => {
const { icons: ICONS } = this.props;
const { otp_enabled } = this.props.user;
- const { updatedPassword } = this.state;
+ const { updatedPassword, isEnableOtpForm } = this.state;
const body = {
...updatedPassword,
...values,
@@ -515,18 +517,34 @@ class UserSecurity extends Component {
throw new SubmissionError({ _error });
});
} else {
- return otpRevoke({ code: values.otp_code })
- .then(() => {
- this.props.otpSetActivated(false);
- this.setState({
- dialogIsOpen: true,
- iconId: 'OTP_DEACTIVATED',
- icon: ICONS['OTP_DEACTIVATED'],
- modalText: STRINGS['ACCOUNT_SECURITY.OTP.DIALOG.REVOKE'],
- stringId: 'ACCOUNT_SECURITY.OTP.DIALOG.REVOKE',
- });
- })
- .catch(errorHandler);
+ if (isEnableOtpForm) {
+ return otpActivate({ code: values.otp_code })
+ .then(() => {
+ this.props.otpSetActivated(true);
+ this.setState({
+ dialogIsOpen: true,
+ iconId: 'OTP_ACTIVE',
+ icon: ICONS['OTP_ACTIVE'],
+ modalText: STRINGS['ACCOUNT_SECURITY.OTP.DIALOG.SUCCESS'],
+ stringId: 'ACCOUNT_SECURITY.OTP.DIALOG.SUCCESS',
+ isEnableOtpForm: false,
+ });
+ })
+ .catch(errorHandler);
+ } else {
+ return otpRevoke({ code: values.otp_code })
+ .then(() => {
+ this.props.otpSetActivated(false);
+ this.setState({
+ dialogIsOpen: true,
+ iconId: 'OTP_DEACTIVATED',
+ icon: ICONS['OTP_DEACTIVATED'],
+ modalText: STRINGS['ACCOUNT_SECURITY.OTP.DIALOG.REVOKE'],
+ stringId: 'ACCOUNT_SECURITY.OTP.DIALOG.REVOKE',
+ });
+ })
+ .catch(errorHandler);
+ }
}
};
@@ -544,7 +562,9 @@ class UserSecurity extends Component {
iconId: '',
icon: '',
updatedPassword: {},
+ isEnableOtpForm: false,
});
+ this.props.setSelectedStep(0);
};
// onSubmitotp = (values) => {
@@ -553,6 +573,10 @@ class UserSecurity extends Component {
// };
+ handleUpdateOtp = (val) => {
+ this.setState({ isEnableOtpForm: val });
+ };
+
renderModalContent = (
{ requested, activated, secret, error },
otp_enabled,
@@ -561,7 +585,7 @@ class UserSecurity extends Component {
constants,
icons
) => {
- const { stringId, icon, iconId } = this.state;
+ const { stringId, icon, iconId, isEnableOtpForm } = this.state;
if (error) {
return (
@@ -571,15 +595,25 @@ class UserSecurity extends Component {
success={false}
/>
);
- } else if (otp_enabled && !modalText) {
- return
;
+ } else if ((otp_enabled && !modalText) || isEnableOtpForm) {
+ return (
+
+ );
} else if (requested && !activated) {
+ const { selectedStep } = this.props;
return renderOTPForm(
secret,
email,
this.onSubmitActivateOtp,
constants,
- icons
+ icons,
+ this.onCloseDialog,
+ this.handleOTPCheckbox,
+ this.handleUpdateOtp,
+ selectedStep
);
} else {
return (
@@ -595,6 +629,11 @@ class UserSecurity extends Component {
}
};
+ onHandleEnableBack = (val) => {
+ this.props.setSelectedStep(val);
+ this.setState({ isEnableOtpForm: false });
+ };
+
render() {
const {
icons: ICONS,
@@ -605,7 +644,14 @@ class UserSecurity extends Component {
if (isLoggedIn() && verification_level === 0) {
return
;
}
- const { dialogIsOpen, modalText, activeTab, tabs, freeze } = this.state;
+ const {
+ dialogIsOpen,
+ modalText,
+ activeTab,
+ tabs,
+ freeze,
+ isEnableOtpForm,
+ } = this.state;
//const { onCloseDialog } = this;
if (freeze === true) {
@@ -676,6 +722,8 @@ class UserSecurity extends Component {
label="security-modal"
onCloseDialog={this.onCloseDialog}
showCloseText={!(otp.error || modalText)}
+ isEnableOtpForm={isEnableOtpForm}
+ onHandleEnableBack={this.onHandleEnableBack}
>
{dialogIsOpen && !otp.requesting ? (
this.renderModalContent(
@@ -722,6 +770,7 @@ const mapStateToProps = (state) => ({
state,
...Object.keys(generateFormValues())
),
+ selectedStep: state.app.selectedStep,
});
const mapDispatchToProps = (dispatch) => ({
@@ -729,6 +778,7 @@ const mapDispatchToProps = (dispatch) => ({
requestOTP: () => dispatch(otpRequest()),
otpSetActivated: (active) => dispatch(otpSetActivated(active)),
openContactForm: bindActionCreators(openContactForm, dispatch),
+ setSelectedStep: bindActionCreators(setSelectedStep, dispatch),
});
export default connect(
diff --git a/web/src/containers/UserSecurity/utils_logins.js b/web/src/containers/UserSecurity/utils_logins.js
index 59f501f975..2447a869d9 100644
--- a/web/src/containers/UserSecurity/utils_logins.js
+++ b/web/src/containers/UserSecurity/utils_logins.js
@@ -1,6 +1,8 @@
import React from 'react';
+import { Button } from 'antd';
import { getFormatTimestamp } from 'utils/utils';
import STRINGS from 'config/localizedStrings';
+import { EditWrapper } from 'components';
export const generateLogins = () => {
return [
@@ -20,3 +22,45 @@ export const generateLogins = () => {
},
];
};
+
+export const RenderBtn = ({ closeDialog, setStep, step, goBack, label }) => {
+ return (
+
+ {
+ closeDialog ? closeDialog() : setStep(goBack);
+ }}
+ className="back-btn"
+ >
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.BACK']}
+
+
+ {
+ setStep(step);
+ }}
+ className="proceed-btn"
+ >
+ {STRINGS[label]}
+
+
+ );
+};
+
+export const RenderBackBtn = ({ setStep, setErrorMsg, setOtpValue, step }) => {
+ return (
+
{
+ setStep(step);
+ setErrorMsg('');
+ setOtpValue('');
+ }}
+ className="back-btn"
+ >
+
+ {STRINGS['ACCOUNT_SECURITY.OTP.BACK']}
+
+
+ );
+};
diff --git a/web/src/containers/UserSettings/RiskForm.js b/web/src/containers/UserSettings/RiskForm.js
deleted file mode 100644
index 69c15dbe05..0000000000
--- a/web/src/containers/UserSettings/RiskForm.js
+++ /dev/null
@@ -1,210 +0,0 @@
-import React, { Component } from 'react';
-import { connect } from 'react-redux';
-import { reduxForm, formValueSelector } from 'redux-form';
-import classnames from 'classnames';
-import { Table, Button, IconTitle } from 'components';
-import renderFields from 'components/Form/factoryFields';
-import STRINGS from 'config/localizedStrings';
-import { formatBaseAmount } from 'utils/currency';
-import { BASE_CURRENCY, DEFAULT_COIN_DATA } from 'config/constants';
-import { EditWrapper } from 'components';
-
-const FORM_NAME = 'WarningForm';
-const selector = formValueSelector(FORM_NAME);
-
-export const generateHeaders = (onAdjustPortfolio) => {
- return [
- {
- stringId: 'USER_SETTINGS.RISK_MANAGEMENT.PORTFOLIO',
- label: STRINGS['USER_SETTINGS.RISK_MANAGEMENT.PORTFOLIO'],
- key: 'percentage',
- renderCell: ({ id, percentage, status }, key, index) => (
-
-
- {percentage.portfolioPercentage}
- {}}
- >
-
- {STRINGS['USER_SETTINGS.RISK_MANAGEMENT.ADJUST']}
-
-
-
-
- ),
- },
- {
- stringId: 'USER_SETTINGS.RISK_MANAGEMENT.VALUE_ASSET',
- label: STRINGS['USER_SETTINGS.RISK_MANAGEMENT.VALUE_ASSET'],
- key: 'assetValue',
- renderCell: ({ id, assetValue, status }, key, index) => (
-
-
- {' '}
- {assetValue.percentPrice}
-
-
- ),
- },
- {
- stringId: 'USER_SETTINGS.RISK_MANAGEMENT.ACTIVATE_RISK_MANAGEMENT',
- label: STRINGS['USER_SETTINGS.RISK_MANAGEMENT.ACTIVATE_RISK_MANAGEMENT'],
- key: 'adjust',
- className: 'text-right',
- renderCell: ({ id, adjust }, key, index) => (
-
-
- {renderFields(adjust)}
-
-
- ),
- },
- ];
-};
-
-export const generateWarningFormValues = (DEFAULT_TOGGLE_OPTIONS) => ({
- popup_warning: {
- type: 'toggle',
- stringId: 'USER_SETTINGS.RISK_MANAGEMENT.WARNING_POP_UP',
- label: STRINGS['USER_SETTINGS.RISK_MANAGEMENT.WARNING_POP_UP'],
- // className: 'toggle-wrapper',
- toggleOnly: true,
- options: DEFAULT_TOGGLE_OPTIONS,
- },
-});
-
-class Form extends Component {
- componentDidUpdate(prevProps) {
- if (
- JSON.stringify(this.props.initialValues) !==
- JSON.stringify(prevProps.initialValues)
- ) {
- this.props.initialize(this.props.initialValues);
- }
- }
- render() {
- const {
- onAdjustPortfolio,
- totalAssets,
- initialValues = {},
- handleSubmit,
- submitting,
- pristine,
- // error,
- valid,
- formFields,
- coins,
- ICONS,
- popup_warning,
- } = this.props;
-
- const percentPrice =
- (totalAssets / 100) * initialValues.order_portfolio_percentage;
- const { fullname, display_name } =
- coins[BASE_CURRENCY] || DEFAULT_COIN_DATA;
- const assetData = [
- {
- id: 1,
- percentage: {
- portfolioPercentage: initialValues.order_portfolio_percentage
- ? `${initialValues.order_portfolio_percentage}%`
- : '',
- popupWarning: initialValues.popup_warning,
- },
- assetValue: {
- percentPrice: percentPrice
- ? `${formatBaseAmount(percentPrice)} ${display_name}`
- : 0,
- popupWarning: initialValues.popup_warning,
- },
- adjust: formFields,
- warning: initialValues.popup_warning,
- status: popup_warning,
- },
- ];
- const sections = [
- {
- stringId:
- 'USER_SETTINGS.CREATE_ORDER_WARING,USER_SETTINGS.RISK_MANAGEMENT.INFO_TEXT,USER_SETTINGS.RISK_MANAGEMENT.INFO_TEXT_1',
- title: STRINGS['USER_SETTINGS.CREATE_ORDER_WARING'],
- content: (
-
-
{children}
}
- >
- {STRINGS['USER_SETTINGS.RISK_MANAGEMENT.INFO_TEXT']}
-
-
{children}
}
- >
- {STRINGS.formatString(
- STRINGS['USER_SETTINGS.RISK_MANAGEMENT.INFO_TEXT_1'],
- fullname,
- totalAssets
- )}
-
-
-
- ),
- isOpen: true,
- },
- ];
- return (
-
- );
- }
-}
-
-const RiskForm = reduxForm({
- form: FORM_NAME,
- enableReinitialize: true,
-})(Form);
-
-const mapStateToForm = (state) => ({
- popup_warning: selector(state, 'popup_warning'),
-});
-
-const RiskFormValues = connect(mapStateToForm)(RiskForm);
-
-export default RiskFormValues;
diff --git a/web/src/containers/UserSettings/index.js b/web/src/containers/UserSettings/index.js
index 3ad08daf73..9d093bf307 100644
--- a/web/src/containers/UserSettings/index.js
+++ b/web/src/containers/UserSettings/index.js
@@ -38,7 +38,6 @@ import NotificationForm, {
generateNotificationFormValues,
} from './NotificationForm';
import AudioCueForm, { generateAudioCueFormValues } from './AudioForm';
-import RiskForm, { generateWarningFormValues } from './RiskForm';
import { isLoggedIn } from 'utils/token';
import STRINGS from 'config/localizedStrings';
import withConfig from 'components/ConfigProvider/withConfig';
@@ -78,16 +77,11 @@ class UserSettings extends Component {
window.location.search.includes('audioCue')
) {
this.setState({ activeTab: 3 });
- } else if (
- window.location.search &&
- window.location.search.includes('manageRisk')
- ) {
- this.setState({ activeTab: 4 });
} else if (
window.location.search &&
window.location.search.includes('account')
) {
- this.setState({ activeTab: 5 });
+ this.setState({ activeTab: 4 });
}
this.openCurrentTab();
}
@@ -146,8 +140,6 @@ class UserSettings extends Component {
} else if (this.state.activeTab === 3) {
currentTab = 'audioCue';
} else if (this.state.activeTab === 4) {
- currentTab = 'manageRisk';
- } else if (this.state.activeTab === 5) {
currentTab = 'account';
}
this.props.router.push(`/settings?${currentTab}`);
@@ -167,7 +159,6 @@ class UserSettings extends Component {
const {
constants = {},
icons: ICONS,
- totalAsset,
themeOptions,
} = this.props;
const formValues = generateFormValues({
@@ -187,7 +178,6 @@ class UserSettings extends Component {
DEFAULT_TOGGLE_OPTIONS
);
const audioFormValues = generateAudioCueFormValues(DEFAULT_TOGGLE_OPTIONS);
- const warningFormValues = generateWarningFormValues(DEFAULT_TOGGLE_OPTIONS);
let audioFormInitialValues = {
all: true,
@@ -314,35 +304,6 @@ class UserSettings extends Component {
/>
),
},
- {
- title: isMobile ? (
-
- ) : (
- //
-
- {STRINGS['USER_SETTINGS.TITLE_MANAGE_RISK']}
-
- ),
- content: (
-
this.onSubmitSettings(formProps, 'risk')}
- formFields={warningFormValues}
- initialValues={settings.risk}
- ICONS={ICONS}
- />
- ),
- },
{
title: isMobile ? (
({
price: state.orderbook.price,
//orders: state.order.activeOrders,
constants: state.app.constants,
- totalAsset: state.asset.totalAsset,
features: state.app.features,
});
diff --git a/web/src/containers/Wallet/AssetsBlock.js b/web/src/containers/Wallet/AssetsBlock.js
index 3ce09432b3..98fd41f932 100644
--- a/web/src/containers/Wallet/AssetsBlock.js
+++ b/web/src/containers/Wallet/AssetsBlock.js
@@ -416,6 +416,10 @@ const AssetsBlock = ({
balance_history_config?.active &&
Number(userPL?.['7d']?.total || 0) !== 0 && (
{
+ handleBalanceHistory(true);
+ }}
+ style={{ cursor: 'pointer' }}
className={
Number(userPL?.['7d']?.total || 0) === 0
? 'profitNeutral'
@@ -466,7 +470,7 @@ const AssetsBlock = ({
{!isUpgrade &&
balance_history_config?.active &&
historyData.length > 1 ? (
-
+
+
handleBalanceHistory(true)}
+ >
+
+ {STRINGS.formatString(
+ STRINGS['PROFIT_LOSS.VIEW_MORE'],
+ '>'
+ )}
+
+
) : (
!plLoading &&
@@ -517,6 +532,7 @@ const AssetsBlock = ({
placeHolder={`${STRINGS['WALLET_ASSETS_SEARCH_TXT']}...`}
handleSearch={handleSearch}
showCross
+ isFocus={true}
/>
@@ -706,7 +722,7 @@ const AssetsBlock = ({
/>
- {!isMobile && (
+ {
{markets.length > 1 ? (
)}
- )}
+ }
{/* {hasEarn && (
{STRINGS['CURRENCY_WALLET.ABOUT']} {currency.toUpperCase()}
@@ -336,7 +336,7 @@ class Wallet extends Component {
>
{currency.toUpperCase()}
,
-
+
here
)}
diff --git a/web/src/containers/Wallet/HeaderSection.js b/web/src/containers/Wallet/HeaderSection.js
index 960e589b78..676203cdf2 100644
--- a/web/src/containers/Wallet/HeaderSection.js
+++ b/web/src/containers/Wallet/HeaderSection.js
@@ -12,7 +12,7 @@ const HeaderSection = ({ icons: ICONS }) => {
-
+
{STRINGS['ACCORDIAN.ACCORDIAN_INFO']}
@@ -20,7 +20,7 @@ const HeaderSection = ({ icons: ICONS }) => {
-
+
{STRINGS['ACCORDIAN.ACCORDIAN_HISTORY']}
diff --git a/web/src/containers/Wallet/ProfitLossSection.js b/web/src/containers/Wallet/ProfitLossSection.js
index 8133397b64..4ab0fc77b5 100644
--- a/web/src/containers/Wallet/ProfitLossSection.js
+++ b/web/src/containers/Wallet/ProfitLossSection.js
@@ -6,14 +6,14 @@ import HighchartsReact from 'highcharts-react-official';
// eslint-disable-next-line
import { Coin, EditWrapper } from 'components';
import { Link } from 'react-router';
-import { Button, Spin, DatePicker, message, Modal } from 'antd';
+import { Button, Spin, DatePicker, message, Modal, Tabs } from 'antd';
import { fetchBalanceHistory, fetchPlHistory } from './actions';
import BigNumber from 'bignumber.js';
import moment from 'moment';
import STRINGS from 'config/localizedStrings';
import { CloseOutlined } from '@ant-design/icons';
import './_ProfitLoss.scss';
-
+const TabPane = Tabs.TabPane;
const ProfitLossSection = ({
coins,
balance_history_config,
@@ -49,6 +49,7 @@ const ProfitLossSection = ({
const [graphData, setGraphData] = useState([]);
const [customDate, setCustomDate] = useState(false);
const [customDateValues, setCustomDateValues] = useState();
+ const [loadingPnl, setLoadingPnl] = useState(false);
const options = {
chart: {
@@ -65,7 +66,9 @@ const ProfitLossSection = ({
labels: {
formatter: (item) => {
const color =
- graphData?.[current || 0]?.[0] === item.value ? '#5D63FF' : 'white';
+ graphData?.[current || 0]?.[0] === item.value
+ ? '#5D63FF'
+ : 'date-text';
const fontWeight =
graphData?.[current || 0]?.[0] === item.value ? 'bold' : 'normal';
return `
${item.value} `;
@@ -120,8 +123,10 @@ const ProfitLossSection = ({
firstRender.current = false;
} else {
setIsLoading(true);
+ setLoadingPnl(true);
fetchPlHistory().then((res) => {
setUserPL(res);
+ setLoadingPnl(false);
});
requestHistory(queryFilters.page, queryFilters.limit);
}
@@ -132,8 +137,10 @@ const ProfitLossSection = ({
if (firstRender.current) {
firstRender.current = false;
} else {
- fetchPlHistory().then((res) => {
+ setLoadingPnl(true);
+ fetchPlHistory({ period: currentDay }).then((res) => {
setUserPL(res);
+ setLoadingPnl(false);
});
requestHistory(queryFilters.page, queryFilters.limit);
}
@@ -282,42 +289,48 @@ const ProfitLossSection = ({
.decimalPlaces(decimalPointNative)
.toNumber();
- return (
-
-
-
- 0) {
+ return (
+
+
+
-
- {coin.display_name}
-
-
-
-
- {sourceAmount} {coin.symbol.toUpperCase()}
-
-
-
- = {sourceAmountNative}{' '}
- {balance_history_config?.currency?.toUpperCase() || 'USDT'}
-
-
- );
+
+
+
{coin.display_name}
+
+
+
+
+ {sourceAmount} {coin.symbol.toUpperCase()}
+
+
+
+ = {sourceAmountNative}{' '}
+ {balance_history_config?.currency?.toUpperCase() || 'USDT'}
+
+
+ );
+ }
+ return null;
})}
>
);
@@ -516,13 +529,19 @@ const ProfitLossSection = ({
return sourceAmount;
};
+
+ const getPeriod = (day) => {
+ if (day === 7) {
+ return '7d';
+ } else if (day === 30) {
+ return '1m';
+ } else return '3m';
+ };
return (
-
+
{customDateModal()}
+
-
-
-
-
- {STRINGS['PROFIT_LOSS.WALLET_PERFORMANCE_TITLE']}
-
-
-
-
- {STRINGS['PROFIT_LOSS.WALLET_PERFORMANCE_DESCRIPTION']}
-
-
-
-
-
-
- {STRINGS['PROFIT_LOSS.EST_TOTAL_BALANCE']}
- {' '}
- {moment(latestBalance?.created_at).format('DD/MMM/YYYY')}
-
-
- {balance_history_config?.currency?.toUpperCase() || 'USDT'}{' '}
- {getSourceDecimals(
- balance_history_config?.currency || 'usdt',
- latestBalance?.total
- )
- ?.toString()
- .replace(/\B(?=(\d{3})+(?!\d))/g, ',') || '0'}
-
+
+
0
- ? 'profitPositive'
- : 'profitNegative'
- }
- >
-
- {STRINGS['PROFIT_LOSS.PL_7_DAY']}
- {' '}
- {Number(userPL?.['7d']?.total || 0) > 0 ? '+' : ' '}
- {''}
- {getSourceDecimals(
- balance_history_config?.currency || 'usdt',
- userPL?.['7d']?.total
- )
- ?.toString()
- .replace(/\B(?=(\d{3})+(?!\d))/g, ',') || '0'}
- {userPL?.['7d']?.totalPercentage
- ? ` (${userPL?.['7d']?.totalPercentage}%) `
- : ' '}
- {balance_history_config?.currency?.toUpperCase() || 'USDT'}
-
-
-
-
-
- {
- setCurrentDay(7);
- setQueryValues({
- start_date: moment().subtract(7, 'days').toISOString(),
- end_date: moment().subtract().toISOString(),
- });
- }}
- >
- 1
-
- {STRINGS['PROFIT_LOSS.WEEK']}
-
-
- {
- setCurrentDay(30);
- setQueryValues({
- start_date: moment().subtract(30, 'days').toISOString(),
- end_date: moment().subtract().toISOString(),
- });
- }}
- >
- 1 {' '}
-
- {STRINGS['PROFIT_LOSS.MONTH']}
-
-
- {
- setCurrentDay(90);
- setQueryValues({
- start_date: moment().subtract(90, 'days').toISOString(),
- end_date: moment().subtract().toISOString(),
- });
- }}
- >
- 3 {' '}
-
- {STRINGS['PROFIT_LOSS.MONTHS']}
-
-
- {
- setCustomDate(true);
- }}
- >
-
- {STRINGS['PROFIT_LOSS.CUSTOM']}
-
-
-
-
-
-
-
-
- {currentBalance && (
- <>
-
-
-
-
- {STRINGS['PROFIT_LOSS.WALLET_BALANCE']}
-
-
-
-
- {STRINGS['PROFIT_LOSS.WALLET_BALANCE_DESCRIPTION_1']}
- {' '}
- {moment(currentBalance?.created_at).format('DD/MMM/YYYY')}.
-
- {STRINGS['PROFIT_LOSS.WALLET_BALANCE_DESCRIPTION_2']}
-
-
-
-
+
-
- {STRINGS['PROFIT_LOSS.EST_TOTAL_BALANCE']}
- {' '}
- {moment(currentBalance?.created_at).format('DD/MMM/YYYY')}
-
-
- {balance_history_config?.currency?.toUpperCase() || 'USDT'}{' '}
- {getSourceDecimals(
- balance_history_config?.currency || 'usdt',
- currentBalance?.total
- )
- ?.toString()
- .replace(/\B(?=(\d{3})+(?!\d))/g, ',') || '0'}
+
+
+ {STRINGS['PROFIT_LOSS.WALLET_PERFORMANCE_TITLE']}
+
+
+
+
+ {STRINGS['PROFIT_LOSS.WALLET_PERFORMANCE_DESCRIPTION']}
+
+
-
- {STRINGS['PROFIT_LOSS.DATE_SELECT']}
-
- :
+
+ {STRINGS['PROFIT_LOSS.EST_TOTAL_BALANCE']}
+ {' '}
+ {moment(latestBalance?.created_at).format('DD/MMM/YYYY')}
+
+
+ {balance_history_config?.currency?.toUpperCase() || 'USDT'}{' '}
+ {getSourceDecimals(
+ balance_history_config?.currency || 'usdt',
+ latestBalance?.total
+ )
+ ?.toString()
+ .replace(/\B(?=(\d{3})+(?!\d))/g, ',') || '0'}
-
{
- return (
- current &&
- (current <
- moment(
- balance_history_config?.date_enabled,
- 'YYYY-MM-DD'
- ) ||
- current.isAfter(moment()))
- );
- }}
- style={{
- width: '12.5em',
- fontSize: '1em',
- }}
- onChange={(date, dateString) => {
- if (!dateString) return;
- setSelectedCustomDate(date);
- fetchBalanceHistory({
- start_date: moment(dateString)
- .startOf('day')
- .toISOString(),
- end_date: moment(dateString).endOf('day').toISOString(),
- limit: 1,
- })
- .then((response) => {
- let balance = response?.data?.[0];
-
- if (balance) setCurrentBalance(balance);
- else {
- message.error('Balance not found');
- }
- })
- .catch((error) => {
- message.error('Something went wrong');
- });
- }}
- format={'YYYY/MM/DD'}
- />
+
+ 0
+ ? 'profitPositive'
+ : 'profitNegative'
+ }
+ >
+ {' '}
+ {currentDay + ' '}
+
+ {STRINGS['PROFIT_LOSS.PL_DAYS']}
+ {' '}
+ {Number(userPL?.[getPeriod(currentDay)]?.total || 0) > 0
+ ? '+'
+ : ' '}
+ {''}
+ {getSourceDecimals(
+ balance_history_config?.currency || 'usdt',
+ userPL?.[getPeriod(currentDay)]?.total
+ )
+ ?.toString()
+ .replace(/\B(?=(\d{3})+(?!\d))/g, ',') || '0'}
+ {userPL?.[getPeriod(currentDay)]?.totalPercentage
+ ? ` (${
+ userPL?.[getPeriod(currentDay)]?.totalPercentage
+ }%) `
+ : ' '}
+ {balance_history_config?.currency?.toUpperCase() ||
+ 'USDT'}
+
+
-
-
-
-
-
-
-
- {STRINGS['PROFIT_LOSS.ASSET_NAME']}
-
-
-
-
- {STRINGS['PROFIT_LOSS.BALANCE_AMOUNT']}
+
+ {
+ setCurrentDay(7);
+ setQueryValues({
+ start_date: moment().subtract(7, 'days').toISOString(),
+ end_date: moment().subtract().toISOString(),
+ });
+ }}
+ >
+ 1
+
+ {STRINGS['PROFIT_LOSS.WEEK']}
+
+
+ {
+ setCurrentDay(30);
+ setQueryValues({
+ start_date: moment().subtract(30, 'days').toISOString(),
+ end_date: moment().subtract().toISOString(),
+ });
+ }}
+ >
+ 1 {' '}
+
+ {STRINGS['PROFIT_LOSS.MONTH']}
+
+
+ {
+ setCurrentDay(90);
+ setQueryValues({
+ start_date: moment().subtract(90, 'days').toISOString(),
+ end_date: moment().subtract().toISOString(),
+ });
+ }}
+ >
+ 3 {' '}
+
+ {STRINGS['PROFIT_LOSS.MONTHS']}
+
+
+ {/* {
+ setCustomDate(true);
+ }}
+ >
+
+ {STRINGS['PROFIT_LOSS.CUSTOM']}
+
+ */}
+
+
+
+
+
+
+
+ {currentBalance && (
+
+
+
+
+
+
+ {STRINGS['PROFIT_LOSS.WALLET_BALANCE']}
-
-
-
- {STRINGS['PROFIT_LOSS.VALUE']}
+
+
+
+ {STRINGS['PROFIT_LOSS.WALLET_BALANCE_DESCRIPTION_1']}
+ {' '}
+ {moment(currentBalance?.created_at).format('DD/MMM/YYYY')}
+ .
+
+ {STRINGS['PROFIT_LOSS.WALLET_BALANCE_DESCRIPTION_2']}
-
-
-
-
- {getRows(coins)}
-
-
-
- >
- )}
+
+
+
+
+
+ {STRINGS['PROFIT_LOSS.EST_TOTAL_BALANCE']}
+ {' '}
+ {moment(currentBalance?.created_at).format('DD/MMM/YYYY')}
+
+
+ {balance_history_config?.currency?.toUpperCase() ||
+ 'USDT'}{' '}
+ {getSourceDecimals(
+ balance_history_config?.currency || 'usdt',
+ currentBalance?.total
+ )
+ ?.toString()
+ .replace(/\B(?=(\d{3})+(?!\d))/g, ',') || '0'}
+
+
+
+
+ {STRINGS['PROFIT_LOSS.DATE_SELECT']}
+
+ :
+
+
{
+ return (
+ current &&
+ (current <
+ moment(
+ balance_history_config?.date_enabled,
+ 'YYYY-MM-DD'
+ ) ||
+ current.isAfter(moment()))
+ );
+ }}
+ style={{
+ width: '12.5em',
+ fontSize: '1em',
+ }}
+ onChange={(date, dateString) => {
+ if (!dateString) return;
+ setSelectedCustomDate(date);
+ fetchBalanceHistory({
+ start_date: moment(dateString)
+ .startOf('day')
+ .toISOString(),
+ end_date: moment(dateString)
+ .endOf('day')
+ .toISOString(),
+ limit: 1,
+ })
+ .then((response) => {
+ let balance = response?.data?.[0];
+
+ if (balance) setCurrentBalance(balance);
+ else {
+ message.error('Balance not found');
+ }
+ })
+ .catch((error) => {
+ message.error('Something went wrong');
+ });
+ }}
+ format={'YYYY/MM/DD'}
+ />
+
+
+
+
+
+
+
+
+
+
+ {STRINGS['PROFIT_LOSS.ASSET_NAME']}
+
+
+
+
+ {STRINGS['PROFIT_LOSS.BALANCE_AMOUNT']}
+
+
+
+
+ {STRINGS['PROFIT_LOSS.VALUE']}
+
+
+
+
+
+ {getRows(coins)}
+
+
+
+
+
+ )}
+
);
diff --git a/web/src/containers/Wallet/_ProfitLoss.scss b/web/src/containers/Wallet/_ProfitLoss.scss
index b199b59b7a..088cdabaa0 100644
--- a/web/src/containers/Wallet/_ProfitLoss.scss
+++ b/web/src/containers/Wallet/_ProfitLoss.scss
@@ -42,6 +42,32 @@
color: '#ccc';
}
+.profit-loss-wrapper {
+ .view-more-content {
+ display: none;
+ cursor: pointer;
+ }
+ .highChartColor {
+ opacity: 0.5;
+ }
+}
+
+.profit-loss-wrapper:hover {
+ transform: translateY(-5%);
+ transition-timing-function: ease-in;
+ transition: 0.2s;
+ .highChartColor {
+ opacity: unset;
+ }
+ .view-more-content {
+ display: block;
+ text-align: end;
+ }
+ .view-more-content :first-child:first-child {
+ text-decoration: underline;
+ }
+}
+
.profit_block-table {
width: 100%;
// font-size: $font-size-subtext;
@@ -93,4 +119,7 @@
min-width: 150px !important;
direction: ltr;
}
+ .date-text {
+ color: var(--labels_important-active-labels-text-graphics);
+ }
}
diff --git a/web/src/containers/Wallet/_Wallet.scss b/web/src/containers/Wallet/_Wallet.scss
index e1a4dc92d0..844e5837df 100644
--- a/web/src/containers/Wallet/_Wallet.scss
+++ b/web/src/containers/Wallet/_Wallet.scss
@@ -603,7 +603,7 @@ $header-margin: 2rem;
width: 300px !important;
}
.currency-wallet-wrapper {
- width: 60%;
+ width: 80%;
margin-left: auto;
margin-right: auto;
font-family: $raleway--font-family;
diff --git a/web/src/containers/Wallet/components/CurrencySlider.js b/web/src/containers/Wallet/components/CurrencySlider.js
index ab3501a6e9..34130ff106 100644
--- a/web/src/containers/Wallet/components/CurrencySlider.js
+++ b/web/src/containers/Wallet/components/CurrencySlider.js
@@ -286,6 +286,9 @@ class CurrencySlider extends Component {
{
+ this.props.handleBalanceHistory(true);
+ }}
className={
Number(this.state.userPL?.['7d']?.total || 0) === 0
? 'profitNeutral'
@@ -298,6 +301,7 @@ class CurrencySlider extends Component {
display: 'flex',
justifyContent: 'center',
fontSize: '1.5rem',
+ cursor: 'pointer',
}}
>
diff --git a/web/src/containers/Withdraw/Fiat/FormUtils.js b/web/src/containers/Withdraw/Fiat/FormUtils.js
index bd4ded35e2..9976a6be15 100644
--- a/web/src/containers/Withdraw/Fiat/FormUtils.js
+++ b/web/src/containers/Withdraw/Fiat/FormUtils.js
@@ -170,15 +170,6 @@ export const generateFormValues = (
};
}
- fields.captcha = {
- type: 'captcha',
- language,
- theme,
- validate: [required],
- strings: STRINGS,
- constants,
- };
-
return fields;
};
diff --git a/web/src/containers/Withdraw/Fiat/WithdrawalForm.js b/web/src/containers/Withdraw/Fiat/WithdrawalForm.js
index 2503327c90..249f9bfe0f 100644
--- a/web/src/containers/Withdraw/Fiat/WithdrawalForm.js
+++ b/web/src/containers/Withdraw/Fiat/WithdrawalForm.js
@@ -6,8 +6,7 @@ import {
formValueSelector,
reset,
SubmissionError,
- stopSubmit,
- change,
+ stopSubmit
} from 'redux-form';
import renderFields from 'components/Form/factoryFields';
import ReviewModalContent from './ReviewModalContent';
@@ -120,9 +119,6 @@ class Index extends Component {
: err.message,
...err.errors,
};
- errorTimeOut = setTimeout(() => {
- this.props.dispatch(change(FORM_NAME, 'captcha', ''));
- }, 5000);
this.props.onSubmitFail(err.errors || err, this.props.dispatch);
this.onCloseDialog();
this.props.dispatch(stopSubmit(FORM_NAME, error));
@@ -179,9 +175,6 @@ class Index extends Component {
: err.message,
...err.errors,
};
- errorTimeOut = setTimeout(() => {
- this.props.dispatch(change(FORM_NAME, 'captcha', ''));
- }, 5000);
this.props.onSubmitFail(err.errors, this.props.dispatch);
this.onCloseDialog();
this.props.dispatch(stopSubmit(FORM_NAME, error));
@@ -193,9 +186,6 @@ class Index extends Component {
? err.response.data.message
: err.message,
};
- errorTimeOut = setTimeout(() => {
- this.props.dispatch(change(FORM_NAME, 'captcha', ''));
- }, 5000);
this.props.onSubmitFail(error, this.props.dispatch);
this.onCloseDialog();
this.props.dispatch(stopSubmit(FORM_NAME, error));
@@ -371,7 +361,7 @@ const FiatWithdrawalForm = reduxForm({
})(Index);
const mapStateToProps = (state) => ({
- data: selector(state, 'bank', 'amount', 'fee', 'captcha'),
+ data: selector(state, 'bank', 'amount', 'fee'),
fiat_fees: state.app.constants.fiat_fees,
});
diff --git a/web/src/containers/Withdraw/form.js b/web/src/containers/Withdraw/form.js
index ec51f8fa09..71a9f5e793 100644
--- a/web/src/containers/Withdraw/form.js
+++ b/web/src/containers/Withdraw/form.js
@@ -5,8 +5,7 @@ import {
formValueSelector,
reset,
SubmissionError,
- stopSubmit,
- change,
+ stopSubmit
} from 'redux-form';
import math from 'mathjs';
import { Button, Dialog, OtpForm, Loader, SmartTarget } from 'components';
@@ -147,9 +146,6 @@ class Form extends Component {
})
.catch((err) => {
const error = { _error: err.message, ...err.errors };
- errorTimeOut = setTimeout(() => {
- this.props.dispatch(change(FORM_NAME, 'captcha', ''));
- }, 5000);
this.props.onSubmitFail(err.errors || err, this.props.dispatch);
this.onCloseDialog();
this.props.dispatch(stopSubmit(FORM_NAME, error));
@@ -183,9 +179,6 @@ class Form extends Component {
if (err instanceof SubmissionError) {
if (err.errors && !err.errors.otp_code) {
const error = { _error: err.message, ...err.errors };
- errorTimeOut = setTimeout(() => {
- this.props.dispatch(change(FORM_NAME, 'captcha', ''));
- }, 5000);
this.props.onSubmitFail(err.errors, this.props.dispatch);
this.onCloseDialog();
this.props.dispatch(stopSubmit(FORM_NAME, error));
@@ -193,9 +186,6 @@ class Form extends Component {
throw err;
} else {
const error = { _error: err.message };
- errorTimeOut = setTimeout(() => {
- this.props.dispatch(change(FORM_NAME, 'captcha', ''));
- }, 5000);
this.props.onSubmitFail(error, this.props.dispatch);
this.onCloseDialog();
this.props.dispatch(stopSubmit(FORM_NAME, error));
@@ -340,7 +330,6 @@ const mapStateToForm = (state) => ({
'address',
'destination_tag',
'amount',
- 'captcha',
'fee',
'fee_coin',
'email',
diff --git a/web/src/containers/Withdraw/formUtils.js b/web/src/containers/Withdraw/formUtils.js
index 3c1cd8ad1a..ed54afe795 100644
--- a/web/src/containers/Withdraw/formUtils.js
+++ b/web/src/containers/Withdraw/formUtils.js
@@ -11,7 +11,6 @@ import {
import STRINGS from 'config/localizedStrings';
import { STATIC_ICONS } from 'config/icons';
import { DEFAULT_COIN_DATA } from 'config/constants';
-import { getLanguage } from 'utils/string';
import { getTheme } from 'utils/theme';
import { toFixed } from 'utils/currency';
import { getDecimals } from 'utils/utils';
@@ -60,7 +59,10 @@ export const generateInitialValues = (
const roundedMarkup = new BigNumber(feeMarkup)
.decimalPlaces(decimalPoint)
.toNumber();
- initialValues.fee += roundedMarkup;
+
+ initialValues.fee = new BigNumber(initialValues.fee || 0)
+ .plus(roundedMarkup || 0)
+ .toNumber();
}
initialValues.destination_tag = '';
@@ -378,12 +380,5 @@ export const generateFormValues = (
};
}
- fields.captcha = {
- type: 'captcha',
- language: getLanguage(),
- theme: theme,
- validate: [required],
- };
-
return fields;
};
diff --git a/web/src/index.css b/web/src/index.css
index 774f4098bf..95f225663a 100644
--- a/web/src/index.css
+++ b/web/src/index.css
@@ -845,16 +845,17 @@ table th {
.direction_rtl .user-limits .user-limits-table .table-icon {
padding-left: 0.5rem; }
-.user_security-wrapper {
+.user_security-wrapper,
+.user_security-wrapper-disabled {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
- margin-top: 30px;
padding: 30px;
background-color: var(--base_wallet-sidebar-and-popup); }
- .user_security-wrapper > *:not(:last-child) {
- margin-bottom: 2rem; }
+
+.user_security-wrapper-disabled {
+ margin-top: 3%; }
.OTP_Success {
width: 30px;
@@ -868,8 +869,97 @@ table th {
flex-direction: column;
min-width: 30rem;
width: 30rem; }
+ .otp_form-wrapper .step-one-title-wrapper {
+ font-family: 'Open Sans'; }
+ .otp_form-wrapper .step-one-pop-up .store-wrapper {
+ cursor: pointer;
+ padding: 2%;
+ width: 30%;
+ color: #000000;
+ font-size: 10px;
+ border-radius: 10px;
+ border: 1px solid var(--calculated_important-border);
+ background-color: #f5f5f7; }
+ .otp_form-wrapper .step-one-pop-up .store-wrapper .store-icons {
+ width: 25%; }
+ .otp_form-wrapper .step-one-pop-up .download-content-title {
+ font-weight: bold;
+ margin: 2% 0; }
+ .otp_form-wrapper .step-one-pop-up .store-icons-wrapper {
+ display: flex;
+ justify-content: space-evenly;
+ margin-bottom: 5%; }
+ .otp_form-wrapper .step-one-pop-up .store-icons-wrapper .play-store-field {
+ cursor: pointer;
+ padding: 2%;
+ width: 100%;
+ height: 50%;
+ color: var(--labels_important-active-labels-text-graphics);
+ font-size: 12px;
+ border-radius: 10px;
+ background-color: var(--labels_important-active-labels-text-graphics); }
+ .otp_form-wrapper .step-one-pop-up .app-info {
+ margin-bottom: 5%; }
+ .otp_form-wrapper .step-one-pop-up .uninstall-info {
+ color: #ffbb00;
+ font-weight: bold; }
+ .otp_form-wrapper .step-one-pop-up .note-txt,
+ .otp_form-wrapper .step-two-pop-up .note-txt {
+ color: #e59b07; }
+ .otp_form-wrapper .step-one-pop-up .otp-border,
+ .otp_form-wrapper .step-one-pop-up .otp-border-footer,
+ .otp_form-wrapper .step-two-pop-up .otp-border,
+ .otp_form-wrapper .step-two-pop-up .otp-border-footer {
+ margin-bottom: 5%;
+ border-bottom: 1px solid var(--calculated_important-border);
+ width: 100%; }
+ .otp_form-wrapper .step-one-pop-up .otp-border-footer,
+ .otp_form-wrapper .step-two-pop-up .otp-border-footer {
+ width: 25%; }
+ .otp_form-wrapper .step-one-pop-up .btn-wrapper,
+ .otp_form-wrapper .step-two-pop-up .btn-wrapper {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 8%; }
+ .otp_form-wrapper .step-one-pop-up .btn-wrapper .back-btn,
+ .otp_form-wrapper .step-one-pop-up .btn-wrapper .proceed-btn,
+ .otp_form-wrapper .step-two-pop-up .btn-wrapper .back-btn,
+ .otp_form-wrapper .step-two-pop-up .btn-wrapper .proceed-btn {
+ background-color: var(--specials_buttons-links-and-highlights);
+ border: none;
+ width: 45%;
+ height: 40px;
+ text-align: center;
+ color: var(--labels_important-active-labels-text-graphics); }
+ .otp_form-wrapper .step-two-pop-up .btn-wrapper {
+ margin-top: 5% !important; }
+ .otp_form-wrapper .step-three-pop-up .verfication-field {
+ background-color: var(--base_wallet-sidebar-and-popup);
+ border: none;
+ border-bottom: 1px solid var(--labels_secondary-inactive-label-text-graphics);
+ border-image: initial;
+ width: 100%;
+ margin-top: 5px; }
+ .otp_form-wrapper .step-three-pop-up .warning-text {
+ color: var(--labels_secondary-inactive-label-text-graphics);
+ margin-top: 15%; }
+ .otp_form-wrapper .step-three-pop-up .btn-wrapper {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 8%; }
+ .otp_form-wrapper .step-three-pop-up .back-btn,
+ .otp_form-wrapper .step-three-pop-up .proceed-btn,
+ .otp_form-wrapper .step-four-pop-up .back-btn,
+ .otp_form-wrapper .step-four-pop-up .proceed-btn {
+ background-color: var(--specials_buttons-links-and-highlights);
+ border: none;
+ width: 45%;
+ height: 40px;
+ text-align: center;
+ color: var(--labels_important-active-labels-text-graphics); }
+ .otp_form-wrapper .step-four-pop-up .back-btn {
+ width: 100%; }
.otp_form-wrapper .otp_form-section-wrapper {
- border-top: 1px solid var(--calculated_important-border);
padding: 0.75rem 0; }
.otp_form-wrapper .otp_form-section-wrapper .otp_form-section-content {
margin: 1rem 0; }
@@ -895,8 +985,8 @@ table th {
.otp_form-wrapper .icon_title-wrapper .icon_title-text.title {
font-size: 2rem; }
.otp_form-wrapper .icon_title-wrapper .icon_title-svg {
- width: 6.5rem;
- height: 6.5rem; }
+ width: 5.5rem;
+ height: 5.5rem; }
.otp_form-wrapper .icon_title-wrapper .icon_title-svg svg {
width: 6.5rem;
height: 6.5rem; }
@@ -1007,6 +1097,17 @@ table th {
.user-security-container .checkbutton-input-wrapper {
margin-top: 0px !important; }
+.otp-field-wrapper {
+ margin-top: 3%; }
+ .otp-field-wrapper .warning_text {
+ padding: 10px;
+ text-align: center;
+ background-color: var(--specials_notifications-alerts-warnings);
+ color: var(--labels_important-active-labels-text-graphics); }
+ .otp-field-wrapper .warning_text .improtant-text {
+ font-weight: bold;
+ text-decoration: underline; }
+
.layout-mobile .user_security-wrapper .warning_text {
font-size: 13px !important; }
@@ -1156,6 +1257,12 @@ table th {
height: 3rem;
width: 3rem; }
+.errorField {
+ border-color: var(--specials_notifications-alerts-warnings) !important; }
+
+.errorText {
+ color: var(--specials_notifications-alerts-warnings) !important; }
+
.signup_success-wrapper {
text-align: center; }
.signup_success-wrapper .signup_success-content {
@@ -1954,7 +2061,7 @@ table th {
width: 300px !important; }
.currency-wallet-wrapper {
- width: 60%;
+ width: 80%;
margin-left: auto;
margin-right: auto;
font-family: "Raleway"; }
@@ -3548,8 +3655,7 @@ table th {
font-size: 1.8rem; }
.trade-details-wrapper .trade-details-content .trade_tabs-container {
margin: 0;
- padding-left: 80px;
- width: 100% !important; }
+ width: auto !important; }
.trade-details-wrapper .trade-details-content .main-coin-wrapper {
opacity: 0.3; }
.trade-details-wrapper .trade-details-content .fullname {
@@ -3714,10 +3820,10 @@ table th {
margin: 2dvh auto; }
.risky-trade-disclaimer .extreme-volatility-msg {
- color: #FFAA00; }
+ color: #ffaa00; }
.risky-trade-disclaimer .disclaimer-checkbox span {
- color: #fff;
+ color: var(--labels_important-active-labels-text-graphics);
opacity: 0.7; }
.risky-trade-disclaimer .disclaimer-checkbox.disclaimer-checkbox-selected span {
@@ -5936,8 +6042,7 @@ table th {
font-size: 1.8rem; }
.trade-details-wrapper .trade-details-content .trade_tabs-container {
margin: 0;
- padding-left: 80px;
- width: 100% !important; }
+ width: auto !important; }
.trade-details-wrapper .trade-details-content .main-coin-wrapper {
opacity: 0.3; }
.trade-details-wrapper .trade-details-content .fullname {
@@ -6134,7 +6239,7 @@ table th {
z-index: -1; }
.hollaex-token-wrapper .token-wrapper .hollaex-container .trade-details-wrapper .trade-details-content .trade_tabs-container {
margin: 0 !important;
- width: 100% !important; }
+ width: auto !important; }
.hollaex-token-wrapper .token-wrapper .hollaex-container .trade-details-wrapper .f-size-16 {
font-size: 16px;
color: var(--labels_secondary-inactive-label-text-graphics);
@@ -6144,7 +6249,7 @@ table th {
font-weight: bold; }
.hollaex-token-wrapper .token-wrapper .hollaex-container .trade-details-wrapper .fullname {
color: var(--labels_secondary-inactive-label-text-graphics);
- font-size: 0.65rem;
+ font-size: 1rem;
white-space: nowrap; }
.hollaex-token-wrapper .token-wrapper .hollaex-container .trade-details-wrapper .sub-title {
color: var(--labels_secondary-inactive-label-text-graphics);
@@ -6225,6 +6330,8 @@ table th {
width: 100%;
padding: 0.5rem 0.5rem 0.8rem 0.5rem;
justify-content: space-around; }
+ .sidebar-bottom-wrapper .sidebar-bottom-button-account .sidebar-bottom-icon svg g .assets-icon-tab {
+ opacity: 0.5; }
.sidebar-bottom-wrapper .sidebar-bottom-button {
justify-content: space-between;
flex-direction: column;
@@ -6237,13 +6344,13 @@ table th {
.sidebar-bottom-wrapper .sidebar-bottom-button .sidebar-bottom-icon svg .quick-trade-tab-active,
.sidebar-bottom-wrapper .sidebar-bottom-button .sidebar-bottom-icon svg .assets-icon-tab,
.sidebar-bottom-wrapper .sidebar-bottom-button .sidebar-bottom-icon svg .onramp-icon {
- fill: var(--calculated_base_top-bar-navigation_text-inactive); }
+ fill: var(--labels_secondary-inactive-label-text-graphics); }
.sidebar-bottom-wrapper .sidebar-bottom-button .sidebar-bottom-icon svg .tab-wallet0,
.sidebar-bottom-wrapper .sidebar-bottom-button .sidebar-bottom-icon svg .trade-active-2,
.sidebar-bottom-wrapper .sidebar-bottom-button .sidebar-bottom-icon svg .chat-0,
.sidebar-bottom-wrapper .sidebar-bottom-button .sidebar-bottom-icon svg .quick-trade-tab-active,
.sidebar-bottom-wrapper .sidebar-bottom-button .sidebar-bottom-icon svg .assets-icon-tab {
- stroke: var(--calculated_base_top-bar-navigation_text-inactive); }
+ stroke: var(--labels_secondary-inactive-label-text-graphics); }
.sidebar-bottom-wrapper .sidebar-bottom-button .sidebar-bottom-icon svg .tab-wallet0,
.sidebar-bottom-wrapper .sidebar-bottom-button .sidebar-bottom-icon svg .quick-trade-tab-active {
fill: transparent; }
@@ -6260,7 +6367,7 @@ table th {
.sidebar-bottom-wrapper .sidebar-bottom-button.active .sidebar-bottom-icon svg .assets-icon-tab {
stroke: var(--calculated_base_top-bar-navigation_text); }
.sidebar-bottom-wrapper .sidebar-bottom-button .bottom-bar-text {
- font-size: 10px;
+ font-size: 9px;
text-align: center;
margin-top: -17px;
font-weight: lighter;
@@ -6326,61 +6433,10 @@ table th {
.sidebar-bottom-button-trade .edit-wrapper__container {
height: 100%; }
-@media screen and (max-width: 375px) {
- .mobile-trade-wrapper .pro-trade-footer-icon {
- height: 50%;
- margin-top: 20% !important; }
- .mobile-trade-wrapper .quick-trade-footer-icon {
- margin-top: 20% !important; }
- .mobile-trade-wrapper .quick-trade-field,
- .mobile-trade-wrapper .pro-trade-field {
- width: 65px !important;
- height: 65px !important; }
- .sidebar-bottom-button-trade {
- height: 130%;
- width: 20% !important; } }
-
-@media screen and (max-width: 450px) and (min-width: 375px) {
- .mobile-trade-wrapper {
- width: 50%; }
- .mobile-trade-wrapper .pro-trade-footer-icon {
- height: 50%;
- margin-top: 18% !important; }
- .mobile-trade-wrapper .quick-trade-footer-icon {
- height: 40%;
- margin-top: 20% !important; }
- .mobile-trade-wrapper .quick-trade-field,
- .mobile-trade-wrapper .pro-trade-field {
- width: 75px !important;
- height: 75px !important; }
- .sidebar-bottom-button-trade {
- height: 135%;
- width: 18% !important; } }
-
-@media screen and (max-width: 550px) and (min-width: 450px) {
- .mobile-trade-wrapper {
- width: 50%; }
- .mobile-trade-wrapper .quick-trade-field,
- .mobile-trade-wrapper .pro-trade-field {
- width: 85px !important;
- height: 85px !important; }
- .mobile-trade-wrapper .pro-trade-footer-icon {
- height: 40%;
- margin-top: 25% !important; }
- .mobile-trade-wrapper .quick-trade-footer-icon {
- height: 35%;
- margin-top: 25% !important; } }
-
@media screen and (max-height: 600px) {
.sidebar-bottom-icon svg {
stroke: none !important; } }
-@media screen and (max-width: 768px) {
- .mobile-trade-wrapper .quick-trade-field,
- .mobile-trade-wrapper .pro-trade-field {
- width: 100px;
- height: 100px; } }
-
.tab_controller-title {
display: flex;
align-items: center;
@@ -7049,6 +7105,8 @@ table th {
.market-bar .selector-trigger.narrow {
min-width: 14rem;
max-width: 14rem; }
+ .market-bar .fav-price-label {
+ color: var(--labels_important-active-labels-text-graphics) !important; }
.market-bar .app_bar-currency-txt {
font-weight: 600; }
.market-bar .app-price-diff-down {
@@ -8436,13 +8494,17 @@ table th {
border: 1px solid var(--labels_secondary-inactive-label-text-graphics);
background: var(--labels_secondary-inactive-label-text-graphics); }
.mainContainer .active {
- border: 1px solid var(--labels_secondary-inactive-label-text-graphics) !important; }
+ border: 2px solid var(--labels_secondary-inactive-label-text-graphics) !important; }
.mainContainer .error {
border: 1px solid var(--specials_notifications-alerts-warnings) !important; }
- .mainContainer .group {
+ .mainContainer .leftGroup,
+ .mainContainer .rightGroup {
padding: 1rem; }
- .mainContainer .group input {
+ .mainContainer .leftGroup input,
+ .mainContainer .rightGroup input {
margin: 0 0.25rem; }
+ .mainContainer .leftGroup .error:first-child {
+ border: 2px solid var(--specials_notifications-alerts-warnings) !important; }
.input_icon {
margin-right: 0.25rem;
@@ -8839,6 +8901,10 @@ table th {
.dialog-content.bottom {
padding-bottom: 2.5rem; }
+.cancel-withdraw-pop-up .ReactModal__Content {
+ width: 25% !important;
+ padding: 0rem 2.5rem 2.5rem 2.5rem !important; }
+
.ReactModal__Content {
padding: 2.5rem !important;
top: auto !important;
@@ -8864,6 +8930,11 @@ table th {
.success_display-wrapper > * {
flex: 0; }
+.success_disable-display-wrapper,
+.success_active-display-wrapper {
+ min-width: 20rem;
+ min-height: 14rem; }
+
.success_display-content {
height: auto;
flex: 1; }
@@ -9337,12 +9408,24 @@ table th {
background-size: contain;
background-position: center;
background-repeat: no-repeat; }
+ .icon_title-wrapper .step-one-title-wrapper {
+ margin-top: unset; }
.direction_ltr .icon_title-wrapper {
font-family: "Raleway"; }
-.fees_limits .icon_title-text.title {
- font-size: 1.5rem !important; }
+.fees_limits .fees-limits-title {
+ font-size: 1.5rem !important;
+ text-transform: capitalize;
+ padding-top: 0.25rem !important; }
+
+.cancel-widrawal-pop-up .icon_title-text.title {
+ font-size: 2rem !important;
+ text-transform: capitalize;
+ padding-top: 0.25rem !important; }
+
+.cancel-widrawal-pop-up:last-child {
+ margin-top: 2rem !important; }
.layout-mobile .icon_title-wrapper .auth_logo-wrapper svg {
height: 8rem !important;
@@ -9635,7 +9718,8 @@ table th {
font-size: 8px !important; } }
.quick-trade-select-wrapper .input-group__coin-icons-wrap {
- display: flex; }
+ display: flex;
+ pointer-events: none; }
.input-group__container {
border-radius: 4px;
@@ -9817,18 +9901,22 @@ table th {
top: 50% !important; }
.quick_trade-container .active-input {
color: var(--labels_important-active-labels-text-graphics) !important; }
- .quick_trade-container .input-group__input, .quick_trade-container .active-input {
+ .quick_trade-container .input-group__input,
+ .quick_trade-container .active-input {
text-align: right;
color: var(--labels_secondary-inactive-label-text-graphics);
font-size: 2.1rem;
margin-left: 1rem;
height: 40px; }
- .quick_trade-container .input-group__input:focus, .quick_trade-container .input-group__input:active, .quick_trade-container .active-input:focus, .quick_trade-container .active-input:active {
+ .quick_trade-container .input-group__input:focus, .quick_trade-container .input-group__input:active,
+ .quick_trade-container .active-input:focus,
+ .quick_trade-container .active-input:active {
background-color: var(--base_secondary-navigation-bar) !important;
box-shadow: inset 1px 1px 3px #00000029;
border-radius: 5px;
border-bottom: 1px solid #ffffff; }
- .quick_trade-container .input-group__input:hover, .quick_trade-container .active-input:hover {
+ .quick_trade-container .input-group__input:hover,
+ .quick_trade-container .active-input:hover {
color: var(--labels_important-active-labels-text-graphics); }
.quick_trade-container .field-error-content {
display: block; }
@@ -11215,6 +11303,12 @@ table th {
.price-change .glance-up.entering:before, .price-change .glance-up.exiting:before {
border-color: var(--calculated_trading_buying-related-text); }
+.price-change .markets-drop-down {
+ display: flex; }
+
+.price-change .markets-drop-down.down:before {
+ margin: 10% 0 0 0; }
+
.hollaex-token-wrapper {
font-family: 'Open Sans' !important; }
diff --git a/web/src/index.js b/web/src/index.js
index 5dd81916e7..59a68336fe 100644
--- a/web/src/index.js
+++ b/web/src/index.js
@@ -120,7 +120,6 @@ const getConfigs = async () => {
features: { home_page = false } = {},
injected_values = [],
injected_html = {},
- captcha = {},
defaults = {},
} = kitData;
@@ -245,7 +244,6 @@ const getConfigs = async () => {
const appConfigs = merge({}, defaultConfig, remoteConfigs, {
coin_icons,
- captcha,
valid_languages,
defaults,
});
diff --git a/web/src/reducers/appReducer.js b/web/src/reducers/appReducer.js
index d907b1938d..11fabc46c7 100644
--- a/web/src/reducers/appReducer.js
+++ b/web/src/reducers/appReducer.js
@@ -58,6 +58,8 @@ import {
SET_EXPLORE_PLUGINS,
OVERWRITE_CURRENCY_NAMES,
SET_TRANSACTION_LIMITS,
+ SET_SELECTED_ACCOUNT,
+ SET_SELECTED_STEP,
} from 'actions/appActions';
import { THEME_DEFAULT } from 'config/constants';
import { getLanguage } from 'utils/string';
@@ -160,6 +162,8 @@ const INITIAL_STATE = {
is_descending: true,
},
default_digital_assets_sort: DIGITAL_ASSETS_SORT.CHANGE,
+ selectedAccount: 1,
+ selectedStep: 0,
};
const reducer = (state = INITIAL_STATE, { type, payload = {} }) => {
@@ -705,6 +709,16 @@ const reducer = (state = INITIAL_STATE, { type, payload = {} }) => {
pinned_assets: payload.pinned_assets,
default_digital_assets_sort: payload.default_digital_assets_sort,
};
+ case SET_SELECTED_ACCOUNT:
+ return {
+ ...state,
+ selectedAccount: payload.selectedAccount,
+ };
+ case SET_SELECTED_STEP:
+ return {
+ ...state,
+ selectedStep: payload.selectedStep,
+ };
default:
return state;
}
diff --git a/web/src/routes.js b/web/src/routes.js
index e47c1b0c03..f8dc69172a 100644
--- a/web/src/routes.js
+++ b/web/src/routes.js
@@ -396,7 +396,7 @@ export const generateRoutes = (routes = []) => {
name="Fees and limits"
component={FeesAndLimits}
/>
-
+
@@ -439,7 +439,7 @@ export const generateRoutes = (routes = []) => {
component={QuickTrade}
/>
diff --git a/web/src/utils/wallet.js b/web/src/utils/wallet.js
index b3e8e26734..5276596e27 100644
--- a/web/src/utils/wallet.js
+++ b/web/src/utils/wallet.js
@@ -38,6 +38,8 @@ export const getNetworkNameByKey = (network) => {
return 'Solana';
case 'xlm':
return 'Stellar';
+ case 'ftm':
+ return 'Fantom';
default:
return network.toUpperCase();
}