Skip to content

Commit

Permalink
[Wallets] Rostislav / WALL-2473 / Pending transactions on mobile (#11289
Browse files Browse the repository at this point in the history
)

* feat: mobile layout

* refactor: extract logic from jsx to memo value

* feat: adding `onInteraction`

* feat: add transaction description

* feat: more `WalletActionModal`

* style: a little fix

* style: use #11215

* Merge remote-tracking branch 'upstream/master' into rostislav/wall-2473/pending-transaction-list-mobile

* refactor: `Tooltip`

* style: sort everything out

* refactor: sonarcloud role=button

* fix: sonarcloud

* refactor: remove unnecessary fallback

* Merge remote-tracking branch 'upstream/master' into rostislav/wall-2473/pending-transaction-list-mobile

* fix: account for #11304

* refactor: apply suggestions

* refactor: some css reverted

* refactor: better css

* refactor: `ToggleSwitch`

* refactor: `onMobileStatusClick`

* refactor: remove unnecessary ternary operator

* refactor: apply suggestions
  • Loading branch information
rostislav-deriv committed Nov 15, 2023
1 parent 0f1cc27 commit 3500b20
Show file tree
Hide file tree
Showing 17 changed files with 417 additions and 192 deletions.
39 changes: 39 additions & 0 deletions packages/api/src/hooks/useCryptoTransactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,43 @@ const getStatusName = (status_code: TModifiedTransaction['status_code']) => {
}
};

const getStatusDescription = (
transaction_type: TModifiedTransaction['transaction_type'],
status_code: TModifiedTransaction['status_code']
) => {
switch (status_code) {
// deposit-specific:
case 'CONFIRMED':
return 'Your deposit is successful.';
case 'PENDING':
return "We've received your request and are waiting for more blockchain confirmations.";
// withdrawal-specific:
case 'CANCELLED':
return "You've cancelled your withdrawal request.";
case 'LOCKED':
return "We're reviewing your withdrawal request. You may still cancel this transaction if you wish.\nOnce we start processing, you won't be able to cancel.";
case 'PERFORMING_BLOCKCHAIN_TXN':
return "We're sending your request to the blockchain.";
case 'PROCESSING':
return "We're awaiting confirmation from the blockchain.";
case 'REJECTED':
case 'REVERTED':
return "Your withdrawal is unsuccessful. We've sent you an email with more information.";
case 'REVERTING':
case 'VERIFIED':
return "We're processing your withdrawal.";
case 'SENT':
return 'Your withdrawal is successful.';
// both:
case 'ERROR':
return `Your ${transaction_type} is unsuccessful due to an error on the blockchain. Please contact ${
transaction_type === 'deposit' ? 'your crypto wallet service provider' : 'us via live chat'
} for more info.`;
default:
return '';
}
};

/** A custom hook that returns the list of pending crypto transactions for the current user. */
const useCryptoTransactions = () => {
const { subscribe, data, ...rest } = useSubscription('cashier_payments');
Expand Down Expand Up @@ -109,6 +146,8 @@ const useCryptoTransactions = () => {

return transactions.map(transaction => ({
...transaction,
/** Description of a transaction status */
description: getStatusDescription(transaction.transaction_type, transaction.status_code),
/** Formatted amount */
formatted_amount: displayMoney(transaction.amount || 0, display_code, {
fractional_digits,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
.wallets-modal-wrapper {
position: relative;

@include mobile {
width: calc(100vw - 3.2rem);
}

&__close-icon {
position: absolute;
top: 2rem;
Expand Down
5 changes: 4 additions & 1 deletion packages/wallets/src/components/Base/Tooltip/Tooltip.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
display: flex;
align-items: center;
position: absolute;
z-index: 1;

&--right {
top: 50%;
Expand Down Expand Up @@ -60,10 +61,12 @@
}

&__message {
max-height: 3.4rem;
width: max-content;
max-width: 28rem;
padding: 0.8rem;
border-radius: 4px;
font-size: 1.2rem;
white-space: pre-wrap;

background: var(--system-light-5-active-background, #d6dadb);
}
Expand Down
24 changes: 14 additions & 10 deletions packages/wallets/src/components/ModalProvider/ModalProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { createContext, RefObject, useContext, useEffect, useMemo, useRef, useState } from 'react';
import React, { createContext, useContext, useEffect, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import { useOnClickOutside } from 'usehooks-ts';
import useDevice from '../../hooks/useDevice';
import { TMarketTypes, TPlatforms } from '../../types';
import { TPlatforms, TMarketTypes } from '../../types';

type TModalState = {
marketType?: TMarketTypes.All;
Expand All @@ -15,10 +15,11 @@ type TModalContext = {
isOpen: boolean;
modalState?: Map<keyof TModalState, TModalState[keyof TModalState]>;
setModalState: <T extends keyof TModalState>(key: T, value: TModalState[T]) => void;
show: (ModalContent: React.ReactNode, options?: TModalShowOptions) => void;
show: (ModalContent: React.ReactNode, options?: TModalOptions) => void;
};

type TModalShowOptions = {
type TModalOptions = {
defaultRootId?: 'wallets_modal_responsive_root' | 'wallets_modal_root';
rootRef?: React.RefObject<HTMLElement>;
};

Expand All @@ -35,10 +36,10 @@ export const useModal = () => {
const ModalProvider = ({ children }: React.PropsWithChildren<unknown>) => {
const modalRef = useRef<HTMLDivElement>(null);
const [content, setContent] = useState<React.ReactNode | null>();
const [modalOptions, setModalOptions] = useState<TModalOptions>({});
const [modalState, setModalState] = useState<Map<keyof TModalState, TModalState[keyof TModalState]>>(new Map());
const { isDesktop } = useDevice();

const [customRootRef, setCustomRootRef] = useState<RefObject<HTMLElement> | null>(null);
const rootRef = useRef<HTMLElement>(document.getElementById('wallets_modal_root'));
const rootResponsiveRef = useRef<HTMLElement | null>(document.getElementById('wallets_modal_responsive_root'));

Expand All @@ -50,9 +51,12 @@ const ModalProvider = ({ children }: React.PropsWithChildren<unknown>) => {
setModalState(new Map(modalState.set(key, value)));
};

const show = (ModalContent: React.ReactNode, options?: TModalShowOptions) => {
const show = (ModalContent: React.ReactNode, options?: TModalOptions) => {
setContent(ModalContent);
setCustomRootRef(options?.rootRef?.current ? options?.rootRef : null);
setModalOptions({
...modalOptions,
...options,
});
};

useEffect(() => {
Expand All @@ -68,10 +72,10 @@ const ModalProvider = ({ children }: React.PropsWithChildren<unknown>) => {
useOnClickOutside(modalRef, isDesktop ? hide : () => undefined);

const modalRootRef = useMemo(() => {
if (customRootRef?.current) return customRootRef;
if (isDesktop) return rootRef;
if (modalOptions?.rootRef?.current) return modalOptions?.rootRef;
if (isDesktop || modalOptions?.defaultRootId === 'wallets_modal_root') return rootRef;
return rootResponsiveRef;
}, [isDesktop, customRootRef]);
}, [isDesktop, modalOptions]);

return (
<ModalContext.Provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const WalletActionModal: React.FC<TWalletActionModal> = ({
title,
}) => {
const { isMobile } = useDevice();

return (
<ModalWrapper hideCloseButton={hideCloseButton}>
<div className='wallets-action-modal'>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
.wallets-transactions {
$root: &;
position: relative;
width: 100%;
height: 100%;
height: fit-content;
display: flex;
flex-direction: column;
align-items: center;
padding-top: 7.2rem; // accounting for the list header

&--crypto-mobile {
@include mobile {
padding-top: 11.2rem; // accounting for the list header when it's a crypto wallet on mobile
}
// ignore CashierContent top padding
margin-top: -4.8rem;
@include mobile {
margin-top: -2.4rem;
}

&__header {
position: absolute;
top: 0; // make absolutely positioned header ignore parent's padding
position: sticky;
top: -4.8rem; // ignore CashierContent padding
width: 100%;
max-width: 80rem;
padding: 2.4rem 0 0.8rem;
display: flex;
gap: 1.6rem;
justify-content: flex-end;
z-index: 9999;
z-index: 1;
background-color: var(--system-light-8-primary-background, #fff);

@include mobile {
top: -2.4rem;
padding: 1.6rem 0;
flex-direction: column;
}
}
Expand All @@ -43,38 +43,5 @@
@include mobile {
align-self: flex-end;
}

&-switch {
height: 0;
width: 0;
visibility: hidden;

&__label {
height: 2.4rem;
width: 4.4rem;
display: flex;
align-items: center;
padding-left: 0.3rem;
background: var(--general-disabled);
border-radius: 4.9rem;
transition: background-color 0.25s;
cursor: pointer;
}

&__button {
width: 1.8rem;
height: 1.8rem;
border-radius: 1.8rem;
transition: transform 0.25s;
background: var(--text-colored-background);
}

&:checked + &__label {
background: #4bb4b3;
}
&:checked + &__label &__button {
transform: translateX(2rem);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useEffect, useMemo, useState } from 'react';
import classNames from 'classnames';
import { useActiveWalletAccount } from '@deriv/api';
import { WalletDropdown, WalletText } from '../../../../components';
import { ToggleSwitch, WalletDropdown, WalletText } from '../../../../components';
import useDevice from '../../../../hooks/useDevice';
import FilterIcon from '../../../../public/images/filter.svg';
import { TransactionsCompleted, TransactionsPending } from './components';
Expand Down Expand Up @@ -71,16 +71,7 @@ const Transactions = () => {
{wallet?.currency_config?.is_crypto && (
<div className='wallets-transactions__toggle'>
<WalletText size='sm'>Pending Transactions</WalletText>
<input
checked={isPendingActive}
className='wallets-transactions__toggle-switch'
id='toggle-pending'
onChange={() => setIsPendingActive(!isPendingActive)}
type='checkbox'
/>
<label className='wallets-transactions__toggle-switch__label' htmlFor='toggle-pending'>
<span className='wallets-transactions__toggle-switch__button' />
</label>
<ToggleSwitch onChange={() => setIsPendingActive(!isPendingActive)} value={isPendingActive} />
</div>
)}
<WalletDropdown
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,10 @@
position: relative;

&__group-title {
margin-bottom: 0.8rem;
width: 7.4rem;
height: 1.4rem;
color: var(--system-light-3-less-prominent-text, #999);
text-align: right;
margin: 0 0 0.8rem 1.6rem;

/* desktop/extra small/XS - regular */
font-size: 1rem;
font-style: normal;
font-weight: 400;
line-height: 1.4rem; /* 140% */
@include mobile {
margin-left: 0;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import moment from 'moment';
import { useTransactions } from '@deriv/api';
import { TSocketRequestPayload } from '@deriv/api/types';
import { Loader } from '../../../../../../components';
import { WalletText } from '../../../../../../components/Base';
import { TransactionsCompletedRow } from '../TransactionsCompletedRow';
import { TransactionsNoDataState } from '../TransactionsNoDataState';
import { TransactionsTable } from '../TransactionsTable';
Expand Down Expand Up @@ -51,9 +52,12 @@ const TransactionsCompleted: React.FC<TProps> = ({ filter }) => {
fetchMore={fetchMoreOnBottomReached}
groupBy={['date']}
rowGroupRender={transaction => (
<p className='wallets-transactions-completed__group-title'>
{transaction.transaction_time && moment.unix(transaction.transaction_time).format('DD MMM YYYY')}
</p>
<div className='wallets-transactions-completed__group-title'>
<WalletText color='primary' size='2xs'>
{transaction.transaction_time &&
moment.unix(transaction.transaction_time).format('DD MMM YYYY')}
</WalletText>
</div>
)}
rowRender={transaction => <TransactionsCompletedRow transaction={transaction} />}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
align-items: center;
border-top: 0.1rem solid var(--system-light-3-border, #e5e5e5);

@include mobile {
padding: 1.6rem 0;
}

&__type-and-wallet-name {
display: flex;
flex-direction: column;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
.wallets-transactions-pending {
position: relative;
width: 100%;
max-width: 80rem;

&__group-title {
width: 7.4rem;
height: 1.4rem;
color: var(--system-light-3-less-prominent-text, #999);
text-align: right;
margin: 0 0 0.8rem 1.6rem;

/* desktop/extra small/XS - regular */
font-size: 1rem;
font-style: normal;
font-weight: 400;
line-height: 1.4rem; /* 140% */
@include mobile {
margin-left: 0;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useEffect } from 'react';
import moment from 'moment';
import { useCryptoTransactions } from '@deriv/api';
import { Loader } from '../../../../../../components';
import { WalletText } from '../../../../../../components/Base';
import { TransactionsNoDataState } from '../TransactionsNoDataState';
import { TransactionsPendingRow } from '../TransactionsPendingRow';
import { TransactionsTable } from '../TransactionsTable';
Expand Down Expand Up @@ -40,9 +41,11 @@ const TransactionsPending: React.FC<TProps> = ({ filter = 'all' }) => {
data={transactions}
groupBy={['date']}
rowGroupRender={transaction => (
<p className='wallets-transactions-pending__group-title'>
{moment.unix(transaction.submit_date).format('DD MMM YYYY')}
</p>
<div className='wallets-transactions-pending__group-title'>
<WalletText color='primary' size='2xs'>
{transaction.submit_date && moment.unix(transaction.submit_date).format('DD MMM YYYY')}
</WalletText>
</div>
)}
rowRender={transaction => <TransactionsPendingRow transaction={transaction} />}
/>
Expand Down
Loading

1 comment on commit 3500b20

@vercel
Copy link

@vercel vercel bot commented on 3500b20 Nov 15, 2023

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
binary.sx
deriv-app.binary.sx
deriv-app-git-master.binary.sx

Please sign in to comment.