diff --git a/package-lock.json b/package-lock.json index d42d1e84..3b52c2e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,11 +11,11 @@ "@babel/preset-env": "^7.24.5", "@chakra-ui/react": "^2.8.2", "@deriv-com/analytics": "^1.10.1", - "@deriv-com/api-hooks": "^1.3.7", + "@deriv-com/api-hooks": "^1.4.5", "@deriv-com/translations": "^1.2.4", "@deriv-com/ui": "^1.29.0", "@deriv-com/utils": "^0.0.28", - "@deriv/quill-icons": "^1.22.10", + "@deriv/quill-icons": "^1.23.5", "@sendbird/chat": "^4.11.3", "@svgr/rollup": "^8.1.0", "@tanstack/react-query": "^5.28.14", @@ -3783,9 +3783,9 @@ } }, "node_modules/@deriv-com/api-hooks": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/@deriv-com/api-hooks/-/api-hooks-1.3.7.tgz", - "integrity": "sha512-5XomMS9zOG3wSgEl5oA4N0gCr9pI/hRCIMgoUVP2D9fThTS6K9iHVv/aWieJKx0esF8lYQx5zaLDYTwxqX0u/g==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@deriv-com/api-hooks/-/api-hooks-1.4.5.tgz", + "integrity": "sha512-FUaeoXHLCCXhLIcuQw3NdkeAYizINW/DhRa3VmAMtxZW4J8NlW0WszrxVwL5eAWLjy6qkhRw2KgMWKN4QP4u0g==", "dependencies": { "@deriv-com/utils": "^0.0.28", "@deriv/api-types": "^1.0.985", @@ -3796,11 +3796,6 @@ "@rollup/rollup-linux-x64-gnu": "^4.18.0" } }, - "node_modules/@deriv-com/api-hooks/node_modules/@deriv-com/utils": { - "version": "0.0.28", - "resolved": "https://registry.npmjs.org/@deriv-com/utils/-/utils-0.0.28.tgz", - "integrity": "sha512-JJayPckG5ajwZjJ0H3VYe9GXcTpMY7oNOkMRiqwv14dtcsMTsYow9cVs3vfbiL4U59WGQBGMkkbh0EwSjYVrvQ==" - }, "node_modules/@deriv-com/api-hooks/node_modules/@rollup/rollup-linux-x64-gnu": { "version": "4.19.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.1.tgz", @@ -3920,9 +3915,9 @@ } }, "node_modules/@deriv/quill-icons": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/@deriv/quill-icons/-/quill-icons-1.22.10.tgz", - "integrity": "sha512-BtyMfKln7iBcTcERiaj3t8ADMplCOfE3J184Asaa/9RnE42e5JtehkYw78lwinYTBTzr1sL5tK0GRNlziFNRKw==", + "version": "1.23.7", + "resolved": "https://registry.npmjs.org/@deriv/quill-icons/-/quill-icons-1.23.7.tgz", + "integrity": "sha512-ERDTnqjQ+7tCD/uDS/V8EGxNYVjCdEjA4WZS3ZkTAzMtaBKIYQboUNZzLHbmZtOWihdK6sR6GOoWktLWiNnkCA==", "peerDependencies": { "react": ">= 16", "react-dom": ">= 16" diff --git a/package.json b/package.json index a2c5dbea..b296e042 100644 --- a/package.json +++ b/package.json @@ -17,11 +17,11 @@ "@babel/preset-env": "^7.24.5", "@chakra-ui/react": "^2.8.2", "@deriv-com/analytics": "^1.10.1", - "@deriv-com/api-hooks": "^1.3.7", + "@deriv-com/api-hooks": "^1.4.5", "@deriv-com/translations": "^1.2.4", "@deriv-com/ui": "^1.29.0", "@deriv-com/utils": "^0.0.28", - "@deriv/quill-icons": "^1.22.10", + "@deriv/quill-icons": "^1.23.5", "@sendbird/chat": "^4.11.3", "@svgr/rollup": "^8.1.0", "@tanstack/react-query": "^5.28.14", @@ -111,4 +111,4 @@ "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "4.9.5" } -} +} \ No newline at end of file diff --git a/src/assets/find-ad.svg b/src/assets/find-ad.svg deleted file mode 100644 index 4f462882..00000000 --- a/src/assets/find-ad.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/pay-user.svg b/src/assets/pay-user.svg deleted file mode 100644 index 4f6d3a1f..00000000 --- a/src/assets/pay-user.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/receive-payment.svg b/src/assets/receive-payment.svg deleted file mode 100644 index 682b6b77..00000000 --- a/src/assets/receive-payment.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/received-fund.svg b/src/assets/received-fund.svg deleted file mode 100644 index 4d40aa42..00000000 --- a/src/assets/received-fund.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/release-fund.svg b/src/assets/release-fund.svg deleted file mode 100644 index d96a6c0c..00000000 --- a/src/assets/release-fund.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/scam-advance-payment.svg b/src/assets/scam-advance-payment.svg deleted file mode 100644 index 479fb6c4..00000000 --- a/src/assets/scam-advance-payment.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/scam-pot.svg b/src/assets/scam-pot.svg deleted file mode 100644 index 2a17db37..00000000 --- a/src/assets/scam-pot.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/scam-sms.svg b/src/assets/scam-sms.svg deleted file mode 100644 index b19e4cf0..00000000 --- a/src/assets/scam-sms.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/components/AppHeader/AccountSwitcher/AccountSwitcher.tsx b/src/components/AppHeader/AccountSwitcher/AccountSwitcher.tsx index daa3a694..e0a5b048 100644 --- a/src/components/AppHeader/AccountSwitcher/AccountSwitcher.tsx +++ b/src/components/AppHeader/AccountSwitcher/AccountSwitcher.tsx @@ -1,5 +1,5 @@ +import { lazy } from 'react'; import { useActiveAccount } from '@/hooks/api/account'; -import { CurrencyUsdIcon } from '@deriv/quill-icons'; import { AccountSwitcher as UIAccountSwitcher } from '@deriv-com/ui'; import { FormatUtils } from '@deriv-com/utils'; @@ -8,12 +8,14 @@ type TAccountSwitcherProps = { account: TActiveAccount; }; +const CurrencyIcon = lazy(() => import('../CurrencyIcon').then(module => ({ default: module.CurrencyIcon }))); + const AccountSwitcher = ({ account }: TAccountSwitcherProps) => { const activeAccount = { balance: FormatUtils.formatMoney(account?.balance ?? 0), currency: account?.currency || 'USD', currencyLabel: account?.currency || 'US Dollar', - icon: , + icon: , isActive: true, isVirtual: Boolean(account?.is_virtual), loginid: account?.loginid || '', diff --git a/src/components/AppHeader/CurrencyIcon/CurrencyIcon.tsx b/src/components/AppHeader/CurrencyIcon/CurrencyIcon.tsx new file mode 100644 index 00000000..4734f0b5 --- /dev/null +++ b/src/components/AppHeader/CurrencyIcon/CurrencyIcon.tsx @@ -0,0 +1,28 @@ +import { ReactElement, Suspense, useEffect, useState } from 'react'; + +type CurrencyIconProps = { + currency: string; + isVirtual: boolean; +}; + +const CurrencyIcon = ({ currency, isVirtual }: CurrencyIconProps) => { + const [currencyIconComponent, setCurrencyIconComponent] = useState(null); + + useEffect(() => { + const currencyName = currency.charAt(0).toUpperCase() + currency.slice(1).toLowerCase(); + const currencyIconName = isVirtual ? 'CurrencyDemoIcon' : `Currency${currencyName}Icon`; + const getIconComponent = async () => { + const module = await import('@deriv/quill-icons'); + /* eslint-disable @typescript-eslint/no-explicit-any */ + const IconComponent = (module as any)[currencyIconName]; + + setCurrencyIconComponent(); + }; + + getIconComponent(); + }, []); + + return }>{currencyIconComponent}; +}; + +export default CurrencyIcon; diff --git a/src/components/AppHeader/CurrencyIcon/index.ts b/src/components/AppHeader/CurrencyIcon/index.ts new file mode 100644 index 00000000..bccb4e79 --- /dev/null +++ b/src/components/AppHeader/CurrencyIcon/index.ts @@ -0,0 +1 @@ +export { default as CurrencyIcon } from './CurrencyIcon'; diff --git a/src/components/AppHeader/__tests__/AppHeader.spec.tsx b/src/components/AppHeader/__tests__/AppHeader.spec.tsx index b022462a..4b0fde20 100644 --- a/src/components/AppHeader/__tests__/AppHeader.spec.tsx +++ b/src/components/AppHeader/__tests__/AppHeader.spec.tsx @@ -4,7 +4,7 @@ import { QueryParamProvider } from 'use-query-params'; import { ReactRouter5Adapter } from 'use-query-params/adapters/react-router-5'; import { useActiveAccount } from '@/hooks/api/account'; import { useAuthData } from '@deriv-com/api-hooks'; -import { render, screen } from '@testing-library/react'; +import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import AppHeader from '../AppHeader'; @@ -116,6 +116,7 @@ describe('', () => { mockUseAuthData.mockReturnValue({ activeLoginid: '12345', logout: jest.fn() }); mockUseActiveAccountValues.data = { currency: 'USD', + is_virtual: 0, } as ReturnType['data']; Object.defineProperty(window, 'matchMedia', { @@ -139,9 +140,9 @@ describe('', () => { ); - const logoutButton = screen.getByRole('button', { name: 'Logout' }); + const logoutButton = await screen.findByRole('button', { name: 'Logout' }); const { logout } = mockUseAuthData(); - expect(logoutButton).toBeInTheDocument(); + await waitFor(() => expect(logoutButton).toBeInTheDocument()); await userEvent.click(logoutButton); expect(logout).toHaveBeenCalled(); diff --git a/src/components/BlockedScenarios/BlockedScenarios.tsx b/src/components/BlockedScenarios/BlockedScenarios.tsx index 9de80346..8206386b 100644 --- a/src/components/BlockedScenarios/BlockedScenarios.tsx +++ b/src/components/BlockedScenarios/BlockedScenarios.tsx @@ -61,13 +61,13 @@ const BlockedScenarios = ({ type }: { type: string }) => { ), description: ( - + ), icon: , title: ( - + ), }, diff --git a/src/components/BlockedScenarios/__tests__/BlockedScenarios.spec.tsx b/src/components/BlockedScenarios/__tests__/BlockedScenarios.spec.tsx index 7fe2889f..cef50ceb 100644 --- a/src/components/BlockedScenarios/__tests__/BlockedScenarios.spec.tsx +++ b/src/components/BlockedScenarios/__tests__/BlockedScenarios.spec.tsx @@ -33,7 +33,7 @@ describe('BlockedScenarios', () => { it('should render the correct message for crypto account', async () => { render(); - expect(screen.getByText('Crypto is not supported for Deriv P2P!')).toBeInTheDocument(); + expect(screen.getByText('Cryptocurrencies not supported')).toBeInTheDocument(); const button = screen.getByRole('button', { name: 'Switch to real USD account' }); await userEvent.click(button); expect(window.open).toHaveBeenCalledWith('https://app.deriv.com', '_blank'); diff --git a/src/components/BuySellForm/BuySellForm.scss b/src/components/BuySellForm/BuySellForm.scss index 54b564b9..a3fd5f21 100644 --- a/src/components/BuySellForm/BuySellForm.scss +++ b/src/components/BuySellForm/BuySellForm.scss @@ -7,6 +7,11 @@ width: 100vw; height: 100vh; box-shadow: none; + + &__footer { + padding: 1.6rem; + border-top: 2px solid #f2f3f4; + } } & .deriv-modal__body { @@ -15,10 +20,12 @@ &--is-buy { height: 64.9rem; + & .deriv-modal__body { max-height: calc(100vh - 13rem); overflow: auto; } + @include mobile-or-tablet-screen { height: unset; max-height: unset; @@ -31,10 +38,6 @@ left: 0; z-index: 1; - & .mobile-wrapper__body { - overflow: overlay; - } - &--is-buy { top: -4rem; } diff --git a/src/components/BuySellForm/BuySellForm.tsx b/src/components/BuySellForm/BuySellForm.tsx index 8c63d89a..ccd867dd 100644 --- a/src/components/BuySellForm/BuySellForm.tsx +++ b/src/components/BuySellForm/BuySellForm.tsx @@ -132,6 +132,8 @@ const BuySellForm = ({ advertId, isModalOpen, onRequestClose }: TBuySellFormProp const history = useHistory(); const { isDesktop } = useDevice(); const isBuy = type === BUY_SELL.BUY; + const hasSelectedPaymentMethods = + (!paymentMethodNames && selectedPaymentMethods.length < 1) || selectedPaymentMethods.length > 0; const shouldDisableField = !isBuy && @@ -265,7 +267,7 @@ const BuySellForm = ({ advertId, isModalOpen, onRequestClose }: TBuySellFormProp isBuy={isBuy} isHidden={isHidden} isModalOpen={isModalOpen} - isValid={isValid && ((isBuy && selectedPaymentMethods.length > 0) || !isBuy)} + isValid={isValid && (!isBuy || hasSelectedPaymentMethods)} onRequestClose={onCloseBuySellForm} onSubmit={onSubmit} > diff --git a/src/components/BuySellForm/BuySellFormDisplayWrapper.tsx b/src/components/BuySellForm/BuySellFormDisplayWrapper.tsx index 62dd7086..dc7b3f11 100644 --- a/src/components/BuySellForm/BuySellFormDisplayWrapper.tsx +++ b/src/components/BuySellForm/BuySellFormDisplayWrapper.tsx @@ -35,10 +35,10 @@ const BuySellFormDisplayWrapper = ({ 'buy-sell-form__full-page-modal--is-buy': currentRoute === 'buy-sell', })} onBack={onRequestClose} - renderFooter={() => } renderHeader={() => } > {children} + ); } diff --git a/src/components/BuySellForm/BuySellFormFooter/BuySellFormFooter.tsx b/src/components/BuySellForm/BuySellFormFooter/BuySellFormFooter.tsx index fd20ddf2..90fe68cd 100644 --- a/src/components/BuySellForm/BuySellFormFooter/BuySellFormFooter.tsx +++ b/src/components/BuySellForm/BuySellFormFooter/BuySellFormFooter.tsx @@ -9,7 +9,7 @@ type TBuySellFormFooterProps = { const BuySellFormFooter = ({ isDisabled, onClickCancel, onSubmit }: TBuySellFormFooterProps) => { const { isDesktop } = useDevice(); return ( -
+
)} + shouldFixedFooter={false} > {shouldShowLostFundsBanner && ( { {isPast ? ( ) : ( - + )} } diff --git a/src/pages/orders/screens/Orders/OrdersEmpty/__tests__/OrdersEmpty.spec.tsx b/src/pages/orders/screens/Orders/OrdersEmpty/__tests__/OrdersEmpty.spec.tsx index 705cfee2..a60e2234 100644 --- a/src/pages/orders/screens/Orders/OrdersEmpty/__tests__/OrdersEmpty.spec.tsx +++ b/src/pages/orders/screens/Orders/OrdersEmpty/__tests__/OrdersEmpty.spec.tsx @@ -18,7 +18,7 @@ jest.mock('react-router-dom', () => ({ describe('OrdersEmpty', () => { it('should render OrdersEmpty', () => { render(); - expect(screen.getByText('You have no orders.')).toBeInTheDocument(); + expect(screen.getByText('You have no active orders.')).toBeInTheDocument(); expect(screen.getByRole('button', { name: 'Buy/Sell' })).toBeInTheDocument(); }); it('should handle clicking on buy/sell button', async () => { diff --git a/src/pages/orders/screens/Orders/OrdersTable/__tests__/OrdersTable.spec.tsx b/src/pages/orders/screens/Orders/OrdersTable/__tests__/OrdersTable.spec.tsx index 156b147c..4c79019e 100644 --- a/src/pages/orders/screens/Orders/OrdersTable/__tests__/OrdersTable.spec.tsx +++ b/src/pages/orders/screens/Orders/OrdersTable/__tests__/OrdersTable.spec.tsx @@ -137,7 +137,7 @@ const mockUseDevice = useDevice as jest.Mock; describe('OrdersTable', () => { it('should render OrdersTable as expected with empty data', () => { render(); - expect(screen.getByText('You have no orders.')).toBeInTheDocument(); + expect(screen.getByText('You have no active orders.')).toBeInTheDocument(); }); it('should render the loader when isLoading', () => { render(); diff --git a/src/pages/orders/screens/OrdersChatSection/OrdersChatSection.scss b/src/pages/orders/screens/OrdersChatSection/OrdersChatSection.scss index b6791185..72e10260 100644 --- a/src/pages/orders/screens/OrdersChatSection/OrdersChatSection.scss +++ b/src/pages/orders/screens/OrdersChatSection/OrdersChatSection.scss @@ -16,10 +16,10 @@ &__full-page { position: absolute; - top: 8rem; + top: 0; left: 0; z-index: 1; - height: calc(100vh - 9rem); + height: calc(100vh - 8rem); & .mobile-wrapper { &__body { diff --git a/src/routes/AppContent/index.scss b/src/routes/AppContent/index.scss index 51330d03..3855fe5b 100644 --- a/src/routes/AppContent/index.scss +++ b/src/routes/AppContent/index.scss @@ -1,4 +1,10 @@ +#root { + height: 100%; +} + .app-content { + height: 100%; + &__body { position: relative; overflow: hidden; @@ -14,7 +20,7 @@ @include mobile-or-tablet-screen { max-width: 60rem; - height: 100vh; + height: 100%; } }