From 45cf5c8cfd9bf348a115abdb0999172689b5b801 Mon Sep 17 00:00:00 2001 From: frazarshad Date: Fri, 31 May 2024 14:57:02 +0500 Subject: [PATCH] feat: added network notice banner as a resuable component (#112) * feat: added network notice banner as a resuable component * refactor: replaced react-icons with svgs * chore: export types --- .../src/lib/components/NoticeBanner.tsx | 41 +++++++++++++++++++ .../src/lib/components/index.ts | 1 + .../src/lib/icons/Megaphone.tsx | 20 +++++++++ packages/react-components/src/lib/icons/X.tsx | 20 +++++++++ .../react-components/src/lib/utils/index.ts | 1 + .../src/lib/utils/networkConfig.ts | 22 ++++++++++ 6 files changed, 105 insertions(+) create mode 100644 packages/react-components/src/lib/components/NoticeBanner.tsx create mode 100644 packages/react-components/src/lib/icons/Megaphone.tsx create mode 100644 packages/react-components/src/lib/icons/X.tsx create mode 100644 packages/react-components/src/lib/utils/networkConfig.ts diff --git a/packages/react-components/src/lib/components/NoticeBanner.tsx b/packages/react-components/src/lib/components/NoticeBanner.tsx new file mode 100644 index 0000000..749b245 --- /dev/null +++ b/packages/react-components/src/lib/components/NoticeBanner.tsx @@ -0,0 +1,41 @@ +import X from '../icons/X'; +import Megaphone from '../icons/Megaphone'; +import { useState } from 'react'; +import { NetworkNotice, activeNotices } from '../utils/networkConfig'; + +export type NoticeBannerProps = { + notices: Array; +}; + +export const NoticeBanner = ({ notices }: NoticeBannerProps) => { + const [isDismissed, setIsDismissed] = useState(false); + const bannerContent = activeNotices(notices).join(' • '); + const isVisible = + !isDismissed && bannerContent && bannerContent.trim().length; + + return ( + isVisible && ( +
+
+
+
+ + +

{bannerContent}

+
+
+ +
+
+
+
+ ) + ); +}; diff --git a/packages/react-components/src/lib/components/index.ts b/packages/react-components/src/lib/components/index.ts index cd0cc84..6c6d722 100644 --- a/packages/react-components/src/lib/components/index.ts +++ b/packages/react-components/src/lib/components/index.ts @@ -3,3 +3,4 @@ export * from './NodeSelectorModal'; export * from './AmountInput'; export * from './NetworkDropdown'; export * from './OnboardIstModal'; +export * from './NoticeBanner'; diff --git a/packages/react-components/src/lib/icons/Megaphone.tsx b/packages/react-components/src/lib/icons/Megaphone.tsx new file mode 100644 index 0000000..fc2d853 --- /dev/null +++ b/packages/react-components/src/lib/icons/Megaphone.tsx @@ -0,0 +1,20 @@ +const Megaphone = (props: { [key: string]: any }) => { + return ( + + + + ); +}; + +export default Megaphone; diff --git a/packages/react-components/src/lib/icons/X.tsx b/packages/react-components/src/lib/icons/X.tsx new file mode 100644 index 0000000..ba3ca5d --- /dev/null +++ b/packages/react-components/src/lib/icons/X.tsx @@ -0,0 +1,20 @@ +const X = (props: { [key: string]: any }) => { + return ( + + + + ); +}; + +export default X; diff --git a/packages/react-components/src/lib/utils/index.ts b/packages/react-components/src/lib/utils/index.ts index c278c00..eca4839 100644 --- a/packages/react-components/src/lib/utils/index.ts +++ b/packages/react-components/src/lib/utils/index.ts @@ -1 +1,2 @@ export * from './leapElementsClient'; +export * from './networkConfig'; diff --git a/packages/react-components/src/lib/utils/networkConfig.ts b/packages/react-components/src/lib/utils/networkConfig.ts new file mode 100644 index 0000000..f22f5d1 --- /dev/null +++ b/packages/react-components/src/lib/utils/networkConfig.ts @@ -0,0 +1,22 @@ +export type NetworkNotice = { + start: string; + // In the future this might be optional to indicate that it's user-dismissable. + // In that case the client would need some persistent state, perhaps keyed by `message`. + end: string; + message: string; +}; + +export const activeNotices = (notices: Array) => { + if (!notices) return []; + + const now = Date.now(); + const active = notices.filter(n => { + const startD = Date.parse(n.start); + if (startD > now) { + return false; + } + const endD = Date.parse(n.end); + return startD < endD; + }); + return active.map(n => n.message); +};