Skip to content

Commit

Permalink
feat: replace legacy toast with new notification toast (#1370)
Browse files Browse the repository at this point in the history
  • Loading branch information
danielsimao authored Jun 28, 2023
1 parent 92554fc commit 7a8db34
Show file tree
Hide file tree
Showing 13 changed files with 251 additions and 158 deletions.
8 changes: 8 additions & 0 deletions src/assets/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@
"fee_token": "Fee token",
"claim_rewards": "Claim Rewards",
"tx_fees": "Tx fees",
"view_subscan": "View Subscan",

"redeem_page": {
"maximum_in_single_request": "Max redeemable in single request",
"redeem": "Redeem",
Expand Down Expand Up @@ -739,5 +741,11 @@
"fee_for_transaction_to_be_included_in_the_parachain": "The fee for the transaction to be included in the parachain",
"premium_redeem": "Premium Redeem",
"premium_redeem_info": "If you select premium redeem, you will try to redeem with a vault that is below the secure collateral threshold. This operation has a higher risk since the vault might be liquidated. For this higher risk, you will receive a compensation."
},
"notifications": {
"signature_submission_failed": "Signature submission failed",
"signature_submission_successful": "Signature submission successful",
"funding_account_failed": "Funding account failed",
"funding_account_successful": "Funding account successful"
}
}
103 changes: 103 additions & 0 deletions src/components/NotificationToast/NotificationToast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { useHover } from '@react-aria/interactions';
import { mergeProps } from '@react-aria/utils';
import { ReactNode } from 'react';
import { useTranslation } from 'react-i18next';

import { CheckCircle, XCircle } from '@/assets/icons';
import { CTA, Divider, Flex, FlexProps, LoadingSpinner, P } from '@/component-library';
import { useCountdown } from '@/utils/hooks/use-countdown';

import { StyledProgressBar, StyledWrapper } from './NotificationToast.styles';

type NotificationToastVariant = 'success' | 'error' | 'loading';

const loadingSpinner = <LoadingSpinner thickness={2} diameter={24} variant='indeterminate' />;

const getIcon = (variant: NotificationToastVariant) =>
({
loading: loadingSpinner,
success: <CheckCircle color='success' />,
error: <XCircle color='error' />
}[variant]);

type Props = {
title?: ReactNode;
variant?: NotificationToastVariant;
description?: string;
timeout?: number;
action?: ReactNode;
onDismiss?: () => void;
};

type InheritAttrs = Omit<FlexProps, keyof Props>;

type NotificationToastProps = Props & InheritAttrs;

const NotificationToast = ({
variant = 'success',
title,
timeout = 8000,
description,
onDismiss,
action,
...props
}: NotificationToastProps): JSX.Element => {
const { t } = useTranslation();

const showCountdown = variant === 'success' || variant === 'error';

const { value: countdown, start, stop } = useCountdown({
timeout,
disabled: !showCountdown,
onEndCountdown: onDismiss
});

const { hoverProps } = useHover({
onHoverStart: stop,
onHoverEnd: start,
isDisabled: !showCountdown
});

const icon = getIcon(variant);

return (
<StyledWrapper direction='column' {...mergeProps(props, hoverProps)}>
<Flex gap='spacing3'>
<Flex elementType='span' flex={0} alignItems={description ? 'flex-start' : 'center'}>
{icon}
</Flex>
<Flex direction='column' gap='spacing1' marginY='spacing1'>
<P weight='bold' size='s'>
{title}
</P>
{description && (
<P rows={2} size='xs'>
{description}
</P>
)}
</Flex>
</Flex>
{showCountdown && (
<StyledProgressBar
aria-label='notification timer'
value={showCountdown ? countdown : 0}
color={variant === 'error' ? 'red' : 'default'}
/>
)}
<Flex gap='spacing2' marginTop='spacing4'>
{action && (
<>
{action}
<Divider orientation='vertical' color='default' />
</>
)}
<CTA size='small' fullWidth variant='text' onPress={onDismiss}>
{t('dismiss')}
</CTA>
</Flex>
</StyledWrapper>
);
};

export { NotificationToast };
export type { NotificationToastProps, NotificationToastVariant };
84 changes: 84 additions & 0 deletions src/components/NotificationToast/TransactionToast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { TFunction } from 'i18next';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';

import { updateTransactionModal } from '@/common/actions/general.actions';
import { CTA, CTALink } from '@/component-library';
import { TransactionStatus } from '@/utils/hooks/transaction/types';

import { NotificationToast, NotificationToastProps, NotificationToastVariant } from './NotificationToast';

const getData = (t: TFunction, variant: TransactionStatus) =>
(({
[TransactionStatus.CONFIRM]: {
title: t('transaction.confirm_transaction'),
status: 'loading'
},
[TransactionStatus.SUBMITTING]: {
title: t('transaction.transaction_processing'),
status: 'loading'
},
[TransactionStatus.SUCCESS]: {
title: t('transaction.transaction_successful'),
status: 'success'
},
[TransactionStatus.ERROR]: {
title: t('transaction.transaction_failed'),
status: 'error'
}
} as Record<TransactionStatus, { title: string; status: NotificationToastVariant }>)[variant]);

type Props = {
variant?: TransactionStatus;
url?: string;
errorMessage?: string;
};

type InheritAttrs = Omit<NotificationToastProps, keyof Props>;

type TransactionToastProps = Props & InheritAttrs;

const TransactionToast = ({
variant = TransactionStatus.SUCCESS,
url,
description,
errorMessage,
onDismiss,
...props
}: TransactionToastProps): JSX.Element => {
const { t } = useTranslation();
const dispatch = useDispatch();

const handleViewDetails = () => {
dispatch(updateTransactionModal(true, { variant: TransactionStatus.ERROR, description, errorMessage }));
onDismiss?.();
};

const { title, status } = getData(t, variant);

const action = url ? (
<CTALink size='small' fullWidth external to={url} variant='text'>
{t('view_subscan')}
</CTALink>
) : (
errorMessage && (
<CTA size='small' fullWidth variant='text' onPress={handleViewDetails}>
View Details
</CTA>
)
);

return (
<NotificationToast
variant={status}
action={action}
title={title}
description={description}
onDismiss={onDismiss}
{...props}
/>
);
};

export { TransactionToast };
export type { TransactionToastProps };
4 changes: 4 additions & 0 deletions src/components/NotificationToast/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type { NotificationToastProps } from './NotificationToast';
export { NotificationToast } from './NotificationToast';
export type { TransactionToastProps } from './TransactionToast';
export { TransactionToast } from './TransactionToast';
4 changes: 2 additions & 2 deletions src/components/TransactionModal/TransactionModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
P,
TextLink
} from '@/component-library';
import { NotificationToast, useNotifications } from '@/utils/context/Notifications';
import { NotificationToastType, useNotifications } from '@/utils/context/Notifications';
import { TransactionStatus } from '@/utils/hooks/transaction/types';

import { StyledCard, StyledCheckCircle, StyledXCircle } from './TransactionModal.style';
Expand Down Expand Up @@ -63,7 +63,7 @@ const TransactionModal = (): JSX.Element => {
// No need to show toast if the transaction is SUCCESS or ERROR
if (timestamp && (variant === TransactionStatus.CONFIRM || variant === TransactionStatus.SUBMITTING)) {
notifications.show(timestamp, {
type: NotificationToast.TRANSACTION,
type: NotificationToastType.TRANSACTION,
props: { variant: variant, url, description }
});
}
Expand Down
132 changes: 0 additions & 132 deletions src/components/TransactionToast/TransactionToast.tsx

This file was deleted.

2 changes: 0 additions & 2 deletions src/components/TransactionToast/index.tsx

This file was deleted.

4 changes: 2 additions & 2 deletions src/components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ export type { LoanPositionsTableProps } from './LoanPositionsTable';
export { LoanPositionsTable } from './LoanPositionsTable';
export type { NotificationsPopoverProps } from './NotificationsPopover';
export { NotificationsPopover } from './NotificationsPopover';
export type { NotificationToastProps, TransactionToastProps } from './NotificationToast';
export { NotificationToast, TransactionToast } from './NotificationToast';
export type { PlusDividerProps } from './PlusDivider';
export { PlusDivider } from './PlusDivider';
export type { PoolsTableProps } from './PoolsTable';
Expand All @@ -22,5 +24,3 @@ export { ToastContainer } from './ToastContainer';
export * from './TransactionDetails';
export type { TransactionFeeDetailsProps } from './TransactionFeeDetails';
export { TransactionFeeDetails } from './TransactionFeeDetails';
export type { TransactionToastProps } from './TransactionToast';
export { TransactionToast } from './TransactionToast';
Loading

2 comments on commit 7a8db34

@vercel
Copy link

@vercel vercel bot commented on 7a8db34 Jun 28, 2023

Choose a reason for hiding this comment

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

@vercel
Copy link

@vercel vercel bot commented on 7a8db34 Jun 28, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.