Skip to content

Commit

Permalink
thisyahlen/chore: update regulation edge cases if one of regulations …
Browse files Browse the repository at this point in the history
…does not have an account (#13046)

* chore: update regulation edge cases if one of regulations does not have an account

* fix: demo real swither bug

* chore: komen
  • Loading branch information
thisyahlen-deriv authored Jan 19, 2024
1 parent a2fecc3 commit 2380193
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 58 deletions.
2 changes: 1 addition & 1 deletion packages/tradershub/src/AppContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const AppContent = () => {

return (
<div className='h-full-mobile lg:h-full-desktop'>
<div className='font-sans max-w-[1232px] mx-auto lg:pt-2500 lg:px-50'>
<div className='font-sans max-w-[1232px] mx-auto lg:py-2500 lg:px-50'>
<div className='z-10' id='v2_modal_show_header_root' />
<Router />
</div>
Expand Down
27 changes: 21 additions & 6 deletions packages/tradershub/src/components/CFDSection/CFDSection.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
import React from 'react';
import useRegulationFlags from '../../hooks/useRegulationFlags';
import { GetADerivAccountBanner } from '../GetADerivAccountBanner';
import { useUIContext } from '../UIProvider';
import { CFDContent } from './CFDContent';
import { CFDHeading } from './CFDHeading';

const CFDSection = () => (
<div className='overflow-y-scroll border-solid pt-800 lg:p-1200 rounded-1200 lg:border-xs lg:border-opacity-black-100'>
<CFDHeading />
<CFDContent />
</div>
);
const CFDSection = () => {
const { getUIState } = useUIContext();
const regulation = getUIState('regulation');
const accountType = getUIState('accountType');
const { isSuccess, noRealCRNonEUAccount, noRealMFEUAccount } = useRegulationFlags(regulation, accountType);

return (
<div className='overflow-y-scroll border-solid pt-800 lg:p-1200 rounded-1200 lg:border-xs lg:border-opacity-black-100'>
<CFDHeading />
{(noRealCRNonEUAccount || noRealMFEUAccount) && isSuccess && (
<div className='pt-1000'>
<GetADerivAccountBanner />
</div>
)}
<CFDContent />
</div>
);
};

export default CFDSection;
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { Provider } from '@deriv/library';
import { Button, Text } from '@deriv/quill-design';
import { StandaloneChevronDownBoldIcon } from '@deriv/quill-icons';
import { IconToCurrencyMapper } from '../../constants/constants';
import useRegulationFlags from '../../hooks/useRegulationFlags';
import { THooks } from '../../types';
import { CurrencySwitcherLoader } from '../Loaders';
import { Modal } from '../Modal';
import { TradingAccountsList } from '../TradingAccountsList';
import { useUIContext } from '../UIProvider';

type AccountActionButtonProps = {
balance: THooks.ActiveTradingAccount['balance'];
Expand Down Expand Up @@ -47,9 +49,18 @@ const CurrencySwitcher = () => {
const { data: activeAccount, isSuccess } = useActiveTradingAccount();
const isDemo = activeAccount?.is_virtual;
const { show } = Provider.useModal();
const { getUIState } = useUIContext();

const accountType = getUIState('accountType');

const regulation = getUIState('regulation');

const { noRealCRNonEUAccount, noRealMFEUAccount } = useRegulationFlags(regulation, accountType);

const iconCurrency = isDemo ? 'virtual' : activeAccount?.currency ?? 'virtual';

if (noRealCRNonEUAccount || noRealMFEUAccount) return null;

if (!isSuccess) return <CurrencySwitcherLoader />;

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useOnClickOutside } from 'usehooks-ts';
import { useActiveTradingAccount, useAuthorize, useTradingAccountsList } from '@deriv/api';
import { Button, qtMerge, Text } from '@deriv/quill-design';
import { LabelPairedChevronDownSmRegularIcon } from '@deriv/quill-icons';
import { useUIContext } from '../UIProvider';

type TAccount = {
label: string;
Expand All @@ -19,19 +20,25 @@ const DemoRealSwitcher = () => {
const { data: activeTradingAccount } = useActiveTradingAccount();
const { switchAccount } = useAuthorize();
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const [selected, setSelected] = useState(accountTypes[0]);
const { label, value } = selected;
const activeAccountType = activeTradingAccount?.is_virtual ? 'demo' : 'real';
const activeType = accountTypes.find(account => account.value === activeAccountType);
const [selected, setSelected] = useState(activeType);
const { label, value } = selected || {};
const { setUIState } = useUIContext();

const ref = useRef(null);
useOnClickOutside(ref, () => setIsDropdownOpen(false));

const firstRealLoginId = tradingAccountsList?.find(acc => !acc.is_virtual)?.loginid;

const demoLoginId = tradingAccountsList?.find(acc => acc.is_virtual)?.loginid;

useEffect(() => {
const activeAccountType = activeTradingAccount?.is_virtual ? 'demo' : 'real';
const activeAccount = accountTypes.find(account => account.value === activeAccountType);
if (activeAccount) {
setSelected(activeAccount);
if (activeType) {
setSelected(activeType);
setUIState('accountType', activeAccountType);
}
}, [activeTradingAccount]);
}, [activeAccountType, activeType, setUIState]);

useEffect(() => {
setIsDropdownOpen(false);
Expand All @@ -41,12 +48,9 @@ const DemoRealSwitcher = () => {
setIsDropdownOpen(prevState => !prevState);
}, []);

const firstRealLoginId = tradingAccountsList?.find(acc => !acc.is_virtual)?.loginid;

const demoLoginId = tradingAccountsList?.find(acc => acc.is_virtual)?.loginid;

const selectAccount = (account: TAccount) => {
setSelected(account);
setUIState('accountType', account.value);

const loginId = account.value === 'demo' ? demoLoginId : firstRealLoginId;
if (loginId) {
Expand Down
2 changes: 1 addition & 1 deletion packages/tradershub/src/components/Modal/ModalHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const ModalHeader = ({ className, hideCloseButton = false, title, titleClassName
className
)}
>
{title && <Heading.H5 className={qtMerge('flex-1', titleClassName)}>{title}</Heading.H5>}
{title && <Heading.H5 className={qtMerge('flex-1 font-sans', titleClassName)}>{title}</Heading.H5>}
{!hideCloseButton && <CloseIcon className='cursor-pointer' onClick={hide} />}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import React, { useEffect } from 'react';
import { useActiveTradingAccount, useAuthorize, useTradingAccountsList } from '@deriv/api';
import { useActiveTradingAccount, useAuthorize, useIsDIELEnabled, useTradingAccountsList } from '@deriv/api';
import { Button, qtJoin } from '@deriv/quill-design';
import { LabelPairedCircleInfoMdRegularIcon } from '@deriv/quill-icons';
import { Text } from '@deriv-com/ui/dist/components/Text';
import { Regulation } from '../../constants/constants';
import useRegulationFlags from '../../hooks/useRegulationFlags';
import { useUIContext } from '../UIProvider';

const RegulationSwitcherDesktop = () => {
const { switchAccount } = useAuthorize();
const { data: tradingAccountsList } = useTradingAccountsList();
const { getUIState, setUIState } = useUIContext();
const { data: isDIEL } = useIsDIELEnabled();
const regulation = getUIState('regulation');
const accountType = getUIState('accountType');
const { isEU, isHighRisk } = useRegulationFlags(regulation, accountType);

const realCRAccount = tradingAccountsList?.find(account => account.loginid.startsWith('CR'))?.loginid ?? '';

Expand All @@ -36,9 +41,9 @@ const RegulationSwitcherDesktop = () => {
};

useEffect(() => {
if (activeTrading?.loginid.startsWith('CR')) {
if (activeTrading?.loginid.startsWith('CR') || isDIEL || isHighRisk) {
setUIState('regulation', Regulation.NonEU);
} else if (activeTrading?.loginid.startsWith('MF')) {
} else if (activeTrading?.loginid.startsWith('MF') || isEU) {
setUIState('regulation', Regulation.EU);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down
11 changes: 7 additions & 4 deletions packages/tradershub/src/components/UIProvider/UIProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,14 @@ export const UIProvider = ({ children }: { children: React.ReactNode }) => {
[uiState]
);

const updateUIState = <T extends keyof TUIState>(key: T, value: TUIState[T]) => {
setUIState(prevState => ({ ...prevState, [key]: value }));
};
const updateUIState = useCallback(
<T extends keyof TUIState>(key: T, value: TUIState[T]) => {
setUIState(prevState => ({ ...prevState, [key]: value }));
},
[setUIState]
);

const providerValue = useMemo(() => ({ getUIState, setUIState: updateUIState }), [getUIState]);
const providerValue = useMemo(() => ({ getUIState, setUIState: updateUIState }), [getUIState, updateUIState]);

return <UIContext.Provider value={providerValue}>{children}</UIContext.Provider>;
};
82 changes: 56 additions & 26 deletions packages/tradershub/src/hooks/useRegulationFlags.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,67 @@
import { useActiveTradingAccount, useIsEuRegion, useTradingAccountsList } from '@deriv/api';
import { useMemo } from 'react';
import { useActiveTradingAccount, useIsEuRegion, useLandingCompany, useTradingAccountsList } from '@deriv/api';
import { Regulation } from '../constants/constants';

/**
* @description A custom hook that returns regulation flags based on the regulation passed in
* @param regulation 'EU' | 'Non-EU'
* @returns { isDemo: boolean, isEU: boolean, isEUReal: boolean, isNonEU: boolean, isNonEUReal: boolean }
*/
const useRegulationFlags = (regulation?: string) => {
const useRegulationFlags = (regulation?: string, accountType?: string) => {
const { isEUCountry } = useIsEuRegion();
const { data: activeTradingAccount } = useActiveTradingAccount();
const { data: tradingAccountsList } = useTradingAccountsList();

const isEURegulation = regulation === Regulation.EU;
const isNonEURegulation = regulation === Regulation.NonEU;

const isEU = isEUCountry || isEURegulation;
const isNonEU = !isEUCountry || isNonEURegulation;
const isDemo = activeTradingAccount?.is_virtual ?? false;

const isEUReal = isEU && !isDemo;
const isNonEUReal = isNonEU && !isDemo;

const noRealCRNonEU = isNonEU && !tradingAccountsList?.find(account => account.broker === 'CR');
const noRealMFEU = isEU && !tradingAccountsList?.find(account => account.broker === 'MF');

return {
isEU,
isEUReal,
isNonEU,
isNonEUReal,
noRealCRNonEU,
noRealMFEU,
};
const { data: activeTradingAccount, isSuccess: activeTradingAccountSuccess } = useActiveTradingAccount();
const { data: tradingAccountsList, isSuccess: tradingAccountListSuccess } = useTradingAccountsList();
const { data: landingCompany, isSuccess: landingCompanySuccess } = useLandingCompany();

return useMemo(() => {
const isHighRisk =
landingCompany?.financial_company?.shortcode === 'svg' &&
landingCompany?.gaming_company?.shortcode === 'svg';

const isEURegulation = regulation === Regulation.EU;
const isNonEURegulation = regulation === Regulation.NonEU;

const isEU = isEUCountry || isEURegulation;
const isNonEU = !isEUCountry || isNonEURegulation;

const isRealAccount = !activeTradingAccount?.is_virtual || accountType === 'real';

const isEURealAccount = isEU && isRealAccount;
const isNonEURealAccount = isNonEU && isRealAccount;

const noRealCRNonEUAccount =
isNonEU && !tradingAccountsList?.find(account => account.broker === 'CR') && isRealAccount;

const noRealMFEUAccount =
isEU && !tradingAccountsList?.find(account => account.broker === 'MF') && isRealAccount;

const hasActiveDerivAccount = !(noRealCRNonEUAccount || noRealMFEUAccount);

const isSuccess = activeTradingAccountSuccess && tradingAccountListSuccess && landingCompanySuccess;

return {
hasActiveDerivAccount,
isEU,
isEURealAccount,
isHighRisk,
isNonEU,
isNonEURealAccount,
isSuccess,
noRealCRNonEUAccount,
noRealMFEUAccount,
};
}, [
landingCompany?.financial_company?.shortcode,
landingCompany?.gaming_company?.shortcode,
regulation,
isEUCountry,
activeTradingAccount?.is_virtual,
accountType,
tradingAccountsList,
activeTradingAccountSuccess,
tradingAccountListSuccess,
landingCompanySuccess,
]);
};

export default useRegulationFlags;
19 changes: 13 additions & 6 deletions packages/tradershub/src/routes/TradersHubRoute/TradersHubRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { useActiveTradingAccount, useIsDIELEnabled } from '@deriv/api';
import { useIsDIELEnabled } from '@deriv/api';
import { Heading, useBreakpoint } from '@deriv/quill-design';
import {
CFDSection,
Expand All @@ -10,14 +10,21 @@ import {
RegulationSwitcherMobile,
TotalAssets,
TradersHubContent,
useUIContext,
} from '../../components';
import useRegulationFlags from '../../hooks/useRegulationFlags';

const TradersHubRoute = () => {
const { isMobile } = useBreakpoint();
const { data: isDIEL } = useIsDIELEnabled();
const { data: activeTradingAccount } = useActiveTradingAccount();
const { getUIState } = useUIContext();
const accountType = getUIState('accountType');
const regulation = getUIState('regulation');
const isReal = accountType === 'real';
const isDemo = accountType === 'demo';
const { hasActiveDerivAccount } = useRegulationFlags(regulation, accountType);

const isSwitcherVisible = isDIEL && !activeTradingAccount?.is_virtual;
const isSwitcherVisible = isDIEL && isReal;

if (isMobile)
return (
Expand Down Expand Up @@ -49,13 +56,13 @@ const TradersHubRoute = () => {

return (
<div className='space-y-1200'>
<div className='flex items-center justify-between align-start gap-100'>
<div className='grid justify-between grid-cols-3 align-start gap-100'>
<div className='flex items-center gap-600'>
<Heading.H3 className='font-sans'>Trader&apos;s Hub</Heading.H3>
<DemoRealSwitcher />
</div>
{isSwitcherVisible && <RegulationSwitcherDesktop />}
<TotalAssets />
<div>{isSwitcherVisible && <RegulationSwitcherDesktop />}</div>
{(hasActiveDerivAccount || isDemo) && <TotalAssets />}
</div>
<TradersHubContent />
</div>
Expand Down

1 comment on commit 2380193

@vercel
Copy link

@vercel vercel bot commented on 2380193 Jan 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

deriv-app – ./

deriv-app.vercel.app
deriv-app.binary.sx
binary.sx
deriv-app-git-master.binary.sx

Please sign in to comment.