Skip to content

Commit 3107b6f

Browse files
authored
Merge pull request #1741 from curvefi/pool-alert-banner
feat: Pool alert banner
2 parents dfef779 + da52f40 commit 3107b6f

File tree

8 files changed

+278
-190
lines changed

8 files changed

+278
-190
lines changed

apps/main/src/dex/components/MonadBannerAlert.tsx

Lines changed: 0 additions & 21 deletions
This file was deleted.

apps/main/src/dex/components/PagePool/index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import useStore from '@/dex/store/useStore'
2121
import { getChainPoolIdActiveKey } from '@/dex/utils'
2222
import { getPath } from '@/dex/utils/utilsRouter'
2323
import { ManageGauge } from '@/dex/widgets/manage-gauge'
24+
import { notFalsy } from '@curvefi/prices-api/objects.util'
2425
import Stack from '@mui/material/Stack'
2526
import AlertBox from '@ui/AlertBox'
2627
import { AppFormContentWrapper } from '@ui/AppForm'
@@ -45,7 +46,7 @@ import { t } from '@ui-kit/lib/i18n'
4546
import { REFRESH_INTERVAL } from '@ui-kit/lib/model'
4647
import { type TabOption, TabsSwitcher } from '@ui-kit/shared/ui/TabsSwitcher'
4748
import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces'
48-
import MonadBannerAlert from '../MonadBannerAlert'
49+
import { PoolAlertBanner } from '../PoolAlertBanner'
4950

5051
const DEFAULT_SEED: Seed = { isSeed: null, loaded: false }
5152
const { MaxWidth } = SizesAndSpaces
@@ -204,10 +205,15 @@ const Transfer = (pageTransferProps: PageTransferProps) => {
204205
</StyledExternalLink>
205206
</AppPageFormTitleWrapper>
206207
)
207-
208208
return (
209209
<>
210-
<MonadBannerAlert chainId={rChainId} poolIdOrAddress={rPoolIdOrAddress} />
210+
{poolAlert?.banner && (
211+
<PoolAlertBanner
212+
alertType={poolAlert.alertType}
213+
banner={poolAlert.banner}
214+
poolAlertBannerKey={notFalsy('pool-alert-banner-dismissed', params.network, params.poolIdOrAddress).join('-')}
215+
/>
216+
)}
211217
<AppPageFormContainer isAdvanceMode={true}>
212218
<AppPageFormsWrapper className="grid-transfer">
213219
<Stack
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { useMemo } from 'react'
2+
import { createPortal } from 'react-dom'
3+
import { useIsDesktop } from '@ui-kit/hooks/useBreakpoints'
4+
import { useDismissBanner } from '@ui-kit/hooks/useLocalStorage'
5+
import { Banner, BannerProps } from '@ui-kit/shared/ui/Banner'
6+
import { AlertType, PoolAlert } from '../types/main.types'
7+
8+
const ONE_DAY_MS = 24 * 60 * 60 * 1000 // 24 hours in milliseconds
9+
10+
/** Maps AlertType to BannerSeverity */
11+
const alertTypeToBannerSeverity: Record<AlertType, BannerProps['severity']> = {
12+
error: 'alert',
13+
danger: 'alert',
14+
warning: 'warning',
15+
info: 'info',
16+
'': 'info',
17+
}
18+
19+
export const PoolAlertBanner = ({
20+
banner,
21+
poolAlertBannerKey,
22+
alertType,
23+
}: {
24+
banner: NonNullable<PoolAlert['banner']>
25+
poolAlertBannerKey: string
26+
alertType: AlertType
27+
}) => {
28+
const { shouldShowBanner, dismissBanner } = useDismissBanner(poolAlertBannerKey, ONE_DAY_MS)
29+
const isDesktop = useIsDesktop()
30+
// eslint-disable-next-line react-hooks/exhaustive-deps -- isDesktop triggers re-query when header changes (desktop ↔ mobile)
31+
const portalTarget = useMemo(() => document.getElementsByTagName('header')[0], [isDesktop])
32+
const severity = alertTypeToBannerSeverity[alertType]
33+
34+
return (
35+
shouldShowBanner &&
36+
portalTarget &&
37+
createPortal(
38+
<Banner subtitle={banner.subtitle} severity={severity} onClick={dismissBanner} learnMoreUrl={banner.learnMoreUrl}>
39+
{banner.title}
40+
</Banner>,
41+
portalTarget,
42+
)
43+
)
44+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import Button from '@mui/material/Button'
2+
import Link from '@mui/material/Link'
3+
import Stack from '@mui/material/Stack'
4+
import { ArrowTopRightIcon } from '@ui-kit/shared/icons/ArrowTopRightIcon'
5+
import { RouterLink } from '@ui-kit/shared/ui/RouterLink'
6+
import { SizesAndSpaces } from '@ui-kit/themes/design/1_sizes_spaces'
7+
8+
const { Spacing } = SizesAndSpaces
9+
10+
export const PoolAlertMessage = ({ children }: { children: React.ReactNode }) => (
11+
<Stack
12+
alignItems="flex-start"
13+
spacing={Spacing.sm}
14+
sx={{
15+
'& a': {
16+
wordBreak: 'break-word',
17+
},
18+
}}
19+
>
20+
{children}
21+
</Stack>
22+
)
23+
24+
export const ExternalLink = ({ href, children }: { href: string; children: React.ReactNode }) => (
25+
<Button
26+
color="ghost"
27+
size="extraSmall"
28+
component={Link}
29+
sx={{ color: 'currentColor', textUnderlineOffset: '2px', '&:hover': { textDecoration: 'underline' } }}
30+
endIcon={<ArrowTopRightIcon fontSize={'small'} />}
31+
href={href}
32+
target="_blank"
33+
rel="noreferrer noopener"
34+
>
35+
{children}
36+
</Button>
37+
)
38+
39+
export const InternalLink = ({ href, children }: { href: string; children: React.ReactNode }) => (
40+
<Button
41+
color="ghost"
42+
size="extraSmall"
43+
component={RouterLink}
44+
href={href}
45+
sx={{ color: 'currentColor', textUnderlineOffset: '2px', '&:hover': { textDecoration: 'underline' } }}
46+
>
47+
{children}
48+
</Button>
49+
)

0 commit comments

Comments
 (0)