From fd6acbbc7b663f6d87fc593a9e62551cc2a352ad Mon Sep 17 00:00:00 2001 From: Micaela Estabillo Date: Mon, 28 Oct 2024 16:20:22 -0700 Subject: [PATCH] chore: quote details wip --- app/_locales/en/messages.json | 12 ++ .../bridge-quote-details-modal.stories.tsx | 152 ++++++++++++++++++ .../quotes/bridge-quote-details-modal.tsx | 92 +++++++++++ .../bridge/quotes/bridge-quotes-modal.tsx | 58 ++++--- ui/pages/bridge/quotes/index.scss | 56 ++++++- ui/pages/bridge/quotes/quote-info-row.tsx | 10 +- 6 files changed, 349 insertions(+), 31 deletions(-) create mode 100644 ui/pages/bridge/quotes/bridge-quote-details-modal.stories.tsx create mode 100644 ui/pages/bridge/quotes/bridge-quote-details-modal.tsx diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 4e1bf29b98c1..b1413bc28489 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -2549,6 +2549,9 @@ "included": { "message": "included" }, + "includedFees": { + "message": "Included fees" + }, "infuraBlockedNotification": { "message": "MetaMask is unable to connect to the blockchain host. Review possible reasons $1.", "description": "$1 is a clickable link with with text defined by the 'here' key" @@ -5655,6 +5658,9 @@ "message": "Allow swapping of $1", "description": "Shows a user that they need to allow a token for swapping on their hardware wallet" }, + "swapAmount": { + "message": "Swap amount" + }, "swapAmountReceived": { "message": "Guaranteed amount" }, @@ -6213,6 +6219,12 @@ "totalFees": { "message": "Total fees" }, + "totalPaid": { + "message": "Total paid" + }, + "totalReceived": { + "message": "Total received" + }, "totalVolume": { "message": "Total volume" }, diff --git a/ui/pages/bridge/quotes/bridge-quote-details-modal.stories.tsx b/ui/pages/bridge/quotes/bridge-quote-details-modal.stories.tsx new file mode 100644 index 000000000000..1f3800acf0d7 --- /dev/null +++ b/ui/pages/bridge/quotes/bridge-quote-details-modal.stories.tsx @@ -0,0 +1,152 @@ +import React from 'react'; +import { Provider, useSelector } from 'react-redux'; +import configureStore from '../../../store/store'; +import { BridgeQuotesModal } from './bridge-quotes-modal'; +import { createBridgeMockStore } from '../../../../test/jest/mock-store'; +import mockBridgeQuotesErc20Erc20 from '../../../../test/data/bridge/mock-quotes-erc20-erc20.json'; +import { BridgeQuoteDetailsModal } from './bridge-quote-details-modal'; +import { getBridgeQuotes } from '../../../ducks/bridge/selectors'; +import { Modal, ModalOverlay } from '../../../components/component-library'; + +// export const NoTokenPricesAvailableStory = () => { +// return {}} isOpen={true} />; +// }; +// NoTokenPricesAvailableStory.storyName = 'Token Prices Not Available'; +// NoTokenPricesAvailableStory.decorators = [ +// (story) => ( +// +// {story()} +// +// ), +// ]; + +export const DefaultStory = () => { + const { activeQuote } = useSelector(getBridgeQuotes); + return activeQuote ? ( + {}} + onSelect={() => {}} + expandedQuote={activeQuote} + /> + ) : null; +}; + +const storybook = { + title: 'Pages/Bridge/BridgeQuoteDetailsModal', + component: DefaultStory, +}; + +DefaultStory.storyName = 'Default'; +DefaultStory.decorators = [ + (Story) => ( + {}}> + + + + + + ), +]; + +// export const PositiveArbitrage = () => { +// return {}} isOpen={true} />; +// }; +// PositiveArbitrage.decorators = [ +// (story) => ( +// +// {story()} +// +// ), +// ]; + +// export const QuoteDetails = () => { +// return {}} isOpen={true} />; +// }; +// QuoteDetails.decorators = [ +// (story) => ( +// +// {story()} +// +// ), +// ]; + +export default storybook; diff --git a/ui/pages/bridge/quotes/bridge-quote-details-modal.tsx b/ui/pages/bridge/quotes/bridge-quote-details-modal.tsx new file mode 100644 index 000000000000..bbf28c9c86db --- /dev/null +++ b/ui/pages/bridge/quotes/bridge-quote-details-modal.tsx @@ -0,0 +1,92 @@ +import React from 'react'; +import { + Box, + Button, + ModalContent, + ModalHeader, + Text, +} from '../../../components/component-library'; +import { Footer } from '../../../components/multichain/pages/page'; +import { + TextAlign, + TextVariant, +} from '../../../helpers/constants/design-system'; +import { useI18nContext } from '../../../hooks/useI18nContext'; +import { QuoteMetadata, QuoteResponse } from '../types'; +import { QuoteInfoRow } from './quote-info-row'; + +export const BridgeQuoteDetailsModal = ({ + onBack, + onSelect, + expandedQuote, +}: { + onBack: () => void; + onSelect: () => void; + expandedQuote: QuoteResponse & QuoteMetadata; +}) => { + const t = useI18nContext(); + + const { + quote, + estimatedProcessingTimeInSeconds, + swapRate, + sentAmount, + totalNetworkFee, + toTokenAmount, + } = expandedQuote; + + return ( + + + + {t('swapQuoteDetails')} + + + +
+ + + +
+
+
+ + + + +
+
+
+ +
+
+
+ +
+
+ ); +}; diff --git a/ui/pages/bridge/quotes/bridge-quotes-modal.tsx b/ui/pages/bridge/quotes/bridge-quotes-modal.tsx index ba420fedd482..de2d375be4d4 100644 --- a/ui/pages/bridge/quotes/bridge-quotes-modal.tsx +++ b/ui/pages/bridge/quotes/bridge-quotes-modal.tsx @@ -3,7 +3,6 @@ import { IconName } from '@metamask/snaps-sdk/jsx'; import { useDispatch, useSelector } from 'react-redux'; import { Box, - Button, Icon, IconSize, Modal, @@ -25,12 +24,12 @@ import { useI18nContext } from '../../../hooks/useI18nContext'; import { getCurrentCurrency } from '../../../selectors'; import { setSelectedQuote, setSortOrder } from '../../../ducks/bridge/actions'; import { SortOrder, QuoteMetadata, QuoteResponse } from '../types'; -import { Footer } from '../../../components/multichain/pages/page'; import { useCountdownTimer } from '../../../hooks/bridge/useCountdownTimer'; import { getBridgeQuotes, getBridgeSortOrder, } from '../../../ducks/bridge/selectors'; +import { BridgeQuoteDetailsModal } from './bridge-quote-details-modal'; export const BridgeQuotesModal = ({ onClose, @@ -56,30 +55,39 @@ export const BridgeQuotesModal = ({ {expandedQuote ? ( - - setExpandedQuote(undefined)}> - - {t('swapQuoteDetails')} - - - - {JSON.stringify(expandedQuote)} - -
- -
-
+ setExpandedQuote(undefined)} + onSelect={() => { + dispatch(setSelectedQuote(expandedQuote)); + setExpandedQuote(undefined); + onClose(); + }} + expandedQuote={expandedQuote} + /> ) : ( + // + // setExpandedQuote(undefined)}> + // + // {t('swapQuoteDetails')} + // + // + // + // {JSON.stringify(expandedQuote)} + // + //
+ // + //
+ //
{ return ( - - + + {label} {tooltipText && ( - - + + {secondaryDescription} {description}