From 46e09d644e29d72fbcd0edb3cd852d5ae795674f Mon Sep 17 00:00:00 2001 From: toniocodo Date: Tue, 3 Oct 2023 21:07:09 +0200 Subject: [PATCH] feat: add redeem support --- libs/oeth/redeem/src/hooks.tsx | 22 ++++- .../components/ActivityItem.tsx | 87 ++++++++++++++++++ .../components/ActivityPopover.tsx | 92 +------------------ .../src/components/ActivityProvider/types.ts | 2 +- 4 files changed, 109 insertions(+), 94 deletions(-) create mode 100644 libs/oeth/shared/src/components/ActivityProvider/components/ActivityItem.tsx diff --git a/libs/oeth/redeem/src/hooks.tsx b/libs/oeth/redeem/src/hooks.tsx index 58ff0c4e7..4890c9249 100644 --- a/libs/oeth/redeem/src/hooks.tsx +++ b/libs/oeth/redeem/src/hooks.tsx @@ -1,6 +1,7 @@ import { useCallback } from 'react'; -import { contracts } from '@origin/shared/contracts'; +import { usePushActivity, useUpdateActivity } from '@origin/oeth/shared'; +import { contracts, tokens } from '@origin/shared/contracts'; import { BlockExplorerLink, usePushNotification, @@ -40,6 +41,8 @@ export const useHandleRedeem = () => { const intl = useIntl(); const { value: slippage } = useSlippage(); const pushNotification = usePushNotification(); + const pushActivity = usePushActivity(); + const updateActivity = useUpdateActivity(); const { address } = useAccount(); const [{ amountIn, amountOut }, setRedeemState] = useRedeemState(); const wagmiClient = useQueryClient(); @@ -49,6 +52,15 @@ export const useHandleRedeem = () => { return; } + const activity = pushActivity({ + type: 'redeem', + status: 'pending', + tokenIn: tokens.mainnet.OETH, + tokenOut: MIX_TOKEN, + amountIn, + amountOut, + }); + setRedeemState( produce((draft) => { draft.isRedeemLoading = true; @@ -75,6 +87,7 @@ export const useHandleRedeem = () => { console.log('redeem vault done!'); wagmiClient.invalidateQueries({ queryKey: ['redeem_balance'] }); + updateActivity({ ...activity, status: 'success', txReceipt }); pushNotification({ title: intl.formatMessage({ defaultMessage: 'Redeem complete' }), severity: 'success', @@ -88,10 +101,7 @@ export const useHandleRedeem = () => { severity: 'info', }); } else { - pushNotification({ - title: intl.formatMessage({ defaultMessage: 'Redeem vault' }), - severity: 'error', - }); + updateActivity({ ...activity, status: 'error', error: e.short }); } } @@ -105,9 +115,11 @@ export const useHandleRedeem = () => { amountIn, amountOut, intl, + pushActivity, pushNotification, setRedeemState, slippage, + updateActivity, wagmiClient, ]); }; diff --git a/libs/oeth/shared/src/components/ActivityProvider/components/ActivityItem.tsx b/libs/oeth/shared/src/components/ActivityProvider/components/ActivityItem.tsx new file mode 100644 index 000000000..373d74a15 --- /dev/null +++ b/libs/oeth/shared/src/components/ActivityProvider/components/ActivityItem.tsx @@ -0,0 +1,87 @@ +import { Box, Stack, Typography } from '@mui/material'; +import { LinkIcon } from '@origin/shared/components'; +import { isNilOrEmpty } from '@origin/shared/utils'; +import { defineMessage, useIntl } from 'react-intl'; +import { formatUnits } from 'viem'; + +import { ActivityIcon } from './ActivityIcon'; + +import type { StackProps } from '@mui/material'; +import type { MessageDescriptor } from 'react-intl'; + +import type { Activity, ActivityType } from '../types'; + +type ActivityItemProps = { + activity: Activity; +} & StackProps; + +const activityLabel: Record = { + swap: defineMessage({ defaultMessage: 'Swapped' }), + approval: defineMessage({ defaultMessage: 'Approved' }), + redeem: defineMessage({ defaultMessage: 'Redeemed' }), +}; + +export const ActivityItem = ({ activity, ...rest }: ActivityItemProps) => { + const intl = useIntl(); + + return ( + + + + + + {intl.formatMessage(activityLabel[activity.type])} + + {!isNilOrEmpty(activity?.txReceipt?.transactionHash) && ( + + )} + + + + {intl.formatMessage( + { + defaultMessage: + '{amountIn} {symbolIn} for {amountOut} {symbolOut}', + }, + { + amountIn: intl.formatNumber( + +formatUnits(activity.amountIn, activity.tokenIn.decimals), + { minimumFractionDigits: 4, maximumFractionDigits: 4 }, + ), + symbolIn: activity.tokenIn.symbol, + amountOut: intl.formatNumber( + +formatUnits(activity.amountOut, activity.tokenOut.decimals), + { minimumFractionDigits: 4, maximumFractionDigits: 4 }, + ), + symbolOut: activity.tokenOut.symbol, + }, + )} + + + + + + + + + + ); +}; diff --git a/libs/oeth/shared/src/components/ActivityProvider/components/ActivityPopover.tsx b/libs/oeth/shared/src/components/ActivityProvider/components/ActivityPopover.tsx index 3b427d73e..b19f927c7 100644 --- a/libs/oeth/shared/src/components/ActivityProvider/components/ActivityPopover.tsx +++ b/libs/oeth/shared/src/components/ActivityProvider/components/ActivityPopover.tsx @@ -1,24 +1,14 @@ -import { - Box, - Divider, - Popover, - Stack, - Typography, - useTheme, -} from '@mui/material'; -import { LinkIcon } from '@origin/shared/components'; +import { Divider, Popover, Stack, Typography, useTheme } from '@mui/material'; import { isNilOrEmpty } from '@origin/shared/utils'; import { descend, pipe, prop, sort, take } from 'ramda'; -import { defineMessage, useIntl } from 'react-intl'; -import { formatUnits } from 'viem'; +import { useIntl } from 'react-intl'; import { useActivityState } from '../state'; -import { ActivityIcon } from './ActivityIcon'; +import { ActivityItem } from './ActivityItem'; import type { StackProps } from '@mui/material'; -import type { MessageDescriptor } from 'react-intl'; -import type { Activity, ActivityType } from '../types'; +import type { Activity } from '../types'; export type AcitivityPopoverProps = { anchor: HTMLElement | null; @@ -89,80 +79,6 @@ export const ActivityPopover = ({ ); }; -type ActivityItemProps = { - activity: Activity; -} & StackProps; - -const activityLabel: Record = { - swap: defineMessage({ defaultMessage: 'Swapped' }), - approval: defineMessage({ defaultMessage: 'Approved' }), -}; - -function ActivityItem({ activity, ...rest }: ActivityItemProps) { - const intl = useIntl(); - - return ( - - - - - - {intl.formatMessage(activityLabel[activity.type])} - - {!isNilOrEmpty(activity?.txReceipt?.transactionHash) && ( - - )} - - - - {intl.formatMessage( - { - defaultMessage: - '{amountIn} {symbolIn} for {amountOut} {symbolOut}', - }, - { - amountIn: intl.formatNumber( - +formatUnits(activity.amountIn, activity.tokenIn.decimals), - { minimumFractionDigits: 4, maximumFractionDigits: 4 }, - ), - symbolIn: activity.tokenIn.symbol, - amountOut: intl.formatNumber( - +formatUnits(activity.amountOut, activity.tokenOut.decimals), - { minimumFractionDigits: 4, maximumFractionDigits: 4 }, - ), - symbolOut: activity.tokenOut.symbol, - }, - )} - - - - - - - - - - ); -} - function EmptyActivity(props: StackProps) { const intl = useIntl(); diff --git a/libs/oeth/shared/src/components/ActivityProvider/types.ts b/libs/oeth/shared/src/components/ActivityProvider/types.ts index bbc77fb12..171386145 100644 --- a/libs/oeth/shared/src/components/ActivityProvider/types.ts +++ b/libs/oeth/shared/src/components/ActivityProvider/types.ts @@ -2,7 +2,7 @@ import type { Token } from '@origin/shared/contracts'; import type { TransactionReceipt } from 'viem'; -export type ActivityType = 'swap' | 'approval'; +export type ActivityType = 'swap' | 'approval' | 'redeem'; export type ActivityStatus = 'pending' | 'success' | 'error';