@rango-dev/widget-embedded 0.23.1-next.1 → 0.23.1-next.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/dist/components/AppRoutes.d.ts.map +1 -1
  2. package/dist/components/Layout/Layout.styles.d.ts +162 -0
  3. package/dist/components/Layout/Layout.styles.d.ts.map +1 -1
  4. package/dist/components/NoResult/NoResult.d.ts.map +1 -1
  5. package/dist/components/NoResult/NoResult.styles.d.ts.map +1 -1
  6. package/dist/components/Quote/Quote.d.ts.map +1 -1
  7. package/dist/components/Quote/Quote.types.d.ts +2 -0
  8. package/dist/components/Quote/Quote.types.d.ts.map +1 -1
  9. package/dist/components/Quote/QuoteCostDetails.d.ts.map +1 -1
  10. package/dist/components/Quote/{QuoteTrigger .d.ts → QuoteTrigger.d.ts} +1 -1
  11. package/dist/components/Quote/QuoteTrigger.d.ts.map +1 -0
  12. package/dist/components/QuoteWarningsAndErrors/HighValueLossWarningModal.d.ts.map +1 -1
  13. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.d.ts +0 -1
  14. package/dist/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.d.ts.map +1 -1
  15. package/dist/components/QuoteWarningsAndErrors/UnknownPriceWarningModal.d.ts.map +1 -1
  16. package/dist/components/Quotes/Quotes.d.ts +4 -0
  17. package/dist/components/Quotes/Quotes.d.ts.map +1 -0
  18. package/dist/components/Quotes/Quotes.styles.d.ts +487 -0
  19. package/dist/components/Quotes/Quotes.styles.d.ts.map +1 -0
  20. package/dist/components/Quotes/Quotes.types.d.ts +9 -0
  21. package/dist/components/Quotes/Quotes.types.d.ts.map +1 -0
  22. package/dist/components/Quotes/SelectStrategy.d.ts +5 -0
  23. package/dist/components/Quotes/SelectStrategy.d.ts.map +1 -0
  24. package/dist/components/Quotes/index.d.ts +2 -0
  25. package/dist/components/Quotes/index.d.ts.map +1 -0
  26. package/dist/components/common/ActivateTabAlert/ActivateTabAlert.d.ts.map +1 -1
  27. package/dist/constants/index.d.ts +1 -0
  28. package/dist/constants/index.d.ts.map +1 -1
  29. package/dist/constants/navigationRoutes.d.ts +0 -1
  30. package/dist/constants/navigationRoutes.d.ts.map +1 -1
  31. package/dist/constants/quote.d.ts +4 -3
  32. package/dist/constants/quote.d.ts.map +1 -1
  33. package/dist/constants/settings.d.ts +6 -0
  34. package/dist/constants/settings.d.ts.map +1 -0
  35. package/dist/containers/ExpandedQuotes/ExpandedQuotes.d.ts +5 -0
  36. package/dist/containers/ExpandedQuotes/ExpandedQuotes.d.ts.map +1 -0
  37. package/dist/containers/ExpandedQuotes/ExpandedQuotes.styles.d.ts +325 -0
  38. package/dist/containers/ExpandedQuotes/ExpandedQuotes.styles.d.ts.map +1 -0
  39. package/dist/containers/ExpandedQuotes/ExpandedQuotes.types.d.ts +9 -0
  40. package/dist/containers/ExpandedQuotes/ExpandedQuotes.types.d.ts.map +1 -0
  41. package/dist/containers/ExpandedQuotes/index.d.ts +2 -0
  42. package/dist/containers/ExpandedQuotes/index.d.ts.map +1 -0
  43. package/dist/containers/Inputs/Inputs.d.ts +4 -0
  44. package/dist/containers/Inputs/Inputs.d.ts.map +1 -0
  45. package/dist/containers/Inputs/Inputs.styles.d.ts +325 -0
  46. package/dist/containers/Inputs/Inputs.styles.d.ts.map +1 -0
  47. package/dist/containers/Inputs/Inputs.types.d.ts +7 -0
  48. package/dist/containers/Inputs/Inputs.types.d.ts.map +1 -0
  49. package/dist/containers/Inputs/index.d.ts +2 -0
  50. package/dist/containers/Inputs/index.d.ts.map +1 -0
  51. package/dist/containers/QuoteInfo/QuoteInfo.d.ts.map +1 -1
  52. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts +1 -0
  53. package/dist/containers/QuoteInfo/QuoteInfo.types.d.ts.map +1 -1
  54. package/dist/containers/Settings/Lists.d.ts +3 -0
  55. package/dist/containers/Settings/Lists.d.ts.map +1 -0
  56. package/dist/hooks/useMobileDetect.d.ts +3 -0
  57. package/dist/hooks/useMobileDetect.d.ts.map +1 -0
  58. package/dist/hooks/useSwapInput.d.ts.map +1 -1
  59. package/dist/index.d.ts +2 -2
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +2 -2
  62. package/dist/index.js.map +4 -4
  63. package/dist/pages/ConfirmSwapPage.d.ts.map +1 -1
  64. package/dist/pages/Home.d.ts +1 -0
  65. package/dist/pages/Home.d.ts.map +1 -1
  66. package/dist/pages/Routes.d.ts.map +1 -1
  67. package/dist/pages/SettingsPage.d.ts.map +1 -1
  68. package/dist/types/config.d.ts +5 -0
  69. package/dist/types/config.d.ts.map +1 -1
  70. package/dist/utils/common.d.ts +1 -0
  71. package/dist/utils/common.d.ts.map +1 -1
  72. package/package.json +7 -7
  73. package/src/components/AppRoutes.tsx +0 -5
  74. package/src/components/Layout/Layout.styles.ts +12 -7
  75. package/src/components/Layout/Layout.tsx +6 -6
  76. package/src/components/NoResult/NoResult.styles.ts +0 -2
  77. package/src/components/NoResult/NoResult.tsx +1 -0
  78. package/src/components/Quote/Quote.styles.ts +1 -1
  79. package/src/components/Quote/Quote.tsx +4 -2
  80. package/src/components/Quote/Quote.types.ts +2 -0
  81. package/src/components/Quote/QuoteCostDetails.tsx +10 -6
  82. package/src/components/Quote/{QuoteTrigger .tsx → QuoteTrigger.tsx} +3 -16
  83. package/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx +15 -12
  84. package/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.ts +0 -1
  85. package/src/components/QuoteWarningsAndErrors/UnknownPriceWarningModal.tsx +16 -13
  86. package/src/components/Quotes/Quotes.styles.ts +18 -0
  87. package/src/components/Quotes/Quotes.tsx +134 -0
  88. package/src/components/Quotes/Quotes.types.ts +9 -0
  89. package/src/components/Quotes/SelectStrategy.tsx +33 -0
  90. package/src/components/Quotes/index.ts +1 -0
  91. package/src/components/SwapDetails/SwapDetails.tsx +1 -1
  92. package/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx +2 -4
  93. package/src/constants/index.ts +1 -0
  94. package/src/constants/navigationRoutes.ts +0 -1
  95. package/src/constants/quote.ts +22 -7
  96. package/src/constants/settings.ts +5 -0
  97. package/src/containers/ExpandedQuotes/ExpandedQuotes.styles.ts +30 -0
  98. package/src/containers/ExpandedQuotes/ExpandedQuotes.tsx +71 -0
  99. package/src/containers/ExpandedQuotes/ExpandedQuotes.types.ts +9 -0
  100. package/src/containers/ExpandedQuotes/index.ts +1 -0
  101. package/src/containers/Inputs/Inputs.styles.ts +12 -0
  102. package/src/containers/Inputs/Inputs.tsx +165 -0
  103. package/src/containers/Inputs/Inputs.types.ts +7 -0
  104. package/src/containers/Inputs/index.ts +1 -0
  105. package/src/containers/QuoteInfo/QuoteInfo.tsx +2 -0
  106. package/src/containers/QuoteInfo/QuoteInfo.types.ts +1 -0
  107. package/src/containers/Settings/Lists.tsx +265 -0
  108. package/src/hooks/useMobileDetect.ts +21 -0
  109. package/src/hooks/useSwapInput.ts +3 -1
  110. package/src/index.ts +2 -0
  111. package/src/pages/ConfirmSwapPage.tsx +0 -1
  112. package/src/pages/Home.tsx +146 -230
  113. package/src/pages/Routes.tsx +6 -69
  114. package/src/pages/SettingsPage.tsx +6 -184
  115. package/src/types/config.ts +6 -0
  116. package/src/utils/common.ts +3 -0
  117. package/dist/components/Quote/QuoteTrigger .d.ts.map +0 -1
  118. package/dist/pages/ThemePage.d.ts +0 -3
  119. package/dist/pages/ThemePage.d.ts.map +0 -1
  120. package/src/pages/ThemePage.tsx +0 -90
@@ -0,0 +1,21 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ const MIN_WIDTH_WINDOW = 768;
4
+
5
+ const useMobileDetect = () => {
6
+ const [isMobile, setIsMobile] = useState(false);
7
+
8
+ const handleResize = () => {
9
+ setIsMobile(window.innerWidth < MIN_WIDTH_WINDOW);
10
+ };
11
+
12
+ useEffect(() => {
13
+ handleResize(); // Initial check
14
+ window.addEventListener('resize', handleResize);
15
+ return () => window.removeEventListener('resize', handleResize);
16
+ }, []);
17
+
18
+ return isMobile;
19
+ };
20
+
21
+ export default useMobileDetect;
@@ -58,6 +58,8 @@ export function useSwapInput({
58
58
  selectedQuote,
59
59
  sortStrategy,
60
60
  resetQuote,
61
+ error,
62
+ warning,
61
63
  setSelectedQuote,
62
64
  updateQuotePartialState,
63
65
  } = useQuoteStore();
@@ -184,7 +186,7 @@ export function useSwapInput({
184
186
  }
185
187
  if (shouldSkipRequest) {
186
188
  setLoading(false);
187
- if (selectedQuote) {
189
+ if (selectedQuote || error || warning) {
188
190
  resetQuote();
189
191
  }
190
192
  return;
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ import type {
7
7
  WidgetColorsKeys,
8
8
  WidgetConfig,
9
9
  WidgetTheme,
10
+ WidgetVariant,
10
11
  } from './types';
11
12
  import type {
12
13
  PendingSwapWithQueueID,
@@ -89,6 +90,7 @@ export type {
89
90
  HandleWalletsUpdate,
90
91
  ConnectedWallet,
91
92
  Tokens,
93
+ WidgetVariant,
92
94
  };
93
95
  export {
94
96
  Widget,
@@ -282,7 +282,6 @@ export function ConfirmSwapPage() {
282
282
  <QuoteWarningsAndErrors
283
283
  warning={quoteWarning}
284
284
  error={quoteError}
285
- loading={fetchingConfirmationQuote}
286
285
  refetchQuote={onRefresh}
287
286
  showWarningModal={showQuoteWarningModal}
288
287
  confirmationDisabled={!isActiveTab}
@@ -1,90 +1,62 @@
1
1
  import { i18n } from '@lingui/core';
2
- import { Button, Divider, styled, SwapInput, WarningIcon } from '@rango-dev/ui';
2
+ import { Button, Divider, styled, WarningIcon } from '@rango-dev/ui';
3
3
  import React, { useEffect, useState } from 'react';
4
4
  import { useNavigate } from 'react-router-dom';
5
5
 
6
6
  import { HeaderButtons } from '../components/HeaderButtons';
7
7
  import { Layout, PageContainer } from '../components/Layout';
8
8
  import { QuoteWarningsAndErrors } from '../components/QuoteWarningsAndErrors';
9
- import { SwitchFromAndToButton } from '../components/SwitchFromAndTo';
10
- import { errorMessages } from '../constants/errors';
11
9
  import { navigationRoutes } from '../constants/navigationRoutes';
12
- import {
13
- PERCENTAGE_CHANGE_MAX_DECIMALS,
14
- PERCENTAGE_CHANGE_MIN_DECIMALS,
15
- TOKEN_AMOUNT_MAX_DECIMALS,
16
- TOKEN_AMOUNT_MIN_DECIMALS,
17
- USD_VALUE_MAX_DECIMALS,
18
- USD_VALUE_MIN_DECIMALS,
19
- } from '../constants/routing';
10
+ import { ExpandedQuotes } from '../containers/ExpandedQuotes';
11
+ import { Inputs } from '../containers/Inputs';
20
12
  import { QuoteInfo } from '../containers/QuoteInfo';
13
+ import useMobileDetect from '../hooks/useMobileDetect';
21
14
  import { useSwapInput } from '../hooks/useSwapInput';
22
15
  import { useAppStore } from '../store/AppStore';
23
16
  import { useQuoteStore } from '../store/quote';
24
17
  import { useUiStore } from '../store/ui';
25
18
  import { useWalletsStore } from '../store/wallets';
26
- import { getContainer } from '../utils/common';
27
- import { formatTooltipNumbers, numberToString } from '../utils/numbers';
28
- import { getPriceImpact, getPriceImpactLevel } from '../utils/quote';
29
- import { canComputePriceImpact, getSwapButtonState } from '../utils/swap';
30
- import { formatBalance, isFetchingBalance } from '../utils/wallets';
31
-
32
- const FromContainer = styled('div', {
33
- position: 'relative',
19
+ import { getSwapButtonState } from '../utils/swap';
20
+
21
+ const MainContainer = styled('div', {
22
+ display: 'grid',
23
+ gridTemplateColumns: 'auto auto',
24
+ alignItems: 'flex-start',
25
+ height: 700,
26
+ '& .footer__alert': {
27
+ paddingTop: '0',
28
+ },
34
29
  });
30
+ export const TIME_TO_NAVIGATE_ANOTHER_PAGE = 300;
35
31
 
36
- const InputsContainer = styled('div', {
37
- display: 'flex',
38
- flexDirection: 'column',
39
- gap: 5,
40
- alignSelf: 'stretch',
41
- });
42
32
  export function Home() {
43
33
  const navigate = useNavigate();
44
34
  const {
45
35
  fromToken,
46
- fromBlockchain,
47
36
  toToken,
48
- toBlockchain,
49
- setInputAmount,
50
37
  inputAmount,
51
- inputUsdValue,
52
- outputAmount,
53
- outputUsdValue,
54
38
  selectedQuote,
55
39
  refetchQuote,
56
40
  error: quoteError,
57
41
  warning: quoteWarning,
58
42
  quotes,
43
+ setSelectedQuote,
59
44
  resetQuoteWallets,
60
45
  setQuoteWarningsConfirmed,
61
46
  updateQuotePartialState,
62
47
  } = useQuoteStore();
63
- const { fetch: fetchQuote, loading } = useSwapInput({ refetchQuote });
48
+ const [isVisibleExpanded, setIsVisibleExpanded] = useState<boolean>(false);
49
+ const isMobile = useMobileDetect();
64
50
 
51
+ const { fetch: fetchQuote, loading } = useSwapInput({ refetchQuote });
65
52
  const { config, fetchStatus: fetchMetaStatus } = useAppStore();
66
53
 
67
- const { connectedWallets, getBalanceFor } = useWalletsStore();
54
+ const { connectedWallets } = useWalletsStore();
68
55
  const { isActiveTab } = useUiStore();
69
56
  const [showQuoteWarningModal, setShowQuoteWarningModal] = useState(false);
70
- const fetchingBalance =
71
- !!fromBlockchain &&
72
- isFetchingBalance(connectedWallets, fromBlockchain.name);
73
57
 
74
58
  const needsToWarnEthOnPath = false;
75
59
 
76
- const priceImpactInputCanNotBeComputed = !canComputePriceImpact(
77
- selectedQuote,
78
- inputAmount,
79
- inputUsdValue
80
- );
81
-
82
- const priceImpactOutputCanNotBeComputed = !canComputePriceImpact(
83
- selectedQuote,
84
- inputAmount,
85
- outputUsdValue
86
- );
87
-
88
60
  const swapButtonState = getSwapButtonState({
89
61
  fetchMetaStatus,
90
62
  fetchingQuote: loading,
@@ -95,204 +67,148 @@ export function Home() {
95
67
  warning: quoteWarning,
96
68
  needsToWarnEthOnPath,
97
69
  });
70
+ const isExpandable = config?.variant === 'expandable' && !isMobile;
71
+ const hasInputs =
72
+ !!inputAmount && !!fromToken && !!toToken && inputAmount !== '0';
73
+ const fetchingQuote = hasInputs && fetchMetaStatus === 'success' && loading;
98
74
 
99
- const fromTokenBalance = fromToken ? getBalanceFor(fromToken) : null;
100
-
101
- const fromTokenFormattedBalance =
102
- formatBalance(fromTokenBalance)?.amount ?? '0';
103
-
104
- const tokenBalanceReal =
105
- !!fromBlockchain && !!fromToken && fromTokenBalance?.amount
106
- ? numberToString(fromTokenBalance?.amount, fromTokenBalance?.decimals)
107
- : '0';
108
-
109
- const fetchingQuote =
110
- fetchMetaStatus === 'success' &&
111
- !!inputAmount &&
112
- !!fromToken &&
113
- !!toToken &&
114
- loading;
75
+ const hasValidQuotes =
76
+ !isExpandable || (isExpandable && quotes?.results.length);
77
+ const hasWarningOrError = quoteWarning || quoteError;
78
+ const showMessages = hasValidQuotes && hasWarningOrError;
115
79
 
116
80
  useEffect(() => {
117
81
  resetQuoteWallets();
118
82
  updateQuotePartialState('refetchQuote', true);
119
83
  }, []);
120
84
 
121
- const percentageChange =
122
- !inputUsdValue || !outputUsdValue || !outputUsdValue.gt(0)
123
- ? null
124
- : getPriceImpact(inputUsdValue.toString(), outputUsdValue.toString());
85
+ useEffect(() => {
86
+ setIsVisibleExpanded(hasInputs);
87
+ }, [hasInputs]);
88
+
89
+ const onClickRefresh =
90
+ (!!selectedQuote || quoteError) && !showQuoteWarningModal
91
+ ? fetchQuote
92
+ : undefined;
93
+
94
+ const onHandleNavigation = (route: string) => {
95
+ if (isExpandable && isVisibleExpanded) {
96
+ setIsVisibleExpanded(false);
97
+ setTimeout(() => {
98
+ navigate(route);
99
+ }, TIME_TO_NAVIGATE_ANOTHER_PAGE);
100
+ } else {
101
+ navigate(route);
102
+ }
103
+ };
125
104
 
126
105
  return (
127
- <Layout
128
- height="auto"
129
- footer={
130
- <Button
131
- type="primary"
132
- size="large"
133
- disabled={swapButtonState.disabled || !isActiveTab}
134
- prefix={
135
- swapButtonState.action === 'confirm-warning' && <WarningIcon />
136
- }
137
- fullWidth
138
- onClick={() => {
139
- if (swapButtonState.action === 'connect-wallet') {
140
- navigate(navigationRoutes.wallets);
141
- } else if (swapButtonState.action === 'confirm-warning') {
142
- setShowQuoteWarningModal(true);
143
- } else {
144
- navigate(navigationRoutes.confirmSwap);
145
- }
146
- }}>
147
- {swapButtonState.title}
148
- </Button>
149
- }
150
- header={{
151
- onWallet: () => {
152
- navigate(navigationRoutes.wallets);
153
- },
154
- hasBackButton: false,
155
- title: config.title || i18n.t('Swap'),
156
- suffix: (
157
- <HeaderButtons
158
- onClickRefresh={
159
- (!!selectedQuote || quoteError) && !showQuoteWarningModal
160
- ? fetchQuote
161
- : undefined
106
+ <MainContainer>
107
+ <Layout
108
+ height="auto"
109
+ footer={
110
+ <Button
111
+ type="primary"
112
+ size="large"
113
+ disabled={swapButtonState.disabled || !isActiveTab}
114
+ prefix={
115
+ swapButtonState.action === 'confirm-warning' && <WarningIcon />
162
116
  }
163
- onClickHistory={() => navigate(navigationRoutes.swaps)}
164
- onClickSettings={() => navigate(navigationRoutes.settings)}
165
- />
166
- ),
167
- }}>
168
- <PageContainer>
169
- <InputsContainer>
170
- <FromContainer>
171
- <SwapInput
172
- label={i18n.t('From')}
173
- mode="From"
174
- onInputChange={setInputAmount}
175
- balance={fromTokenFormattedBalance}
176
- chain={{
177
- displayName: fromBlockchain?.displayName || '',
178
- image: fromBlockchain?.logo || '',
179
- }}
180
- token={{
181
- displayName: fromToken?.symbol || '',
182
- image: fromToken?.image || '',
183
- }}
184
- onClickToken={() => navigate(navigationRoutes.fromSwap)}
185
- price={{
186
- value: inputAmount,
187
- usdValue: priceImpactInputCanNotBeComputed
188
- ? undefined
189
- : numberToString(
190
- inputUsdValue,
191
- USD_VALUE_MIN_DECIMALS,
192
- USD_VALUE_MAX_DECIMALS
193
- ),
194
- realUsdValue: priceImpactInputCanNotBeComputed
195
- ? undefined
196
- : formatTooltipNumbers(inputUsdValue),
197
- error: priceImpactInputCanNotBeComputed
198
- ? errorMessages().unknownPriceError.impactTitle
199
- : undefined,
200
- }}
201
- disabled={fetchMetaStatus === 'failed'}
202
- loading={fetchMetaStatus === 'loading'}
203
- loadingBalance={fetchingBalance}
204
- tooltipContainer={getContainer()}
205
- onSelectMaxBalance={() => {
206
- setInputAmount(tokenBalanceReal.split(',').join(''));
117
+ fullWidth
118
+ onClick={() => {
119
+ if (swapButtonState.action === 'connect-wallet') {
120
+ onHandleNavigation(navigationRoutes.wallets);
121
+ } else if (swapButtonState.action === 'confirm-warning') {
122
+ setShowQuoteWarningModal(true);
123
+ } else {
124
+ onHandleNavigation(navigationRoutes.confirmSwap);
125
+ }
126
+ }}>
127
+ {swapButtonState.title}
128
+ </Button>
129
+ }
130
+ header={{
131
+ onWallet: () => {
132
+ onHandleNavigation(navigationRoutes.wallets);
133
+ },
134
+ hasBackButton: false,
135
+ title: config.title || i18n.t('Swap'),
136
+ suffix: (
137
+ <HeaderButtons
138
+ hidden={isExpandable ? ['refresh'] : undefined}
139
+ onClickRefresh={onClickRefresh}
140
+ onClickHistory={() => onHandleNavigation(navigationRoutes.swaps)}
141
+ onClickSettings={() => {
142
+ onHandleNavigation(navigationRoutes.settings);
207
143
  }}
208
144
  />
209
- <SwitchFromAndToButton />
210
- </FromContainer>
211
- <SwapInput
212
- sharpBottomStyle={!!selectedQuote || fetchingQuote}
213
- label={i18n.t('To')}
214
- mode="To"
145
+ ),
146
+ }}>
147
+ <PageContainer>
148
+ <Inputs
215
149
  fetchingQuote={fetchingQuote}
216
- chain={{
217
- displayName: toBlockchain?.displayName || '',
218
- image: toBlockchain?.logo || '',
219
- }}
220
- token={{
221
- displayName: toToken?.symbol || '',
222
- image: toToken?.image || '',
150
+ fetchMetaStatus={fetchMetaStatus}
151
+ onClickToken={(mode) => {
152
+ onHandleNavigation(
153
+ mode === 'from'
154
+ ? navigationRoutes.fromSwap
155
+ : navigationRoutes.toSwap
156
+ );
223
157
  }}
224
- percentageChange={numberToString(
225
- getPriceImpact(inputUsdValue, outputUsdValue),
226
- PERCENTAGE_CHANGE_MIN_DECIMALS,
227
- PERCENTAGE_CHANGE_MAX_DECIMALS
228
- )}
229
- warningLevel={getPriceImpactLevel(percentageChange ?? 0)}
230
- price={{
231
- value: numberToString(
232
- outputAmount,
233
- TOKEN_AMOUNT_MIN_DECIMALS,
234
- TOKEN_AMOUNT_MAX_DECIMALS
235
- ),
236
- usdValue: priceImpactOutputCanNotBeComputed
237
- ? undefined
238
- : numberToString(
239
- outputUsdValue,
240
- USD_VALUE_MIN_DECIMALS,
241
- USD_VALUE_MAX_DECIMALS
242
- ),
243
- realValue: formatTooltipNumbers(outputAmount),
244
- realUsdValue: priceImpactOutputCanNotBeComputed
245
- ? undefined
246
- : formatTooltipNumbers(outputUsdValue),
247
- error: priceImpactOutputCanNotBeComputed
248
- ? errorMessages().unknownPriceError.impactTitle
249
- : undefined,
250
- }}
251
- onClickToken={() => navigate(navigationRoutes.toSwap)}
252
- disabled={fetchMetaStatus === 'failed'}
253
- loading={fetchMetaStatus === 'loading'}
254
- tooltipContainer={getContainer()}
255
158
  />
256
- </InputsContainer>
257
- <Divider size="2" />
258
- <QuoteInfo
259
- quote={selectedQuote}
260
- loading={fetchingQuote}
261
- error={quoteError}
262
- tagHidden={false}
263
- warning={quoteWarning}
264
- type="basic"
265
- onClickAllRoutes={
266
- !!quotes && quotes.results.length > 1
267
- ? () => {
268
- updateQuotePartialState('refetchQuote', false);
269
- navigate(navigationRoutes.routes);
270
- }
271
- : undefined
272
- }
273
- />
274
- {quoteWarning || quoteError ? (
275
- <>
276
- <Divider size="10" />
277
- <QuoteWarningsAndErrors
278
- warning={quoteWarning}
279
- error={quoteError}
159
+ <Divider size="2" />
160
+ {!isExpandable ? (
161
+ <QuoteInfo
162
+ quote={selectedQuote}
280
163
  loading={fetchingQuote}
281
- refetchQuote={fetchQuote}
282
- showWarningModal={showQuoteWarningModal}
283
- confirmationDisabled={!isActiveTab}
284
- onOpenWarningModal={() => setShowQuoteWarningModal(true)}
285
- onCloseWarningModal={() => setShowQuoteWarningModal(false)}
286
- onConfirmWarningModal={() => {
287
- setShowQuoteWarningModal(false);
288
- setQuoteWarningsConfirmed(true);
289
- navigate(navigationRoutes.confirmSwap);
290
- }}
291
- onChangeSettings={() => navigate(navigationRoutes.settings)}
164
+ error={quoteError}
165
+ tagHidden={false}
166
+ warning={quoteWarning}
167
+ type="basic"
168
+ onClickAllRoutes={
169
+ !!quotes && quotes.results.length > 1
170
+ ? () => {
171
+ updateQuotePartialState('refetchQuote', false);
172
+ onHandleNavigation(navigationRoutes.routes);
173
+ }
174
+ : undefined
175
+ }
292
176
  />
293
- </>
294
- ) : null}
295
- </PageContainer>
296
- </Layout>
177
+ ) : null}
178
+
179
+ {showMessages ? (
180
+ <>
181
+ <Divider size="10" />
182
+ <QuoteWarningsAndErrors
183
+ warning={quoteWarning}
184
+ error={quoteError}
185
+ refetchQuote={fetchQuote}
186
+ showWarningModal={showQuoteWarningModal}
187
+ confirmationDisabled={!isActiveTab}
188
+ onOpenWarningModal={() => setShowQuoteWarningModal(true)}
189
+ onCloseWarningModal={() => setShowQuoteWarningModal(false)}
190
+ onConfirmWarningModal={() => {
191
+ setShowQuoteWarningModal(false);
192
+ setQuoteWarningsConfirmed(true);
193
+ onHandleNavigation(navigationRoutes.confirmSwap);
194
+ }}
195
+ onChangeSettings={() =>
196
+ onHandleNavigation(navigationRoutes.settings)
197
+ }
198
+ />
199
+ </>
200
+ ) : null}
201
+ </PageContainer>
202
+ </Layout>
203
+ {isExpandable ? (
204
+ <ExpandedQuotes
205
+ loading={fetchingQuote}
206
+ onClickOnQuote={(quote) => setSelectedQuote(quote)}
207
+ fetch={fetchQuote}
208
+ onClickRefresh={onClickRefresh}
209
+ isVisible={isVisibleExpanded}
210
+ />
211
+ ) : null}
212
+ </MainContainer>
297
213
  );
298
214
  }
@@ -1,42 +1,28 @@
1
1
  import type { SelectedQuote } from '../types';
2
- import type { MultiRouteSimulationResult } from 'rango-sdk';
3
2
 
4
3
  import { i18n } from '@lingui/core';
5
- import { Divider } from '@rango-dev/ui';
6
4
  import React from 'react';
7
5
  import { useNavigate } from 'react-router-dom';
8
6
 
9
7
  import { HeaderButtons } from '../components/HeaderButtons';
10
8
  import { Layout, PageContainer } from '../components/Layout';
11
- import { QuoteSkeleton } from '../components/QuoteSkeleton';
9
+ import { Quotes } from '../components/Quotes';
12
10
  import { navigationRoutes } from '../constants/navigationRoutes';
13
- import { QuoteInfo } from '../containers/QuoteInfo';
14
- import { getQuoteError } from '../hooks/useConfirmSwap/useConfirmSwap.helpers';
15
11
  import { useNavigateBack } from '../hooks/useNavigateBack';
16
12
  import { useSwapInput } from '../hooks/useSwapInput';
17
- import { useAppStore } from '../store/AppStore';
18
13
  import { useQuoteStore } from '../store/quote';
19
- import { generateQuoteWarnings } from '../utils/quote';
20
14
 
21
- const ITEM_SKELETON_COUNT = 3;
22
15
  export function RoutesPage() {
23
16
  const navigate = useNavigate();
24
17
  const navigateBack = useNavigateBack();
25
18
 
26
19
  const {
27
20
  selectedQuote,
28
- quotes,
29
21
  refetchQuote,
30
22
  setSelectedQuote,
31
23
  updateQuotePartialState,
32
- fromToken,
33
- toToken,
34
24
  error: quoteError,
35
25
  } = useQuoteStore();
36
- const { slippage, customSlippage } = useAppStore();
37
- const tokens = useAppStore().tokens();
38
-
39
- const userSlippage = customSlippage ?? slippage;
40
26
 
41
27
  const { fetch: fetchQuote, loading: fetchingQuote } = useSwapInput({
42
28
  refetchQuote,
@@ -47,22 +33,7 @@ export function RoutesPage() {
47
33
  updateQuotePartialState('refetchQuote', false);
48
34
  navigateBack();
49
35
  };
50
- const getQuoteWarning = (quote: MultiRouteSimulationResult) => {
51
- if (!fromToken || !toToken || !quotes) {
52
- return null;
53
- }
54
- const mergedQuote: SelectedQuote = {
55
- requestAmount: quotes.requestAmount, // Assuming quotes is an array
56
- ...quote,
57
- };
58
36
 
59
- return generateQuoteWarnings(mergedQuote, {
60
- fromToken,
61
- toToken,
62
- userSlippage,
63
- tokens,
64
- });
65
- };
66
37
  const settings_url = `../${navigationRoutes.settings}`;
67
38
  const wallets_url = `../${navigationRoutes.wallets}`;
68
39
  return (
@@ -86,45 +57,11 @@ export function RoutesPage() {
86
57
  ),
87
58
  }}>
88
59
  <PageContainer>
89
- {fetchingQuote
90
- ? Array.from({ length: ITEM_SKELETON_COUNT }, (_, index) => (
91
- <React.Fragment key={index}>
92
- <QuoteSkeleton
93
- tagHidden={false}
94
- type="list-item"
95
- expanded={false}
96
- />
97
- <Divider size={16} />
98
- </React.Fragment>
99
- ))
100
- : !!quotes &&
101
- quotes.results?.map((quote) => {
102
- const quoteWarning = getQuoteWarning(quote);
103
- const quoteError = getQuoteError(quote.swaps);
104
-
105
- return (
106
- <React.Fragment key={quote.requestId}>
107
- <QuoteInfo
108
- selected={selectedQuote?.requestId === quote.requestId}
109
- tagHidden={false}
110
- quote={{ ...quote, requestAmount: quotes.requestAmount }}
111
- loading={fetchingQuote}
112
- error={quoteError?.options || null}
113
- warning={quoteWarning}
114
- onClick={(quote) => {
115
- updateQuotePartialState('warning', quoteWarning);
116
- updateQuotePartialState(
117
- 'error',
118
- quoteError?.options || null
119
- );
120
- onClickOnQuote(quote);
121
- }}
122
- type="list-item"
123
- />
124
- <Divider size={16} />
125
- </React.Fragment>
126
- );
127
- })}
60
+ <Quotes
61
+ fetch={fetchQuote}
62
+ loading={fetchingQuote}
63
+ onClickOnQuote={onClickOnQuote}
64
+ />
128
65
  </PageContainer>
129
66
  </Layout>
130
67
  );