From 43b592b3da9be1aee3b5e44d89def92e40e3f6b6 Mon Sep 17 00:00:00 2001 From: rozaso Date: Sat, 3 Aug 2024 18:10:39 -0700 Subject: [PATCH 01/42] fix: setup design system and an initial home page. --- blocks/Blocks.colors.ts | 110 ++ blocks/Blocks.constants.ts | 3 + blocks/Blocks.hooks.ts | 13 + blocks/Blocks.types.ts | 71 + blocks/Blocks.utils.ts | 177 +++ blocks/alert/Alert.tsx | 141 ++ blocks/alert/Alert.types.ts | 1 + blocks/alert/Alert.utils.ts | 38 + blocks/alert/index.ts | 3 + blocks/box/Box.constants.ts | 28 + blocks/box/Box.tsx | 63 + blocks/box/Box.types.ts | 100 ++ blocks/box/Box.utils.ts | 25 + blocks/box/index.ts | 4 + blocks/button/Button.tsx | 114 ++ blocks/button/Button.types.ts | 3 + blocks/button/Button.utils.ts | 399 ++++++ blocks/button/index.ts | 3 + blocks/dropdown/Dropdown.tsx | 53 + blocks/dropdown/Dropdown.types.ts | 18 + blocks/dropdown/index.ts | 2 + blocks/hoverableSVG/HoverableSVG.tsx | 77 ++ blocks/hoverableSVG/index.ts | 1 + blocks/icons/IconWrapper.tsx | 61 + blocks/icons/Icons.types.ts | 12 + blocks/icons/components/Add.tsx | 40 + blocks/icons/components/AddEmoji.tsx | 62 + blocks/icons/components/ArrowUpRight.tsx | 51 + blocks/icons/components/Asterisk.tsx | 30 + blocks/icons/components/Back.tsx | 40 + blocks/icons/components/BellRingFilled.tsx | 50 + blocks/icons/components/BellSimple.tsx | 37 + blocks/icons/components/CalendarBlank.tsx | 54 + blocks/icons/components/CameraFilled.tsx | 30 + blocks/icons/components/CaretDown.tsx | 33 + blocks/icons/components/CaretUp.tsx | 33 + blocks/icons/components/Channel.tsx | 39 + blocks/icons/components/ChannelFilled.tsx | 32 + blocks/icons/components/ChannelHome.tsx | 40 + blocks/icons/components/ChannelHomeFilled.tsx | 32 + blocks/icons/components/Chat.tsx | 31 + blocks/icons/components/ChatFilled.tsx | 30 + blocks/icons/components/Copy.tsx | 52 + blocks/icons/components/Cross.tsx | 40 + blocks/icons/components/CrossFilled.tsx | 32 + blocks/icons/components/Dash.tsx | 31 + blocks/icons/components/Dashboard.tsx | 66 + blocks/icons/components/EditProfile.tsx | 107 ++ blocks/icons/components/Ellipse.tsx | 27 + blocks/icons/components/EmptyInbox.tsx | 49 + blocks/icons/components/Envelope.tsx | 42 + blocks/icons/components/ErrorFilled.tsx | 30 + blocks/icons/components/ExternalLink.tsx | 33 + blocks/icons/components/Front.tsx | 40 + blocks/icons/components/Gif.tsx | 47 + blocks/icons/components/Governance.tsx | 82 ++ blocks/icons/components/GovernanceFilled.tsx | 32 + blocks/icons/components/Group.tsx | 30 + blocks/icons/components/GroupFilled.tsx | 42 + blocks/icons/components/InboxBell.tsx | 36 + blocks/icons/components/InboxBellFilled.tsx | 36 + blocks/icons/components/Info.tsx | 37 + blocks/icons/components/InfoFilled.tsx | 30 + .../icons/components/KebabMenuHorizontal.tsx | 50 + blocks/icons/components/KebabMenuVertical.tsx | 49 + blocks/icons/components/LightFilled.tsx | 62 + blocks/icons/components/MaximizeLeft.tsx | 32 + blocks/icons/components/MaximizeRight.tsx | 32 + blocks/icons/components/MegaPhone.tsx | 40 + blocks/icons/components/Moon.tsx | 44 + blocks/icons/components/MoonFilled.tsx | 41 + blocks/icons/components/NFTGated.tsx | 44 + blocks/icons/components/NextIconSlider.tsx | 40 + blocks/icons/components/NoRewards.tsx | 77 ++ .../icons/components/NotificationMobile.tsx | 50 + blocks/icons/components/OptOut.tsx | 40 + blocks/icons/components/Pin.tsx | 33 + blocks/icons/components/PlusCircle.tsx | 47 + blocks/icons/components/PlusCircleFilled.tsx | 30 + blocks/icons/components/PlusSquare.tsx | 58 + blocks/icons/components/PlusSquareFilled.tsx | 59 + blocks/icons/components/PrevIconSlider.tsx | 40 + blocks/icons/components/PrivateChat.tsx | 61 + blocks/icons/components/PublicChat.tsx | 31 + blocks/icons/components/QRCode.tsx | 107 ++ .../icons/components/ReceiveNotification.tsx | 39 + .../components/ReceiveNotificationFilled.tsx | 38 + blocks/icons/components/Refresh.tsx | 40 + blocks/icons/components/SealCheck.tsx | 37 + blocks/icons/components/SealCheckFilled.tsx | 30 + blocks/icons/components/Search.tsx | 39 + blocks/icons/components/SearchFilled.tsx | 32 + blocks/icons/components/SendFilled.tsx | 30 + blocks/icons/components/SendNotification.tsx | 40 + .../components/SendNotificationFilled.tsx | 30 + blocks/icons/components/Settings.tsx | 38 + blocks/icons/components/Smiley.tsx | 48 + blocks/icons/components/Star.tsx | 30 + blocks/icons/components/Swap.tsx | 40 + blocks/icons/components/Tick.tsx | 32 + blocks/icons/components/TickCircleFilled.tsx | 32 + .../components/TickDecoratedCircleFilled.tsx | 31 + blocks/icons/components/UserFilled.tsx | 30 + blocks/icons/components/UserSwitch.tsx | 79 ++ blocks/icons/components/VideoCamera.tsx | 55 + blocks/icons/components/VideoCameraFilled.tsx | 41 + blocks/icons/components/VideoCameraSlash.tsx | 54 + .../components/VideoCameraSlashFilled.tsx | 30 + .../icons/components/WarningCircleFilled.tsx | 30 + blocks/icons/components/Waveform.tsx | 54 + blocks/icons/components/WaveformFilled.tsx | 54 + blocks/icons/components/YieldFarming.tsx | 37 + .../icons/components/YieldFarmingFilled.tsx | 43 + blocks/icons/index.ts | 152 ++ blocks/illustrations/IllustrationWrapper.tsx | 51 + blocks/illustrations/Illustrations.types.ts | 8 + blocks/illustrations/components/Arbitrum.tsx | 38 + blocks/illustrations/components/BNB.tsx | 47 + blocks/illustrations/components/Chat.tsx | 103 ++ blocks/illustrations/components/ChatDark.tsx | 103 ++ .../components/Communication.tsx | 95 ++ .../components/CommunicationDark.tsx | 95 ++ blocks/illustrations/components/Cyber.tsx | 54 + blocks/illustrations/components/Discord.tsx | 34 + .../illustrations/components/EarnOnPush.tsx | 1006 ++++++++++++++ blocks/illustrations/components/Ethereum.tsx | 58 + blocks/illustrations/components/Fuse.tsx | 44 + blocks/illustrations/components/Metamask.tsx | 142 ++ .../illustrations/components/Notification.tsx | 86 ++ .../components/NotificationDark.tsx | 86 ++ blocks/illustrations/components/Optimisim.tsx | 49 + blocks/illustrations/components/Points.tsx | 125 ++ blocks/illustrations/components/Polygon.tsx | 36 + blocks/illustrations/components/PolygonZK.tsx | 61 + blocks/illustrations/components/PushAlpha.tsx | 52 + blocks/illustrations/components/PushBot.tsx | 126 ++ blocks/illustrations/components/PushDev.tsx | 130 ++ blocks/illustrations/components/PushLogo.tsx | 154 +++ blocks/illustrations/components/Referral.tsx | 1134 +++++++++++++++ .../components/RewardsActivity.tsx | 39 + .../illustrations/components/RewardsBell.tsx | 58 + blocks/illustrations/components/Twitter.tsx | 34 + blocks/illustrations/index.ts | 36 + blocks/index.ts | 28 + blocks/link/Link.tsx | 40 + blocks/link/index.ts | 1 + blocks/lozenge/Lozenge.constants.tsx | 91 ++ blocks/lozenge/Lozenge.tsx | 73 + blocks/lozenge/Lozenge.types.tsx | 5 + blocks/lozenge/index.tsx | 3 + blocks/menu/Menu.constants.ts | 10 + blocks/menu/Menu.tsx | 36 + blocks/menu/Menu.types.ts | 43 + blocks/menu/MenuItem.tsx | 77 ++ blocks/menu/index.ts | 4 + blocks/modal/AlertModal.tsx | 108 ++ blocks/modal/Modal.constants.ts | 23 + blocks/modal/Modal.tsx | 159 +++ blocks/modal/Modal.types.ts | 7 + blocks/modal/index.ts | 2 + blocks/progressBar/ProgressBar.tsx | 41 + blocks/progressBar/ProgressBar.types.ts | 11 + blocks/progressBar/ProgressBar.utils.ts | 4 + blocks/progressBar/index.ts | 3 + blocks/separator/Separator.constants.ts | 9 + blocks/separator/Separator.tsx | 36 + blocks/separator/Separator.types.ts | 31 + blocks/separator/Separator.utils.ts | 15 + blocks/separator/index.ts | 4 + blocks/skeleton/Skeleton.constants.ts | 4 + blocks/skeleton/Skeleton.tsx | 50 + blocks/skeleton/Skeleton.types.ts | 43 + blocks/skeleton/Skeleton.utils.ts | 28 + blocks/skeleton/index.ts | 3 + blocks/spinner/Spinner.tsx | 56 + blocks/spinner/Spinner.types.ts | 2 + blocks/spinner/Spinner.utils.ts | 28 + blocks/spinner/index.ts | 1 + blocks/tabs/Tabs.styled.ts | 127 ++ blocks/tabs/Tabs.tsx | 76 + blocks/tabs/index.ts | 1 + blocks/text/Text.constants.ts | 379 +++++ blocks/text/Text.tsx | 97 ++ blocks/text/Text.types.ts | 43 + blocks/text/Text.utils.ts | 36 + blocks/text/index.ts | 4 + blocks/textInput/TextInput.tsx | 223 +++ blocks/textInput/index.ts | 1 + blocks/textarea/TextArea.tsx | 185 +++ blocks/textarea/index.ts | 1 + blocks/theme/Theme.ts | 8 + blocks/theme/Theme.types.ts | 41 + blocks/theme/Theme.utils.ts | 33 + blocks/theme/colors/colors.brands.ts | 69 + blocks/theme/colors/colors.primitives.ts | 91 ++ blocks/theme/colors/colors.semantics.ts | 104 ++ blocks/theme/device/theme.device.ts | 32 + blocks/theme/index.ts | 4 + blocks/theme/semantics/semantics.alert.ts | 24 + blocks/theme/semantics/semantics.button.ts | 130 ++ blocks/theme/semantics/semantics.checkbox.ts | 21 + blocks/theme/semantics/semantics.dropdown.ts | 45 + blocks/theme/semantics/semantics.icon.ts | 29 + blocks/theme/semantics/semantics.input.ts | 45 + blocks/theme/semantics/semantics.modal.ts | 25 + .../theme/semantics/semantics.progress-bar.ts | 6 + blocks/theme/semantics/semantics.radio.ts | 19 + blocks/theme/semantics/semantics.skeleton.ts | 12 + blocks/theme/semantics/semantics.spinner.ts | 6 + blocks/theme/semantics/semantics.stroke.ts | 31 + blocks/theme/semantics/semantics.surface.ts | 35 + blocks/theme/semantics/semantics.switch.ts | 22 + blocks/theme/semantics/semantics.text.ts | 35 + blocks/theme/semantics/semantics.textarea.ts | 45 + blocks/theme/semantics/semantics.toast.ts | 35 + blocks/theme/semantics/semantics.tooltip.ts | 8 + blocks/theme/variables/variables.blur.ts | 8 + .../theme/variables/variables.borderRadius.ts | 13 + .../theme/variables/variables.borderSize.ts | 8 + blocks/theme/variables/variables.opacity.ts | 13 + blocks/theme/variables/variables.spacing.ts | 12 + blocks/toggleSwtich/ToggleSwitch.tsx | 127 ++ blocks/toggleSwtich/index.ts | 1 + blocks/tooltip/Tooltip.constants.ts | 10 + blocks/tooltip/Tooltip.tsx | 122 ++ blocks/tooltip/Tooltip.types.ts | 42 + blocks/tooltip/Tooltip.utils.ts | 49 + blocks/tooltip/index.ts | 4 + common/hooks/index.ts | 2 + common/hooks/useIsVisible.ts | 24 + common/index.ts | 1 + components/Home/LiveBlocks/index.tsx | 93 ++ .../Home/LiveBlocks/liveblocks.styles.ts | 17 + components/Home/LiveTransactions/index.tsx | 95 ++ .../livetransactions.styles.ts | 17 + components/Home/OverViewSet/index.tsx | 69 + .../Home/OverViewSet/overview.styles.ts | 17 + components/Home/Search/index.tsx | 63 + components/Home/Search/search.styles.ts | 17 + components/Loader/HomeLoader.tsx | 28 + components/Reusables/SharedStyling/index.ts | 14 + package-lock.json | 1228 ++++++++++++++++- package.json | 6 + pages/home/index.tsx | 26 + pages/index.tsx | 4 +- sections/Home/home.styles.ts | 0 sections/Home/index.tsx | 38 + theme/globalStyles.ts | 5 +- theme/palette.ts | 8 +- utils/constants.js | 2 +- yarn.lock | 429 +++++- 251 files changed, 15310 insertions(+), 30 deletions(-) create mode 100644 blocks/Blocks.colors.ts create mode 100644 blocks/Blocks.constants.ts create mode 100644 blocks/Blocks.hooks.ts create mode 100644 blocks/Blocks.types.ts create mode 100644 blocks/Blocks.utils.ts create mode 100644 blocks/alert/Alert.tsx create mode 100644 blocks/alert/Alert.types.ts create mode 100644 blocks/alert/Alert.utils.ts create mode 100644 blocks/alert/index.ts create mode 100644 blocks/box/Box.constants.ts create mode 100644 blocks/box/Box.tsx create mode 100644 blocks/box/Box.types.ts create mode 100644 blocks/box/Box.utils.ts create mode 100644 blocks/box/index.ts create mode 100644 blocks/button/Button.tsx create mode 100644 blocks/button/Button.types.ts create mode 100644 blocks/button/Button.utils.ts create mode 100644 blocks/button/index.ts create mode 100644 blocks/dropdown/Dropdown.tsx create mode 100644 blocks/dropdown/Dropdown.types.ts create mode 100644 blocks/dropdown/index.ts create mode 100644 blocks/hoverableSVG/HoverableSVG.tsx create mode 100644 blocks/hoverableSVG/index.ts create mode 100644 blocks/icons/IconWrapper.tsx create mode 100644 blocks/icons/Icons.types.ts create mode 100644 blocks/icons/components/Add.tsx create mode 100644 blocks/icons/components/AddEmoji.tsx create mode 100644 blocks/icons/components/ArrowUpRight.tsx create mode 100644 blocks/icons/components/Asterisk.tsx create mode 100644 blocks/icons/components/Back.tsx create mode 100644 blocks/icons/components/BellRingFilled.tsx create mode 100644 blocks/icons/components/BellSimple.tsx create mode 100644 blocks/icons/components/CalendarBlank.tsx create mode 100644 blocks/icons/components/CameraFilled.tsx create mode 100644 blocks/icons/components/CaretDown.tsx create mode 100644 blocks/icons/components/CaretUp.tsx create mode 100644 blocks/icons/components/Channel.tsx create mode 100644 blocks/icons/components/ChannelFilled.tsx create mode 100644 blocks/icons/components/ChannelHome.tsx create mode 100644 blocks/icons/components/ChannelHomeFilled.tsx create mode 100644 blocks/icons/components/Chat.tsx create mode 100644 blocks/icons/components/ChatFilled.tsx create mode 100644 blocks/icons/components/Copy.tsx create mode 100644 blocks/icons/components/Cross.tsx create mode 100644 blocks/icons/components/CrossFilled.tsx create mode 100644 blocks/icons/components/Dash.tsx create mode 100644 blocks/icons/components/Dashboard.tsx create mode 100644 blocks/icons/components/EditProfile.tsx create mode 100644 blocks/icons/components/Ellipse.tsx create mode 100644 blocks/icons/components/EmptyInbox.tsx create mode 100644 blocks/icons/components/Envelope.tsx create mode 100644 blocks/icons/components/ErrorFilled.tsx create mode 100644 blocks/icons/components/ExternalLink.tsx create mode 100644 blocks/icons/components/Front.tsx create mode 100644 blocks/icons/components/Gif.tsx create mode 100644 blocks/icons/components/Governance.tsx create mode 100644 blocks/icons/components/GovernanceFilled.tsx create mode 100644 blocks/icons/components/Group.tsx create mode 100644 blocks/icons/components/GroupFilled.tsx create mode 100644 blocks/icons/components/InboxBell.tsx create mode 100644 blocks/icons/components/InboxBellFilled.tsx create mode 100644 blocks/icons/components/Info.tsx create mode 100644 blocks/icons/components/InfoFilled.tsx create mode 100644 blocks/icons/components/KebabMenuHorizontal.tsx create mode 100644 blocks/icons/components/KebabMenuVertical.tsx create mode 100644 blocks/icons/components/LightFilled.tsx create mode 100644 blocks/icons/components/MaximizeLeft.tsx create mode 100644 blocks/icons/components/MaximizeRight.tsx create mode 100644 blocks/icons/components/MegaPhone.tsx create mode 100644 blocks/icons/components/Moon.tsx create mode 100644 blocks/icons/components/MoonFilled.tsx create mode 100644 blocks/icons/components/NFTGated.tsx create mode 100644 blocks/icons/components/NextIconSlider.tsx create mode 100644 blocks/icons/components/NoRewards.tsx create mode 100644 blocks/icons/components/NotificationMobile.tsx create mode 100644 blocks/icons/components/OptOut.tsx create mode 100644 blocks/icons/components/Pin.tsx create mode 100644 blocks/icons/components/PlusCircle.tsx create mode 100644 blocks/icons/components/PlusCircleFilled.tsx create mode 100644 blocks/icons/components/PlusSquare.tsx create mode 100644 blocks/icons/components/PlusSquareFilled.tsx create mode 100644 blocks/icons/components/PrevIconSlider.tsx create mode 100644 blocks/icons/components/PrivateChat.tsx create mode 100644 blocks/icons/components/PublicChat.tsx create mode 100644 blocks/icons/components/QRCode.tsx create mode 100644 blocks/icons/components/ReceiveNotification.tsx create mode 100644 blocks/icons/components/ReceiveNotificationFilled.tsx create mode 100644 blocks/icons/components/Refresh.tsx create mode 100644 blocks/icons/components/SealCheck.tsx create mode 100644 blocks/icons/components/SealCheckFilled.tsx create mode 100644 blocks/icons/components/Search.tsx create mode 100644 blocks/icons/components/SearchFilled.tsx create mode 100644 blocks/icons/components/SendFilled.tsx create mode 100644 blocks/icons/components/SendNotification.tsx create mode 100644 blocks/icons/components/SendNotificationFilled.tsx create mode 100644 blocks/icons/components/Settings.tsx create mode 100644 blocks/icons/components/Smiley.tsx create mode 100644 blocks/icons/components/Star.tsx create mode 100644 blocks/icons/components/Swap.tsx create mode 100644 blocks/icons/components/Tick.tsx create mode 100644 blocks/icons/components/TickCircleFilled.tsx create mode 100644 blocks/icons/components/TickDecoratedCircleFilled.tsx create mode 100644 blocks/icons/components/UserFilled.tsx create mode 100644 blocks/icons/components/UserSwitch.tsx create mode 100644 blocks/icons/components/VideoCamera.tsx create mode 100644 blocks/icons/components/VideoCameraFilled.tsx create mode 100644 blocks/icons/components/VideoCameraSlash.tsx create mode 100644 blocks/icons/components/VideoCameraSlashFilled.tsx create mode 100644 blocks/icons/components/WarningCircleFilled.tsx create mode 100644 blocks/icons/components/Waveform.tsx create mode 100644 blocks/icons/components/WaveformFilled.tsx create mode 100644 blocks/icons/components/YieldFarming.tsx create mode 100644 blocks/icons/components/YieldFarmingFilled.tsx create mode 100644 blocks/icons/index.ts create mode 100644 blocks/illustrations/IllustrationWrapper.tsx create mode 100644 blocks/illustrations/Illustrations.types.ts create mode 100644 blocks/illustrations/components/Arbitrum.tsx create mode 100644 blocks/illustrations/components/BNB.tsx create mode 100644 blocks/illustrations/components/Chat.tsx create mode 100644 blocks/illustrations/components/ChatDark.tsx create mode 100644 blocks/illustrations/components/Communication.tsx create mode 100644 blocks/illustrations/components/CommunicationDark.tsx create mode 100644 blocks/illustrations/components/Cyber.tsx create mode 100644 blocks/illustrations/components/Discord.tsx create mode 100644 blocks/illustrations/components/EarnOnPush.tsx create mode 100644 blocks/illustrations/components/Ethereum.tsx create mode 100644 blocks/illustrations/components/Fuse.tsx create mode 100644 blocks/illustrations/components/Metamask.tsx create mode 100644 blocks/illustrations/components/Notification.tsx create mode 100644 blocks/illustrations/components/NotificationDark.tsx create mode 100644 blocks/illustrations/components/Optimisim.tsx create mode 100644 blocks/illustrations/components/Points.tsx create mode 100644 blocks/illustrations/components/Polygon.tsx create mode 100644 blocks/illustrations/components/PolygonZK.tsx create mode 100644 blocks/illustrations/components/PushAlpha.tsx create mode 100644 blocks/illustrations/components/PushBot.tsx create mode 100644 blocks/illustrations/components/PushDev.tsx create mode 100644 blocks/illustrations/components/PushLogo.tsx create mode 100644 blocks/illustrations/components/Referral.tsx create mode 100644 blocks/illustrations/components/RewardsActivity.tsx create mode 100644 blocks/illustrations/components/RewardsBell.tsx create mode 100644 blocks/illustrations/components/Twitter.tsx create mode 100644 blocks/illustrations/index.ts create mode 100644 blocks/index.ts create mode 100644 blocks/link/Link.tsx create mode 100644 blocks/link/index.ts create mode 100644 blocks/lozenge/Lozenge.constants.tsx create mode 100644 blocks/lozenge/Lozenge.tsx create mode 100644 blocks/lozenge/Lozenge.types.tsx create mode 100644 blocks/lozenge/index.tsx create mode 100644 blocks/menu/Menu.constants.ts create mode 100644 blocks/menu/Menu.tsx create mode 100644 blocks/menu/Menu.types.ts create mode 100644 blocks/menu/MenuItem.tsx create mode 100644 blocks/menu/index.ts create mode 100644 blocks/modal/AlertModal.tsx create mode 100644 blocks/modal/Modal.constants.ts create mode 100644 blocks/modal/Modal.tsx create mode 100644 blocks/modal/Modal.types.ts create mode 100644 blocks/modal/index.ts create mode 100644 blocks/progressBar/ProgressBar.tsx create mode 100644 blocks/progressBar/ProgressBar.types.ts create mode 100644 blocks/progressBar/ProgressBar.utils.ts create mode 100644 blocks/progressBar/index.ts create mode 100644 blocks/separator/Separator.constants.ts create mode 100644 blocks/separator/Separator.tsx create mode 100644 blocks/separator/Separator.types.ts create mode 100644 blocks/separator/Separator.utils.ts create mode 100644 blocks/separator/index.ts create mode 100644 blocks/skeleton/Skeleton.constants.ts create mode 100644 blocks/skeleton/Skeleton.tsx create mode 100644 blocks/skeleton/Skeleton.types.ts create mode 100644 blocks/skeleton/Skeleton.utils.ts create mode 100644 blocks/skeleton/index.ts create mode 100644 blocks/spinner/Spinner.tsx create mode 100644 blocks/spinner/Spinner.types.ts create mode 100644 blocks/spinner/Spinner.utils.ts create mode 100644 blocks/spinner/index.ts create mode 100644 blocks/tabs/Tabs.styled.ts create mode 100644 blocks/tabs/Tabs.tsx create mode 100644 blocks/tabs/index.ts create mode 100644 blocks/text/Text.constants.ts create mode 100644 blocks/text/Text.tsx create mode 100644 blocks/text/Text.types.ts create mode 100644 blocks/text/Text.utils.ts create mode 100644 blocks/text/index.ts create mode 100644 blocks/textInput/TextInput.tsx create mode 100644 blocks/textInput/index.ts create mode 100644 blocks/textarea/TextArea.tsx create mode 100644 blocks/textarea/index.ts create mode 100644 blocks/theme/Theme.ts create mode 100644 blocks/theme/Theme.types.ts create mode 100644 blocks/theme/Theme.utils.ts create mode 100644 blocks/theme/colors/colors.brands.ts create mode 100644 blocks/theme/colors/colors.primitives.ts create mode 100644 blocks/theme/colors/colors.semantics.ts create mode 100644 blocks/theme/device/theme.device.ts create mode 100644 blocks/theme/index.ts create mode 100644 blocks/theme/semantics/semantics.alert.ts create mode 100644 blocks/theme/semantics/semantics.button.ts create mode 100644 blocks/theme/semantics/semantics.checkbox.ts create mode 100644 blocks/theme/semantics/semantics.dropdown.ts create mode 100644 blocks/theme/semantics/semantics.icon.ts create mode 100644 blocks/theme/semantics/semantics.input.ts create mode 100644 blocks/theme/semantics/semantics.modal.ts create mode 100644 blocks/theme/semantics/semantics.progress-bar.ts create mode 100644 blocks/theme/semantics/semantics.radio.ts create mode 100644 blocks/theme/semantics/semantics.skeleton.ts create mode 100644 blocks/theme/semantics/semantics.spinner.ts create mode 100644 blocks/theme/semantics/semantics.stroke.ts create mode 100644 blocks/theme/semantics/semantics.surface.ts create mode 100644 blocks/theme/semantics/semantics.switch.ts create mode 100644 blocks/theme/semantics/semantics.text.ts create mode 100644 blocks/theme/semantics/semantics.textarea.ts create mode 100644 blocks/theme/semantics/semantics.toast.ts create mode 100644 blocks/theme/semantics/semantics.tooltip.ts create mode 100644 blocks/theme/variables/variables.blur.ts create mode 100644 blocks/theme/variables/variables.borderRadius.ts create mode 100644 blocks/theme/variables/variables.borderSize.ts create mode 100644 blocks/theme/variables/variables.opacity.ts create mode 100644 blocks/theme/variables/variables.spacing.ts create mode 100644 blocks/toggleSwtich/ToggleSwitch.tsx create mode 100644 blocks/toggleSwtich/index.ts create mode 100644 blocks/tooltip/Tooltip.constants.ts create mode 100644 blocks/tooltip/Tooltip.tsx create mode 100644 blocks/tooltip/Tooltip.types.ts create mode 100644 blocks/tooltip/Tooltip.utils.ts create mode 100644 blocks/tooltip/index.ts create mode 100644 common/hooks/index.ts create mode 100644 common/hooks/useIsVisible.ts create mode 100644 common/index.ts create mode 100644 components/Home/LiveBlocks/index.tsx create mode 100644 components/Home/LiveBlocks/liveblocks.styles.ts create mode 100644 components/Home/LiveTransactions/index.tsx create mode 100644 components/Home/LiveTransactions/livetransactions.styles.ts create mode 100644 components/Home/OverViewSet/index.tsx create mode 100644 components/Home/OverViewSet/overview.styles.ts create mode 100644 components/Home/Search/index.tsx create mode 100644 components/Home/Search/search.styles.ts create mode 100644 components/Loader/HomeLoader.tsx create mode 100644 pages/home/index.tsx create mode 100644 sections/Home/home.styles.ts create mode 100644 sections/Home/index.tsx diff --git a/blocks/Blocks.colors.ts b/blocks/Blocks.colors.ts new file mode 100644 index 0000000..49e3c0b --- /dev/null +++ b/blocks/Blocks.colors.ts @@ -0,0 +1,110 @@ +import { BlocksColorData, BlocksColors, GlobalColors } from './Blocks.types'; + +// TODO This file needs to be removed after all the blcoks components uses the new design theme + +const brandColors = { + /* New brand colors */ + + 'GRAY-100': '#F5F6F8', + 'GRAY-200': '#EAEBF2', + 'GRAY-300': '#C4CBD5', + 'GRAY-400': '#B0B3B9', + 'GRAY-500': '#8C93A0', + 'GRAY-600': '#757D8D', + 'GRAY-700': '#484D58', + 'GRAY-800': '#313338', + 'GRAY-900': '#202124', + 'GRAY-1000': '#17181B', + + 'PINK-100': '#FCEBFF', + 'PINK-200': '#FBE8FF', + 'PINK-300': '#F3AEFF', + 'PINK-400': '#CF59E2', + 'PINK-500': '#D548EC', + 'PINK-600': '#C742DD', + 'PINK-700': '#AA30BE', + 'PINK-800': '#7B0090', + 'PINK-900': '#570066', + 'PINK-1000': '#35003F', + + 'RED-100': '#FFECEC', + 'RED-200': '#FFD9D9', + 'RED-300': '#FFB1B1', + 'RED-400': '#FF8585', + 'RED-500': '#FF4E4E', + 'RED-600': '#F11F1F', + 'RED-700': '#D43B3B', + 'RED-800': '#A40A0A', + 'RED-900': '#670000', + 'RED-1000': '#400000', + + 'GREEN-100': '#D8F7F0', + 'GREEN-200': '#AFEFE1', + 'GREEN-300': '#51DCBD', + 'GREEN-400': '#00C296', + 'GREEN-500': '#00A47F', + 'GREEN-600': '#008769', + 'GREEN-700': '#006B53', + 'GREEN-800': '#A40A0A', + 'GREEN-900': '#00382B', + 'GREEN-1000': '#002019', +}; + +export const blocksColorsLegacy = { + /* Legacy colors used through out the app */ + PRIMARY: 'rgba(27.0, 150.0, 227.0, 1.0)', + PRIMARY_PINK: '#CF1C84', + PLACEHOLDER_DARK_GRAY: '#D9D9D9', + + LINKS: 'rgba(20.0, 126.0, 251.0, 1.0)', + + GRADIENT_PRIMARY: 'rgba(226.0, 8.0, 128.0, 1.0)', + GRADIENT_SECONDARY: 'rgba(53.0, 197.0, 243.0, 1.0)', + GRADIENT_THIRD: 'rgba(103.0, 76.0, 159.0, 1.0)', + + TRANSPARENT: 'transparent', + + WHITE: 'rgba(255.0, 255.0, 255.0, 1.0)', + DARK_WHITE: 'rgba(255.0, 255.0, 255.0, 0.75)', + MID_WHITE: 'rgba(255.0, 255.0, 255.0, 0.5)', + LIGHT_WHITE: 'rgba(255.0, 255.0, 255.0, 0.25)', + + SLIGHTER_GRAY: 'rgba(250.0, 250.0, 250.0, 1)', + SLIGHT_GRAY: 'rgba(231.0, 231.0, 231.0, 1)', + LIGHT_GRAY: 'rgba(225.0, 225.0, 225.0, 1)', + MID_GRAY: 'rgba(200.0, 200.0, 200.0, 1)', + DARK_GRAY: 'rgba(160.0, 160.0, 160.0, 1)', + DARKER_GRAY: 'rgba(100.0, 100.0, 100.0, 1)', + + LIGHT_BLACK_TRANS: 'rgba(0.0, 0.0, 0.0, 0.1)', + SEMI_MID_BLACK_TRANS: 'rgba(0.0, 0.0, 0.0, 0.25)', + MID_BLACK_TRANS: 'rgba(0.0, 0.0, 0.0, 0.5)', + DARK_BLACK_TRANS: 'rgba(0.0, 0.0, 0.0, 0.75)', + BLACK: 'rgba(0.0, 0.0, 0.0, 1.0)', + + CONFIRM_GREEN: 'rgba(50.0, 205.0, 50.0, 1.0)', + + CONFIRM: 'rgba(34.0, 139.0, 34.0, 1.0)', + WARNING: 'rgba(255.0, 153.0, 0.0, 1.0)', + + SUBLIME_RED: 'rgba(237.0, 59.0, 72.0, 1.0)', + BADGE_RED: 'rgba(208.0, 44.0, 30.0, 1.0)', + LIGHT_MAROON: 'rgba(159.0, 0.0, 0.0, 1.0)', + LIGHTER_MAROON: 'rgba(129.0, 0.0, 0.0, 1.0)', + + ...brandColors, +}; + +const createBlocksColors = () => { + const globalColors: GlobalColors = blocksColorsLegacy; + + const appColors = Object.keys(globalColors).reduce((acc: Partial, key) => { + const newKey = key.toLowerCase().replace(/_([a-z])/g, (match, letter) => letter.toUpperCase()) as BlocksColors; + acc[newKey as keyof BlocksColorData] = globalColors[key as keyof GlobalColors]; + return acc; + }, {}); + + return appColors as BlocksColorData; +}; + +export const blocksColors = createBlocksColors(); diff --git a/blocks/Blocks.constants.ts b/blocks/Blocks.constants.ts new file mode 100644 index 0000000..7ebcd2a --- /dev/null +++ b/blocks/Blocks.constants.ts @@ -0,0 +1,3 @@ +export const radiusRegex = /\bradius-[a-z]+\b/g; + +export const spacingRegex = /\bspacing-[a-z]+\b/g; diff --git a/blocks/Blocks.hooks.ts b/blocks/Blocks.hooks.ts new file mode 100644 index 0000000..e32526e --- /dev/null +++ b/blocks/Blocks.hooks.ts @@ -0,0 +1,13 @@ +import { themeDark, themeLight } from './../theme/palette'; +import { useTheme } from 'styled-components'; +import { ThemeMode } from './Blocks.types'; + +// TODO: Remove this when we remove dependency from this hook + +type ThemeData = typeof themeLight | typeof themeDark; + +export const useBlocksTheme = () => { + const { scheme } = useTheme() as ThemeData; + + return { mode: scheme as ThemeMode }; +}; diff --git a/blocks/Blocks.types.ts b/blocks/Blocks.types.ts new file mode 100644 index 0000000..27495a4 --- /dev/null +++ b/blocks/Blocks.types.ts @@ -0,0 +1,71 @@ +import { HTMLAttributes } from 'react'; +import { BoxResponsiveCSSProperties, BoxResponsiveCSSPropertiesData, BoxResponsivePropValues } from './box'; +import { blocksColorsLegacy } from './Blocks.colors'; +import { StrokeColors, ThemeBorderRadius, ThemeBorderSize, ThemeSpacing } from './theme/Theme.types'; +import { + SkeletonResponsiveCSSProperties, + SkeletonResponsiveCSSPropertiesData, + SkeletonResponsivePropValues, +} from './skeleton'; +import { + SeparatorResponsiveCSSProperties, + SeparatorResponsiveCSSPropertiesData, + SeparatorResponsivePropValues, +} from './separator'; + +export type DeviceSize = '320px' | '375px' | '425px' | '768px' | '1024px' | '1440px' | '2560px'; + +export type DeviceSizeName = 'mobileS' | 'mobileM' | 'mobileL' | 'tablet' | 'laptop' | 'laptopL' | 'desktop'; + +export type Breakpoint = 'initial' | 'ms' | 'mm' | 'ml' | 'tb' | 'lp' | 'll' | 'dp'; + +export type ResponsiveProp = T | { [key in Breakpoint]?: T }; + +export type BlocksRadiusType = + | ThemeBorderRadius + | `${ThemeBorderRadius} ${ThemeBorderRadius}` + | `${ThemeBorderRadius} ${ThemeBorderRadius} ${ThemeBorderRadius} ${ThemeBorderRadius}`; + +export type BlocksSpaceType = + | ThemeSpacing + | `${ThemeSpacing} ${ThemeSpacing}` + | `${ThemeSpacing} ${ThemeSpacing} ${ThemeSpacing} ${ThemeSpacing}`; + +export type BlocksGapType = ThemeSpacing | `${ThemeSpacing} ${ThemeSpacing}`; + +export type PixelValue = `${number}px`; + +export type ValueOf = T[keyof T]; + +export type CSSPropName = + | BoxResponsiveCSSProperties + | SeparatorResponsiveCSSProperties + | SkeletonResponsiveCSSProperties; + +export type CSSPropValueType = BoxResponsivePropValues | SeparatorResponsivePropValues | SkeletonResponsivePropValues; + +export type ResponsiveCSSPropertyData = + | BoxResponsiveCSSPropertiesData + | SeparatorResponsiveCSSPropertiesData + | SkeletonResponsiveCSSPropertiesData; + +export type TransformedHTMLAttributes = Omit, 'style' | 'color'>; + +/* This needs to be removed when the color dependency from Globals.js is removed. */ +export type GlobalColors = Record; + +type CamelCase = S extends `${infer P1}_${infer P2}${infer P3}` + ? `${Lowercase}${Capitalize>}${CamelCase}` + : Lowercase; + +export type BlocksColorData = { + [K in keyof typeof blocksColorsLegacy as CamelCase]: (typeof blocksColorsLegacy)[K]; +}; + +export type BlocksColors = keyof BlocksColorData; + +export type ThemeMode = 'light' | 'dark'; + +export type BorderValue = `${ThemeBorderSize} ${string} ${StrokeColors}` | 'none'; + +export type ModeProp = { mode: ThemeMode }; diff --git a/blocks/Blocks.utils.ts b/blocks/Blocks.utils.ts new file mode 100644 index 0000000..1b86463 --- /dev/null +++ b/blocks/Blocks.utils.ts @@ -0,0 +1,177 @@ +import { css } from 'styled-components'; +import { deviceMediaQ, deviceSizes, breakpointMap } from './theme'; +import { + Breakpoint, + CSSPropName, + CSSPropValueType, + DeviceSizeName, + PixelValue, + ResponsiveCSSPropertyData, + BorderValue, + BlocksRadiusType, +} from './Blocks.types'; +import { radiusRegex, spacingRegex } from './Blocks.constants'; +import { textVariants, TextVariants } from './text'; +import { ThemeColors } from './theme/Theme.types'; + +/** + * @param propName + * @param value + * @returns value of a CSS property + */ +const getCSSValue = (propName: CSSPropName, value: CSSPropValueType | undefined) => { + if (propName === 'padding' || propName === 'margin') { + if (typeof value === 'string') { + return value.replace(spacingRegex, (match) => `var(--${match})`); + } + } else if (propName === 'gap' || propName === 'border-radius') { + return `var(--${value})`; + } + return value; +}; + +/** + * @param pixelStr + * @returns numeric values fetched from px values + * + * Helper function to parse the pixel values from the strings. + */ +const parsePixels = (pixelStr: PixelValue) => parseFloat(pixelStr.replace('px', '')); + +/** + * @param values + * @param operation + * @returns computed values in px + */ +const computePixels = (values: PixelValue[], operation: 'add' | 'sub') => + values.reduce((acc, value) => (operation === 'add' ? acc + parsePixels(value) : acc - parsePixels(value)), 0) + 'px'; + +/** + * @param breakpointData + * @returns media query css in string forma for all screen sizes passed on to it + * + * Separates css for different screen size from all css properties + * and combine them into common media queries to avoid applying multiple + * media queries for every css property. + */ +const createBreakpointCSS = (breakpointData: Record) => { + const validBreakpointList = Object.entries(breakpointData).filter(([_, css]) => css); + + if (!validBreakpointList.length) return ''; + + const singleDeviceMedia = `@media ${deviceMediaQ[validBreakpointList[0][0] as DeviceSizeName]} { + ${validBreakpointList[0][1]} + }`; + + if (validBreakpointList.length === 1) { + return singleDeviceMedia; + } else { + return ( + `${singleDeviceMedia}` + + validBreakpointList + .map(([_bp, css], index) => { + if (!index) { + return ''; + } else { + const previousBp = validBreakpointList[index - 1][0] as DeviceSizeName; + + const previousBpWidth = computePixels([deviceSizes[previousBp], '1px'], 'add'); + + const previousBpMediaQ = `@media (min-width: ${previousBpWidth})`; + + const currentBp = _bp as DeviceSizeName; + + const currentBpMediaQ = deviceMediaQ?.[currentBp] ? `and ${deviceMediaQ?.[currentBp]}` : ''; + + return `${previousBpMediaQ} ${currentBpMediaQ} { ${css} }`; + } + }) + .join(';') + ); + } +}; + +/** + * + * @param data + * @returns styled components css + * + * This function collects css values for different screen sizes + * and then combines them into to same media queries classes. + * + */ +export const getResponsiveCSS = (data: ResponsiveCSSPropertyData[]) => { + let initialCSS = ''; + const breakpointData: Record = { + mobileS: '', + mobileM: '', + mobileL: '', + tablet: '', + laptop: '', + laptopL: '', + desktop: '', + }; + + data.forEach(({ prop, propName }) => { + if (typeof prop === 'object') { + Object.entries(prop).forEach(([key, value]) => { + const breakpoint = breakpointMap[key as Breakpoint]; + if (breakpoint) { + breakpointData[breakpoint] += `${propName}: ${getCSSValue(propName, value)};`; + } else { + initialCSS += `${propName}: ${getCSSValue(propName, value)};`; + } + }); + } else if (prop) { + initialCSS += `${propName}: ${getCSSValue(propName, prop)};`; + } + }); + + return css` + ${initialCSS} + ${createBreakpointCSS(breakpointData)} + `; +}; + +/** + * @param border + * @returns border + */ +export const getBlocksBorder = (border?: BorderValue) => { + // If border is not given return undefined, to avoid any breakages + if (!border) return border; + + let borderValues; + + borderValues = border.split(' '); + + borderValues[0] = `var(--${borderValues[0]})`; + + borderValues[2] = `var(--${borderValues[2]})`; + return borderValues.join(' '); +}; + +/** + * @param radius + * @returns + */ +export const getBlocksBorderRadius = (radius?: BlocksRadiusType) => { + // If border-radius is not given return undefined, to avoid any breakages + if (!radius) return radius; + + const result = radius.replace(radiusRegex, (match) => `var(--${match})`); + + return result; +}; + +export const getTextVariantStyles = (variant: TextVariants, color: ThemeColors) => css` + color: var(--${color}); + font-family: var(--font-family); + font-size: ${textVariants[variant].fontSize}; + font-style: ${textVariants[variant].fontStyle}; + font-weight: ${textVariants[variant].fontWeight}; + line-height: ${textVariants[variant].lineHeight}; + letter-spacing: ${textVariants[variant].letterSpacing}; + text-transform: ${textVariants[variant].textTransform}; + margin: var(--spacing-none); +`; diff --git a/blocks/alert/Alert.tsx b/blocks/alert/Alert.tsx new file mode 100644 index 0000000..bc51cfe --- /dev/null +++ b/blocks/alert/Alert.tsx @@ -0,0 +1,141 @@ +import type { FC } from 'react'; +import styled, { FlattenSimpleInterpolation } from 'styled-components'; + +import type { TransformedHTMLAttributes } from '../Blocks.types'; +import type { AlertVariant } from './Alert.types'; +import { alertVariants } from './Alert.utils'; +import { Cross } from 'blocks/icons'; +import { HoverableSVG } from 'blocks/hoverableSVG'; +import { getTextVariantStyles } from 'blocks/Blocks.utils'; + +export type AlertProps = { + /* Additional prop from styled components to apply custom css to Alert */ + css?: FlattenSimpleInterpolation; + /* Sets the variant of the alert */ + variant: AlertVariant; + /* Close function to be called on close button click */ + onClose?: () => void; + /* Retry function to be called on action button click */ + onAction?: () => void; + /* Text to be displayed on the action button */ + actionText?: string; + /* Boolean to set the visibility of the icon */ + showIcon?: boolean; + /* Header text for the alert */ + heading?: string; + /* Description text for the alert */ + description?: string; +} & TransformedHTMLAttributes; + +const StyledAlert = styled.div` + /* Common Alert CSS */ + + display: flex; + font-family: var(--font-family); + border-radius: var(--radius-sm); + justify-content: center; + white-space: nowrap; + padding: var(--spacing-xs); + justify-content: space-between; + ${({ variant }) => ` + border: var(--border-sm) solid var(--${alertVariants[variant].borderColor}); + background-color: var(--${alertVariants[variant].bgColor}); + `} + + /* Common icon css added through CSS class */ + .icon { + display: flex; + justify-content: center; + margin-right: var(--spacing-xxxs); + color: var(--${({ variant }) => alertVariants[variant].iconColor}); + } + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''} +`; + +const StyledLink = styled.div<{ variant: AlertVariant }>` + /* Link CSS */ + text-decoration: none; + cursor: pointer; + color: var(--${({ variant }) => alertVariants[variant].ctaColor}); +`; + +const TextContainer = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--spacing-xxxs); + flex: 1 0 0; +`; + +const RightContainer = styled.div` + display: flex; + gap: var(--spacing-xs, 12px); + align-items: center; + height: 24px; +`; + +const Heading = styled.p` + ${() => getTextVariantStyles('h5-semibold', 'components-alert-text-default')} +`; + +const Description = styled.p` + ${() => getTextVariantStyles('bs-regular', 'components-alert-text-body')} +`; + +const Alert: FC = ({ + description, + heading, + onClose, + onAction, + actionText = 'Try Again', + showIcon = true, + variant = 'info', + ...props +}) => { + const { icon: Icon } = alertVariants[variant]; + + return ( + + {showIcon && ( + + + + )} + + {heading && {heading}} + {description && {description}} + + + {onAction && ( + + {actionText} + + )} + {onClose && ( + + } + onClick={onClose} + /> + )} + + + ); +}; + +Alert.displayName = 'Alert'; + +export { Alert }; diff --git a/blocks/alert/Alert.types.ts b/blocks/alert/Alert.types.ts new file mode 100644 index 0000000..2e0a42f --- /dev/null +++ b/blocks/alert/Alert.types.ts @@ -0,0 +1 @@ +export type AlertVariant = 'success' | 'warning' | 'error' | 'info'; diff --git a/blocks/alert/Alert.utils.ts b/blocks/alert/Alert.utils.ts new file mode 100644 index 0000000..be53753 --- /dev/null +++ b/blocks/alert/Alert.utils.ts @@ -0,0 +1,38 @@ +import { AlertVariant } from './Alert.types'; +import { IconProps, InfoFilled, TickCircleFilled, WarningCircleFilled } from '../icons'; +import { ThemeColors } from 'blocks/theme/Theme.types'; +import { FC } from 'react'; + +export const alertVariants: Record< + AlertVariant, + { icon: FC; iconColor: ThemeColors; borderColor: ThemeColors; bgColor: ThemeColors; ctaColor: ThemeColors } +> = { + success: { + icon: TickCircleFilled, + iconColor: 'components-alert-icon-success', + borderColor: 'components-alert-stroke-success', + bgColor: 'components-alert-background-success', + ctaColor: 'components-alert-text-cta-success', + }, + warning: { + icon: WarningCircleFilled, + iconColor: 'components-alert-icon-warning', + borderColor: 'components-alert-stroke-warning', + bgColor: 'components-alert-background-warning', + ctaColor: 'components-alert-text-cta-warning', + }, + info: { + icon: InfoFilled, + iconColor: 'components-alert-icon-info', + borderColor: 'components-alert-stroke-info', + bgColor: 'components-alert-background-info', + ctaColor: 'components-alert-text-cta-info', + }, + error: { + icon: WarningCircleFilled, + iconColor: 'components-alert-icon-error', + borderColor: 'components-alert-stroke-error', + bgColor: 'components-alert-background-error', + ctaColor: 'components-alert-text-cta-error', + }, +}; diff --git a/blocks/alert/index.ts b/blocks/alert/index.ts new file mode 100644 index 0000000..cfb6dd8 --- /dev/null +++ b/blocks/alert/index.ts @@ -0,0 +1,3 @@ +export * from './Alert'; +export * from './Alert.utils'; +export * from './Alert.types'; diff --git a/blocks/box/Box.constants.ts b/blocks/box/Box.constants.ts new file mode 100644 index 0000000..2950c54 --- /dev/null +++ b/blocks/box/Box.constants.ts @@ -0,0 +1,28 @@ +import { ModeProp } from '../Blocks.types'; +import { BoxCSSProps } from './Box.types'; + +export const boxRestrictedCSSPropKeys: (keyof BoxCSSProps | keyof ModeProp)[] = [ + 'border', + 'borderRadius', + 'backgroundColor', + 'color', + 'cursor', + 'position', + 'boxShadow', + 'alignItems', + 'alignSelf', + 'display', + 'flexDirection', + 'gap', + 'height', + 'justifyContent', + 'margin', + 'maxHeight', + 'minHeight', + 'maxWidth', + 'minWidth', + 'overflow', + 'padding', + 'textAlign', + 'width', +]; diff --git a/blocks/box/Box.tsx b/blocks/box/Box.tsx new file mode 100644 index 0000000..f06a460 --- /dev/null +++ b/blocks/box/Box.tsx @@ -0,0 +1,63 @@ +import { forwardRef } from 'react'; +import styled from 'styled-components'; + +import { TransformedHTMLAttributes } from '../Blocks.types'; +import { getBlocksBorder, getBlocksBorderRadius } from '../Blocks.utils'; +import { BoxCSSProps, BoxComponentProps } from './Box.types'; +import { getBoxResponsiveCSS } from './Box.utils'; +import { boxRestrictedCSSPropKeys } from './Box.constants'; +import { colorBrands } from 'blocks/theme/colors/colors.brands'; + +export type BoxProps = BoxCSSProps & BoxComponentProps & TransformedHTMLAttributes; + +const StyledBox = styled.div.withConfig({ + shouldForwardProp: (prop, defaultValidatorFn) => + !boxRestrictedCSSPropKeys.includes(prop as keyof BoxCSSProps) && defaultValidatorFn(prop), +})` + /* Responsive props */ + ${(props) => getBoxResponsiveCSS(props)} + + /* Non-responsive props */ + color: ${(props) => (props?.color ? `var(--${props.color})` : ``)}; + background-color: ${(props) => (props?.backgroundColor ? `var(--${props.backgroundColor})` : ``)}; + box-shadow: ${(props) => props.boxShadow}; + border-radius: ${(props) => getBlocksBorderRadius(props.borderRadius)}; + cursor: ${(props) => props.cursor}; + overflow: ${(props) => props.overflow}; + border: ${(props) => getBlocksBorder(props.border)}; + position: ${(props) => props.position}; + + // push custom scroll + ${(props) => + props.customScrollbar && + ` + &::-webkit-scrollbar-track { + background-color: none; + border-radius: 9px; + } + + &::-webkit-scrollbar { + background-color: none; + width: 4px; + } + + &::-webkit-scrollbar-thumb { + border-radius: 10px; + background: ${colorBrands[`primary-500`]}; + } + `} + + /* Extra CSS prop */ + ${(props) => props.css || ''} +`; +const Box = forwardRef(({ as = 'div', ...props }, ref) => ( + +)); + +Box.displayName = 'Box'; + +export { Box }; diff --git a/blocks/box/Box.types.ts b/blocks/box/Box.types.ts new file mode 100644 index 0000000..4f4181b --- /dev/null +++ b/blocks/box/Box.types.ts @@ -0,0 +1,100 @@ +import { CSSProperties, ReactNode } from 'react'; + +import { + BorderValue, + BlocksRadiusType, + ResponsiveProp, + BlocksSpaceType, + ValueOf, + BlocksGapType, +} from '../Blocks.types'; +import { FlattenSimpleInterpolation } from 'styled-components'; +import { SurfaceColors, TextColors } from 'blocks/theme/Theme.types'; + +export type BoxResponsiveProps = { + /* Sets align-items css property */ + alignItems?: ResponsiveProp; + /* Sets align-self css property */ + alignSelf?: ResponsiveProp; + /* Sets flex-direction css property */ + flexDirection?: ResponsiveProp; + /* Sets gap between the elements */ + gap?: ResponsiveProp; + /* Sets display css property */ + display?: ResponsiveProp; + /* Sets height css property */ + height?: ResponsiveProp; + /* Sets justify-content css property */ + justifyContent?: ResponsiveProp; + /* Sets margin css property */ + margin?: ResponsiveProp; + /* Sets max-height css property */ + maxHeight?: ResponsiveProp; + /* Sets min-height css property */ + minHeight?: ResponsiveProp; + /* Sets max-width css property */ + maxWidth?: ResponsiveProp; + /* Sets min-width css property */ + minWidth?: ResponsiveProp; + /* Sets padding css property */ + padding?: ResponsiveProp; + /* Sets text-align css property */ + textAlign?: ResponsiveProp; + /* Sets width css property */ + width?: ResponsiveProp; +}; + +export type BoxNonResponsiveProps = { + /* Sets border css property */ + border?: BorderValue; + /* Sets border-radius css property */ + borderRadius?: BlocksRadiusType; + /* Sets background-color css property */ + backgroundColor?: SurfaceColors; + /* Sets color css property */ + color?: TextColors; + /* Sets cursor css property */ + cursor?: CSSProperties['cursor']; + /* Sets position css property */ + position?: CSSProperties['position']; + /* Sets box-shadow css property */ + boxShadow?: string; + /* Sets overflow css property */ + overflow?: CSSProperties['overflow']; +}; + +export type BoxCSSProps = BoxResponsiveProps & BoxNonResponsiveProps; + +type BoxHTMLTags = 'div' | 'span'; + +export type BoxComponentProps = { + /* Decides which HTML tag to render inside Box */ + as?: BoxHTMLTags; + /* Additional prop from styled components to apply custom css to Box */ + css?: FlattenSimpleInterpolation; + /* Child react nodes rendered by Box */ + children?: ReactNode; + // option to add custom scroll bar to box + customScrollbar?: boolean; +}; + +export type BoxResponsiveCSSProperties = + | 'align-items' + | 'align-self' + | 'display' + | 'flex-direction' + | 'gap' + | 'height' + | 'justify-content' + | 'margin' + | 'max-height' + | 'min-height' + | 'max-width' + | 'min-width' + | 'padding' + | 'text-align' + | 'width'; + +export type BoxResponsivePropValues = ValueOf; + +export type BoxResponsiveCSSPropertiesData = { propName: BoxResponsiveCSSProperties; prop: BoxResponsivePropValues }; diff --git a/blocks/box/Box.utils.ts b/blocks/box/Box.utils.ts new file mode 100644 index 0000000..42341d3 --- /dev/null +++ b/blocks/box/Box.utils.ts @@ -0,0 +1,25 @@ +import { getResponsiveCSS } from '../Blocks.utils'; +import { BoxResponsiveCSSPropertiesData, BoxResponsiveProps } from './Box.types'; + +const getBoxResponsiveCSSProperties = (props: BoxResponsiveProps): BoxResponsiveCSSPropertiesData[] => [ + { propName: 'align-items', prop: props.alignItems }, + { propName: 'align-self', prop: props.alignSelf }, + { propName: 'display', prop: props.display }, + { propName: 'flex-direction', prop: props.flexDirection }, + { propName: 'gap', prop: props.gap }, + { propName: 'height', prop: props.height }, + { propName: 'justify-content', prop: props.justifyContent }, + { propName: 'margin', prop: props.margin }, + { propName: 'max-height', prop: props.maxHeight }, + { propName: 'min-height', prop: props.minHeight }, + { propName: 'max-width', prop: props.maxWidth }, + { propName: 'min-width', prop: props.minWidth }, + { propName: 'padding', prop: props.padding }, + { propName: 'text-align', prop: props.textAlign }, + { propName: 'width', prop: props.width }, +]; + +export const getBoxResponsiveCSS = (props: BoxResponsiveProps) => { + const data = getBoxResponsiveCSSProperties(props); + return getResponsiveCSS(data); +}; diff --git a/blocks/box/index.ts b/blocks/box/index.ts new file mode 100644 index 0000000..b62abe7 --- /dev/null +++ b/blocks/box/index.ts @@ -0,0 +1,4 @@ +export * from './Box'; +export * from './Box.constants'; +export * from './Box.types'; +export * from './Box.utils'; diff --git a/blocks/button/Button.tsx b/blocks/button/Button.tsx new file mode 100644 index 0000000..ceef6f8 --- /dev/null +++ b/blocks/button/Button.tsx @@ -0,0 +1,114 @@ +import { ReactNode, forwardRef } from 'react'; +import styled, { FlattenSimpleInterpolation } from 'styled-components'; + +import type { TransformedHTMLAttributes } from '../Blocks.types'; +import type { ButtonSize, ButtonVariant } from './Button.types'; +import { getButtonSizeStyles, getButtonVariantStyles } from './Button.utils'; +import { Spinner } from '../spinner'; + +export type ButtonProps = { + /* Child react nodes rendered by Box */ + children?: ReactNode; + /* Renders the iconOnly button as circular */ + circular?: boolean; + /* Additional prop from styled components to apply custom css to Button */ + css?: FlattenSimpleInterpolation; + /* Sets button as disabled */ + disabled?: boolean; + /* Used to render the button with icon only */ + iconOnly?: ReactNode; + /* Render an icon before button contents */ + leadingIcon?: ReactNode; + /* Sets the size of the button */ + size?: ButtonSize; + /* Render an icon after button contents */ + trailingIcon?: ReactNode; + /* Sets the variant of the button */ + variant?: ButtonVariant; + /* Button takes the full width if enabled */ + block?: boolean; + /* Button loading state */ + loading?: boolean; +} & TransformedHTMLAttributes; + +const StyledButton = styled.button` + /* Common Button CSS */ + + align-items: center; + cursor: ${(props) => (props.disabled ? 'not-allowed' : 'pointer')}; + display: flex; + font-family: var(--font-family); + justify-content: center; + white-space: nowrap; + + /* Common icon css added through CSS class */ + .icon { + display: flex; + align-items: center; + justify-content: center; + } + /* Button variant CSS styles */ + ${({ variant, loading }) => getButtonVariantStyles(variant || 'primary', loading!)} + + ${({ loading }) => loading && 'opacity: var(--opacity-80);'} + + /* Button and font size CSS styles */ + ${({ iconOnly, size }) => getButtonSizeStyles({ iconOnly: !!iconOnly, size: size || 'medium' })} + + /* Circular CSS for rounded icon only buttons */ + ${({ circular, iconOnly }) => circular && iconOnly && `border-radius: var(--r10)`} + + /* Prop specific CSS */ + ${({ block }) => block && 'width: 100%;'} + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''} +`; + +const SpinnerContainer = styled.div` + padding: 5px; +`; +const Button = forwardRef( + ( + { + disabled, + variant = 'primary', + size = 'medium', + leadingIcon, + trailingIcon, + loading = false, + iconOnly, + circular = false, + children, + ...props + }, + ref + ) => ( + + {loading && ( + + + + )} + {leadingIcon && {leadingIcon}} + {!iconOnly && children} + {trailingIcon && {trailingIcon}} + {iconOnly && !loading && !children && {iconOnly}} + + ) +); + +Button.displayName = 'Button'; + +export { Button }; diff --git a/blocks/button/Button.types.ts b/blocks/button/Button.types.ts new file mode 100644 index 0000000..8b9f7b8 --- /dev/null +++ b/blocks/button/Button.types.ts @@ -0,0 +1,3 @@ +export type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'danger' | 'dangerSecondary' | 'outline'; + +export type ButtonSize = 'extraSmall' | 'small' | 'medium' | 'large'; diff --git a/blocks/button/Button.utils.ts b/blocks/button/Button.utils.ts new file mode 100644 index 0000000..8dd243f --- /dev/null +++ b/blocks/button/Button.utils.ts @@ -0,0 +1,399 @@ +import { FlattenSimpleInterpolation, css } from 'styled-components'; +import { ButtonSize, ButtonVariant } from './Button.types'; + +export const getButtonVariantStyles = (variant: ButtonVariant, loading: boolean) => { + switch (variant) { + case 'primary': { + return ` + background-color: var(--${ + loading ? 'components-button-primary-background-loading' : 'components-button-primary-background-default' + }); + color: var(--components-button-primary-text-default); + ${ + !loading && + ` + &:hover { + background-color: var(--components-button-primary-background-hover) + } + &:active { + background-color: var(--components-button-primary-background-pressed); + } + ` + }; + + &:focus-visible { + background-color: var(--components-button-primary-background-focus); + border: var(--border-sm) solid var(--components-button-primary-stroke-focus); + outline: none; + } + ${ + !loading && + `&:disabled { + background-color: var(--components-button-primary-background-disabled); + color: var(--components-button-primary-text-disabled); + }` + }; + + `; + } + case 'secondary': { + return ` + background-color: var(--components-button-secondary-background-default); + color: var(--components-button-secondary-text-default); + ${ + !loading && + ` + &:hover { + background-color: var(--components-button-secondary-background-hover); + } + + &:active { + background-color: var(--components-button-secondary-background-pressed); + }` + }; + + &:focus-visible { + background-color: var(--components-button-secondary-background-focus); + border: var(--border-sm) solid var(--components-button-secondary-stroke-focus); + outline: none; + } + ${ + !loading && + `&:disabled { + background-color: var(--components-button-secondary-background-disabled); + color: var(--components-button-secondary-text-disabled); + };` + }; + + `; + } + case 'tertiary': { + return ` + background-color: var(--components-button-tertiary-background-default); + color: var(--components-button-tertiary-text-default); + ${ + !loading && + ` + &:hover { + color: var(--components-button-tertiary-text-default); + background-color: var(--components-button-tertiary-background-hover); + } + + &:active { + background-color: var(--components-button-tertiary-background-pressed); + color: var(--components-button-secondary-text-default); + }` + }; + + &:focus-visible { + border: var(--border-sm) solid var(--components-button-tertiary-stroke-focus); + background-color: var(--components-button-tertiary-background-focus); + color: var(--components-button-tertiary-text-default); + outline: none; + } + ${ + !loading && + `&:disabled { + background-color: var(--components-button-tertiary-background-disabled); + color: var(--components-button-tertiary-text-disabled); + }` + }; + `; + } + case 'danger': { + return ` + background-color: var(--components-button-danger-background-default); + color: var(--components-button-danger-text-default); + ${ + !loading && + ` + &:hover { + background-color: var(--components-button-danger-background-hover); + } + + &:active { + background-color: var(--components-button-danger-background-pressed); + }` + }; + + &:focus-visible { + background-color: var(--components-button-danger-background-focus); + border: var(--border-sm) solid var(--components-button-danger-stroke-focus); + outline: none; + } + ${ + !loading && + `&:disabled { + background-color: var(--components-button-danger-background-disabled); + color: var(--components-button-danger-text-disabled); + }` + }; + `; + } + case 'dangerSecondary': { + return ` + background-color: var(--components-button-danger-secondary-background-default); + color: var(--components-button-danger-secondary-text-default); + ${ + !loading && + ` + &:hover { + background-color: var(--components-button-danger-secondary-background-hover); + } + + &:active { + background-color: var(--components-button-danger-secondary-background-pressed); + }` + }; + + &:focus-visible { + background-color: var(--components-button-danger-secondary-background-focus); + border: var(--border-sm) solid var(--components-button-danger-secondary-stroke-focus); + outline: none; + } + ${ + !loading && + `&:disabled { + background-color: var(--components-button-danger-secondary-background-disabled); + color:var(--components-button-danger-secondary-text-disabled); + }` + }; + `; + } + case 'outline': { + return ` + background-color: var(--components-button-outline-background-default); + border: var(--border-sm) solid var(--components-button-outline-stroke-default); + color: var(--components-button-outline-text-default); + outline: none; + ${ + !loading && + ` + &:hover { + border: var(--border-sm) solid var(--components-button-outline-stroke-hover); + background-color: var(--components-button-outline-background-hover); + } + + &:active { + border: var(--border-sm) solid var(--components-button-outline-stroke-pressed); + background-color: var(--components-button-outline-background-pressed); + }` + }; + + &:focus-visible { + border: var(--border-sm) solid var(--components-button-outline-stroke-focus); + background-color: var(--components-button-outline-background-focus); + } + + ${ + !loading && + `&:disabled { + border: none; + background-color: var(--components-button-tertiary-background-disabled); + color: var(--components-button-outline-text-disabled); + }` + }; + `; + } + } +}; + +export const getButtonSizeStyles = ({ + iconOnly, + size, +}: { + iconOnly?: boolean; + size: ButtonSize; +}): FlattenSimpleInterpolation => { + if (size === 'extraSmall') { + return css` + /* Button tag container size css */ + + ${iconOnly + ? ` + border-radius: var(--radius-xxs); + gap: var(--spacing-none); + height: 32px; + width: 32px; + padding: var(--spacing-none); + ` + : ` + border-radius: var(--radius-xxs); + gap: var(--spacing-xxxs); + height: 32px; + padding: var(--spacing-xs) var(--spacing-sm); + min-width: 100px; + `} + + /* Button text size css */ + leading-trim: both; + text-edge: cap; + font-size: 12px; + font-style: normal; + font-weight: 500; + line-height: 16px; + + [role='img'] { + width: 16px; + height: 16px; + } + [role='spinner'] { + width: 10.66px; + height: 10.66px; + } + + .icon-text > span { + height: 16px; + width: 16px; + } + + .icon-only > span { + height: 16px; + width: 16px; + } + `; + } + if (size === 'small') { + return css` + /* Button tag container size css */ + + ${iconOnly + ? ` + border-radius: var(--radius-xs); + gap: var(--spacing-none); + height: 40px; + width: 40px; + padding: var(--spacing-none); + ` + : ` + border-radius: var(--radius-xs); + gap: var(--spacing-xxxs); + height: 40px; + padding: var(--spacing-xs) var(--spacing-md); + min-width: 100px; + `} + + /* Button text size css */ + leading-trim: both; + text-edge: cap; + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: 16px; + + [role='img'] { + width: 24px; + height: 24px; + } + [role='spinner'] { + width: 16px; + height: 16px; + } + + .icon-text > span { + height: 16px; + width: 16px; + } + + .icon-only > span { + height: 24px; + width: 24px; + } + `; + } + + if (size === 'medium') { + return css` + /* Button tag container size css */ + + ${iconOnly + ? ` + border-radius: var(--spacing-sm); + gap: var(--spacing-none); + height: 48px; + width: 48px; + padding: var(--spacing-none); + ` + : ` + border-radius: var(--radius-xs); + gap: var(--spacing-xxxs); + height: 48px; + padding: var(--spacing-sm) var(--spacing-md); + min-width: 100px; + `} + + /* Button text size css */ + leading-trim: both; + text-edge: cap; + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 16px; + + [role='img'] { + width: 24px; + height: 24px; + } + [role='spinner'] { + width: 16px; + height: 16px; + } + + .icon-text > span { + height: 24px; + width: 24px; + } + + .icon-only > span { + height: 24px; + width: 24px; + } + `; + } + + return css` + /* Button tag container size css */ + + ${iconOnly + ? ` + border-radius: var(--spacing-sm); + gap: var(--spacing-none); + height: 52px; + width: 52px; + padding: var(--spacing-none); + ` + : ` + border-radius: var(--radius-xs); + gap: var(--spacing-xxxs); + height: 52px; + padding: var(--spacing-sm) var(--spacing-lg); + min-width: 100px; + `} + + /* Button text size css */ + leading-trim: both; + text-edge: cap; + font-size: 18px; + font-style: normal; + font-weight: 500; + line-height: 16px; + + [role='img'] { + width: 32px; + height: 32px; + } + [role='spinner'] { + width: 21.333px; + height: 21.333px; + } + .icon-text > span { + height: 24px; + width: 24px; + } + + .icon-only > span { + height: 32px; + width: 32px; + } + `; +}; diff --git a/blocks/button/index.ts b/blocks/button/index.ts new file mode 100644 index 0000000..c8e82e3 --- /dev/null +++ b/blocks/button/index.ts @@ -0,0 +1,3 @@ +export * from './Button'; +export * from './Button.utils'; +export * from './Button.types'; diff --git a/blocks/dropdown/Dropdown.tsx b/blocks/dropdown/Dropdown.tsx new file mode 100644 index 0000000..39e0bf5 --- /dev/null +++ b/blocks/dropdown/Dropdown.tsx @@ -0,0 +1,53 @@ +import { FC, forwardRef, useState } from 'react'; +import styled from 'styled-components'; +import * as RadixDropdown from '@radix-ui/react-dropdown-menu'; +import { DropdownProps } from './Dropdown.types'; + +const RadixDropdownContent = styled(RadixDropdown.Content)` + /* Extra CSS props */ + ${(props) => props.css || ''} +`; + +const Dropdown: FC = forwardRef( + ({ overlay, trigger = 'click', children, ...props }, ref) => { + const [isOpen, setIsOpen] = useState(false); + + const showDropdown = () => setIsOpen(true); + const hideDropdown = () => setIsOpen(false); + const toggleDropdown = () => setIsOpen(!isOpen); + + return ( + + trigger == 'hover' && showDropdown()} + onMouseLeave={() => trigger == 'hover' && hideDropdown()} + onClick={() => trigger == 'click' && toggleDropdown} + > + {children && typeof children === 'function' ? children({ isOpen }) : children} + + + trigger == 'hover' && showDropdown()} + onMouseLeave={() => trigger == 'hover' && hideDropdown()} + onPointerDownOutside={() => hideDropdown()} + {...props} + > + {overlay} + + + + ); + } +); + +Dropdown.displayName = 'Dropdown'; + +export { Dropdown }; diff --git a/blocks/dropdown/Dropdown.types.ts b/blocks/dropdown/Dropdown.types.ts new file mode 100644 index 0000000..d468bf9 --- /dev/null +++ b/blocks/dropdown/Dropdown.types.ts @@ -0,0 +1,18 @@ +import { ReactElement, ReactNode } from 'react'; +import { FlattenSimpleInterpolation } from 'styled-components'; +import { DropdownMenuContentProps } from '@radix-ui/react-dropdown-menu'; + +export type DropdownTrigger = 'hover' | 'click'; + +export type DropdownComponentProps = { + // This will be content upon clicking on which the dropdown overlay will open + children: ((props: { isOpen: boolean }) => ReactElement) | ReactNode | any; + // on which action to open the dropdown + trigger?: DropdownTrigger; + // This is used for custom css instead of style prop, check Box/Text component + css?: FlattenSimpleInterpolation; + // This will be the contents of the dropdown overlay + overlay?: ReactNode; +}; + +export type DropdownProps = DropdownComponentProps & DropdownMenuContentProps; diff --git a/blocks/dropdown/index.ts b/blocks/dropdown/index.ts new file mode 100644 index 0000000..7b97b2e --- /dev/null +++ b/blocks/dropdown/index.ts @@ -0,0 +1,2 @@ +export * from './Dropdown'; +export * from './Dropdown.types'; diff --git a/blocks/hoverableSVG/HoverableSVG.tsx b/blocks/hoverableSVG/HoverableSVG.tsx new file mode 100644 index 0000000..18f5961 --- /dev/null +++ b/blocks/hoverableSVG/HoverableSVG.tsx @@ -0,0 +1,77 @@ +import { FC } from 'react'; +import styled from 'styled-components'; +import { BlocksSpaceType, TransformedHTMLAttributes } from '../Blocks.types'; +import { getBlocksBorderRadius } from '../Blocks.utils'; +import { IconColors, SurfaceColors, ThemeBorderRadius } from '../theme/Theme.types'; + +export type HoverableSVGProps = { + /* Icon component */ + icon: React.ReactNode; + /* Sets the initial color for SVG */ + defaultColor?: IconColors; + /* Sets button as disabled */ + disabled?: boolean; + /* Sets the hover color for SVG */ + hoverColor?: IconColors; + /* Sets the initial background color for SVG */ + defaultBackground?: SurfaceColors; + /* Sets the initial background color for SVG */ + hoverBackground?: SurfaceColors; + /* Sets the padding for SVG button container */ + padding?: BlocksSpaceType; + /* Sets the margin for SVG button container */ + margin?: BlocksSpaceType; + /* Sets the margin for SVG button container */ + borderRadius?: ThemeBorderRadius; +} & TransformedHTMLAttributes; + +const StyledButton = styled.button>` + display: inline-flex; + align-items: center; + justify-content: center; + padding: var(--${(props) => props.padding || 'spacing-none'}); + margin: var(--${(props) => props.margin || 'spacing-none'}); + border-radius: ${(props) => getBlocksBorderRadius(props.borderRadius)}; + background-color: var(--${({ defaultBackground }) => defaultBackground || 'surface-transparent'}); + color: ${({ defaultColor }) => `var(--${defaultColor})` || 'inherit'}; + border: none; + cursor: ${({ disabled }) => (disabled ? 'not-allowed' : 'pointer')}; + transition: background-color 0.3s, color 0.3s; + height: fit-content; + &:hover { + background-color: var(--${({ hoverBackground }) => hoverBackground || 'surface-transparent'}); + color: ${({ hoverColor }) => `var(--${hoverColor})` || 'inherit'}; + } + &:disabled { + color: var(--icon-state-disabled); + } +`; +const HoverableSVG: FC = ({ + icon, + defaultColor, + disabled, + hoverColor, + defaultBackground, + hoverBackground, + padding, + margin, + borderRadius, + ...props +}) => { + return ( + + {icon} + + ); +}; +export { HoverableSVG }; diff --git a/blocks/hoverableSVG/index.ts b/blocks/hoverableSVG/index.ts new file mode 100644 index 0000000..e2614ec --- /dev/null +++ b/blocks/hoverableSVG/index.ts @@ -0,0 +1 @@ +export * from './HoverableSVG'; diff --git a/blocks/icons/IconWrapper.tsx b/blocks/icons/IconWrapper.tsx new file mode 100644 index 0000000..6857dc7 --- /dev/null +++ b/blocks/icons/IconWrapper.tsx @@ -0,0 +1,61 @@ +import { FC, ReactNode } from 'react'; +import styled, { FlattenSimpleInterpolation } from 'styled-components'; +import { IconProps } from './Icons.types'; + +type IconWrapperProps = Omit & { + /* Name of the component to be used as aria-label for accessibility */ + componentName: string; + /* css prop provided by styled components to provide additional css to icon */ + css?: FlattenSimpleInterpolation; + /* The svg contents of the icon */ + icon: ReactNode; +}; + +type StyledIconWrapperProps = { + /* Color to be applied to the svg */ + color: string; + /* css prop provided by styled components to provide additional css to icon */ + css?: FlattenSimpleInterpolation; + /* Child react nodes rendered by Wrapper */ + children: ReactNode; + /* height and width to b applied to the svg */ + size: string; +}; + +const StyledIconWrapper = styled.span` + /* Common Wrapper CSS */ + color: ${({ color }) => color}; + width: ${({ size }) => size}; + height: ${({ size }) => size}; + display: inline-flex; + font-size: inherit; + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''} +`; + +const IconWrapper: FC = ({ + autoSize, + color: colorProp, + componentName, + icon, + size: sizeProp, + ...restProps +}) => { + const color = colorProp ? `var(--${colorProp})` : 'currentColor'; + const size = sizeProp ? `${sizeProp}px` : autoSize ? '1em' : '16px'; + return ( + + ); +}; + +export { IconWrapper }; diff --git a/blocks/icons/Icons.types.ts b/blocks/icons/Icons.types.ts new file mode 100644 index 0000000..371e88a --- /dev/null +++ b/blocks/icons/Icons.types.ts @@ -0,0 +1,12 @@ +import { IconColors } from 'blocks/theme/Theme.types'; + +export type IconProps = { + /** Set icon fill color from design system */ + color?: IconColors; + /** Set width and height of icon in pixels */ + size?: number; + /** Whether to scale icon according to font-size. Sets width and height to 1em. */ + autoSize?: boolean; + /** Props to pass directly to svg element */ + svgProps?: React.SVGProps; +} & Omit, 'color' | 'size'>; diff --git a/blocks/icons/components/Add.tsx b/blocks/icons/components/Add.tsx new file mode 100644 index 0000000..dcfac97 --- /dev/null +++ b/blocks/icons/components/Add.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Add: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Add; diff --git a/blocks/icons/components/AddEmoji.tsx b/blocks/icons/components/AddEmoji.tsx new file mode 100644 index 0000000..9a5453e --- /dev/null +++ b/blocks/icons/components/AddEmoji.tsx @@ -0,0 +1,62 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const AddEmoji: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default AddEmoji; diff --git a/blocks/icons/components/ArrowUpRight.tsx b/blocks/icons/components/ArrowUpRight.tsx new file mode 100644 index 0000000..fa04fd8 --- /dev/null +++ b/blocks/icons/components/ArrowUpRight.tsx @@ -0,0 +1,51 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const ArrowUpRight: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default ArrowUpRight; diff --git a/blocks/icons/components/Asterisk.tsx b/blocks/icons/components/Asterisk.tsx new file mode 100644 index 0000000..6313a21 --- /dev/null +++ b/blocks/icons/components/Asterisk.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Asterisk: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default Asterisk; diff --git a/blocks/icons/components/Back.tsx b/blocks/icons/components/Back.tsx new file mode 100644 index 0000000..5376673 --- /dev/null +++ b/blocks/icons/components/Back.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Back: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Back; diff --git a/blocks/icons/components/BellRingFilled.tsx b/blocks/icons/components/BellRingFilled.tsx new file mode 100644 index 0000000..78ce277 --- /dev/null +++ b/blocks/icons/components/BellRingFilled.tsx @@ -0,0 +1,50 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const BellRingFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default BellRingFilled; diff --git a/blocks/icons/components/BellSimple.tsx b/blocks/icons/components/BellSimple.tsx new file mode 100644 index 0000000..141433a --- /dev/null +++ b/blocks/icons/components/BellSimple.tsx @@ -0,0 +1,37 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const BellSimple: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default BellSimple; diff --git a/blocks/icons/components/CalendarBlank.tsx b/blocks/icons/components/CalendarBlank.tsx new file mode 100644 index 0000000..6c2405b --- /dev/null +++ b/blocks/icons/components/CalendarBlank.tsx @@ -0,0 +1,54 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CalendarBlank: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default CalendarBlank; diff --git a/blocks/icons/components/CameraFilled.tsx b/blocks/icons/components/CameraFilled.tsx new file mode 100644 index 0000000..6488724 --- /dev/null +++ b/blocks/icons/components/CameraFilled.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CameraFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default CameraFilled; diff --git a/blocks/icons/components/CaretDown.tsx b/blocks/icons/components/CaretDown.tsx new file mode 100644 index 0000000..db53082 --- /dev/null +++ b/blocks/icons/components/CaretDown.tsx @@ -0,0 +1,33 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CaretDown: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default CaretDown; diff --git a/blocks/icons/components/CaretUp.tsx b/blocks/icons/components/CaretUp.tsx new file mode 100644 index 0000000..dcfd556 --- /dev/null +++ b/blocks/icons/components/CaretUp.tsx @@ -0,0 +1,33 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CaretUp: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default CaretUp; diff --git a/blocks/icons/components/Channel.tsx b/blocks/icons/components/Channel.tsx new file mode 100644 index 0000000..2ad5275 --- /dev/null +++ b/blocks/icons/components/Channel.tsx @@ -0,0 +1,39 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Channel: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Channel; diff --git a/blocks/icons/components/ChannelFilled.tsx b/blocks/icons/components/ChannelFilled.tsx new file mode 100644 index 0000000..4bec415 --- /dev/null +++ b/blocks/icons/components/ChannelFilled.tsx @@ -0,0 +1,32 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const ChannelFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default ChannelFilled; diff --git a/blocks/icons/components/ChannelHome.tsx b/blocks/icons/components/ChannelHome.tsx new file mode 100644 index 0000000..e7a3dc5 --- /dev/null +++ b/blocks/icons/components/ChannelHome.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const ChannelHome: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default ChannelHome; diff --git a/blocks/icons/components/ChannelHomeFilled.tsx b/blocks/icons/components/ChannelHomeFilled.tsx new file mode 100644 index 0000000..06af42f --- /dev/null +++ b/blocks/icons/components/ChannelHomeFilled.tsx @@ -0,0 +1,32 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const ChannelHomeFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default ChannelHomeFilled; diff --git a/blocks/icons/components/Chat.tsx b/blocks/icons/components/Chat.tsx new file mode 100644 index 0000000..f6e6c6d --- /dev/null +++ b/blocks/icons/components/Chat.tsx @@ -0,0 +1,31 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Chat: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default Chat; diff --git a/blocks/icons/components/ChatFilled.tsx b/blocks/icons/components/ChatFilled.tsx new file mode 100644 index 0000000..8d32611 --- /dev/null +++ b/blocks/icons/components/ChatFilled.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const ChatFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default ChatFilled; diff --git a/blocks/icons/components/Copy.tsx b/blocks/icons/components/Copy.tsx new file mode 100644 index 0000000..c30b530 --- /dev/null +++ b/blocks/icons/components/Copy.tsx @@ -0,0 +1,52 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Copy: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Copy; diff --git a/blocks/icons/components/Cross.tsx b/blocks/icons/components/Cross.tsx new file mode 100644 index 0000000..0fb903f --- /dev/null +++ b/blocks/icons/components/Cross.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Cross: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Cross; diff --git a/blocks/icons/components/CrossFilled.tsx b/blocks/icons/components/CrossFilled.tsx new file mode 100644 index 0000000..a340636 --- /dev/null +++ b/blocks/icons/components/CrossFilled.tsx @@ -0,0 +1,32 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CrossFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default CrossFilled; diff --git a/blocks/icons/components/Dash.tsx b/blocks/icons/components/Dash.tsx new file mode 100644 index 0000000..9e3102d --- /dev/null +++ b/blocks/icons/components/Dash.tsx @@ -0,0 +1,31 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Dash: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default Dash; diff --git a/blocks/icons/components/Dashboard.tsx b/blocks/icons/components/Dashboard.tsx new file mode 100644 index 0000000..fc44aee --- /dev/null +++ b/blocks/icons/components/Dashboard.tsx @@ -0,0 +1,66 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Dashboard: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default Dashboard; diff --git a/blocks/icons/components/EditProfile.tsx b/blocks/icons/components/EditProfile.tsx new file mode 100644 index 0000000..770c278 --- /dev/null +++ b/blocks/icons/components/EditProfile.tsx @@ -0,0 +1,107 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const EditProfile: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default EditProfile; diff --git a/blocks/icons/components/Ellipse.tsx b/blocks/icons/components/Ellipse.tsx new file mode 100644 index 0000000..9d96c0f --- /dev/null +++ b/blocks/icons/components/Ellipse.tsx @@ -0,0 +1,27 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Ellipse: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default Ellipse; diff --git a/blocks/icons/components/EmptyInbox.tsx b/blocks/icons/components/EmptyInbox.tsx new file mode 100644 index 0000000..71546af --- /dev/null +++ b/blocks/icons/components/EmptyInbox.tsx @@ -0,0 +1,49 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const EmptyInbox: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default EmptyInbox; diff --git a/blocks/icons/components/Envelope.tsx b/blocks/icons/components/Envelope.tsx new file mode 100644 index 0000000..36aa199 --- /dev/null +++ b/blocks/icons/components/Envelope.tsx @@ -0,0 +1,42 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Envelope: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Envelope; diff --git a/blocks/icons/components/ErrorFilled.tsx b/blocks/icons/components/ErrorFilled.tsx new file mode 100644 index 0000000..b292c24 --- /dev/null +++ b/blocks/icons/components/ErrorFilled.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const ErrorFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default ErrorFilled; diff --git a/blocks/icons/components/ExternalLink.tsx b/blocks/icons/components/ExternalLink.tsx new file mode 100644 index 0000000..94d1a94 --- /dev/null +++ b/blocks/icons/components/ExternalLink.tsx @@ -0,0 +1,33 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const ExternalLink: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default ExternalLink; diff --git a/blocks/icons/components/Front.tsx b/blocks/icons/components/Front.tsx new file mode 100644 index 0000000..6ec6de1 --- /dev/null +++ b/blocks/icons/components/Front.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Front: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Front; diff --git a/blocks/icons/components/Gif.tsx b/blocks/icons/components/Gif.tsx new file mode 100644 index 0000000..0ea39c1 --- /dev/null +++ b/blocks/icons/components/Gif.tsx @@ -0,0 +1,47 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Gif: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default Gif; diff --git a/blocks/icons/components/Governance.tsx b/blocks/icons/components/Governance.tsx new file mode 100644 index 0000000..8c24107 --- /dev/null +++ b/blocks/icons/components/Governance.tsx @@ -0,0 +1,82 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Governance: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Governance; diff --git a/blocks/icons/components/GovernanceFilled.tsx b/blocks/icons/components/GovernanceFilled.tsx new file mode 100644 index 0000000..dac8ec0 --- /dev/null +++ b/blocks/icons/components/GovernanceFilled.tsx @@ -0,0 +1,32 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const GovernanceFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default GovernanceFilled; diff --git a/blocks/icons/components/Group.tsx b/blocks/icons/components/Group.tsx new file mode 100644 index 0000000..f208cd8 --- /dev/null +++ b/blocks/icons/components/Group.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Group: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default Group; diff --git a/blocks/icons/components/GroupFilled.tsx b/blocks/icons/components/GroupFilled.tsx new file mode 100644 index 0000000..b3939b8 --- /dev/null +++ b/blocks/icons/components/GroupFilled.tsx @@ -0,0 +1,42 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const GroupFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default GroupFilled; diff --git a/blocks/icons/components/InboxBell.tsx b/blocks/icons/components/InboxBell.tsx new file mode 100644 index 0000000..b9bbc3d --- /dev/null +++ b/blocks/icons/components/InboxBell.tsx @@ -0,0 +1,36 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const InboxBell: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default InboxBell; diff --git a/blocks/icons/components/InboxBellFilled.tsx b/blocks/icons/components/InboxBellFilled.tsx new file mode 100644 index 0000000..a4a75dc --- /dev/null +++ b/blocks/icons/components/InboxBellFilled.tsx @@ -0,0 +1,36 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const InboxBellFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default InboxBellFilled; diff --git a/blocks/icons/components/Info.tsx b/blocks/icons/components/Info.tsx new file mode 100644 index 0000000..c96e9c4 --- /dev/null +++ b/blocks/icons/components/Info.tsx @@ -0,0 +1,37 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Info: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Info; diff --git a/blocks/icons/components/InfoFilled.tsx b/blocks/icons/components/InfoFilled.tsx new file mode 100644 index 0000000..beff241 --- /dev/null +++ b/blocks/icons/components/InfoFilled.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const InfoFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default InfoFilled; diff --git a/blocks/icons/components/KebabMenuHorizontal.tsx b/blocks/icons/components/KebabMenuHorizontal.tsx new file mode 100644 index 0000000..4bebc2a --- /dev/null +++ b/blocks/icons/components/KebabMenuHorizontal.tsx @@ -0,0 +1,50 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const KebabMenuHorizontal: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default KebabMenuHorizontal; diff --git a/blocks/icons/components/KebabMenuVertical.tsx b/blocks/icons/components/KebabMenuVertical.tsx new file mode 100644 index 0000000..9cd56e0 --- /dev/null +++ b/blocks/icons/components/KebabMenuVertical.tsx @@ -0,0 +1,49 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const KebabMenuVertical: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default KebabMenuVertical; diff --git a/blocks/icons/components/LightFilled.tsx b/blocks/icons/components/LightFilled.tsx new file mode 100644 index 0000000..cc2044e --- /dev/null +++ b/blocks/icons/components/LightFilled.tsx @@ -0,0 +1,62 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const LightFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default LightFilled; diff --git a/blocks/icons/components/MaximizeLeft.tsx b/blocks/icons/components/MaximizeLeft.tsx new file mode 100644 index 0000000..c8d80fe --- /dev/null +++ b/blocks/icons/components/MaximizeLeft.tsx @@ -0,0 +1,32 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const MaximizeLeft: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default MaximizeLeft; diff --git a/blocks/icons/components/MaximizeRight.tsx b/blocks/icons/components/MaximizeRight.tsx new file mode 100644 index 0000000..6798d66 --- /dev/null +++ b/blocks/icons/components/MaximizeRight.tsx @@ -0,0 +1,32 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const MaximizeRight: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default MaximizeRight; diff --git a/blocks/icons/components/MegaPhone.tsx b/blocks/icons/components/MegaPhone.tsx new file mode 100644 index 0000000..4b398d1 --- /dev/null +++ b/blocks/icons/components/MegaPhone.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const MegaPhone: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default MegaPhone; diff --git a/blocks/icons/components/Moon.tsx b/blocks/icons/components/Moon.tsx new file mode 100644 index 0000000..41ef132 --- /dev/null +++ b/blocks/icons/components/Moon.tsx @@ -0,0 +1,44 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Moon: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Moon; diff --git a/blocks/icons/components/MoonFilled.tsx b/blocks/icons/components/MoonFilled.tsx new file mode 100644 index 0000000..283d4ea --- /dev/null +++ b/blocks/icons/components/MoonFilled.tsx @@ -0,0 +1,41 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const MoonFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default MoonFilled; diff --git a/blocks/icons/components/NFTGated.tsx b/blocks/icons/components/NFTGated.tsx new file mode 100644 index 0000000..44fb2f5 --- /dev/null +++ b/blocks/icons/components/NFTGated.tsx @@ -0,0 +1,44 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const NFTGated: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default NFTGated; diff --git a/blocks/icons/components/NextIconSlider.tsx b/blocks/icons/components/NextIconSlider.tsx new file mode 100644 index 0000000..73e0dbd --- /dev/null +++ b/blocks/icons/components/NextIconSlider.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const NextIconSlider: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default NextIconSlider; diff --git a/blocks/icons/components/NoRewards.tsx b/blocks/icons/components/NoRewards.tsx new file mode 100644 index 0000000..c11fde9 --- /dev/null +++ b/blocks/icons/components/NoRewards.tsx @@ -0,0 +1,77 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const NoRewards: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default NoRewards; diff --git a/blocks/icons/components/NotificationMobile.tsx b/blocks/icons/components/NotificationMobile.tsx new file mode 100644 index 0000000..b1c0d12 --- /dev/null +++ b/blocks/icons/components/NotificationMobile.tsx @@ -0,0 +1,50 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const NotificationMobile: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default NotificationMobile; diff --git a/blocks/icons/components/OptOut.tsx b/blocks/icons/components/OptOut.tsx new file mode 100644 index 0000000..899e31c --- /dev/null +++ b/blocks/icons/components/OptOut.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const OptOut: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default OptOut; diff --git a/blocks/icons/components/Pin.tsx b/blocks/icons/components/Pin.tsx new file mode 100644 index 0000000..b601a1c --- /dev/null +++ b/blocks/icons/components/Pin.tsx @@ -0,0 +1,33 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Pin: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default Pin; diff --git a/blocks/icons/components/PlusCircle.tsx b/blocks/icons/components/PlusCircle.tsx new file mode 100644 index 0000000..c0e708d --- /dev/null +++ b/blocks/icons/components/PlusCircle.tsx @@ -0,0 +1,47 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const PlusCircle: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + } + {...restProps} + /> + ); +}; + +export default PlusCircle; diff --git a/blocks/icons/components/PlusCircleFilled.tsx b/blocks/icons/components/PlusCircleFilled.tsx new file mode 100644 index 0000000..558921c --- /dev/null +++ b/blocks/icons/components/PlusCircleFilled.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const PlusCircleFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default PlusCircleFilled; diff --git a/blocks/icons/components/PlusSquare.tsx b/blocks/icons/components/PlusSquare.tsx new file mode 100644 index 0000000..b94d0e3 --- /dev/null +++ b/blocks/icons/components/PlusSquare.tsx @@ -0,0 +1,58 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const PlusSquare: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default PlusSquare; diff --git a/blocks/icons/components/PlusSquareFilled.tsx b/blocks/icons/components/PlusSquareFilled.tsx new file mode 100644 index 0000000..1563bf1 --- /dev/null +++ b/blocks/icons/components/PlusSquareFilled.tsx @@ -0,0 +1,59 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const PlusSquareFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default PlusSquareFilled; diff --git a/blocks/icons/components/PrevIconSlider.tsx b/blocks/icons/components/PrevIconSlider.tsx new file mode 100644 index 0000000..22b1e4a --- /dev/null +++ b/blocks/icons/components/PrevIconSlider.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const PrevIconSlider: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default PrevIconSlider; diff --git a/blocks/icons/components/PrivateChat.tsx b/blocks/icons/components/PrivateChat.tsx new file mode 100644 index 0000000..e096747 --- /dev/null +++ b/blocks/icons/components/PrivateChat.tsx @@ -0,0 +1,61 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const PrivateChat: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + } + {...restProps} + /> + ); +}; + +export default PrivateChat; diff --git a/blocks/icons/components/PublicChat.tsx b/blocks/icons/components/PublicChat.tsx new file mode 100644 index 0000000..dbf7859 --- /dev/null +++ b/blocks/icons/components/PublicChat.tsx @@ -0,0 +1,31 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const PublicChat: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default PublicChat; diff --git a/blocks/icons/components/QRCode.tsx b/blocks/icons/components/QRCode.tsx new file mode 100644 index 0000000..7de820f --- /dev/null +++ b/blocks/icons/components/QRCode.tsx @@ -0,0 +1,107 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const QRCode: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default QRCode; diff --git a/blocks/icons/components/ReceiveNotification.tsx b/blocks/icons/components/ReceiveNotification.tsx new file mode 100644 index 0000000..7277fae --- /dev/null +++ b/blocks/icons/components/ReceiveNotification.tsx @@ -0,0 +1,39 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const ReceiveNotification: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default ReceiveNotification; diff --git a/blocks/icons/components/ReceiveNotificationFilled.tsx b/blocks/icons/components/ReceiveNotificationFilled.tsx new file mode 100644 index 0000000..aeaeb21 --- /dev/null +++ b/blocks/icons/components/ReceiveNotificationFilled.tsx @@ -0,0 +1,38 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const ReceiveNotificationFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default ReceiveNotificationFilled; diff --git a/blocks/icons/components/Refresh.tsx b/blocks/icons/components/Refresh.tsx new file mode 100644 index 0000000..3f1c07e --- /dev/null +++ b/blocks/icons/components/Refresh.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Refresh: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Refresh; diff --git a/blocks/icons/components/SealCheck.tsx b/blocks/icons/components/SealCheck.tsx new file mode 100644 index 0000000..301eceb --- /dev/null +++ b/blocks/icons/components/SealCheck.tsx @@ -0,0 +1,37 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const SealCheck: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default SealCheck; diff --git a/blocks/icons/components/SealCheckFilled.tsx b/blocks/icons/components/SealCheckFilled.tsx new file mode 100644 index 0000000..eb05b37 --- /dev/null +++ b/blocks/icons/components/SealCheckFilled.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const SealCheckFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default SealCheckFilled; diff --git a/blocks/icons/components/Search.tsx b/blocks/icons/components/Search.tsx new file mode 100644 index 0000000..5503dc4 --- /dev/null +++ b/blocks/icons/components/Search.tsx @@ -0,0 +1,39 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Search: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Search; diff --git a/blocks/icons/components/SearchFilled.tsx b/blocks/icons/components/SearchFilled.tsx new file mode 100644 index 0000000..85b07be --- /dev/null +++ b/blocks/icons/components/SearchFilled.tsx @@ -0,0 +1,32 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const SearchFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default SearchFilled; diff --git a/blocks/icons/components/SendFilled.tsx b/blocks/icons/components/SendFilled.tsx new file mode 100644 index 0000000..ac89f24 --- /dev/null +++ b/blocks/icons/components/SendFilled.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const SendFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default SendFilled; diff --git a/blocks/icons/components/SendNotification.tsx b/blocks/icons/components/SendNotification.tsx new file mode 100644 index 0000000..3352c25 --- /dev/null +++ b/blocks/icons/components/SendNotification.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const SendNotification: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default SendNotification; diff --git a/blocks/icons/components/SendNotificationFilled.tsx b/blocks/icons/components/SendNotificationFilled.tsx new file mode 100644 index 0000000..b1d89f0 --- /dev/null +++ b/blocks/icons/components/SendNotificationFilled.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const SendNotificationFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default SendNotificationFilled; diff --git a/blocks/icons/components/Settings.tsx b/blocks/icons/components/Settings.tsx new file mode 100644 index 0000000..0cc0b5c --- /dev/null +++ b/blocks/icons/components/Settings.tsx @@ -0,0 +1,38 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Settings: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Settings; diff --git a/blocks/icons/components/Smiley.tsx b/blocks/icons/components/Smiley.tsx new file mode 100644 index 0000000..443e291 --- /dev/null +++ b/blocks/icons/components/Smiley.tsx @@ -0,0 +1,48 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Smiley: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default Smiley; diff --git a/blocks/icons/components/Star.tsx b/blocks/icons/components/Star.tsx new file mode 100644 index 0000000..1d70e00 --- /dev/null +++ b/blocks/icons/components/Star.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Star: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default Star; diff --git a/blocks/icons/components/Swap.tsx b/blocks/icons/components/Swap.tsx new file mode 100644 index 0000000..9b56c6a --- /dev/null +++ b/blocks/icons/components/Swap.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Swap: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Swap; diff --git a/blocks/icons/components/Tick.tsx b/blocks/icons/components/Tick.tsx new file mode 100644 index 0000000..29d114a --- /dev/null +++ b/blocks/icons/components/Tick.tsx @@ -0,0 +1,32 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Tick: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default Tick; diff --git a/blocks/icons/components/TickCircleFilled.tsx b/blocks/icons/components/TickCircleFilled.tsx new file mode 100644 index 0000000..c03372a --- /dev/null +++ b/blocks/icons/components/TickCircleFilled.tsx @@ -0,0 +1,32 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const TickCircleFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default TickCircleFilled; diff --git a/blocks/icons/components/TickDecoratedCircleFilled.tsx b/blocks/icons/components/TickDecoratedCircleFilled.tsx new file mode 100644 index 0000000..c0eaa74 --- /dev/null +++ b/blocks/icons/components/TickDecoratedCircleFilled.tsx @@ -0,0 +1,31 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const TickDecoratedCircleFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default TickDecoratedCircleFilled; diff --git a/blocks/icons/components/UserFilled.tsx b/blocks/icons/components/UserFilled.tsx new file mode 100644 index 0000000..b0c945a --- /dev/null +++ b/blocks/icons/components/UserFilled.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const UserFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default UserFilled; diff --git a/blocks/icons/components/UserSwitch.tsx b/blocks/icons/components/UserSwitch.tsx new file mode 100644 index 0000000..84ae1af --- /dev/null +++ b/blocks/icons/components/UserSwitch.tsx @@ -0,0 +1,79 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const UserSwitch: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default UserSwitch; diff --git a/blocks/icons/components/VideoCamera.tsx b/blocks/icons/components/VideoCamera.tsx new file mode 100644 index 0000000..b88e1de --- /dev/null +++ b/blocks/icons/components/VideoCamera.tsx @@ -0,0 +1,55 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const VideoCamera: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default VideoCamera; diff --git a/blocks/icons/components/VideoCameraFilled.tsx b/blocks/icons/components/VideoCameraFilled.tsx new file mode 100644 index 0000000..f4a981b --- /dev/null +++ b/blocks/icons/components/VideoCameraFilled.tsx @@ -0,0 +1,41 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const VideoCameraFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default VideoCameraFilled; diff --git a/blocks/icons/components/VideoCameraSlash.tsx b/blocks/icons/components/VideoCameraSlash.tsx new file mode 100644 index 0000000..daba825 --- /dev/null +++ b/blocks/icons/components/VideoCameraSlash.tsx @@ -0,0 +1,54 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const VideoCameraSlash: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default VideoCameraSlash; diff --git a/blocks/icons/components/VideoCameraSlashFilled.tsx b/blocks/icons/components/VideoCameraSlashFilled.tsx new file mode 100644 index 0000000..5a98c6e --- /dev/null +++ b/blocks/icons/components/VideoCameraSlashFilled.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const VideoCameraSlashFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default VideoCameraSlashFilled; diff --git a/blocks/icons/components/WarningCircleFilled.tsx b/blocks/icons/components/WarningCircleFilled.tsx new file mode 100644 index 0000000..214d78f --- /dev/null +++ b/blocks/icons/components/WarningCircleFilled.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const WarningCircleFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default WarningCircleFilled; diff --git a/blocks/icons/components/Waveform.tsx b/blocks/icons/components/Waveform.tsx new file mode 100644 index 0000000..6792429 --- /dev/null +++ b/blocks/icons/components/Waveform.tsx @@ -0,0 +1,54 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Waveform: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default Waveform; diff --git a/blocks/icons/components/WaveformFilled.tsx b/blocks/icons/components/WaveformFilled.tsx new file mode 100644 index 0000000..8eea4d4 --- /dev/null +++ b/blocks/icons/components/WaveformFilled.tsx @@ -0,0 +1,54 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const WaveformFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default WaveformFilled; diff --git a/blocks/icons/components/YieldFarming.tsx b/blocks/icons/components/YieldFarming.tsx new file mode 100644 index 0000000..ae107b9 --- /dev/null +++ b/blocks/icons/components/YieldFarming.tsx @@ -0,0 +1,37 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const YieldFarming: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default YieldFarming; diff --git a/blocks/icons/components/YieldFarmingFilled.tsx b/blocks/icons/components/YieldFarmingFilled.tsx new file mode 100644 index 0000000..bad6e32 --- /dev/null +++ b/blocks/icons/components/YieldFarmingFilled.tsx @@ -0,0 +1,43 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const YieldFarmingFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + } + {...restProps} + /> + ); +}; + +export default YieldFarmingFilled; diff --git a/blocks/icons/index.ts b/blocks/icons/index.ts new file mode 100644 index 0000000..e32de6a --- /dev/null +++ b/blocks/icons/index.ts @@ -0,0 +1,152 @@ +export * from './IconWrapper'; +export * from './Icons.types'; + +export { default as Add } from './components/Add'; + +export { default as AddEmoji } from './components/AddEmoji'; + +export { default as ArrowUpRight } from './components/ArrowUpRight'; + +export { default as Asterisk } from './components/Asterisk'; + +export { default as Back } from './components/Back'; + +export { default as BellRingFilled } from './components/BellRingFilled'; +export { default as BellSimple } from './components/BellSimple'; + +export { default as CalendarBlank } from './components/CalendarBlank'; + +export { default as CaretDown } from './components/CaretDown'; +export { default as CaretUp } from './components/CaretUp'; + +export { default as CameraFilled } from './components/CameraFilled'; + +export { default as Channel } from './components/Channel'; +export { default as ChannelFilled } from './components/ChannelFilled'; + +export { default as ChannelHome } from './components/ChannelHome'; +export { default as ChannelHomeFilled } from './components/ChannelHomeFilled'; + +export { default as Chat } from './components/Chat'; +export { default as ChatFilled } from './components/ChatFilled'; + +export { default as Copy } from './components/Copy'; + +export { default as Cross } from './components/Cross'; +export { default as CrossFilled } from './components/CrossFilled'; + +export { default as Dash } from './components/Dash'; + +export { default as Dashboard } from './components/Dashboard'; + +export { default as EditProfile } from './components/EditProfile'; + +export { default as Ellipse } from './components/Ellipse'; + +export { default as Envelope } from './components/Envelope'; + +export { default as ErrorFilled } from './components/ErrorFilled'; + +export { default as ExternalLink } from './components/ExternalLink'; + +export { default as Front } from './components/Front'; + +export { default as Gif } from './components/Gif'; + +export { default as InfoFilled } from './components/InfoFilled'; + +export { default as Governance } from './components/Governance'; +export { default as GovernanceFilled } from './components/GovernanceFilled'; + +export { default as Group } from './components/Group'; +export { default as GroupFilled } from './components/GroupFilled'; + +export { default as InboxBell } from './components/InboxBell'; +export { default as EmptyInbox } from './components/EmptyInbox'; +export { default as InboxBellFilled } from './components/InboxBellFilled'; + +export { default as Info } from './components/Info'; + +export { default as KebabMenuVertical } from './components/KebabMenuVertical'; +export { default as KebabMenuHorizontal } from './components/KebabMenuHorizontal'; + +export { default as LightFilled } from './components/LightFilled'; + +export { default as MaximizeRight } from './components/MaximizeRight'; +export { default as MaximizeLeft } from './components/MaximizeLeft'; + +export { default as MegaPhone } from './components/MegaPhone'; + +export { default as Moon } from './components/Moon'; +export { default as MoonFilled } from './components/MoonFilled'; + +export { default as NFTGated } from './components/NFTGated'; + +export { default as NoRewards } from './components/NoRewards'; + +export { default as NextIconSlider } from './components/NextIconSlider'; + +export { default as NotificationMobile } from './components/NotificationMobile'; + +export { default as OptOut } from './components/OptOut'; + +export { default as PlusCircle } from './components/PlusCircle'; +export { default as PlusCircleFilled } from './components/PlusCircleFilled'; + +export { default as PlusSquare } from './components/PlusSquare'; +export { default as PlusSquareFilled } from './components/PlusSquareFilled'; + +export { default as PrevIconSlider } from './components/PrevIconSlider'; + +export { default as Pin } from './components/Pin'; + +export { default as PublicChat } from './components/PublicChat'; +export { default as PrivateChat } from './components/PrivateChat'; + +export { default as QRCode } from './components/QRCode'; + +export { default as ReceiveNotification } from './components/ReceiveNotification'; +export { default as ReceiveNotificationFilled } from './components/ReceiveNotificationFilled'; + +export { default as Refresh } from './components/Refresh'; + +export { default as SealCheck } from './components/SealCheck'; +export { default as SealCheckFilled } from './components/SealCheckFilled'; + +export { default as Search } from './components/Search'; +export { default as SearchFilled } from './components/SearchFilled'; + +export { default as SendFilled } from './components/SendFilled'; + +export { default as SendNotification } from './components/SendNotification'; +export { default as SendNotificationFilled } from './components/SendNotificationFilled'; + +export { default as Smiley } from './components/Smiley'; + +export { default as Star } from './components/Star'; + +export { default as Settings } from './components/Settings'; + +export { default as Swap } from './components/Swap'; + +export { default as Tick } from './components/Tick'; +export { default as TickCircleFilled } from './components/TickCircleFilled'; +export { default as TickDecoratedCircleFilled } from './components/TickDecoratedCircleFilled'; + +export { default as UserFilled } from './components/UserFilled'; + +export { default as UserSwitch } from './components/UserSwitch'; + +export { default as VideoCamera } from './components/VideoCamera'; +export { default as VideoCameraFilled } from './components/VideoCameraFilled'; + +export { default as VideoCameraSlash } from './components/VideoCameraSlash'; +export { default as VideoCameraslashFilled } from './components/VideoCameraSlashFilled'; + +export { default as WarningCircleFilled } from './components/WarningCircleFilled'; + +export { default as Waveform } from './components/Waveform'; +export { default as WaveformFilled } from './components/WaveformFilled'; + +export { default as YieldFarming } from './components/YieldFarming'; +export { default as YieldFarmingFilled } from './components/YieldFarmingFilled'; diff --git a/blocks/illustrations/IllustrationWrapper.tsx b/blocks/illustrations/IllustrationWrapper.tsx new file mode 100644 index 0000000..a4b7ee4 --- /dev/null +++ b/blocks/illustrations/IllustrationWrapper.tsx @@ -0,0 +1,51 @@ +import { FC, ReactNode } from 'react'; +import styled, { FlattenSimpleInterpolation } from 'styled-components'; +import { IllustrationProps } from './Illustrations.types'; + +type IconWrapperProps = Omit & { + /* Name of the component to be used as aria-label for accessibility */ + componentName: string; + /* css prop provided by styled components to provide additional css to icon */ + css?: FlattenSimpleInterpolation; + /* The svg contents of the icon */ + illustration: ReactNode; +}; + +type StyledIllustrationWrapperProps = { + /* css prop provided by styled components to provide additional css to icon */ + css?: FlattenSimpleInterpolation; + /* Child react nodes rendered by Wrapper */ + children: ReactNode; + /** Set height of icon in pixels */ + height?: number; + /** Set height of icon in pixels */ + width?: number; +}; + +const StyledIllustrationWrapper = styled.span` + /* Common Wrapper CSS */ + width: ${({ width }) => (width ? `${width}px` : 'auto')}; + height: ${({ height }) => (height ? `${height}px` : 'auto')}; + display: inline-flex; + font-size: inherit; + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''} +`; + +const IllustrationWrapper: FC = ({ componentName, illustration, height, width, ...restProps }) => { + return ( + + ); +}; + +export { IllustrationWrapper }; diff --git a/blocks/illustrations/Illustrations.types.ts b/blocks/illustrations/Illustrations.types.ts new file mode 100644 index 0000000..8bff327 --- /dev/null +++ b/blocks/illustrations/Illustrations.types.ts @@ -0,0 +1,8 @@ +export type IllustrationProps = { + /** Set height of icon in pixels */ + height?: number; + /** Set height of icon in pixels */ + width?: number; + /** Props to pass directly to svg element */ + svgProps?: React.SVGProps; +} & Omit, 'color' | 'size'>; diff --git a/blocks/illustrations/components/Arbitrum.tsx b/blocks/illustrations/components/Arbitrum.tsx new file mode 100644 index 0000000..277cd88 --- /dev/null +++ b/blocks/illustrations/components/Arbitrum.tsx @@ -0,0 +1,38 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Arbitrum: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + } + {...restProps} + /> + ); +}; + +export default Arbitrum; diff --git a/blocks/illustrations/components/BNB.tsx b/blocks/illustrations/components/BNB.tsx new file mode 100644 index 0000000..f6ad9b7 --- /dev/null +++ b/blocks/illustrations/components/BNB.tsx @@ -0,0 +1,47 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const BNB: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default BNB; diff --git a/blocks/illustrations/components/Chat.tsx b/blocks/illustrations/components/Chat.tsx new file mode 100644 index 0000000..9b52a41 --- /dev/null +++ b/blocks/illustrations/components/Chat.tsx @@ -0,0 +1,103 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const ChatIllustration: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default ChatIllustration; diff --git a/blocks/illustrations/components/ChatDark.tsx b/blocks/illustrations/components/ChatDark.tsx new file mode 100644 index 0000000..ba450b8 --- /dev/null +++ b/blocks/illustrations/components/ChatDark.tsx @@ -0,0 +1,103 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const ChatDark: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default ChatDark; diff --git a/blocks/illustrations/components/Communication.tsx b/blocks/illustrations/components/Communication.tsx new file mode 100644 index 0000000..303c610 --- /dev/null +++ b/blocks/illustrations/components/Communication.tsx @@ -0,0 +1,95 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Communication: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Communication; diff --git a/blocks/illustrations/components/CommunicationDark.tsx b/blocks/illustrations/components/CommunicationDark.tsx new file mode 100644 index 0000000..8e1f8ed --- /dev/null +++ b/blocks/illustrations/components/CommunicationDark.tsx @@ -0,0 +1,95 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const CommunicationDark: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default CommunicationDark; diff --git a/blocks/illustrations/components/Cyber.tsx b/blocks/illustrations/components/Cyber.tsx new file mode 100644 index 0000000..9001b07 --- /dev/null +++ b/blocks/illustrations/components/Cyber.tsx @@ -0,0 +1,54 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Cyber: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Cyber; diff --git a/blocks/illustrations/components/Discord.tsx b/blocks/illustrations/components/Discord.tsx new file mode 100644 index 0000000..9ebba0e --- /dev/null +++ b/blocks/illustrations/components/Discord.tsx @@ -0,0 +1,34 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Discord: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Discord; diff --git a/blocks/illustrations/components/EarnOnPush.tsx b/blocks/illustrations/components/EarnOnPush.tsx new file mode 100644 index 0000000..1485281 --- /dev/null +++ b/blocks/illustrations/components/EarnOnPush.tsx @@ -0,0 +1,1006 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const EarnOnPush: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default EarnOnPush; diff --git a/blocks/illustrations/components/Ethereum.tsx b/blocks/illustrations/components/Ethereum.tsx new file mode 100644 index 0000000..8a0c294 --- /dev/null +++ b/blocks/illustrations/components/Ethereum.tsx @@ -0,0 +1,58 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Ethereum: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Ethereum; diff --git a/blocks/illustrations/components/Fuse.tsx b/blocks/illustrations/components/Fuse.tsx new file mode 100644 index 0000000..8f4df0f --- /dev/null +++ b/blocks/illustrations/components/Fuse.tsx @@ -0,0 +1,44 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Fuse: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default Fuse; diff --git a/blocks/illustrations/components/Metamask.tsx b/blocks/illustrations/components/Metamask.tsx new file mode 100644 index 0000000..b7c5acb --- /dev/null +++ b/blocks/illustrations/components/Metamask.tsx @@ -0,0 +1,142 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Metamask: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Metamask; diff --git a/blocks/illustrations/components/Notification.tsx b/blocks/illustrations/components/Notification.tsx new file mode 100644 index 0000000..6ebd6e6 --- /dev/null +++ b/blocks/illustrations/components/Notification.tsx @@ -0,0 +1,86 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Notification: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Notification; diff --git a/blocks/illustrations/components/NotificationDark.tsx b/blocks/illustrations/components/NotificationDark.tsx new file mode 100644 index 0000000..bda48dd --- /dev/null +++ b/blocks/illustrations/components/NotificationDark.tsx @@ -0,0 +1,86 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const NotificationDark: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default NotificationDark; diff --git a/blocks/illustrations/components/Optimisim.tsx b/blocks/illustrations/components/Optimisim.tsx new file mode 100644 index 0000000..b785cfd --- /dev/null +++ b/blocks/illustrations/components/Optimisim.tsx @@ -0,0 +1,49 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Optimisim: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Optimisim; diff --git a/blocks/illustrations/components/Points.tsx b/blocks/illustrations/components/Points.tsx new file mode 100644 index 0000000..af87661 --- /dev/null +++ b/blocks/illustrations/components/Points.tsx @@ -0,0 +1,125 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Points: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Points; diff --git a/blocks/illustrations/components/Polygon.tsx b/blocks/illustrations/components/Polygon.tsx new file mode 100644 index 0000000..5bcd93d --- /dev/null +++ b/blocks/illustrations/components/Polygon.tsx @@ -0,0 +1,36 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Polygon: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Polygon; diff --git a/blocks/illustrations/components/PolygonZK.tsx b/blocks/illustrations/components/PolygonZK.tsx new file mode 100644 index 0000000..e966af2 --- /dev/null +++ b/blocks/illustrations/components/PolygonZK.tsx @@ -0,0 +1,61 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const PolygonZK: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default PolygonZK; diff --git a/blocks/illustrations/components/PushAlpha.tsx b/blocks/illustrations/components/PushAlpha.tsx new file mode 100644 index 0000000..1ba77e5 --- /dev/null +++ b/blocks/illustrations/components/PushAlpha.tsx @@ -0,0 +1,52 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const PushAlpha: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default PushAlpha; diff --git a/blocks/illustrations/components/PushBot.tsx b/blocks/illustrations/components/PushBot.tsx new file mode 100644 index 0000000..1a60c2d --- /dev/null +++ b/blocks/illustrations/components/PushBot.tsx @@ -0,0 +1,126 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const PushBot: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default PushBot; diff --git a/blocks/illustrations/components/PushDev.tsx b/blocks/illustrations/components/PushDev.tsx new file mode 100644 index 0000000..be48e8f --- /dev/null +++ b/blocks/illustrations/components/PushDev.tsx @@ -0,0 +1,130 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const PushDev: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default PushDev; diff --git a/blocks/illustrations/components/PushLogo.tsx b/blocks/illustrations/components/PushLogo.tsx new file mode 100644 index 0000000..53ac3f2 --- /dev/null +++ b/blocks/illustrations/components/PushLogo.tsx @@ -0,0 +1,154 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const PushLogo: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default PushLogo; diff --git a/blocks/illustrations/components/Referral.tsx b/blocks/illustrations/components/Referral.tsx new file mode 100644 index 0000000..76d86c8 --- /dev/null +++ b/blocks/illustrations/components/Referral.tsx @@ -0,0 +1,1134 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Referral: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Referral; diff --git a/blocks/illustrations/components/RewardsActivity.tsx b/blocks/illustrations/components/RewardsActivity.tsx new file mode 100644 index 0000000..af1df98 --- /dev/null +++ b/blocks/illustrations/components/RewardsActivity.tsx @@ -0,0 +1,39 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const RewardsActivity: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + } + {...restProps} + /> + ); +}; + +export default RewardsActivity; diff --git a/blocks/illustrations/components/RewardsBell.tsx b/blocks/illustrations/components/RewardsBell.tsx new file mode 100644 index 0000000..51521c3 --- /dev/null +++ b/blocks/illustrations/components/RewardsBell.tsx @@ -0,0 +1,58 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const RewardsBell: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default RewardsBell; diff --git a/blocks/illustrations/components/Twitter.tsx b/blocks/illustrations/components/Twitter.tsx new file mode 100644 index 0000000..b95c224 --- /dev/null +++ b/blocks/illustrations/components/Twitter.tsx @@ -0,0 +1,34 @@ +import { FC } from 'react'; +import { IllustrationWrapper } from '../IllustrationWrapper'; +import { IllustrationProps } from '../Illustrations.types'; + +const Twitter: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Twitter; diff --git a/blocks/illustrations/index.ts b/blocks/illustrations/index.ts new file mode 100644 index 0000000..c5f8cc9 --- /dev/null +++ b/blocks/illustrations/index.ts @@ -0,0 +1,36 @@ +export * from './IllustrationWrapper'; +export * from './Illustrations.types'; + +export { default as ChatIllustration } from './components/Chat'; +export { default as ChatDark } from './components/ChatDark'; + +export { default as Communication } from './components/Communication'; +export { default as CommunicationDark } from './components/CommunicationDark'; + +export { default as Discord } from './components/Discord'; + +export { default as EarnOnPush } from './components/EarnOnPush'; + +export { default as Ethereum } from './components/Ethereum'; + +export { default as PushAlpha } from './components/PushAlpha'; + +export { default as PushBot } from './components/PushBot'; + +export { default as PushDev } from './components/PushDev'; + +export { default as Points } from './components/Points'; + +export { default as Metamask } from './components/Metamask'; + +export { default as Notification } from './components/Notification'; +export { default as NotificationDark } from './components/NotificationDark'; + +export { default as RewardsBell } from './components/RewardsBell'; +export { default as Referral } from './components/Referral'; + +export { default as Twitter } from './components/Twitter'; + +export { default as RewardsActivity } from './components/RewardsActivity'; + +export { default as PushLogo } from './components/PushLogo'; diff --git a/blocks/index.ts b/blocks/index.ts new file mode 100644 index 0000000..2c3677f --- /dev/null +++ b/blocks/index.ts @@ -0,0 +1,28 @@ +export { Alert, type AlertProps } from './alert'; +export { Box, type BoxProps } from './box'; +export { Button, type ButtonProps } from './button'; +export { Dropdown, type DropdownProps } from './dropdown'; +export { HoverableSVG, type HoverableSVGProps } from './hoverableSVG'; +export { Link, type LinkProps } from './link'; +export { Lozenge, type LozengeProps } from './lozenge'; +export { Menu, type MenuProps, MenuItem, type MenuItemComponentProps } from './menu'; +export { Modal, type ModalProps, modal } from './modal'; +export { ProgressBar, type ProgressBarProps } from './progressBar'; +export { Separator, type SeparatorProps } from './separator'; +export { Skeleton, type SkeletonProps } from './skeleton'; +export { Tabs, type TabsProps, type TabItem } from './tabs'; +export { Text, type TextProps } from './text'; +export { Tooltip, type TooltipProps } from './tooltip'; +export { TextArea, type TextAreaProps } from './textarea'; +export { TextInput } from './textInput'; +export { ToggleSwitch } from './toggleSwtich'; +export { Spinner, type SpinnerProps } from './spinner'; + +export * from './Blocks.colors'; +export * from './Blocks.types'; +export * from './Blocks.utils'; + +export * from './icons'; +export * from './illustrations'; + +export * from './theme'; diff --git a/blocks/link/Link.tsx b/blocks/link/Link.tsx new file mode 100644 index 0000000..fe99a8a --- /dev/null +++ b/blocks/link/Link.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { Link as RouterLink, LinkProps as RouterLinkProps } from 'react-router-dom'; +import styled, { FlattenSimpleInterpolation } from 'styled-components'; + +import { TransformedHTMLAttributes } from '../Blocks.types'; +import { Text, TextProps } from '../text'; + +export type LinkProps = RouterLinkProps & { + css?: FlattenSimpleInterpolation; + textProps?: TextProps; + isText?: boolean; +} & TransformedHTMLAttributes; + +const StyledLink = styled(RouterLink)` + /* Link CSS */ + + text-decoration: none; + + &:hover > * { + color: ${({ isText }) => (isText ? 'var(--text-brand-medium)' : '')}; + } + + /* Extra CSS props */ + ${(props) => props.css || ''} +`; + +const Link: FC = ({ textProps, isText = true, ...props }) => { + return ( + + {isText ? {props?.children} : props.children} + + ); +}; + +Link.displayName = 'Link'; + +export { Link }; diff --git a/blocks/link/index.ts b/blocks/link/index.ts new file mode 100644 index 0000000..3db78f5 --- /dev/null +++ b/blocks/link/index.ts @@ -0,0 +1 @@ +export * from './Link'; diff --git a/blocks/lozenge/Lozenge.constants.tsx b/blocks/lozenge/Lozenge.constants.tsx new file mode 100644 index 0000000..5cb4478 --- /dev/null +++ b/blocks/lozenge/Lozenge.constants.tsx @@ -0,0 +1,91 @@ +import { FlattenSimpleInterpolation, css } from 'styled-components'; + +import { textVariants } from '../text'; +import { LozengeSize, LozengeVariant } from './Lozenge.types'; + +export const getLozengeVariantStyles = (variant: LozengeVariant): FlattenSimpleInterpolation => { + if (variant === 'primary') { + return css` + background-color: var(--surface-brand-subtle); + color: var(--text-brand-bold); + .icon { + color: var(--icon-brand-medium); + } + `; + } + + return css``; +}; + +export const getLozengeSizeStyles = ({ + iconOnly, + size, +}: { + iconOnly?: boolean; + size: LozengeSize; +}): FlattenSimpleInterpolation => { + if (size === 'small') { + return css` + /* Lozenge tag container size css */ + max-height: 14px; + min-height: 14px; + + border-radius: var(--radius-xxxs); + ${iconOnly + ? ` + gap: var(--spacing-none); + padding: var(--spacing-xxxs); + ` + : ` + gap: var(--spacing-xxxs); + padding: var(--spacing-xxxs) var(--spacing-xxs); + `} + + /* Lozenge text size css */ + leading-trim: both; + text-edge: cap; + font-size: ${textVariants['os-bold'].fontSize}; + font-style: ${textVariants['os-bold'].fontStyle}; + font-weight: ${textVariants['os-bold'].fontWeight}; + line-height: ${textVariants['os-bold'].lineHeight}; + text-transform: ${textVariants['os-bold'].textTransform}; + + .icon > span { + height: 8px; + width: 8px; + } + `; + } + + return css` + /* Lozenge tag container size css + note: - add medium small and large sizes */ + + var(--spacing-sm); + + ${ + iconOnly + ? ` + border-radius: var(--radius-sm); + gap: var(--spacing-none); + ` + : ` + border-radius: var(--radius-xs); + gap: var(--spacing-xxxs); + ` + } + + /* Lozenge text size css */ + leading-trim: both; + text-edge: cap; + font-size: 18px; + font-style: normal; + font-weight: 500; + line-height: 16px; + + .icon > span { + height: 24px; + width: 24px; + } + `; +}; diff --git a/blocks/lozenge/Lozenge.tsx b/blocks/lozenge/Lozenge.tsx new file mode 100644 index 0000000..0672a58 --- /dev/null +++ b/blocks/lozenge/Lozenge.tsx @@ -0,0 +1,73 @@ +import { ReactNode, forwardRef } from 'react'; + +import styled, { FlattenSimpleInterpolation } from 'styled-components'; + +import { getLozengeSizeStyles, getLozengeVariantStyles } from './Lozenge.constants'; + +import { TransformedHTMLAttributes } from '../Blocks.types'; +import { LozengeSize, LozengeVariant } from './Lozenge.types'; + +export type LozengeProps = { + /* Child react nodes rendered by Box */ + children?: ReactNode; + /* Additional prop from styled components to apply custom css to Lozenge */ + css?: FlattenSimpleInterpolation; + /* Render an icon before lozenge contents */ + icon?: ReactNode; + /* Sets the size of the lozenge */ + size?: LozengeSize; + /* Sets the variant of the lozenge */ + variant?: LozengeVariant; +} & TransformedHTMLAttributes; + +type StyledLozengeProps = LozengeProps & { iconOnly: boolean }; + +const StyledLozenge = styled.div` + /* Common Lozenge CSS */ + + align-items: center; + display: flex; + font-family: var(--font-family); + justify-content: center; + white-space: nowrap; + + /* Common icon css added through CSS class */ + .icon { + display: flex; + align-items: center; + justify-content: center; + } + + /* Lozenge variant CSS styles */ + ${({ variant }) => getLozengeVariantStyles(variant || 'primary')} + + /* Lozenge and font size CSS styles */ + ${({ iconOnly, size }) => getLozengeSizeStyles({ iconOnly, size: size || 'small' })} + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''} +`; + +const Lozenge = forwardRef( + ({ variant = 'primary', size = 'small', icon, children, ...props }, ref) => { + const iconOnly = !children; + + return ( + + {icon && {icon}} + {children} + + ); + } +); + +Lozenge.displayName = 'Lozenge'; + +export { Lozenge }; diff --git a/blocks/lozenge/Lozenge.types.tsx b/blocks/lozenge/Lozenge.types.tsx new file mode 100644 index 0000000..83ef5aa --- /dev/null +++ b/blocks/lozenge/Lozenge.types.tsx @@ -0,0 +1,5 @@ +export type LozengeVariant = 'primary'; + +export type LozengeSize = 'small'; + +export type LozengeVariantStyles = Record; diff --git a/blocks/lozenge/index.tsx b/blocks/lozenge/index.tsx new file mode 100644 index 0000000..6d3411b --- /dev/null +++ b/blocks/lozenge/index.tsx @@ -0,0 +1,3 @@ +export * from './Lozenge'; +export * from './Lozenge.constants'; +export * from './Lozenge.types'; diff --git a/blocks/menu/Menu.constants.ts b/blocks/menu/Menu.constants.ts new file mode 100644 index 0000000..cc560bc --- /dev/null +++ b/blocks/menu/Menu.constants.ts @@ -0,0 +1,10 @@ +import { MenuProps } from './Menu.types'; + +export const menuCSSPropsKeys: (keyof MenuProps)[] = [ + 'height', + 'maxHeight', + 'minHeight', + 'maxWidth', + 'minWidth', + 'width', +]; diff --git a/blocks/menu/Menu.tsx b/blocks/menu/Menu.tsx new file mode 100644 index 0000000..e338340 --- /dev/null +++ b/blocks/menu/Menu.tsx @@ -0,0 +1,36 @@ +import { FC } from 'react'; +import styled from 'styled-components'; + +import type { MenuProps } from './Menu.types'; +import { menuCSSPropsKeys } from './Menu.constants'; + +const StyledMenu = styled.div.withConfig({ + shouldForwardProp: (prop, defaultValidatorFn) => + !menuCSSPropsKeys.includes(prop as keyof MenuProps) && defaultValidatorFn(prop), +})` + display: flex; + flex-direction: column; + background-color: var(--surface-primary); + border: var(--border-sm) solid var(--stroke-secondary); + border-radius: var(--radius-xs); + padding: var(--spacing-xxs); + margin: var(--spacing-none); + gap: var(--spacing-xs); + + /* Menu non-responsive styles */ + width: ${(props) => props.width}; + min-width: ${(props) => props.minWidth || '145px'}; + max-width: ${(props) => props.maxWidth}; + height: ${(props) => props.height}; + min-height: ${(props) => props.minHeight}; + max-height: ${(props) => props.maxHeight}; + + /* Extra CSS props */ + ${(props) => props.css || ''} +`; + +const Menu: FC = ({ children, ...props }) => {children}; + +Menu.displayName = 'Menu'; + +export { Menu }; diff --git a/blocks/menu/Menu.types.ts b/blocks/menu/Menu.types.ts new file mode 100644 index 0000000..2654e26 --- /dev/null +++ b/blocks/menu/Menu.types.ts @@ -0,0 +1,43 @@ +import { ReactNode } from 'react'; +import { FlattenSimpleInterpolation } from 'styled-components'; + +export type MenuNonResponsiveProps = { + /* Sets height css property */ + height?: string; + /* Sets max-height css property */ + maxHeight?: string; + /* Sets min-height css property */ + minHeight?: string; + /* Sets max-width css property */ + maxWidth?: string; + /* Sets min-width css property */ + minWidth?: string; + /* Sets width css property */ + width?: string; +}; + +export type MenuComponentProps = { + /* Additional prop from styled components to apply custom css to Menu */ + css?: FlattenSimpleInterpolation; + /* Child react nodes rendered by Menu */ + children: ReactNode; +}; + +export type MenuItemComponentProps = { + /* icon element */ + icon?: ReactNode; + /* function attached to the menu item */ + onClick?: () => void; + /* menu item text */ + label?: string; + /* link option incase you need to redirect or open a link */ + destination?: string; + // add the option to open in a new tab + newTab?: boolean; + /* disabled option on the item*/ + disabled?: boolean; + /* Additional prop from styled components to apply custom css to Menu */ + css?: FlattenSimpleInterpolation; +}; + +export type MenuProps = MenuNonResponsiveProps & MenuComponentProps; diff --git a/blocks/menu/MenuItem.tsx b/blocks/menu/MenuItem.tsx new file mode 100644 index 0000000..4d2d329 --- /dev/null +++ b/blocks/menu/MenuItem.tsx @@ -0,0 +1,77 @@ +import { FC } from 'react'; +import styled from 'styled-components'; + +import { MenuItemComponentProps } from './Menu.types'; +import * as RadixDropdown from '@radix-ui/react-dropdown-menu'; +import { Link } from '../link'; +import { textVariants } from '../text'; + +const StyledMenuItem = styled(RadixDropdown.Item)` + // Menu default styles + padding: var(--spacing-none) var(--spacing-xxxs); + display: flex; + flex-direction: row; + flex: 1; + align-items: center; + gap: var(--spacing-xxxs); + border-radius: var(--radius-xxs); + + [role='img'] { + width: 24px; + height: 24px; + } + + &:hover { + background-color: var(--surface-secondary); + outline: none !important; + } + + cursor: pointer; + min-height: 32px; + + /* Extra CSS props */ + ${(props) => props.css || ''}; +`; + +const StyledLabel = styled.span` + color: var(--components-dropdown-text-default); + text-align: center; + + font-family: var(--font-family); + font-size: ${textVariants['bs-regular'].fontSize}; + font-style: ${textVariants['bs-regular'].fontStyle}; + font-weight: ${textVariants['bs-regular'].fontWeight}; + line-height: ${textVariants['bs-regular'].lineHeight}; +`; + +const MenuItem: FC = ({ icon, label, onClick, destination, newTab, disabled, ...props }) => { + const menuContent = ( + + {icon} + {label} + + ); + + return ( +
+ {destination ? ( + + {menuContent} + + ) : ( + menuContent + )} +
+ ); +}; + +MenuItem.displayName = 'MenuItem'; + +export { MenuItem }; diff --git a/blocks/menu/index.ts b/blocks/menu/index.ts new file mode 100644 index 0000000..6cb2776 --- /dev/null +++ b/blocks/menu/index.ts @@ -0,0 +1,4 @@ +export * from './Menu'; +export * from './MenuItem'; +export * from './Menu.types'; +export * from './Menu.constants'; diff --git a/blocks/modal/AlertModal.tsx b/blocks/modal/AlertModal.tsx new file mode 100644 index 0000000..b71465f --- /dev/null +++ b/blocks/modal/AlertModal.tsx @@ -0,0 +1,108 @@ +import { FC } from 'react'; +import ReactDOM from 'react-dom/client'; +import styled from 'styled-components'; +import { getTextVariantStyles } from '../Blocks.utils'; +import { ThemeColors } from '../theme/Theme.types'; +import { Modal, ModalProps } from './Modal'; +import { AlertModalTypes, ModalSize, ShowAlertModalConfig } from './Modal.types'; +import { alertModalIcon } from './Modal.constants'; + +export type AlertModalProps = { + description: string; + title: string; + type: AlertModalTypes; +} & Omit; + +const Container = styled.div<{ iconColor: ThemeColors; size: ModalSize }>` + display: flex; + padding: var(--spacing-none); + align-items: flex-start; + gap: var(--spacing-xxxs); + margin-top: ${({ size }) => (size === 'small' ? '-24px' : '-28px')}; + + [role='img'] { + color: var(--${({ iconColor }) => iconColor}); + } +`; + +const TextContainer = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--spacing-xxxs); + flex: 1 0 0; +`; + +const Title = styled.p<{ size: ModalSize }>` + ${({ size }) => { + const variant = size === 'small' ? 'h5-semibold' : size === 'medium' ? 'h4-semibold' : 'h3-semibold'; + return getTextVariantStyles(variant, 'components-modal-text-default'); + }} +`; + +const Description = styled.div<{ size: ModalSize }>` + ${({ size }) => { + const variant = size === 'small' ? 'bes-regular' : size === 'medium' ? 'bs-regular' : 'bm-regular'; + return getTextVariantStyles(variant, 'components-modal-text-secondary'); + }} +`; + +const AlertModal: FC = ({ description, title, type, size = 'small', ...restProps }) => { + const Icon = alertModalIcon[type].icon; + return ( + + + + + {title} + {description} + + + + ); +}; + +const renderModal = (props: AlertModalProps) => { + const div = document.createElement('div'); + document.body.appendChild(div); + + const root = ReactDOM.createRoot(div); + + const handleClose = () => { + root.unmount(); + document.body.removeChild(div); + if (props.onClose) props.onClose(); + }; + + root.render( + + ); +}; + +const showModal = (type: AlertModalTypes, config: ShowAlertModalConfig) => { + renderModal({ + ...config, + isOpen: true, + type, + onClose: () => {}, + }); +}; + +const modal = { + info: (config: ShowAlertModalConfig) => showModal('info', config), + success: (config: ShowAlertModalConfig) => showModal('success', config), + error: (config: ShowAlertModalConfig) => showModal('error', config), + warning: (config: ShowAlertModalConfig) => showModal('warning', config), +}; + +export { modal }; diff --git a/blocks/modal/Modal.constants.ts b/blocks/modal/Modal.constants.ts new file mode 100644 index 0000000..6f4c942 --- /dev/null +++ b/blocks/modal/Modal.constants.ts @@ -0,0 +1,23 @@ +import { FC } from 'react'; +import { IconProps, InfoFilled, TickCircleFilled, WarningCircleFilled } from '../icons'; +import { AlertModalTypes } from './Modal.types'; +import { ThemeColors } from 'blocks/theme/Theme.types'; + +export const alertModalIcon: Record; color: ThemeColors }> = { + error: { + icon: InfoFilled, + color: 'components-modal-icon-error', + }, + info: { + icon: InfoFilled, + color: 'components-modal-icon-info', + }, + success: { + icon: TickCircleFilled, + color: 'components-modal-icon-success', + }, + warning: { + icon: WarningCircleFilled, + color: 'components-modal-icon-warning', + }, +}; diff --git a/blocks/modal/Modal.tsx b/blocks/modal/Modal.tsx new file mode 100644 index 0000000..339ea89 --- /dev/null +++ b/blocks/modal/Modal.tsx @@ -0,0 +1,159 @@ +import { FC, ReactNode } from 'react'; +import * as Dialog from '@radix-ui/react-dialog'; +import styled from 'styled-components'; +import { Button, ButtonProps } from '../button'; +import { Back, Cross } from '../icons'; +import { ModalSize } from './Modal.types'; + +type ButtonAlignment = 'end' | 'center'; + +export type ModalProps = { + acceptButtonProps?: ButtonProps | null; + buttonAlignment?: ButtonAlignment; + cancelButtonProps?: ButtonProps | null; + children: ReactNode; + closeOnOverlayClick?: boolean; + isOpen: boolean; + onBack?: () => void; + onClose: () => void; + size?: ModalSize; +}; + +const Overlay = styled(Dialog.Overlay)` + background: var(--surface-glass-bold); + backdrop-filter: blur(calc(var(--blur-lg) / 2)); + position: fixed; + inset: 0; + z-index: 1000; +`; + +const ContentContainer = styled(Dialog.Content)<{ size: ModalSize }>` + display: flex; + border-radius: var(--radius-sm); + border: var(--border-sm) solid var(--stroke-secondary); + background: var(--components-modal-background-default); + padding: var(--spacing-${({ size }) => (size === 'small' ? 'xs' : 'sm')}); + flex-direction: column; + align-items: flex-start; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + min-width: 300px; + width: ${({ size }) => (size === 'small' ? '360px' : size === 'medium' ? '500px' : '700px')}; + gap: var(--spacing-sm); + z-index: 1100; +`; + +const ContentChildren = styled.div<{ size: ModalSize }>` + display: flex; + flex-direction: column; + align-items: flex-start; + flex: 1 0 0; + width: 100%; + padding-top: var(--spacing-${({ size }) => (size === 'small' ? 'xxs' : 'xs')}); +`; + +const HeaderContainer = styled.div` + position: relative; + width: 100%; +`; + +const BackButton = styled.div` + cursor: pointer; + color: var(--components-modal-icon-default); + padding: var(--spacing-none); + position: absolute; + left: 0; + top: 0; +`; + +const CloseButton = styled.div` + background-color: var(--surface-transparent); + cursor: pointer; + color: var(--components-modal-icon-default); + padding: var(--spacing-none); + position: absolute; + right: 0; + top: 0; +`; + +const ButtonsContainer = styled.div<{ buttonAlignment: ButtonAlignment }>` + display: flex; + padding: var(--spacing-xxs); + justify-content: center; + align-items: center; + gap: var(--spacing-xs); + align-self: ${({ buttonAlignment }) => (buttonAlignment === 'end' ? 'flex-end' : 'center')}; +`; + +const Modal: FC = ({ + acceptButtonProps = { children: 'Accept' }, + closeOnOverlayClick = false, + buttonAlignment = 'center', + cancelButtonProps = { children: 'Cancel', onClick: () => onClose() }, + children, + isOpen, + onBack, + onClose, + size = 'medium', +}) => { + const handleOverlayClick = () => { + if (closeOnOverlayClick) { + onClose(); + } + }; + + const iconSize = size === 'small' ? 16 : 24; + return ( + + + + e.preventDefault()} + > + + {onBack && ( + + + + )} + + + + + {children} + + {cancelButtonProps && ( + + )} + {acceptButtonProps && ( + + )} + + + + + ); +}; + +export { Modal }; diff --git a/blocks/modal/Modal.types.ts b/blocks/modal/Modal.types.ts new file mode 100644 index 0000000..a37b860 --- /dev/null +++ b/blocks/modal/Modal.types.ts @@ -0,0 +1,7 @@ +import { AlertModalProps } from './AlertModal'; + +export type AlertModalTypes = 'error' | 'info' | 'success' | 'warning'; + +export type ShowAlertModalConfig = Omit; + +export type ModalSize = 'small' | 'medium' | 'large'; diff --git a/blocks/modal/index.ts b/blocks/modal/index.ts new file mode 100644 index 0000000..403c495 --- /dev/null +++ b/blocks/modal/index.ts @@ -0,0 +1,2 @@ +export * from './Modal'; +export * from './AlertModal'; diff --git a/blocks/progressBar/ProgressBar.tsx b/blocks/progressBar/ProgressBar.tsx new file mode 100644 index 0000000..e83c8c9 --- /dev/null +++ b/blocks/progressBar/ProgressBar.tsx @@ -0,0 +1,41 @@ +import type { FC } from 'react'; +import styled, { FlattenSimpleInterpolation } from 'styled-components'; + +import type { ProgressBarProps } from './ProgressBar.types'; +import { getProgressWidthPercentage } from './ProgressBar.utils'; + +const StyledProgressBarContainer = styled.div<{ css?: FlattenSimpleInterpolation }>` + /* Default CSS */ + background-color: var(--components-progress-bar-background-default); + width: 100%; + height: 4px; + border-radius: var(--radius-xxs, 8px); + + /* Extra CSS prop */ + ${({ css }) => css || ''} +`; + +const StyledProgressBar = styled.div<{ width: string }>` + /* Default CSS */ + border-radius: var(--radius-xxs, 8px); + background-color: var(--components-progress-bar-background-progress); + height: 100%; + width: ${({ width }) => width}; + transition: width 0.3s ease; +`; + +const ProgressBar: FC = ({ progress, max = 100, ...rest }) => ( + + + +); + +ProgressBar.displayName = 'ProgressBar'; + +export { ProgressBar }; diff --git a/blocks/progressBar/ProgressBar.types.ts b/blocks/progressBar/ProgressBar.types.ts new file mode 100644 index 0000000..5e6a3a8 --- /dev/null +++ b/blocks/progressBar/ProgressBar.types.ts @@ -0,0 +1,11 @@ +import { TransformedHTMLAttributes } from 'blocks/Blocks.types'; +import { FlattenSimpleInterpolation } from 'styled-components'; + +export type ProgressBarProps = { + /* Additional prop from styled components to apply custom css to ProgressBar */ + css?: FlattenSimpleInterpolation; + /* Progress value */ + progress: number; + /* Max value */ + max?: number; +} & TransformedHTMLAttributes; diff --git a/blocks/progressBar/ProgressBar.utils.ts b/blocks/progressBar/ProgressBar.utils.ts new file mode 100644 index 0000000..cfa6875 --- /dev/null +++ b/blocks/progressBar/ProgressBar.utils.ts @@ -0,0 +1,4 @@ +export const getProgressWidthPercentage = (progress: number, total = 100) => { + const percentage = (progress / total) * 100; + return Math.min(Math.max(percentage, 0), 100); +}; diff --git a/blocks/progressBar/index.ts b/blocks/progressBar/index.ts new file mode 100644 index 0000000..8b5ee63 --- /dev/null +++ b/blocks/progressBar/index.ts @@ -0,0 +1,3 @@ +export * from './ProgressBar'; +export * from './ProgressBar.utils'; +export * from './ProgressBar.types'; diff --git a/blocks/separator/Separator.constants.ts b/blocks/separator/Separator.constants.ts new file mode 100644 index 0000000..ada8e13 --- /dev/null +++ b/blocks/separator/Separator.constants.ts @@ -0,0 +1,9 @@ +import { ModeProp } from '../Blocks.types'; +import { SeparatorProps } from './Separator.types'; + +export const separatorRestrictedPropsKeys: (keyof SeparatorProps | keyof ModeProp)[] = [ + 'height', + 'margin', + 'width', + 'orientation', +]; diff --git a/blocks/separator/Separator.tsx b/blocks/separator/Separator.tsx new file mode 100644 index 0000000..6346ccb --- /dev/null +++ b/blocks/separator/Separator.tsx @@ -0,0 +1,36 @@ +import { FC } from 'react'; +import styled from 'styled-components'; + +import { SeparatorProps } from './Separator.types'; +import { getSeparatorResponsiveCSS } from './Separator.utils'; +import { separatorRestrictedPropsKeys } from './Separator.constants'; + +const StyledSeparator = styled.div.withConfig({ + shouldForwardProp: (prop, defaultValidatorFn) => + !separatorRestrictedPropsKeys.includes(prop as keyof SeparatorProps) && defaultValidatorFn(prop), +})` + /* Initial values */ + width: ${({ width, orientation }) => width || (orientation === 'horizontal' ? '100%' : '1px')}; + height: ${({ height, orientation }) => height || (orientation === 'horizontal' ? '1px' : '100%')}; + + /* Responsive props */ + ${(props) => getSeparatorResponsiveCSS(props)} + + /* Non-responsive props */ + background-color: var(--surface-tertiary); + + /* Extra CSS prop */ + ${({ css }) => css || ''} +`; + +const Separator: FC = ({ orientation = 'horizontal', ...rest }) => ( + +); + +Separator.displayName = 'Separator'; + +export { Separator }; diff --git a/blocks/separator/Separator.types.ts b/blocks/separator/Separator.types.ts new file mode 100644 index 0000000..bdb498c --- /dev/null +++ b/blocks/separator/Separator.types.ts @@ -0,0 +1,31 @@ +import { TransformedHTMLAttributes, ResponsiveProp, BlocksSpaceType, ValueOf } from '../Blocks.types'; +import { FlattenSimpleInterpolation } from 'styled-components'; + +export type SeparatorResponsiveProps = { + /* Sets height css property */ + height?: ResponsiveProp; + /* Sets margin css property */ + margin?: ResponsiveProp; + /* Sets width css property */ + width?: ResponsiveProp; +}; + +export type SeparatorComponentProps = { + /* Additional prop from styled components to apply custom css to Separator */ + css?: FlattenSimpleInterpolation; + /* Orientation of the separator */ + orientation?: 'horizontal' | 'vertical'; +}; + +export type SeparatorProps = SeparatorResponsiveProps & + SeparatorComponentProps & + TransformedHTMLAttributes; + +export type SeparatorResponsiveCSSProperties = 'height' | 'margin' | 'width'; + +export type SeparatorResponsivePropValues = ValueOf; + +export type SeparatorResponsiveCSSPropertiesData = { + propName: SeparatorResponsiveCSSProperties; + prop: SeparatorResponsivePropValues; +}; diff --git a/blocks/separator/Separator.utils.ts b/blocks/separator/Separator.utils.ts new file mode 100644 index 0000000..b3d724b --- /dev/null +++ b/blocks/separator/Separator.utils.ts @@ -0,0 +1,15 @@ +import { getResponsiveCSS } from '../Blocks.utils'; +import { SeparatorResponsiveCSSPropertiesData, SeparatorResponsiveProps } from './Separator.types'; + +const getSeparatorResponsiveCSSProperties = ( + props: SeparatorResponsiveProps +): SeparatorResponsiveCSSPropertiesData[] => [ + { propName: 'height', prop: props.height }, + { propName: 'margin', prop: props.margin }, + { propName: 'width', prop: props.width }, +]; + +export const getSeparatorResponsiveCSS = (props: SeparatorResponsiveProps) => { + const data = getSeparatorResponsiveCSSProperties(props); + return getResponsiveCSS(data); +}; diff --git a/blocks/separator/index.ts b/blocks/separator/index.ts new file mode 100644 index 0000000..8be5fe3 --- /dev/null +++ b/blocks/separator/index.ts @@ -0,0 +1,4 @@ +export * from './Separator'; +export * from './Separator.constants'; +export * from './Separator.types'; +export * from './Separator.utils'; diff --git a/blocks/skeleton/Skeleton.constants.ts b/blocks/skeleton/Skeleton.constants.ts new file mode 100644 index 0000000..6039f66 --- /dev/null +++ b/blocks/skeleton/Skeleton.constants.ts @@ -0,0 +1,4 @@ +import { ModeProp } from '../Blocks.types'; +import type { SkeletonProps } from './Skeleton.types'; + +export const skeletonCSSPropsKeys: (keyof SkeletonProps | keyof ModeProp)[] = ['height', 'width']; diff --git a/blocks/skeleton/Skeleton.tsx b/blocks/skeleton/Skeleton.tsx new file mode 100644 index 0000000..a22928b --- /dev/null +++ b/blocks/skeleton/Skeleton.tsx @@ -0,0 +1,50 @@ +import { type FC } from 'react'; +import styled from 'styled-components'; + +import { SkeletonProps } from './Skeleton.types'; +import { getSkeletonPulseAnimation, getSkeletonResponsiveCSS } from './Skeleton.utils'; +import { skeletonCSSPropsKeys } from './Skeleton.constants'; + +const StyledSkeleton = styled.div.withConfig({ + shouldForwardProp: (prop, defaultValidatorFn) => + !skeletonCSSPropsKeys.includes(prop as keyof SkeletonProps) && defaultValidatorFn(prop), +})` + /* Responsive props */ + ${(props) => getSkeletonResponsiveCSS(props)} + + /* Extra CSS prop */ + ${(props) => props.css || ''} + + /* Animation props */ + animation: ${getSkeletonPulseAnimation( + 'var(--components-skeleton-loader-gradient-light)', + 'var(--components-skeleton-loader-gradient-dark)' + )} + 1s infinite alternate-reverse; + + /* Hide children */ + & > * { + visibility: hidden !important; + } +`; + +const Skeleton: FC = ({ borderRadius = 'radius-xxs', children, isLoading, ...rest }) => { + if (!isLoading) return children; + + return ( + + ); +}; + +Skeleton.displayName = 'Skeleton'; + +export { Skeleton }; diff --git a/blocks/skeleton/Skeleton.types.ts b/blocks/skeleton/Skeleton.types.ts new file mode 100644 index 0000000..a8aa57b --- /dev/null +++ b/blocks/skeleton/Skeleton.types.ts @@ -0,0 +1,43 @@ +import { ReactNode } from 'react'; + +import type { + TransformedHTMLAttributes, + BlocksRadiusType, + ResponsiveProp, + BlocksSpaceType, + ValueOf, +} from '../Blocks.types'; +import type { FlattenSimpleInterpolation } from 'styled-components'; + +export type SkeletonResponsiveProps = { + /* Sets height css property */ + height?: ResponsiveProp; + /* Sets margin css property */ + margin?: ResponsiveProp; + /* Sets width css property */ + width?: ResponsiveProp; + /* Sets border radius css property */ + borderRadius?: ResponsiveProp; +}; + +export type SkeletonProps = SkeletonResponsiveProps & + SkeletonComponentProps & + TransformedHTMLAttributes; + +export type SkeletonComponentProps = { + /* Sets loading state of Skeleton */ + isLoading?: boolean; + /* Additional prop from styled components to apply custom css to Skeleton */ + css?: FlattenSimpleInterpolation; + /* Child react nodes rendered by Skeleton */ + children?: ReactNode; +}; + +export type SkeletonResponsiveCSSProperties = 'height' | 'margin' | 'width' | 'border-radius'; + +export type SkeletonResponsivePropValues = ValueOf; + +export type SkeletonResponsiveCSSPropertiesData = { + propName: SkeletonResponsiveCSSProperties; + prop: SkeletonResponsivePropValues; +}; diff --git a/blocks/skeleton/Skeleton.utils.ts b/blocks/skeleton/Skeleton.utils.ts new file mode 100644 index 0000000..af5ca44 --- /dev/null +++ b/blocks/skeleton/Skeleton.utils.ts @@ -0,0 +1,28 @@ +import { CSSProperties } from 'react'; +import { keyframes } from 'styled-components'; +import { getResponsiveCSS } from '../Blocks.utils'; +import type { SkeletonResponsiveProps, SkeletonResponsiveCSSPropertiesData } from './Skeleton.types'; + +const getSkeletonResponsiveCSSProperties = (props: SkeletonResponsiveProps): SkeletonResponsiveCSSPropertiesData[] => [ + { propName: 'height', prop: props.height }, + { propName: 'margin', prop: props.margin }, + { propName: 'width', prop: props.width }, + { propName: 'border-radius', prop: props.borderRadius }, +]; + +export const getSkeletonResponsiveCSS = (props: SkeletonResponsiveProps) => { + const data = getSkeletonResponsiveCSSProperties(props); + return getResponsiveCSS(data); +}; + +export const getSkeletonPulseAnimation = ( + startColor: CSSProperties['color'], + endColor: CSSProperties['color'] +) => keyframes` + 0% { + background-color: ${startColor}; + } + 100% { + background-color: ${endColor} + } +`; diff --git a/blocks/skeleton/index.ts b/blocks/skeleton/index.ts new file mode 100644 index 0000000..b331e7d --- /dev/null +++ b/blocks/skeleton/index.ts @@ -0,0 +1,3 @@ +export * from './Skeleton'; +export * from './Skeleton.types'; +export * from './Skeleton.utils'; diff --git a/blocks/spinner/Spinner.tsx b/blocks/spinner/Spinner.tsx new file mode 100644 index 0000000..9d93ec3 --- /dev/null +++ b/blocks/spinner/Spinner.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import styled, { FlattenSimpleInterpolation, keyframes } from 'styled-components'; +import { SpinnerSize, SpinnerVariant } from './Spinner.types'; +import { getSpinnerSize } from './Spinner.utils'; +import { Ellipse } from '../icons'; + +export type SpinnerProps = { + /* Additional prop from styled components to apply custom css to Spinner */ + css?: FlattenSimpleInterpolation; + /* Sizes for the Spinner */ + size?: SpinnerSize; + /* Variants for the Spinner */ + variant?: SpinnerVariant; +}; + +const spin = keyframes` + from { + transform:rotate(0deg); + } + to { + transform:rotate(360deg); + } +`; + +const Container = styled.div<{ css?: FlattenSimpleInterpolation; size: SpinnerSize }>` + display: flex; + align-items: center; + justify-content: center; + animation-name: ${spin}; + animation-duration: 1s; + animation-iteration-count: infinite; + animation-timing-function: linear; + ${({ size }) => ` + width: ${getSpinnerSize(size)}px; + height: ${getSpinnerSize(size)}px; + `} + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''}; +`; + +const Spinner: React.FC = ({ size = 'small', css }) => { + return ( + + + + ); +}; + +Spinner.displayName = 'Spinner'; + +export { Spinner }; diff --git a/blocks/spinner/Spinner.types.ts b/blocks/spinner/Spinner.types.ts new file mode 100644 index 0000000..a2a7433 --- /dev/null +++ b/blocks/spinner/Spinner.types.ts @@ -0,0 +1,2 @@ +export type SpinnerSize = 'small' | 'medium' | 'large' | 'extraLarge'; +export type SpinnerVariant = 'default' | 'secondary'; diff --git a/blocks/spinner/Spinner.utils.ts b/blocks/spinner/Spinner.utils.ts new file mode 100644 index 0000000..ebac408 --- /dev/null +++ b/blocks/spinner/Spinner.utils.ts @@ -0,0 +1,28 @@ +import { SpinnerSize, SpinnerVariant } from './Spinner.types'; + +export const getSpinnerSize = (size: SpinnerSize) => { + switch (size) { + case 'small': + return 16; + case 'medium': + return 24; + case 'large': + return 32; + default: + return 48; + } +}; +export const getSpinnerStrokeWidth = (size: SpinnerSize) => { + switch (size) { + case 'small': + return 'border-sm'; + case 'medium': + return 'border-xmd'; + case 'large': + return 'border-md'; + case 'extraLarge': + return 'border-lg'; + default: + return 'border-xs'; + } +}; diff --git a/blocks/spinner/index.ts b/blocks/spinner/index.ts new file mode 100644 index 0000000..b3294f3 --- /dev/null +++ b/blocks/spinner/index.ts @@ -0,0 +1 @@ +export { Spinner, type SpinnerProps } from './Spinner'; diff --git a/blocks/tabs/Tabs.styled.ts b/blocks/tabs/Tabs.styled.ts new file mode 100644 index 0000000..0856119 --- /dev/null +++ b/blocks/tabs/Tabs.styled.ts @@ -0,0 +1,127 @@ +import { Tabs as ReachTabs, TabList, Tab } from '@reach/tabs'; +import { textVariants } from '../text'; +import styled from 'styled-components'; + +export const StyledFillTabs = styled(ReachTabs)` + display: flex; + flex-direction: column; + gap: var(--spacing-sm); +`; + +export const StyledFillTabList = styled(TabList)` + display: flex; + width: fit-content; + padding: var(--spacing-xxxs); + background-color: var(--surface-secondary); + border-radius: var(--radius-sm); + gap: var(--spacing-xxs); +`; + +export const StyledFillTab = styled(Tab)` + display: flex; + padding: var(--spacing-none) var(--spacing-sm); + height: 40px; + justify-content: center; + align-items: center; + gap: var(--spacing-xxs); + align-self: stretch; + cursor: pointer; + color: var(--text-secondary); + background-color: var(--surface-transparent); + border-radius: var(--radius-xs); + transition: background-color 0.3s, color 0.3s; + border-bottom: none; + + &[data-selected] { + background-color: var(--components-button-tertiary-background-inverse); + color: var(--text-secondary); + } + + &:focus { + outline: none; + } + + &:hover { + color: var(--components-button-secondary-text-default); + } + + &:focus-visible { + outline: var(--border-sm) solid var(--stroke-state-focused); + } + + &:active { + background-color: var(--surface-transparent); + color: var(--components-button-secondary-text-default); + } + + &[aria-disabled='true'] { + cursor: not-allowed; + color: var(--components-button-secondary-text-disabled); + opacity: 1; + } +`; + +export const StyledLineTabs = styled(ReachTabs)` + display: flex; + flex-direction: column; + gap: var(--spacing-sm); +`; + +export const StyledLineTabList = styled(TabList)` + display: flex; + background-color: var(--surface-transparent); + gap: var(--spacing-xs); + justify-content: flex-start; + border-bottom: var(--border-sm) solid var(--stroke-secondary); +`; + +export const StyledLineTab = styled(Tab)` + display: flex; + padding: var(--spacing-none) var(--spacing-sm); + height: 40px; + justify-content: center; + align-items: center; + gap: var(--spacing-xxs); + cursor: pointer; + margin-bottom: -1px; + background-color: var(--surface-transparent); + color: var(--text-secondary); + transition: background-color 0.3s, color 0.3s; + border-bottom: var(--border-md) solid var(--surface-transparent); + + &[data-selected] { + border-bottom: var(--border-md) solid var(--stroke-brand-medium); + color: var(--text-primary); + } + + &:hover { + color: var(--text-primary); + } + + &:focus-visible { + outline: var(--border-md) solid var(--stroke-state-focused); + border-bottom: var(--border-md) solid var(--surface-transparent); + border-radius: var(--radius-xs); + margin-bottom: -2px; + } + + &:active { + background-color: var(--surface-transparent); + color: var(--text-primary); + } + + &[aria-disabled='true'] { + cursor: not-allowed; + color: var(--text-state-disabled); + border-bottom: var(--border-md) solid var(--stroke-state-disabled); + opacity: 1; + } +`; + +export const StyledTabLabel = styled.span` + font-family: var(--font-family); + font-size: ${textVariants['h5-semibold'].fontSize}; + font-style: ${textVariants['h5-semibold'].fontStyle}; + font-weight: ${textVariants['h5-semibold'].fontWeight}; + line-height: ${textVariants['h5-semibold'].lineHeight}; +`; diff --git a/blocks/tabs/Tabs.tsx b/blocks/tabs/Tabs.tsx new file mode 100644 index 0000000..357a50d --- /dev/null +++ b/blocks/tabs/Tabs.tsx @@ -0,0 +1,76 @@ +import React from 'react'; +import { TabPanels, TabPanel, TabsKeyboardActivation } from '@reach/tabs'; +import '@reach/tabs/styles.css'; +import { + StyledFillTab, + StyledFillTabList, + StyledFillTabs, + StyledLineTab, + StyledLineTabList, + StyledLineTabs, + StyledTabLabel, +} from './Tabs.styled'; + +export type TabItem = { + key: string; + label: React.ReactNode; + children: React.ReactNode; + disabled?: boolean; + icon?: React.ReactNode; +}; + +export type TabsProps = { + items: TabItem[]; + onChange?: (activeKey: string) => void; + activeKey?: string; + variant?: 'line' | 'fill'; +}; + +const Tabs: React.FC = ({ items, onChange, variant = 'line', activeKey }) => { + const handleChange = (index: number) => { + const activeItem = items[index]; + if (activeItem && !activeItem.disabled) { + onChange?.(activeItem.key); + } + }; + + const TabsContainer = variant === 'line' ? StyledLineTabs : StyledFillTabs; + + const TabList = variant === 'line' ? StyledLineTabList : StyledFillTabList; + + const Tab = variant === 'line' ? StyledLineTab : StyledFillTab; + + const activeTabIndex = activeKey ? items.findIndex((item) => item.key === activeKey) : undefined; + + return ( + + + {items.map((item) => ( + + {item.icon && item.icon} + {item.label} + + ))} + + + {items.map((item) => ( + {item.children} + ))} + + + ); +}; + +Tabs.displayName = 'Tabs'; + +export { Tabs }; diff --git a/blocks/tabs/index.ts b/blocks/tabs/index.ts new file mode 100644 index 0000000..856dbbb --- /dev/null +++ b/blocks/tabs/index.ts @@ -0,0 +1 @@ +export * from './Tabs'; diff --git a/blocks/text/Text.constants.ts b/blocks/text/Text.constants.ts new file mode 100644 index 0000000..9eaa127 --- /dev/null +++ b/blocks/text/Text.constants.ts @@ -0,0 +1,379 @@ +export const textVariants = { + 'dl-bold': { + fontSize: '72px', + fontStyle: null, + fontWeight: '700', + lineHeight: '92.16px', + letterSpacing: '-1.5px', + textTransform: null, + }, + 'dl-semibold': { + fontSize: '72px', + fontStyle: null, + fontWeight: '500', + lineHeight: '92.16px', + letterSpacing: '-1.5px', + textTransform: null, + }, + 'dl-regular': { + fontSize: '72px', + fontStyle: null, + fontWeight: '400', + lineHeight: '92.16px', + letterSpacing: '-1.5px', + textTransform: null, + }, + 'ds-bold': { + fontSize: '58px', + fontStyle: null, + fontWeight: '700', + lineHeight: '74.24px', + letterSpacing: '-0.5px', + textTransform: null, + }, + 'ds-semibold': { + fontSize: '58px', + fontStyle: null, + fontWeight: '500', + lineHeight: '74.24px', + letterSpacing: '-0.5px', + textTransform: null, + }, + 'ds-regular': { + fontSize: '58px', + fontStyle: null, + fontWeight: '400', + lineHeight: '74.24px', + letterSpacing: '-0.5px', + textTransform: null, + }, + 'h1-bold': { + fontSize: '48px', + fontStyle: null, + fontWeight: '700', + lineHeight: '62px', + letterSpacing: null, + textTransform: null, + }, + 'h2-bold': { + fontSize: '34px', + fontStyle: null, + fontWeight: '700', + lineHeight: '48px', + letterSpacing: null, + textTransform: null, + }, + 'h3-bold': { + fontSize: '26px', + fontStyle: null, + fontWeight: '700', + lineHeight: '36px', + letterSpacing: null, + textTransform: null, + }, + 'h4-bold': { + fontSize: '20px', + fontStyle: null, + fontWeight: '700', + lineHeight: '30px', + letterSpacing: null, + textTransform: null, + }, + + 'h5-bold': { + fontSize: '16px', + fontStyle: null, + fontWeight: '700', + lineHeight: '23px', + letterSpacing: null, + textTransform: null, + }, + 'h6-bold': { + fontSize: '14px', + fontStyle: null, + fontWeight: '700', + lineHeight: '21px', + letterSpacing: null, + textTransform: null, + }, + 'h1-semibold': { + fontSize: '48px', + fontStyle: null, + fontWeight: '500', + lineHeight: '62px', + letterSpacing: null, + textTransform: null, + }, + 'h2-semibold': { + fontSize: '34px', + fontStyle: null, + fontWeight: '500', + lineHeight: '48px', + letterSpacing: null, + textTransform: null, + }, + 'h3-semibold': { + fontSize: '26px', + fontStyle: null, + fontWeight: '500', + lineHeight: '36px', + letterSpacing: null, + textTransform: null, + }, + 'h4-semibold': { + fontSize: '20px', + fontStyle: null, + fontWeight: '500', + lineHeight: '30px', + letterSpacing: null, + textTransform: null, + }, + 'h5-semibold': { + fontSize: '16px', + fontStyle: null, + fontWeight: '500', + lineHeight: '23px', + letterSpacing: null, + textTransform: null, + }, + 'h6-semibold': { + fontSize: '14px', + fontStyle: null, + fontWeight: '500', + lineHeight: '21px', + letterSpacing: null, + textTransform: null, + }, + 'h1-regular': { + fontSize: '48px', + fontStyle: null, + fontWeight: '400', + lineHeight: '62px', + letterSpacing: null, + textTransform: null, + }, + 'h2-regular': { + fontSize: '34px', + fontStyle: null, + fontWeight: '400', + lineHeight: '48px', + letterSpacing: null, + textTransform: null, + }, + 'h3-regular': { + fontSize: '26px', + fontStyle: null, + fontWeight: '400', + lineHeight: '36px', + letterSpacing: null, + textTransform: null, + }, + 'h4-regular': { + fontSize: '20px', + fontStyle: null, + fontWeight: '400', + lineHeight: '30px', + letterSpacing: null, + textTransform: null, + }, + 'h5-regular': { + fontSize: '16px', + fontStyle: null, + fontWeight: '400', + lineHeight: '23px', + letterSpacing: null, + textTransform: null, + }, + 'h6-regular': { + fontSize: '14px', + fontStyle: null, + fontWeight: '400', + lineHeight: '21px', + letterSpacing: null, + textTransform: null, + }, + 'bl-bold': { + fontSize: '18px', + fontStyle: null, + fontWeight: '700', + lineHeight: '27px', + letterSpacing: '0.5px', + textTransform: null, + }, + 'bl-semibold': { + fontSize: '18px', + fontStyle: null, + fontWeight: '500', + lineHeight: '27px', + letterSpacing: null, + textTransform: null, + }, + 'bl-regular': { + fontSize: '18px', + fontStyle: null, + fontWeight: '400', + lineHeight: '27px', + letterSpacing: null, + textTransform: null, + }, + 'bl-bold-italic': { + fontSize: '18px', + fontStyle: 'italic', + fontWeight: '400', + lineHeight: '27px', + letterSpacing: null, + textTransform: null, + }, + 'bm-bold': { + fontSize: '16px', + fontStyle: null, + fontWeight: '700', + lineHeight: '22px', + letterSpacing: null, + textTransform: null, + }, + 'bm-semibold': { + fontSize: '16px', + fontStyle: null, + fontWeight: '500', + lineHeight: '22px', + letterSpacing: null, + textTransform: null, + }, + 'bm-regular': { + fontSize: '16px', + fontStyle: null, + fontWeight: '400', + lineHeight: '22px', + letterSpacing: null, + textTransform: null, + }, + 'bm-regular-italic': { + fontSize: '16px', + fontStyle: 'italic', + fontWeight: '400', + lineHeight: '22px', + letterSpacing: null, + textTransform: null, + }, + 'bs-bold': { + fontSize: '14px', + fontStyle: null, + fontWeight: '700', + lineHeight: '20px', + letterSpacing: null, + textTransform: null, + }, + 'bs-semibold': { + fontSize: '14px', + fontStyle: null, + fontWeight: '500', + lineHeight: '20px', + letterSpacing: null, + textTransform: null, + }, + 'bs-regular': { + fontSize: '14px', + fontStyle: null, + fontWeight: '400', + lineHeight: '20px', + letterSpacing: null, + textTransform: null, + }, + 'bs-regular-italic': { + fontSize: '14px', + fontStyle: 'italic', + fontWeight: '400', + lineHeight: '20px', + letterSpacing: null, + textTransform: null, + }, + 'bes-bold': { + fontSize: '12px', + fontStyle: null, + fontWeight: '700', + lineHeight: '18px', + letterSpacing: null, + textTransform: null, + }, + 'bes-semibold': { + fontSize: '12px', + fontStyle: null, + fontWeight: '500', + lineHeight: '18px', + letterSpacing: null, + textTransform: null, + }, + 'bes-regular': { + fontSize: '12px', + fontStyle: null, + fontWeight: '400', + lineHeight: '18px', + letterSpacing: null, + textTransform: null, + }, + 'bes-regular-italic': { + fontSize: '12px', + fontStyle: 'italic', + fontWeight: '400', + lineHeight: '18px', + letterSpacing: null, + textTransform: null, + }, + 'ol-bold': { + fontSize: '12px', + fontStyle: null, + fontWeight: '700', + lineHeight: '16px', + letterSpacing: null, + textTransform: 'uppercase', + }, + 'ol-regular': { + fontSize: '12px', + fontStyle: null, + fontWeight: '500', + lineHeight: '16px', + letterSpacing: null, + textTransform: 'uppercase', + }, + 'os-bold': { + fontSize: '10px', + fontStyle: null, + fontWeight: '700', + lineHeight: '14px', + letterSpacing: null, + textTransform: 'uppercase', + }, + 'os-regular': { + fontSize: '10px', + fontStyle: null, + fontWeight: '500', + lineHeight: '14px', + letterSpacing: null, + textTransform: 'uppercase', + }, + 'c-semibold': { + fontSize: '10px', + fontStyle: null, + fontWeight: 500, + lineHeight: '14px', + letterSpacing: null, + textTransform: null, + }, + 'c-bold': { + fontSize: '12px', + fontStyle: null, + fontWeight: '700', + lineHeight: '16px', + letterSpacing: null, + textTransform: null, + }, + 'c-regular': { + fontSize: '12px', + fontStyle: null, + fontWeight: '400', + lineHeight: '16px', + letterSpacing: null, + textTransform: null, + }, +}; diff --git a/blocks/text/Text.tsx b/blocks/text/Text.tsx new file mode 100644 index 0000000..dbe1ebd --- /dev/null +++ b/blocks/text/Text.tsx @@ -0,0 +1,97 @@ +import { ReactNode, forwardRef } from 'react'; +import styled, { FlattenSimpleInterpolation } from 'styled-components'; + +import { TransformedHTMLAttributes } from '../Blocks.types'; +import { TextColors } from '../theme/Theme.types'; +import { TextAlign, TextHTMLTags, TextResponsiveProps, TextTransform, TextVariants } from './Text.types'; +import { getVariantStyles } from './Text.utils'; +import { getTextResponsiveCSS } from './Text.utils'; + +export type TextProps = { + /* Sets the html tag for Text component */ + as?: TextHTMLTags; + /* Children pass to the Text component */ + children?: ReactNode; + /* Sets the css property for text color */ + color?: TextColors; + /* Extra css prop from styled components to apply custom css not supported by Text component */ + css?: FlattenSimpleInterpolation; + /* For truncating the contents with ... when there's container overflow */ + ellipsis?: boolean; + /* For taking max available width of parent container */ + fullWidth?: boolean; + /* To limit the number of lines the Text component will show */ + numberOfLines?: number; + /* Sets css property for the content alignment */ + textAlign?: TextAlign; + /* Sets the text-transform css property */ + textTransform?: TextTransform; + /* Design system variant of the Text component */ + variant?: TextVariants; + /* Sets the css wrap property to move the text to next line in case of overflow */ + wrap?: boolean; +} & TextResponsiveProps & + TransformedHTMLAttributes; + +const StyledText = styled.p.withConfig({ + shouldForwardProp: (prop, defaultValidatorFn) => !['color', 'display'].includes(prop) && defaultValidatorFn(prop), +})` + /* Variant CSS */ + ${({ variant }) => getVariantStyles(variant)} + + color: ${({ color }) => `var(--${color})`}; + font-family: var(--font-family); + margin: 0px; + text-align: ${({ textAlign }) => textAlign}; + text-transform: ${({ textTransform }) => textTransform}; + + /* Ellipsis for single line overflow */ + ${({ ellipsis }) => + ellipsis && + ` + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + `} + + /* Text wrapping */ + ${({ wrap }) => + wrap && + ` + white-space: normal; + word-wrap: break-word; + `} + + /* Limit number of lines */ + ${({ numberOfLines }) => + numberOfLines && + ` + display: -webkit-box; + -webkit-line-clamp: ${numberOfLines}; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; + `} + + /* Full width of parent container */ + width: ${({ fullWidth }) => (fullWidth ? '100%' : 'auto')}; + + /* Responsive props */ + ${(props) => getTextResponsiveCSS(props)} + + /* Extra CSS props */ + ${(props) => props.css || ''} +`; + +const Text = forwardRef(({ as = 'p', color = 'text-primary', ...props }, ref) => ( + +)); + +Text.displayName = 'Text'; + +export { Text }; diff --git a/blocks/text/Text.types.ts b/blocks/text/Text.types.ts new file mode 100644 index 0000000..a47b848 --- /dev/null +++ b/blocks/text/Text.types.ts @@ -0,0 +1,43 @@ +import { CSSProperties } from 'react'; +import { ResponsiveProp, ValueOf } from '../Blocks.types'; +import { textVariants } from './Text.constants'; + +export type TextVariants = keyof typeof textVariants; + +export type TextHTMLTags = + | 'span' + | 'div' + | 'p' + | 'b' + | 'i' + | 'u' + | 'abbr' + | 'cite' + | 'kbd' + | 's' + | 'sample' + | 'sub' + | 'sup' + | 'ins' + | 'del' + | 'mark' + | 'em' + | 'i' + | 'strong' + | 'small' + | 'label'; + +export type TextAlign = 'left' | 'center' | 'right'; + +export type TextTransform = 'lowercase' | 'uppercase' | 'capitalize' | 'inherit'; + +export type TextResponsiveProps = { + /* Used to decide the visibility of text component for different screen sizes */ + display?: ResponsiveProp; +}; + +export type TextResponsiveCSSProperties = 'display'; + +export type TextResponsivePropValues = ValueOf; + +export type TextResponsiveCSSPropertiesData = { propName: TextResponsiveCSSProperties; prop: TextResponsivePropValues }; diff --git a/blocks/text/Text.utils.ts b/blocks/text/Text.utils.ts new file mode 100644 index 0000000..e46cf8d --- /dev/null +++ b/blocks/text/Text.utils.ts @@ -0,0 +1,36 @@ +import { css } from 'styled-components'; + +import { TextVariants } from './Text.types'; +import { textVariants } from './Text.constants'; +import { getResponsiveCSS } from '../Blocks.utils'; +import { TextResponsiveCSSPropertiesData, TextResponsiveProps } from './Text.types'; + +export const getVariantStyles = (variantName?: TextVariants) => { + if (variantName) { + const variantValue = textVariants[variantName]; + return css` + font-size: ${variantValue.fontSize}; + ${variantValue.fontStyle ? `font-style: ${variantValue.fontStyle};` : ''} + font-weight: ${variantValue.fontWeight}; + line-height: ${variantValue.lineHeight}; + ${variantValue.letterSpacing ? `letter-spacing: ${variantValue.letterSpacing};` : ''} + ${variantValue.textTransform ? `text-transform: ${variantValue.textTransform};` : ''} + `; + } + + // When no variant is passed, fallback to bes-regular + return css` + font-size: ${textVariants['bes-regular'].fontSize}; + line-height: ${textVariants['bes-regular'].lineHeight}; + font-weight: ${textVariants['bes-regular'].fontWeight}; + `; +}; + +const getTextResponsiveCSSProperties = (props: TextResponsiveProps): TextResponsiveCSSPropertiesData[] => [ + { propName: 'display', prop: props.display }, +]; + +export const getTextResponsiveCSS = (props: TextResponsiveProps) => { + const data = getTextResponsiveCSSProperties(props); + return getResponsiveCSS(data); +}; diff --git a/blocks/text/index.ts b/blocks/text/index.ts new file mode 100644 index 0000000..b5b6084 --- /dev/null +++ b/blocks/text/index.ts @@ -0,0 +1,4 @@ +export * from './Text'; +export * from './Text.constants'; +export * from './Text.types'; +export * from './Text.utils'; diff --git a/blocks/textInput/TextInput.tsx b/blocks/textInput/TextInput.tsx new file mode 100644 index 0000000..3e3f75f --- /dev/null +++ b/blocks/textInput/TextInput.tsx @@ -0,0 +1,223 @@ +import { Asterisk, CrossFilled } from '../icons'; +import { TextVariants, textVariants } from '../text'; +import React, { ReactNode, forwardRef } from 'react'; +import styled, { FlattenSimpleInterpolation, css } from 'styled-components'; + +export type TextInputProps = { + css?: FlattenSimpleInterpolation; + description?: string; + disabled?: boolean; + icon?: ReactNode; + error?: boolean; + type?: 'text' | 'password'; + errorMessage?: string; + label?: string; + onChange: (e: React.ChangeEvent) => void; + onClear?: () => void; + placeholder?: string; + required?: boolean; + success?: boolean; + totalCount?: number; + value: string; +}; + +const Container = styled.div<{ css?: FlattenSimpleInterpolation }>` + align-items: flex-start; + display: flex; + flex-direction: column; + flex: 1 0 0; + gap: var(--spacing-xxs, 8px); + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''}; +`; + +const StyledTextInput = styled.div<{ + error?: boolean; + success?: boolean; + disabled?: boolean; +}>` + ${({ success, error, disabled }) => { + const defaultState = error ? 'danger' : success ? 'success' : disabled ? 'disabled' : 'default'; + const focusState = error ? 'danger' : success ? 'success' : 'focus'; + return css` + align-self: stretch; + justify-content: space-between; + align-items: flex-start; + border-radius: var(--radius-xs, 12px); + border: 1.5px solid var(--components-inputs-stroke-${defaultState}); + background: var(--components-inputs-background-${defaultState}); + + display: flex; + + font-family: var(--font-family); + font-size: ${textVariants['bs-regular'].fontSize}; + font-style: ${textVariants['bs-regular'].fontStyle}; + font-weight: ${textVariants['bs-regular'].fontWeight}; + line-height: ${textVariants['bs-regular'].lineHeight}; + + gap: var(--spacing-xxs, 8px); + + padding: var(--spacing-xs, 12px); + [role='img'] { + width: 24px; + height: 24px; + + color: var(--components-inputs-icon-${defaultState}); + } + & input { + color: var(--components-inputs-text-${defaultState}); + + width: 100%; + ::placeholder { + color: var(--components-inputs-text-placeholder); + } + border: none; + background: transparent; + &:focus, + :disabled { + outline: none; + } + } + + &:hover { + border: 1.5px solid var(--components-inputs-stroke-hover); + } + + &:focus-within { + border: 1.5px solid var(--components-inputs-stroke-${focusState}); + outline: none; + } + + &:disabled { + border: 1.5px solid var(--components-inputs-stroke-default); + background: var(--components-inputs-background-disabled); + cursor: not-allowed; + color: var(--components-inputs-text-disabled); + } + `; + }} +`; + +const LabelContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; +`; + +const InputText = styled.span<{ color: string; variant: TextVariants }>` + color: var(--${({ color }) => color}); + font-family: var(--font-family); + ${({ variant }) => + ` + font-size: ${textVariants[variant].fontSize}; + font-style: ${textVariants[variant].fontStyle}; + font-weight: ${textVariants[variant].fontWeight}; + line-height: ${textVariants[variant].lineHeight}; + `} +`; + +const LabelTextContainer = styled.div` + display: flex; + align-items: flex-start; + gap: var(--spacing-xxxs, 4px); +`; + +const InputContainer = styled.div` + display: flex; + gap: var(--spacing-xxs); + width: 100%; +`; + +export const TextInput = forwardRef( + ( + { + css, + description, + disabled, + error, + errorMessage, + label, + onChange, + onClear, + placeholder, + required, + type = 'text', + icon, + success, + totalCount, + value, + }, + ref + ) => { + return ( + + {label && ( + + + + {label} + {required && } + + + {totalCount && ( + + {`${value?.length || 0} / ${totalCount}`} + + )} + + )} + + + {icon} + + + {onClear && onClear?.()} />} + + {description && ( + + {description} + + )} + {errorMessage && ( + + {errorMessage} + + )} + + ); + } +); diff --git a/blocks/textInput/index.ts b/blocks/textInput/index.ts new file mode 100644 index 0000000..a7fcf6f --- /dev/null +++ b/blocks/textInput/index.ts @@ -0,0 +1 @@ +export * from './TextInput'; diff --git a/blocks/textarea/TextArea.tsx b/blocks/textarea/TextArea.tsx new file mode 100644 index 0000000..2cbedb7 --- /dev/null +++ b/blocks/textarea/TextArea.tsx @@ -0,0 +1,185 @@ +import { Asterisk } from 'blocks/icons'; +import { textVariants } from '../text'; +import React, { forwardRef } from 'react'; +import styled, { FlattenSimpleInterpolation, css } from 'styled-components'; + +export type TextAreaProps = { + css?: FlattenSimpleInterpolation; + description?: string; + disabled?: boolean; + error?: boolean; + errorMessage?: string; + label?: string; + numberOfLines?: number; + onChange: (e: React.ChangeEvent) => void; + placeholder?: string; + required?: boolean; + resizable?: boolean; + success?: boolean; + totalCount?: number; + value: string; +}; + +const Container = styled.div<{ css?: FlattenSimpleInterpolation }>` + align-items: flex-start; + display: flex; + flex-direction: column; + flex: 1 0 0; + gap: var(--spacing-xxs, 8px); + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''}; +`; + +const StyledTextArea = styled.textarea<{ + error?: boolean; + success?: boolean; + resizable?: boolean; +}>` + ${({ resizable, success, error }) => { + const defaultState = error ? 'danger' : success ? 'success' : 'default'; + const focusState = error ? 'danger' : success ? 'success' : 'focus'; + return css` + align-self: stretch; + align-items: flex-start; + border-radius: var(--radius-xs, 12px); + border: 1.5px solid var(--components-inputs-stroke-${defaultState}); + background: var(--components-inputs-background-${defaultState}); + + color: var(--components-inputs-text-${defaultState}); + + display: flex; + + font-family: var(--font-family); + font-size: 14px; + font-style: normal; + font-weight: 400; + + gap: var(--spacing-none, 0px); + + line-height: 20px; + + padding: var(--spacing-xs, 12px); + ::placeholder { + color: var(--components-inputs-text-placeholder); + } + + resize: ${resizable ? 'vertical' : 'none'}; + + &:hover { + outline: none; + } + + &:focus { + border: 1.5px solid var(--components-inputs-stroke-${focusState}); + outline: none; + } + + &:disabled { + border: 1.5px solid var(--components-inputs-stroke-default); + background: var(--components-inputs-background-disabled); + cursor: not-allowed; + color: var(--components-inputs-text-disabled); + } + `; + }} +`; + +const LabelContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; +`; + +const LabelText = styled.span<{ color: string }>` + color: var(--${({ color }) => color}); + font-family: var(--font-family); + font-size: ${textVariants['h6-semibold'].fontSize}; + font-style: ${textVariants['h6-semibold'].fontStyle}; + font-weight: ${textVariants['h6-semibold'].fontWeight}; + line-height: ${textVariants['h6-semibold'].lineHeight}; +`; + +const LabelTextContainer = styled.div` + display: flex; + align-items: flex-start; + gap: var(--spacing-xxxs, 4px); +`; + +const LabelCount = styled.span<{ color: string }>` + color: var(--${({ color }) => color}); + font-family: var(--font-family); + font-size: ${textVariants['c-regular'].fontSize}; + font-style: ${textVariants['c-regular'].fontStyle}; + font-weight: ${textVariants['c-regular'].fontWeight}; + line-height: ${textVariants['c-regular'].lineHeight}; +`; + +export const TextArea = forwardRef( + ( + { + css, + description, + disabled, + error, + errorMessage, + label, + numberOfLines = 4, + onChange, + placeholder, + required, + resizable, + success, + totalCount, + value, + }, + ref + ) => { + return ( + + {label && ( + + + + {label} + {required && } + + + {totalCount && ( + + {`${value?.length || 0} / ${totalCount}`} + + )} + + )} + + {description && ( + + {description} + + )} + {errorMessage && {errorMessage}} + + ); + } +); diff --git a/blocks/textarea/index.ts b/blocks/textarea/index.ts new file mode 100644 index 0000000..4853311 --- /dev/null +++ b/blocks/textarea/index.ts @@ -0,0 +1 @@ +export * from './TextArea'; diff --git a/blocks/theme/Theme.ts b/blocks/theme/Theme.ts new file mode 100644 index 0000000..48cc30e --- /dev/null +++ b/blocks/theme/Theme.ts @@ -0,0 +1,8 @@ +import { createTheme } from './Theme.utils'; + +const blocksTheme = { + light: createTheme('light'), + dark: createTheme('dark'), +}; + +export { blocksTheme }; diff --git a/blocks/theme/Theme.types.ts b/blocks/theme/Theme.types.ts new file mode 100644 index 0000000..988ce06 --- /dev/null +++ b/blocks/theme/Theme.types.ts @@ -0,0 +1,41 @@ +import { colorSemantics, semanticKeys } from './colors/colors.semantics'; +import { blurVariables } from './variables/variables.blur'; +import { borderRadiusVariables } from './variables/variables.borderRadius'; +import { borderSizeVariables } from './variables/variables.borderSize'; +import { opacityVariables } from './variables/variables.opacity'; +import { spacingVariables } from './variables/variables.spacing'; + +export type ThemeMode = 'light' | 'dark'; + +type ColorSemantics = typeof colorSemantics; + +type StringKeys = Extract; + +type ThemeColorsConfig = { + [K1 in StringKeys as `${K1}-${StringKeys}`]: string; +}; + +export type ThemeColors = keyof ThemeColorsConfig; + +export type Theme = { + colors: ThemeColorsConfig; + blur: typeof blurVariables; + borderRadius: typeof borderRadiusVariables; + borderSize: typeof borderSizeVariables; + opacity: typeof opacityVariables; + spacing: typeof spacingVariables; +}; + +export type ThemeBorderRadius = keyof Theme['borderRadius']; + +export type ThemeBorderSize = keyof Theme['borderSize']; + +export type ThemeSpacing = keyof Theme['spacing']; + +export type SurfaceColors = keyof ThemeColorsConfig<{ [semanticKeys.surface]: ColorSemantics['surface'] }>; + +export type TextColors = keyof ThemeColorsConfig<{ [semanticKeys.text]: ColorSemantics['text'] }>; + +export type IconColors = keyof ThemeColorsConfig<{ [semanticKeys.icon]: ColorSemantics['icon'] }>; + +export type StrokeColors = keyof ThemeColorsConfig<{ [semanticKeys.stroke]: ColorSemantics['stroke'] }>; diff --git a/blocks/theme/Theme.utils.ts b/blocks/theme/Theme.utils.ts new file mode 100644 index 0000000..7ec82dd --- /dev/null +++ b/blocks/theme/Theme.utils.ts @@ -0,0 +1,33 @@ +import { Theme, ThemeMode } from './Theme.types'; +import { colorSemantics } from './colors/colors.semantics'; +import { blurVariables } from './variables/variables.blur'; +import { borderRadiusVariables } from './variables/variables.borderRadius'; +import { borderSizeVariables } from './variables/variables.borderSize'; +import { opacityVariables } from './variables/variables.opacity'; +import { spacingVariables } from './variables/variables.spacing'; + +const getThemeColors = (mode: ThemeMode) => + Object.entries(colorSemantics).reduce((acc, [semanticName, sematicsVariants]) => { + Object.entries(sematicsVariants).forEach(([variantKey, variantValue]) => { + acc[`${semanticName}-${variantKey}` as keyof Theme['colors']] = variantValue[mode]; + }); + return acc; + }, {} as Theme['colors']); + +export const createTheme = (mode: ThemeMode): Theme => ({ + colors: getThemeColors(mode), + blur: blurVariables, + borderRadius: borderRadiusVariables, + borderSize: borderSizeVariables, + opacity: opacityVariables, + spacing: spacingVariables, +}); + +export const getBlocksCSSVariables = (theme: Theme) => + Object.values(theme) + .map((value) => + Object.entries(value) + .map(([key, value]) => `--${key}: ${value};`) + .join('') + ) + .join(''); \ No newline at end of file diff --git a/blocks/theme/colors/colors.brands.ts b/blocks/theme/colors/colors.brands.ts new file mode 100644 index 0000000..c2a159d --- /dev/null +++ b/blocks/theme/colors/colors.brands.ts @@ -0,0 +1,69 @@ +import { colorPrimitives } from './colors.primitives'; + +export const colorBrands = { + 'primary-100': colorPrimitives['pink-100'], + 'primary-200': colorPrimitives['pink-200'], + 'primary-300': colorPrimitives['pink-300'], + 'primary-400': colorPrimitives['pink-400'], + 'primary-500': colorPrimitives['pink-500'], + 'primary-600': colorPrimitives['pink-600'], + 'primary-700': colorPrimitives['pink-700'], + 'primary-800': colorPrimitives['pink-800'], + 'primary-900': colorPrimitives['pink-900'], + 'primary-1000': colorPrimitives['pink-1000'], + + 'neutral-100': colorPrimitives['gray-100'], + 'neutral-200': colorPrimitives['gray-200'], + 'neutral-300': colorPrimitives['gray-300'], + 'neutral-400': colorPrimitives['gray-400'], + 'neutral-500': colorPrimitives['gray-500'], + 'neutral-600': colorPrimitives['gray-600'], + 'neutral-700': colorPrimitives['gray-700'], + 'neutral-800': colorPrimitives['gray-800'], + 'neutral-900': colorPrimitives['gray-900'], + 'neutral-1000': colorPrimitives['gray-1000'], + + 'info-100': colorPrimitives['blue-100'], + 'info-200': colorPrimitives['blue-200'], + 'info-300': colorPrimitives['blue-300'], + 'info-400': colorPrimitives['blue-400'], + 'info-500': colorPrimitives['blue-500'], + 'info-600': colorPrimitives['blue-600'], + 'info-700': colorPrimitives['blue-700'], + 'info-800': colorPrimitives['blue-800'], + 'info-900': colorPrimitives['blue-900'], + 'info-1000': colorPrimitives['blue-1000'], + + 'success-100': colorPrimitives['green-100'], + 'success-200': colorPrimitives['green-200'], + 'success-300': colorPrimitives['green-300'], + 'success-400': colorPrimitives['green-400'], + 'success-500': colorPrimitives['green-500'], + 'success-600': colorPrimitives['green-600'], + 'success-700': colorPrimitives['green-700'], + 'success-800': colorPrimitives['green-800'], + 'success-900': colorPrimitives['green-900'], + 'success-1000': colorPrimitives['green-1000'], + + 'warning-100': colorPrimitives['yellow-100'], + 'warning-200': colorPrimitives['yellow-200'], + 'warning-300': colorPrimitives['yellow-300'], + 'warning-400': colorPrimitives['yellow-400'], + 'warning-500': colorPrimitives['yellow-500'], + 'warning-600': colorPrimitives['yellow-600'], + 'warning-700': colorPrimitives['yellow-700'], + 'warning-800': colorPrimitives['yellow-800'], + 'warning-900': colorPrimitives['yellow-900'], + 'warning-1000': colorPrimitives['yellow-1000'], + + 'danger-100': colorPrimitives['red-100'], + 'danger-200': colorPrimitives['red-200'], + 'danger-300': colorPrimitives['red-300'], + 'danger-400': colorPrimitives['red-400'], + 'danger-500': colorPrimitives['red-500'], + 'danger-600': colorPrimitives['red-600'], + 'danger-700': colorPrimitives['red-700'], + 'danger-800': colorPrimitives['red-800'], + 'danger-900': colorPrimitives['red-900'], + 'danger-1000': colorPrimitives['red-1000'], +}; diff --git a/blocks/theme/colors/colors.primitives.ts b/blocks/theme/colors/colors.primitives.ts new file mode 100644 index 0000000..e639c3c --- /dev/null +++ b/blocks/theme/colors/colors.primitives.ts @@ -0,0 +1,91 @@ +export const colorPrimitives = { + 'gray-100': '#F5F6F8', + 'gray-200': '#EAEBF2', + 'gray-300': '#C4CBD5', + 'gray-400': '#B0B3B9', + 'gray-500': '#8C93A0', + 'gray-600': '#757D8D', + 'gray-700': '#484D58', + 'gray-800': '#313338', + 'gray-900': '#202124', + 'gray-1000': '#17181B', + + 'pink-100': '#FCEBFF', + 'pink-200': '#FBE8FF', + 'pink-300': '#F3AEFF', + 'pink-400': '#CF59E2', + 'pink-500': '#D548EC', + 'pink-600': '#C742DD', + 'pink-700': '#AA30BE', + 'pink-800': '#7B0090', + 'pink-900': '#570066', + 'pink-1000': '#35003F', + + 'blue-100': '#E8F2FF', + 'blue-200': '#D1E4FF', + 'blue-300': '#A2C9FF', + 'blue-400': '#73ADFF', + 'blue-500': '#4090FF', + 'blue-600': '#076EFF', + 'blue-700': '#0056D0', + 'blue-800': '#00419D', + 'blue-900': '#002D6D', + 'blue-1000': '#001A40', + + 'green-100': '#D8F7F0', + 'green-200': '#AFEFE1', + 'green-300': '#51DCBD', + 'green-400': '#00C296', + 'green-500': '#00A47F', + 'green-600': '#008769', + 'green-700': '#006B53', + 'green-800': '#00513F', + 'green-900': '#00382B', + 'green-1000': '#002019', + + 'red-100': '#FFECEC', + 'red-200': '#FFD9D9', + 'red-300': '#FFB1B1', + 'red-400': '#FF8585', + 'red-500': '#FF4E4E', + 'red-600': '#F11F1F', + 'red-700': '#D43B3B', + 'red-800': '#A40A0A', + 'red-900': '#670000', + 'red-1000': '#400000', + + 'yellow-100': '#FFF0CB', + 'yellow-200': '#FFDF93', + 'yellow-300': '#FFBB16', + 'yellow-400': '#E99B00', + 'yellow-500': '#C77100', + 'yellow-600': '#A85A00', + 'yellow-700': '#8A4900', + 'yellow-800': '#663600', + 'yellow-900': '#472600', + 'yellow-1000': '#291500', + + 'white-10': 'rgba(255,255,255,0.1)', + 'white-20': 'rgba(255,255,255,0.2)', + 'white-30': 'rgba(255,255,255,0.3)', + 'white-40': 'rgba(255,255,255,0.4)', + 'white-50': 'rgba(255,255,255,0.5)', + 'white-60': 'rgba(255,255,255,0.6)', + 'white-70': 'rgba(255,255,255,0.7)', + 'white-80': 'rgba(255,255,255,0.8)', + 'white-90': 'rgba(255,255,255,0.9)', + 'white-100': 'rgba(255,255,255,1)', + + 'black-10': 'rgba(0,0,0,0.1)', + 'black-20': 'rgba(0,0,0,0.2)', + 'black-30': 'rgba(0,0,0,0.3)', + 'black-40': 'rgba(0,0,0,0.4)', + 'black-50': 'rgba(0,0,0,0.5)', + 'black-60': 'rgba(0,0,0,0.6)', + 'black-70': 'rgba(0,0,0,0.7)', + 'black-80': 'rgba(0,0,0,0.8)', + 'black-90': 'rgba(0,0,0,0.9)', + 'black-100': 'rgba(0,0,0,1)', + + transparent: 'transparent', +}; diff --git a/blocks/theme/colors/colors.semantics.ts b/blocks/theme/colors/colors.semantics.ts new file mode 100644 index 0000000..e3b36b8 --- /dev/null +++ b/blocks/theme/colors/colors.semantics.ts @@ -0,0 +1,104 @@ +import { alertSemantics } from '../semantics/semantics.alert'; +import { + secondaryButtonSemantics, + dangerButtonSemantics, + dangerSecondaryButtonSemantics, + outlineButtonSemantics, + primaryButtonSemantics, + tertiaryButtonSemantics, +} from '../semantics/semantics.button'; +import { checkboxSemantics } from '../semantics/semantics.checkbox'; +import { dropdownSemantics } from '../semantics/semantics.dropdown'; +import { iconSemantics } from '../semantics/semantics.icon'; +import { inputSemantics } from '../semantics/semantics.input'; +import { modalSemantics } from '../semantics/semantics.modal'; +import { progressBarSemantics } from '../semantics/semantics.progress-bar'; +import { radioSemantics } from '../semantics/semantics.radio'; +import { skeletonSemantics } from '../semantics/semantics.skeleton'; +import { strokeSemantics } from '../semantics/semantics.stroke'; +import { surfaceSemantics } from '../semantics/semantics.surface'; +import { switchSemantics } from '../semantics/semantics.switch'; +import { textSemantics } from '../semantics/semantics.text'; +import { textAreaSemantics } from '../semantics/semantics.textarea'; +import { toastSemantics } from '../semantics/semantics.toast'; +import { tooltipSemantics } from '../semantics/semantics.tooltip'; +import { spinnerSemantics } from '../semantics/semantics.spinner'; + +// TODO: find a better way to do this in future +type SemanticKeys = { + alert: 'components-alert'; + buttonPrimary: 'components-button-primary'; + buttonSecondary: 'components-button-secondary'; + buttonTertiary: 'components-button-tertiary'; + buttonOutline: 'components-button-outline'; + buttonDanger: 'components-button-danger'; + buttonDangerSecondary: 'components-button-danger-secondary'; + checkbox: 'components-checkbox'; + dropdown: 'components-dropdown'; + icon: 'icon'; + input: 'components-inputs'; + modal: 'components-modal'; + progressBar: 'components-progress-bar'; + radio: 'components-radio-button'; + surface: 'surface'; + stroke: 'stroke'; + skeleton: 'components-skeleton-loader'; + text: 'text'; + textArea: 'components-textarea'; + toast: 'components-toast'; + toggle: 'components-toggle-switch'; + tooltip: 'components-tooltip'; + spinner: 'components-spinner'; +}; + +export const semanticKeys: SemanticKeys = { + alert: 'components-alert', + buttonPrimary: 'components-button-primary', + buttonSecondary: 'components-button-secondary', + buttonTertiary: 'components-button-tertiary', + buttonOutline: 'components-button-outline', + buttonDanger: 'components-button-danger', + buttonDangerSecondary: 'components-button-danger-secondary', + checkbox: 'components-checkbox', + dropdown: 'components-dropdown', + icon: 'icon', + input: 'components-inputs', + modal: 'components-modal', + progressBar: 'components-progress-bar', + radio: 'components-radio-button', + surface: 'surface', + stroke: 'stroke', + skeleton: 'components-skeleton-loader', + text: 'text', + textArea: 'components-textarea', + toast: 'components-toast', + toggle: 'components-toggle-switch', + tooltip: 'components-tooltip', + spinner: 'components-spinner', +}; + +export const colorSemantics = { + [semanticKeys.alert]: alertSemantics, + [semanticKeys.buttonPrimary]: primaryButtonSemantics, + [semanticKeys.buttonSecondary]: secondaryButtonSemantics, + [semanticKeys.buttonTertiary]: tertiaryButtonSemantics, + [semanticKeys.buttonOutline]: outlineButtonSemantics, + [semanticKeys.buttonDanger]: dangerButtonSemantics, + [semanticKeys.buttonDangerSecondary]: dangerSecondaryButtonSemantics, + [semanticKeys.checkbox]: checkboxSemantics, + [semanticKeys.dropdown]: dropdownSemantics, + [semanticKeys.icon]: iconSemantics, + [semanticKeys.input]: inputSemantics, + [semanticKeys.modal]: modalSemantics, + [semanticKeys.progressBar]: progressBarSemantics, + [semanticKeys.radio]: radioSemantics, + [semanticKeys.surface]: surfaceSemantics, + [semanticKeys.stroke]: strokeSemantics, + [semanticKeys.skeleton]: skeletonSemantics, + [semanticKeys.text]: textSemantics, + [semanticKeys.textArea]: textAreaSemantics, + [semanticKeys.toast]: toastSemantics, + [semanticKeys.toggle]: switchSemantics, + [semanticKeys.tooltip]: tooltipSemantics, + [semanticKeys.spinner]: spinnerSemantics, +}; diff --git a/blocks/theme/device/theme.device.ts b/blocks/theme/device/theme.device.ts new file mode 100644 index 0000000..0d9fcd9 --- /dev/null +++ b/blocks/theme/device/theme.device.ts @@ -0,0 +1,32 @@ +import { DeviceSizeName, DeviceSize, Breakpoint } from '../../Blocks.types'; + +export const deviceSizes: Record = { + mobileS: '320px', + mobileM: '375px', + mobileL: '425px', + tablet: '768px', + laptop: '1024px', + laptopL: '1440px', + desktop: '2560px', +}; + +export const deviceMediaQ: Record = { + mobileS: `(max-width: ${deviceSizes.mobileS})`, + mobileM: `(max-width: ${deviceSizes.mobileM})`, + mobileL: `(max-width: ${deviceSizes.mobileL})`, + tablet: `(max-width: ${deviceSizes.tablet})`, + laptop: `(max-width: ${deviceSizes.laptop})`, + laptopL: `(max-width: ${deviceSizes.laptopL})`, + desktop: `(max-width: ${deviceSizes.desktop})`, +}; + +export const breakpointMap: Record = { + initial: '', + ms: 'mobileS', + mm: 'mobileM', + ml: 'mobileL', + tb: 'tablet', + lp: 'laptop', + ll: 'laptopL', + dp: 'desktop', +}; diff --git a/blocks/theme/index.ts b/blocks/theme/index.ts new file mode 100644 index 0000000..30b7cc6 --- /dev/null +++ b/blocks/theme/index.ts @@ -0,0 +1,4 @@ +export * from './device/theme.device'; + +export * from './Theme'; +export * from './Theme.utils'; diff --git a/blocks/theme/semantics/semantics.alert.ts b/blocks/theme/semantics/semantics.alert.ts new file mode 100644 index 0000000..7b9ab7b --- /dev/null +++ b/blocks/theme/semantics/semantics.alert.ts @@ -0,0 +1,24 @@ +import { colorBrands } from '../colors/colors.brands'; +import { colorPrimitives } from '../colors/colors.primitives'; +import { textSemantics } from './semantics.text'; + +export const alertSemantics = { + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-body': { light: textSemantics['tertiary'].light, dark: textSemantics['tertiary'].dark }, + 'icon-success': { light: colorBrands['success-500'], dark: colorBrands['success-300'] }, + 'icon-warning': { light: colorBrands['warning-700'], dark: colorBrands['warning-100'] }, + 'icon-error': { light: colorBrands['danger-600'], dark: colorBrands['danger-500'] }, + 'icon-info': { light: colorPrimitives['blue-700'], dark: colorPrimitives['blue-100'] }, + 'text-cta-success': { light: colorBrands['success-500'], dark: colorBrands['success-300'] }, + 'text-cta-warning': { light: colorBrands['warning-700'], dark: colorBrands['warning-100'] }, + 'text-cta-error': { light: colorBrands['danger-600'], dark: colorBrands['danger-500'] }, + 'text-cta-info': { light: colorPrimitives['blue-700'], dark: colorPrimitives['blue-100'] }, + 'background-success': { light: colorBrands['success-100'], dark: colorBrands['success-900'] }, + 'background-warning': { light: colorBrands['warning-100'], dark: colorBrands['warning-900'] }, + 'background-error': { light: colorBrands['danger-100'], dark: colorBrands['danger-900'] }, + 'background-info': { light: colorPrimitives['blue-100'], dark: colorPrimitives['blue-900'] }, + 'stroke-success': { light: colorBrands['success-300'], dark: colorBrands['success-700'] }, + 'stroke-warning': { light: colorBrands['warning-300'], dark: colorBrands['warning-700'] }, + 'stroke-error': { light: colorBrands['danger-300'], dark: colorBrands['danger-700'] }, + 'stroke-info': { light: colorPrimitives['blue-300'], dark: colorPrimitives['blue-700'] }, +}; diff --git a/blocks/theme/semantics/semantics.button.ts b/blocks/theme/semantics/semantics.button.ts new file mode 100644 index 0000000..3ac4dda --- /dev/null +++ b/blocks/theme/semantics/semantics.button.ts @@ -0,0 +1,130 @@ +import { colorBrands } from '../colors/colors.brands'; +import { colorPrimitives } from '../colors/colors.primitives'; +import { iconSemantics } from './semantics.icon'; +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const primaryButtonSemantics = { + 'background-default': { light: colorBrands['primary-500'], dark: colorBrands['primary-500'] }, + 'background-hover': { light: colorBrands['primary-400'], dark: colorBrands['primary-400'] }, + 'background-pressed': { light: colorBrands['primary-800'], dark: colorBrands['primary-600'] }, + 'background-focus': { light: colorBrands['primary-500'], dark: colorBrands['primary-400'] }, + 'background-loading': { light: colorBrands['primary-400'], dark: colorBrands['primary-400'] }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + + 'text-default': { light: colorPrimitives['white-100'], dark: colorPrimitives['white-100'] }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + + 'icon-default': { light: colorPrimitives['white-100'], dark: colorPrimitives['white-100'] }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, + + 'stroke-focus': { light: colorBrands['primary-700'], dark: colorBrands['primary-200'] }, +}; + +export const secondaryButtonSemantics = { + 'background-default': { light: colorBrands['neutral-100'], dark: colorBrands['neutral-800'] }, + 'background-hover': { light: colorBrands['neutral-200'], dark: colorBrands['neutral-700'] }, + 'background-pressed': { light: colorBrands['neutral-300'], dark: colorBrands['neutral-1000'] }, + 'background-focus': { light: colorBrands['neutral-100'], dark: colorBrands['neutral-800'] }, + 'background-loading': { light: colorBrands['neutral-100'], dark: colorBrands['neutral-800'] }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + + 'text-default': { light: colorBrands['neutral-1000'], dark: colorPrimitives['white-100'] }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + + 'icon-default': { light: colorBrands['neutral-800'], dark: colorPrimitives['white-60'] }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, + + 'stroke-focus': { light: colorBrands['primary-300'], dark: colorBrands['primary-400'] }, +}; + +export const tertiaryButtonSemantics = { + 'background-default': { light: colorBrands['neutral-1000'], dark: colorBrands['neutral-700'] }, + 'background-inverse': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-hover': { light: colorBrands['neutral-900'], dark: colorBrands['neutral-300'] }, + 'background-pressed': { light: colorBrands['neutral-100'], dark: colorPrimitives['gray-1000'] }, + 'background-focus': { light: colorBrands['neutral-1000'], dark: colorBrands['neutral-700'] }, + 'background-loading': { light: colorBrands['neutral-900'], dark: colorBrands['neutral-700'] }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + + 'text-default': { light: colorPrimitives['white-100'], dark: colorPrimitives['gray-200'] }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + + 'icon-default': { light: colorBrands['neutral-300'], dark: colorPrimitives['white-50'] }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, + + 'stroke-focus': { light: colorBrands['primary-400'], dark: colorBrands['primary-400'] }, +}; + +export const outlineButtonSemantics = { + 'background-default': { light: colorPrimitives['transparent'], dark: colorPrimitives['transparent'] }, + 'background-hover': { light: colorPrimitives['transparent'], dark: colorPrimitives['transparent'] }, + 'background-pressed': { light: colorPrimitives['transparent'], dark: colorPrimitives['transparent'] }, + 'background-focus': { light: colorPrimitives['transparent'], dark: colorPrimitives['transparent'] }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + + 'icon-default': { light: iconSemantics['primary'].light, dark: iconSemantics['secondary'].dark }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, + + 'stroke-default': { light: strokeSemantics['tertiary'].light, dark: strokeSemantics['tertiary'].dark }, + 'stroke-focus': { light: colorBrands['primary-300'], dark: colorBrands['primary-400'] }, + 'stroke-loading': { light: colorBrands['neutral-200'], dark: colorBrands['primary-400'] }, + 'stroke-hover': { light: strokeSemantics['brand-subtle'].light, dark: strokeSemantics['secondary'].dark }, + 'stroke-pressed': { light: colorBrands['neutral-600'], dark: colorBrands['neutral-300'] }, +}; + +export const dangerButtonSemantics = { + 'background-default': { light: colorBrands['danger-600'], dark: colorBrands['danger-500'] }, + 'background-hover': { light: colorBrands['danger-500'], dark: colorBrands['danger-400'] }, + 'background-pressed': { light: colorBrands['danger-800'], dark: colorBrands['danger-700'] }, + 'background-focus': { light: colorBrands['danger-500'], dark: colorBrands['danger-400'] }, + 'background-loading': { light: colorBrands['danger-500'], dark: colorBrands['danger-400'] }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + + 'text-default': { light: colorPrimitives['white-100'], dark: colorPrimitives['white-100'] }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + + 'icon-default': { light: colorPrimitives['white-70'], dark: colorPrimitives['white-70'] }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, + + 'stroke-focus': { light: colorBrands['danger-800'], dark: colorBrands['danger-600'] }, +}; + +export const dangerSecondaryButtonSemantics = { + 'background-default': { light: colorBrands['danger-200'], dark: colorBrands['danger-800'] }, + 'background-hover': { light: colorBrands['danger-100'], dark: colorBrands['danger-700'] }, + 'background-pressed': { light: colorBrands['danger-500'], dark: colorBrands['danger-1000'] }, + 'background-focus': { light: colorBrands['danger-100'], dark: colorBrands['danger-700'] }, + 'background-loading': { light: colorBrands['danger-100'], dark: colorBrands['danger-700'] }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + + 'text-default': { light: colorBrands['danger-700'], dark: colorPrimitives['white-100'] }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + + 'icon-default': { light: colorBrands['danger-400'], dark: colorPrimitives['white-70'] }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, + + 'stroke-focus': { light: colorBrands['danger-800'], dark: colorBrands['danger-400'] }, +}; diff --git a/blocks/theme/semantics/semantics.checkbox.ts b/blocks/theme/semantics/semantics.checkbox.ts new file mode 100644 index 0000000..d7bd691 --- /dev/null +++ b/blocks/theme/semantics/semantics.checkbox.ts @@ -0,0 +1,21 @@ +import { colorPrimitives } from '../colors/colors.primitives'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const checkboxSemantics = { + 'background-default': { light: surfaceSemantics['primary'].light, dark: surfaceSemantics['primary'].dark }, + 'background-selected': { light: surfaceSemantics['brand-medium'].light, dark: surfaceSemantics['brand-medium'].dark }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-secondary': { light: textSemantics['secondary'].light, dark: textSemantics['secondary'].dark }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + + 'stroke-default': { light: textSemantics['brand-medium'].light, dark: textSemantics['brand-medium'].dark }, + 'stroke-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + + 'icon-default': { light: colorPrimitives['white-100'], dark: colorPrimitives['white-100'] }, +}; diff --git a/blocks/theme/semantics/semantics.dropdown.ts b/blocks/theme/semantics/semantics.dropdown.ts new file mode 100644 index 0000000..932a53b --- /dev/null +++ b/blocks/theme/semantics/semantics.dropdown.ts @@ -0,0 +1,45 @@ +import { colorBrands } from '../colors/colors.brands'; +import { colorPrimitives } from '../colors/colors.primitives'; +import { iconSemantics } from './semantics.icon'; +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const dropdownSemantics = { + 'background-default': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-hover': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-pressed': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-focus': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + 'background-success': { light: colorBrands['success-100'], dark: colorBrands['success-200'] }, + 'background-danger': { light: colorBrands['danger-100'], dark: colorBrands['danger-200'] }, + + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-placeholder': { light: colorBrands['neutral-400'], dark: colorBrands['neutral-600'] }, + 'text-secondary': { light: colorBrands['neutral-600'], dark: colorBrands['neutral-500'] }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + 'text-success': { + light: textSemantics['state-success-bold'].light, + dark: textSemantics['state-success-subtle'].dark, + }, + 'text-danger': { light: textSemantics['state-danger-bold'].light, dark: textSemantics['state-danger-subtle'].dark }, + + 'icon-default': { light: iconSemantics['tertiary'].light, dark: iconSemantics['secondary'].dark }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, + 'icon-success': { + light: iconSemantics['state-success-bold'].light, + dark: iconSemantics['state-success-subtle'].dark, + }, + 'icon-danger': { light: iconSemantics['state-danger-bold'].light, dark: iconSemantics['state-danger-subtle'].dark }, + + 'stroke-default': { light: strokeSemantics['secondary'].light, dark: strokeSemantics['secondary'].dark }, + 'stroke-hover': { light: strokeSemantics['tertiary'].light, dark: strokeSemantics['tertiary'].dark }, + 'stroke-focus': { light: colorBrands['primary-300'], dark: colorBrands['primary-300'] }, + 'stroke-pressed': { light: strokeSemantics['tertiary'].light, dark: strokeSemantics['tertiary'].dark }, + 'stroke-disabled': { light: colorBrands['neutral-300'], dark: colorBrands['neutral-900'] }, + 'stroke-success': { light: colorBrands['success-500'], dark: colorBrands['success-400'] }, + 'stroke-danger': { light: colorBrands['danger-400'], dark: colorBrands['danger-400'] }, +}; diff --git a/blocks/theme/semantics/semantics.icon.ts b/blocks/theme/semantics/semantics.icon.ts new file mode 100644 index 0000000..003bd4b --- /dev/null +++ b/blocks/theme/semantics/semantics.icon.ts @@ -0,0 +1,29 @@ +import { colorBrands } from '../colors/colors.brands'; + +export const iconSemantics = { + primary: { light: colorBrands['neutral-900'], dark: colorBrands['neutral-400'] }, + secondary: { light: colorBrands['neutral-200'], dark: colorBrands['neutral-100'] }, + tertiary: { light: colorBrands['neutral-300'], dark: colorBrands['neutral-700'] }, + + 'hero-icons': { light: colorBrands['neutral-1000'], dark: colorBrands['neutral-100'] }, + + 'brand-subtle': { light: colorBrands['primary-300'], dark: colorBrands['primary-400'] }, + 'brand-medium': { light: colorBrands['primary-500'], dark: colorBrands['primary-400'] }, + 'brand-bold': { light: colorBrands['primary-800'], dark: colorBrands['primary-300'] }, + + // icon states + + 'state-success-subtle': { light: colorBrands['success-200'], dark: colorBrands['success-600'] }, + 'state-success-bold': { light: colorBrands['success-600'], dark: colorBrands['success-300'] }, + + 'state-info-subtle': { light: colorBrands['info-200'], dark: colorBrands['info-600'] }, + 'state-info-bold': { light: colorBrands['info-600'], dark: colorBrands['info-200'] }, + + 'state-warning-subtle': { light: colorBrands['warning-200'], dark: colorBrands['warning-600'] }, + 'state-warning-bold': { light: colorBrands['warning-600'], dark: colorBrands['warning-200'] }, + + 'state-danger-subtle': { light: colorBrands['danger-200'], dark: colorBrands['danger-600'] }, + 'state-danger-bold': { light: colorBrands['danger-600'], dark: colorBrands['danger-300'] }, + + 'state-disabled': { light: colorBrands['neutral-400'], dark: colorBrands['neutral-700'] }, +}; diff --git a/blocks/theme/semantics/semantics.input.ts b/blocks/theme/semantics/semantics.input.ts new file mode 100644 index 0000000..e1e8221 --- /dev/null +++ b/blocks/theme/semantics/semantics.input.ts @@ -0,0 +1,45 @@ +import { colorBrands } from '../colors/colors.brands'; +import { colorPrimitives } from '../colors/colors.primitives'; +import { iconSemantics } from './semantics.icon'; +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const inputSemantics = { + 'background-default': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-hover': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-pressed': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-focus': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + 'background-success': { light: colorBrands['success-100'], dark: colorBrands['success-200'] }, + 'background-danger': { light: colorBrands['danger-100'], dark: colorBrands['danger-200'] }, + + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-placeholder': { light: colorBrands['neutral-400'], dark: colorBrands['neutral-600'] }, + 'text-secondary': { light: colorBrands['neutral-600'], dark: colorBrands['neutral-500'] }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + 'text-success': { + light: textSemantics['state-success-bold'].light, + dark: textSemantics['state-success-subtle'].dark, + }, + 'text-danger': { light: textSemantics['state-danger-bold'].light, dark: textSemantics['state-danger-subtle'].dark }, + + 'icon-default': { light: iconSemantics['tertiary'].light, dark: iconSemantics['secondary'].dark }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, + 'icon-success': { + light: iconSemantics['state-success-bold'].light, + dark: iconSemantics['state-success-subtle'].dark, + }, + 'icon-danger': { light: iconSemantics['state-danger-bold'].light, dark: iconSemantics['state-danger-subtle'].dark }, + + 'stroke-default': { light: strokeSemantics['secondary'].light, dark: strokeSemantics['secondary'].dark }, + 'stroke-hover': { light: strokeSemantics['tertiary'].light, dark: strokeSemantics['tertiary'].dark }, + 'stroke-focus': { light: colorBrands['primary-300'], dark: colorBrands['primary-300'] }, + 'stroke-pressed': { light: strokeSemantics['tertiary'].light, dark: strokeSemantics['tertiary'].dark }, + 'stroke-disabled': { light: colorBrands['neutral-300'], dark: colorBrands['neutral-900'] }, + 'stroke-success': { light: colorBrands['success-500'], dark: colorBrands['success-400'] }, + 'stroke-danger': { light: colorBrands['danger-400'], dark: colorBrands['danger-400'] }, +}; diff --git a/blocks/theme/semantics/semantics.modal.ts b/blocks/theme/semantics/semantics.modal.ts new file mode 100644 index 0000000..e29fe2c --- /dev/null +++ b/blocks/theme/semantics/semantics.modal.ts @@ -0,0 +1,25 @@ +import { colorPrimitives } from '../colors/colors.primitives'; +import { iconSemantics } from './semantics.icon'; +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const modalSemantics = { + 'background-default': { light: surfaceSemantics['primary'].light, dark: surfaceSemantics['primary'].dark }, + + 'stroke-bg': { light: strokeSemantics['secondary'].light, dark: strokeSemantics['secondary'].dark }, + + 'text-default': { + light: textSemantics['primary'].light, + dark: textSemantics['primary'].dark, + }, + 'text-secondary': { light: textSemantics['tertiary'].light, dark: textSemantics['tertiary'].dark }, + 'text-link': { light: colorPrimitives['pink-700'], dark: colorPrimitives['pink-400'] }, + + 'icon-success': { light: colorPrimitives['green-400'], dark: colorPrimitives['green-300'] }, + 'icon-error': { light: colorPrimitives['red-700'], dark: colorPrimitives['red-600'] }, + 'icon-warning': { light: colorPrimitives['yellow-400'], dark: colorPrimitives['yellow-300'] }, + 'icon-info': { light: colorPrimitives['blue-600'], dark: colorPrimitives['blue-500'] }, + 'icon-default': { light: iconSemantics['primary'].light, dark: iconSemantics['primary'].dark }, + 'icon-secondary': { light: iconSemantics['secondary'].light, dark: iconSemantics['secondary'].dark }, +}; diff --git a/blocks/theme/semantics/semantics.progress-bar.ts b/blocks/theme/semantics/semantics.progress-bar.ts new file mode 100644 index 0000000..a8cf427 --- /dev/null +++ b/blocks/theme/semantics/semantics.progress-bar.ts @@ -0,0 +1,6 @@ +import { surfaceSemantics } from './semantics.surface'; + +export const progressBarSemantics = { + 'background-default': { light: surfaceSemantics['secondary'].light, dark: surfaceSemantics['secondary'].dark }, + 'background-progress': { light: surfaceSemantics['brand-medium'].light, dark: surfaceSemantics['brand-medium'].dark }, +}; diff --git a/blocks/theme/semantics/semantics.radio.ts b/blocks/theme/semantics/semantics.radio.ts new file mode 100644 index 0000000..7e00931 --- /dev/null +++ b/blocks/theme/semantics/semantics.radio.ts @@ -0,0 +1,19 @@ +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const radioSemantics = { + 'background-default': { light: surfaceSemantics['primary'].light, dark: surfaceSemantics['primary'].dark }, + 'background-selected': { light: surfaceSemantics['brand-medium'].light, dark: surfaceSemantics['brand-medium'].dark }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-secondary': { light: textSemantics['secondary'].light, dark: textSemantics['secondary'].dark }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + + 'stroke-default': { light: strokeSemantics['brand-medium'].light, dark: strokeSemantics['brand-medium'].dark }, + 'stroke-disabled': { light: strokeSemantics['state-disabled'].light, dark: strokeSemantics['state-disabled'].dark }, +}; diff --git a/blocks/theme/semantics/semantics.skeleton.ts b/blocks/theme/semantics/semantics.skeleton.ts new file mode 100644 index 0000000..30a7095 --- /dev/null +++ b/blocks/theme/semantics/semantics.skeleton.ts @@ -0,0 +1,12 @@ +import { colorBrands } from '../colors/colors.brands'; + +export const skeletonSemantics = { + 'gradient-light': { + light: colorBrands['neutral-200'], + dark: colorBrands['neutral-800'], + }, + 'gradient-dark': { + light: colorBrands['neutral-300'], + dark: colorBrands['neutral-700'], + }, +}; diff --git a/blocks/theme/semantics/semantics.spinner.ts b/blocks/theme/semantics/semantics.spinner.ts new file mode 100644 index 0000000..785380a --- /dev/null +++ b/blocks/theme/semantics/semantics.spinner.ts @@ -0,0 +1,6 @@ +import { colorBrands } from '../colors/colors.brands'; + +export const spinnerSemantics = { + 'icon-default': { light: colorBrands['primary-500'], dark: colorBrands['primary-500'] }, + 'icon-secondary': { light: colorBrands['neutral-1000'], dark: colorBrands['neutral-100'] }, +}; diff --git a/blocks/theme/semantics/semantics.stroke.ts b/blocks/theme/semantics/semantics.stroke.ts new file mode 100644 index 0000000..67e0282 --- /dev/null +++ b/blocks/theme/semantics/semantics.stroke.ts @@ -0,0 +1,31 @@ +import { colorBrands } from '../colors/colors.brands'; + +export const strokeSemantics = { + primary: { light: colorBrands['neutral-100'], dark: colorBrands['neutral-900'] }, + secondary: { light: colorBrands['neutral-200'], dark: colorBrands['neutral-800'] }, + tertiary: { light: colorBrands['neutral-300'], dark: colorBrands['neutral-700'] }, + + 'brand-subtle': { light: colorBrands['primary-300'], dark: colorBrands['primary-500'] }, + 'brand-medium': { light: colorBrands['primary-500'], dark: colorBrands['primary-400'] }, + 'brand-bold': { light: colorBrands['primary-800'], dark: colorBrands['primary-300'] }, + + // stroke states + + 'state-success-subtle': { light: colorBrands['success-300'], dark: colorBrands['success-500'] }, + 'state-success-bold': { light: colorBrands['success-700'], dark: colorBrands['success-300'] }, + + 'state-info-subtle': { light: colorBrands['info-300'], dark: colorBrands['info-500'] }, + 'state-info-bold': { light: colorBrands['info-700'], dark: colorBrands['info-300'] }, + + 'state-warning-subtle': { light: colorBrands['warning-300'], dark: colorBrands['warning-500'] }, + 'state-warning-bold': { light: colorBrands['warning-700'], dark: colorBrands['warning-300'] }, + + 'state-danger-subtle': { light: colorBrands['danger-300'], dark: colorBrands['danger-500'] }, + 'state-danger-bold': { light: colorBrands['danger-500'], dark: colorBrands['danger-300'] }, + + 'state-hover': { light: colorBrands['success-300'], dark: colorBrands['success-800'] }, + 'state-focus': { light: colorBrands['success-300'], dark: colorBrands['success-300'] }, + + 'state-pressed': { light: colorBrands['info-800'], dark: colorBrands['info-300'] }, + 'state-disabled': { light: colorBrands['info-300'], dark: colorBrands['info-800'] }, +}; diff --git a/blocks/theme/semantics/semantics.surface.ts b/blocks/theme/semantics/semantics.surface.ts new file mode 100644 index 0000000..2930a9c --- /dev/null +++ b/blocks/theme/semantics/semantics.surface.ts @@ -0,0 +1,35 @@ +import { colorBrands } from '../colors/colors.brands'; +import { colorPrimitives } from '../colors/colors.primitives'; + +export const surfaceSemantics = { + primary: { light: colorPrimitives['white-100'], dark: colorBrands['neutral-900'] }, + secondary: { light: colorBrands['neutral-100'], dark: colorBrands['neutral-1000'] }, + tertiary: { light: colorBrands['neutral-200'], dark: colorBrands['neutral-800'] }, + + 'primary-inverse': { light: colorPrimitives['black-100'], dark: colorPrimitives['white-100'] }, + + 'brand-subtle': { light: colorBrands['primary-200'], dark: colorBrands['primary-300'] }, + 'brand-medium': { light: colorBrands['primary-600'], dark: colorBrands['primary-500'] }, + 'brand-bold': { light: colorBrands['primary-700'], dark: colorBrands['primary-200'] }, + + 'glass-subtle': { light: colorPrimitives['white-80'], dark: colorPrimitives['black-80'] }, + 'glass-bold': { light: colorPrimitives['white-50'], dark: colorPrimitives['black-50'] }, + + transparent: { light: colorPrimitives['transparent'], dark: colorPrimitives['transparent'] }, + + // surface states + + 'state-success-subtle': { light: colorBrands['success-100'], dark: colorBrands['success-500'] }, + 'state-success-bold': { light: colorBrands['success-500'], dark: colorBrands['success-200'] }, + + 'state-info-subtle': { light: colorBrands['info-100'], dark: colorBrands['info-500'] }, + 'state-info-bold': { light: colorBrands['info-500'], dark: colorBrands['info-200'] }, + + 'state-warning-subtle': { light: colorBrands['warning-100'], dark: colorBrands['warning-500'] }, + 'state-warning-bold': { light: colorBrands['warning-500'], dark: colorBrands['warning-200'] }, + + 'state-danger-subtle': { light: colorBrands['danger-100'], dark: colorBrands['danger-800'] }, + 'state-danger-bold': { light: colorBrands['danger-500'], dark: colorBrands['danger-200'] }, + + 'state-disabled': { light: colorBrands['neutral-200'], dark: colorBrands['neutral-800'] }, +}; diff --git a/blocks/theme/semantics/semantics.switch.ts b/blocks/theme/semantics/semantics.switch.ts new file mode 100644 index 0000000..10868a8 --- /dev/null +++ b/blocks/theme/semantics/semantics.switch.ts @@ -0,0 +1,22 @@ +import { colorBrands } from '../colors/colors.brands'; +import { colorPrimitives } from '../colors/colors.primitives'; +import { iconSemantics } from './semantics.icon'; +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; + +export const switchSemantics = { + 'background-selected': { light: colorBrands['primary-600'], dark: colorBrands['primary-600'] }, + 'background-unselected': { light: colorBrands['neutral-300'], dark: colorBrands['neutral-800'] }, + 'background-hover': { light: colorBrands['primary-500'], dark: colorBrands['primary-500'] }, + 'background-focus': { light: colorBrands['primary-500'], dark: colorBrands['primary-600'] }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + + 'icon-default': { light: colorPrimitives['white-100'], dark: colorPrimitives['white-100'] }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, + + 'stroke-focus': { light: colorBrands['primary-300'], dark: colorBrands['primary-500'] }, + 'stroke-default': { light: strokeSemantics['tertiary'].light, dark: strokeSemantics['tertiary'].dark }, +}; diff --git a/blocks/theme/semantics/semantics.text.ts b/blocks/theme/semantics/semantics.text.ts new file mode 100644 index 0000000..f59a2f9 --- /dev/null +++ b/blocks/theme/semantics/semantics.text.ts @@ -0,0 +1,35 @@ +import { colorBrands } from '../colors/colors.brands'; +import { colorPrimitives } from '../colors/colors.primitives'; + +export const textSemantics = { + primary: { light: colorBrands['neutral-1000'], dark: colorBrands['neutral-100'] }, + secondary: { light: colorBrands['neutral-800'], dark: colorBrands['neutral-300'] }, + tertiary: { light: colorBrands['neutral-500'], dark: colorBrands['neutral-600'] }, + + 'primary-inverse': { light: colorPrimitives['white-100'], dark: colorPrimitives['black-100'] }, + 'secondary-inverse': { light: colorBrands['neutral-400'], dark: colorBrands['neutral-700'] }, + 'tertiary-inverse': { light: colorBrands['neutral-600'], dark: colorBrands['neutral-500'] }, + + 'brand-subtle': { light: colorBrands['primary-200'], dark: colorBrands['primary-200'] }, + 'brand-medium': { light: colorBrands['primary-600'], dark: colorBrands['primary-400'] }, + 'brand-bold': { light: colorBrands['primary-700'], dark: colorBrands['primary-800'] }, + + 'on-light-bg': { light: colorPrimitives['black-100'], dark: colorPrimitives['black-100'] }, + 'on-dark-bg': { light: colorPrimitives['white-100'], dark: colorPrimitives['white-100'] }, + + // text states + + 'state-success-subtle': { light: colorBrands['success-100'], dark: colorBrands['success-700'] }, + 'state-success-bold': { light: colorBrands['success-500'], dark: colorBrands['success-300'] }, + + 'state-info-subtle': { light: colorBrands['info-100'], dark: colorBrands['info-700'] }, + 'state-info-bold': { light: colorBrands['info-700'], dark: colorBrands['info-100'] }, + + 'state-warning-subtle': { light: colorBrands['warning-100'], dark: colorBrands['warning-700'] }, + 'warning-bold': { light: colorBrands['warning-700'], dark: colorBrands['warning-100'] }, + + 'state-danger-subtle': { light: colorBrands['danger-100'], dark: colorBrands['danger-700'] }, + 'state-danger-bold': { light: colorBrands['danger-700'], dark: colorBrands['danger-300'] }, + + 'state-disabled': { light: colorBrands['neutral-400'], dark: colorBrands['neutral-700'] }, +}; diff --git a/blocks/theme/semantics/semantics.textarea.ts b/blocks/theme/semantics/semantics.textarea.ts new file mode 100644 index 0000000..8948357 --- /dev/null +++ b/blocks/theme/semantics/semantics.textarea.ts @@ -0,0 +1,45 @@ +import { colorBrands } from '../colors/colors.brands'; +import { colorPrimitives } from '../colors/colors.primitives'; +import { iconSemantics } from './semantics.icon'; +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const textAreaSemantics = { + 'background-default': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-hover': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-pressed': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-focus': { light: colorPrimitives['white-100'], dark: colorBrands['neutral-800'] }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + 'background-success': { light: colorBrands['success-100'], dark: colorBrands['success-200'] }, + 'background-danger': { light: colorBrands['danger-100'], dark: colorBrands['danger-200'] }, + + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-placeholder': { light: colorBrands['neutral-400'], dark: colorBrands['neutral-600'] }, + 'text-secondary': { light: colorBrands['neutral-600'], dark: colorBrands['neutral-500'] }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + 'text-success': { + light: textSemantics['state-success-bold'].light, + dark: textSemantics['state-success-subtle'].dark, + }, + 'text-danger': { light: textSemantics['state-danger-bold'].light, dark: textSemantics['state-danger-subtle'].dark }, + + 'icon-default': { light: iconSemantics['tertiary'].light, dark: iconSemantics['secondary'].dark }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, + 'icon-success': { + light: iconSemantics['state-success-bold'].light, + dark: iconSemantics['state-success-subtle'].dark, + }, + 'icon-danger': { light: iconSemantics['state-danger-bold'].light, dark: iconSemantics['state-danger-subtle'].dark }, + + 'stroke-default': { light: strokeSemantics['secondary'].light, dark: strokeSemantics['secondary'].dark }, + 'stroke-hover': { light: strokeSemantics['tertiary'].light, dark: strokeSemantics['tertiary'].dark }, + 'stroke-focus': { light: colorBrands['primary-300'], dark: colorBrands['primary-300'] }, + 'stroke-pressed': { light: strokeSemantics['tertiary'].light, dark: strokeSemantics['tertiary'].dark }, + 'stroke-disabled': { light: colorBrands['neutral-300'], dark: colorBrands['neutral-900'] }, + 'stroke-success': { light: colorBrands['success-500'], dark: colorBrands['success-400'] }, + 'stroke-danger': { light: colorBrands['danger-400'], dark: colorBrands['danger-400'] }, +}; diff --git a/blocks/theme/semantics/semantics.toast.ts b/blocks/theme/semantics/semantics.toast.ts new file mode 100644 index 0000000..41cb839 --- /dev/null +++ b/blocks/theme/semantics/semantics.toast.ts @@ -0,0 +1,35 @@ +import { colorBrands } from '../colors/colors.brands'; +import { colorPrimitives } from '../colors/colors.primitives'; +import { iconSemantics } from './semantics.icon'; +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const toastSemantics = { + 'background-default': { light: surfaceSemantics['primary'].light, dark: surfaceSemantics['primary'].dark }, + 'background-success': { light: colorPrimitives['white-100'], dark: surfaceSemantics['state-success-bold'].dark }, + 'background-warning': { + light: surfaceSemantics['state-danger-bold'].light, + dark: surfaceSemantics['state-danger-bold'].dark, + }, + 'background-error': { + light: surfaceSemantics['state-warning-bold'].light, + dark: surfaceSemantics['state-warning-bold'].dark, + }, + 'background-info': { + light: surfaceSemantics['state-info-bold'].light, + dark: surfaceSemantics['state-info-bold'].dark, + }, + + 'stroke-bg': { light: strokeSemantics['secondary'].light, dark: strokeSemantics['secondary'].dark }, + + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-secondary': { light: textSemantics['secondary'].light, dark: textSemantics['secondary'].dark }, + 'text-link': { light: colorPrimitives['pink-700'], dark: colorPrimitives['pink-400'] }, + + 'icon-success': { light: colorPrimitives['green-400'], dark: colorBrands['success-300'] }, + 'icon-warning': { light: colorPrimitives['red-700'], dark: colorBrands['danger-600'] }, + 'icon-error': { light: colorPrimitives['yellow-400'], dark: colorBrands['warning-300'] }, + 'icon-info': { light: colorPrimitives['blue-600'], dark: colorBrands['info-500'] }, + 'icon-default': { light: iconSemantics['primary'].light, dark: iconSemantics['primary'].dark }, +}; diff --git a/blocks/theme/semantics/semantics.tooltip.ts b/blocks/theme/semantics/semantics.tooltip.ts new file mode 100644 index 0000000..8cd53e7 --- /dev/null +++ b/blocks/theme/semantics/semantics.tooltip.ts @@ -0,0 +1,8 @@ +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const tooltipSemantics = { + 'background-default': { light: surfaceSemantics['primary'].light, dark: surfaceSemantics['primary'].dark }, + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-primary': { light: textSemantics['secondary'].light, dark: textSemantics['secondary'].dark }, +}; diff --git a/blocks/theme/variables/variables.blur.ts b/blocks/theme/variables/variables.blur.ts new file mode 100644 index 0000000..01a25d1 --- /dev/null +++ b/blocks/theme/variables/variables.blur.ts @@ -0,0 +1,8 @@ +export const blurVariables = { + 'blur-xs': '8px', + 'blur-sm': '16px', + 'blur-md': '24px', + 'blur-lg': '40px', + 'blur-xl': '72px', + 'blur-xxl': '128px', +}; diff --git a/blocks/theme/variables/variables.borderRadius.ts b/blocks/theme/variables/variables.borderRadius.ts new file mode 100644 index 0000000..63d1ff0 --- /dev/null +++ b/blocks/theme/variables/variables.borderRadius.ts @@ -0,0 +1,13 @@ +export const borderRadiusVariables = { + 'radius-none': '0px', + 'radius-xxxs': '4px', + 'radius-xxs': '8px', + 'radius-xs': '12px', + 'radius-sm': '16px', + 'radius-md': '24px', + 'radius-lg': '32px', + 'radius-xl': '40px', + 'radius-xxl': '48px', + 'radius-xxxl': '64px', + 'radius-round': '1000px', +}; diff --git a/blocks/theme/variables/variables.borderSize.ts b/blocks/theme/variables/variables.borderSize.ts new file mode 100644 index 0000000..574f3a4 --- /dev/null +++ b/blocks/theme/variables/variables.borderSize.ts @@ -0,0 +1,8 @@ +export const borderSizeVariables = { + 'border-xs': '0.5px', + 'border-sm': '1px', + 'border-xmd': '1.5px', + 'border-md': '2px', + 'border-lg': '3px', + 'border-xl': '4px', +}; diff --git a/blocks/theme/variables/variables.opacity.ts b/blocks/theme/variables/variables.opacity.ts new file mode 100644 index 0000000..e41d086 --- /dev/null +++ b/blocks/theme/variables/variables.opacity.ts @@ -0,0 +1,13 @@ +export const opacityVariables = { + 'opacity-0': '0', + 'opacity-10': '0.1', + 'opacity-20': '0.2', + 'opacity-30': '0.3', + 'opacity-40': '0.4', + 'opacity-50': '0.5', + 'opacity-60': '0.6', + 'opacity-70': '0.7', + 'opacity-80': '0.8', + 'opacity-90': '0.9', + 'opacity-100': '1', +}; diff --git a/blocks/theme/variables/variables.spacing.ts b/blocks/theme/variables/variables.spacing.ts new file mode 100644 index 0000000..2108365 --- /dev/null +++ b/blocks/theme/variables/variables.spacing.ts @@ -0,0 +1,12 @@ +export const spacingVariables = { + 'spacing-none': '0px', + 'spacing-xxxs': '4px', + 'spacing-xxs': '8px', + 'spacing-xs': '12px', + 'spacing-sm': '16px', + 'spacing-md': '24px', + 'spacing-lg': '32px', + 'spacing-xl': '40px', + 'spacing-xxl': '48px', + 'spacing-xxxl': '64px', +}; diff --git a/blocks/toggleSwtich/ToggleSwitch.tsx b/blocks/toggleSwtich/ToggleSwitch.tsx new file mode 100644 index 0000000..035bda6 --- /dev/null +++ b/blocks/toggleSwtich/ToggleSwitch.tsx @@ -0,0 +1,127 @@ +import React from 'react'; + +import styled, { FlattenSimpleInterpolation } from 'styled-components'; +import * as Switch from '@radix-ui/react-switch'; + +import { TextVariants, textVariants } from '../text'; +import { ThemeColors } from 'blocks/theme/Theme.types'; + +export type ToggleSwitchProps = { + /* Additional prop from styled components to apply custom css to Toggle switch */ + css?: FlattenSimpleInterpolation; + /* Label for the toggle switch */ + label?: string; + /* Description for the toggle switch */ + description?: string; + /* Sets toggle switch as disabled */ + disabled?: boolean; + /* Render the toggle before text contents */ + leadingToggle?: boolean; + /* Sets toggle switch to checked */ + checked: boolean; + /* Function invoked when toggle switch is clicked*/ + onCheckedChange: (checked: boolean) => void; +}; + +const StyledToggleRoot = styled(Switch.Root)` + width: 38px; + height: 20px; + padding: 3px; + background-color: var(--components-toggle-switch-background-unselected); + border-radius: var(--radius-md); + position: relative; + &[data-state='checked'] { + background-color: var(--components-toggle-switch-background-selected); + } + &:disabled { + cursor: not-allowed; + background: var(--components-toggle-switch-background-disabled); + span { + background: var(--components-toggle-switch-icon-disabled); + } + } +`; +const StyledToggleThumb = styled(Switch.Thumb)` + display: block; + cursor: pointer; + width: 14px; + height: 14px; + background-color: var(--components-toggle-switch-icon-default); + border-radius: var(--radius-round); + transition: transform 100ms; + will-change: transform; + &[data-state='checked'] { + transform: translateX(17.5px); + } +`; + +const Container = styled.div<{ css?: FlattenSimpleInterpolation; flexDirection: string }>` + display: flex; + flex-direction: ${({ flexDirection }) => flexDirection || ''}; + gap: var(--spacing-xxs); + justifycontent: space-between; + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''}; +`; + +const LabelContainer = styled.div` + display: flex; + align-items: flex-start; + flex-direction: column; +`; +const TextContainer = styled.p<{ variant: TextVariants; color: ThemeColors }>` + margin: 0; + color: ${({ color }) => color}; + ${({ variant }) => + `font-family: var(--font-family); + font-size: ${textVariants[variant].fontSize}; + font-style: ${textVariants[variant].fontStyle}; + font-weight: ${textVariants[variant].fontWeight}; + line-height: ${textVariants[variant].lineHeight};`} +`; +const ToggleSwitch: React.FC = ({ + label, + description, + disabled = false, + onCheckedChange, + leadingToggle = true, + checked, +}) => { + return ( + + + + + {(label || description) && ( + + {label && ( + + {label} + + )} + {description && ( + + {description} + + )} + + )} + + ); +}; + +ToggleSwitch.displayName = 'ToggleSwitch'; + +export { ToggleSwitch }; diff --git a/blocks/toggleSwtich/index.ts b/blocks/toggleSwtich/index.ts new file mode 100644 index 0000000..05bf93c --- /dev/null +++ b/blocks/toggleSwtich/index.ts @@ -0,0 +1 @@ +export { ToggleSwitch, type ToggleSwitchProps } from './ToggleSwitch'; diff --git a/blocks/tooltip/Tooltip.constants.ts b/blocks/tooltip/Tooltip.constants.ts new file mode 100644 index 0000000..518ce26 --- /dev/null +++ b/blocks/tooltip/Tooltip.constants.ts @@ -0,0 +1,10 @@ +import type { TooltipProps } from './Tooltip.types'; + +export const tooltipCSSPropsKeys: (keyof TooltipProps)[] = [ + 'height', + 'maxHeight', + 'minHeight', + 'maxWidth', + 'minWidth', + 'width', +]; diff --git a/blocks/tooltip/Tooltip.tsx b/blocks/tooltip/Tooltip.tsx new file mode 100644 index 0000000..53f6c77 --- /dev/null +++ b/blocks/tooltip/Tooltip.tsx @@ -0,0 +1,122 @@ +import { type FC, useRef, useState } from 'react'; +import styled from 'styled-components'; +import * as RadixTooltip from '@radix-ui/react-tooltip'; +import type { TooltipProps } from './Tooltip.types'; +import { getTooltipPositionalCSS } from './Tooltip.utils'; +import { tooltipCSSPropsKeys } from './Tooltip.constants'; +import { useIsVisible } from '../../common'; +import { textVariants } from '../text'; + +const RadixTooltipContent = styled(RadixTooltip.Content).withConfig({ + shouldForwardProp: (prop) => !tooltipCSSPropsKeys.includes(prop as keyof TooltipProps), +})` + /* Tooltip default styles */ + display: flex; + flex-direction: column; + gap: var(--s1); + padding: var(--s2); + border-radius: var(--r3); + font-family: var(--font-family); + word-wrap: break-word; + color: var(--text-primary-inverse); + background-color: var(--surface-primary-inverse); + + /* Tooltip non-responsive styles */ + width: ${({ width }) => width}; + min-width: ${({ minWidth }) => minWidth}; + max-width: ${({ maxWidth }) => maxWidth}; + height: ${({ height }) => height}; + min-height: ${({ minHeight }) => minHeight}; + max-height: ${({ maxHeight }) => maxHeight}; + + ${(props) => props.css || ''}; +`; + +const StyledTitle = styled.span` + color: var(--text-primary-inverse); + font-family: var(--font-family); + font-size: ${textVariants['c-semibold'].fontSize}; + font-style: ${textVariants['c-semibold'].fontStyle}; + font-weight: ${textVariants['c-semibold'].fontWeight}; + line-height: ${textVariants['c-semibold'].lineHeight}; +`; + +const StyledDescription = styled.span` + color: var(--text-primary-inverse); + font-family: var(--font-family); + font-size: ${textVariants['c-regular'].fontSize}; + font-style: ${textVariants['c-regular'].fontStyle}; + font-weight: ${textVariants['c-regular'].fontWeight}; + line-height: ${textVariants['c-regular'].lineHeight}; +`; + +const Tooltip: FC = ({ + width = 'max-content', + maxWidth = '274px', + trigger = 'hover', + tooltipPosition = 'top-right', + children, + description, + title, + overlay, + ...props +}) => { + const [visible, setVisible] = useState(false); + const triggerRef = useRef(null); + + const showTooltip = () => setVisible(true); + const hideTooltip = () => setVisible(false); + + const onVisibilityChange = (isVisible: boolean) => { + if (!isVisible) hideTooltip(); + }; + + const isInView = useIsVisible(triggerRef, onVisibilityChange); + + const { style, ...cssProps } = getTooltipPositionalCSS(tooltipPosition); + const triggerArray = typeof trigger === 'string' ? [trigger] : trigger; + + return ( + + + triggerArray.includes('hover') && showTooltip()} + onMouseLeave={() => triggerArray.includes('hover') && hideTooltip()} + onClick={showTooltip} + onFocus={showTooltip} + onBlur={hideTooltip} + /* Makes the element focusable to support focus related functions on mobile devices */ + tabIndex={0} + > + {children} + + + + {overlay ? ( + overlay + ) : ( + <> + {title && {title}} + {description && {description}} + + )} + + + + + ); +}; + +Tooltip.displayName = 'Tooltip'; + +export { Tooltip }; diff --git a/blocks/tooltip/Tooltip.types.ts b/blocks/tooltip/Tooltip.types.ts new file mode 100644 index 0000000..a44753d --- /dev/null +++ b/blocks/tooltip/Tooltip.types.ts @@ -0,0 +1,42 @@ +import type { ReactNode } from 'react'; + +import type { FlattenSimpleInterpolation } from 'styled-components'; +import type { TooltipContentProps } from '@radix-ui/react-tooltip'; + +export type TooltipNonResponsiveProps = { + /* Sets height css property */ + height?: string; + /* Sets max-height css property */ + maxHeight?: string; + /* Sets min-height css property */ + minHeight?: string; + /* Sets max-width css property */ + maxWidth?: string; + /* Sets min-width css property */ + minWidth?: string; + /* Sets width css property */ + width?: string; +}; + +export type TooltipPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'; + +export type TooltipTrigger = 'hover' | 'click'; + +export type TooltipComponentProps = { + /* Additional prop from styled components to apply custom css to Tooltip */ + css?: FlattenSimpleInterpolation; + /* Child react nodes rendered by Tooltip */ + children?: ReactNode; + /* Overlay content component of the Tooltip */ + overlay?: ReactNode; + /* Title of the Tooltip */ + title?: string; + /* Description to be displayed in the tooltip */ + description?: string; + /* Position of the Tooltip */ + tooltipPosition?: TooltipPosition; + /* Trigger for the Tooltip to open */ + trigger?: TooltipTrigger | Array; +}; + +export type TooltipProps = TooltipNonResponsiveProps & TooltipComponentProps & TooltipContentProps; diff --git a/blocks/tooltip/Tooltip.utils.ts b/blocks/tooltip/Tooltip.utils.ts new file mode 100644 index 0000000..d1c4420 --- /dev/null +++ b/blocks/tooltip/Tooltip.utils.ts @@ -0,0 +1,49 @@ +import { CSSProperties } from 'react'; +import type { TooltipPosition } from './Tooltip.types'; +import { TooltipContentProps } from '@radix-ui/react-tooltip'; + +export const getTooltipPositionalCSS = (tooltipPosition: TooltipPosition) => { + let style: { + align: TooltipContentProps['align']; + side: TooltipContentProps['side']; + style: CSSProperties; + } = { + align: 'start', + side: 'top', + style: { + borderBottomLeftRadius: 4, + }, + }; + + switch (tooltipPosition) { + case 'bottom-left': + style = { + align: 'end', + side: 'bottom', + style: { + borderTopRightRadius: 4, + }, + }; + break; + case 'top-left': + style = { + align: 'end', + side: 'top', + style: { + borderBottomRightRadius: 4, + }, + }; + break; + case 'bottom-right': + style = { + align: 'start', + side: 'bottom', + style: { + borderTopLeftRadius: 4, + }, + }; + break; + } + + return style; +}; diff --git a/blocks/tooltip/index.ts b/blocks/tooltip/index.ts new file mode 100644 index 0000000..61d73f7 --- /dev/null +++ b/blocks/tooltip/index.ts @@ -0,0 +1,4 @@ +export * from './Tooltip'; +export * from './Tooltip.types'; +export * from './Tooltip.utils'; +export * from './Tooltip.constants'; diff --git a/common/hooks/index.ts b/common/hooks/index.ts new file mode 100644 index 0000000..7bbc6ac --- /dev/null +++ b/common/hooks/index.ts @@ -0,0 +1,2 @@ +export { useIsVisible } from './useIsVisible'; +// export { usePushStakingStats } from './usePushStakingStats'; diff --git a/common/hooks/useIsVisible.ts b/common/hooks/useIsVisible.ts new file mode 100644 index 0000000..59e4122 --- /dev/null +++ b/common/hooks/useIsVisible.ts @@ -0,0 +1,24 @@ +import { RefObject, useEffect, useMemo, useState } from 'react'; + +export const useIsVisible = (ref: RefObject, onChange?: (isVisible: boolean) => void) => { + const [isVisible, setIsVisible] = useState(false); + + const observer = useMemo( + () => + new IntersectionObserver(([entry]) => { + setIsVisible(entry.isIntersecting); + onChange?.(entry.isIntersecting); + }), + [ref] + ); + + useEffect(() => { + if (ref.current) observer.observe(ref.current); + + return () => { + if (ref.current) observer.unobserve(ref.current); + }; + }, []); + + return isVisible; +}; diff --git a/common/index.ts b/common/index.ts new file mode 100644 index 0000000..abd99c5 --- /dev/null +++ b/common/index.ts @@ -0,0 +1 @@ +export * from './hooks'; \ No newline at end of file diff --git a/components/Home/LiveBlocks/index.tsx b/components/Home/LiveBlocks/index.tsx new file mode 100644 index 0000000..90bd20b --- /dev/null +++ b/components/Home/LiveBlocks/index.tsx @@ -0,0 +1,93 @@ +// React, NextJS imports +import React from 'react'; +import Image from 'next/image'; + +// External Library imports +import { useTheme } from 'styled-components'; +import { useMediaQuery } from '@mui/material'; + +// Internal Components imports +import { OverviewItem } from './liveblocks.styles'; +import { Text } from '../../Reusables/SharedStyling'; +import { useTheme as getTheme } from '../../../contexts/ThemeContext'; +import { ItemHV2, ItemVV2 } from '../../Reusables/SharedStyling'; +import { ThemeType } from '../../../types/theme'; + +export default function LiveBlocks() { + const isMobile = useMediaQuery('(max-width:480px)'); + const { isDarkMode } = getTheme(); + + const theme = useTheme() as ThemeType; + + const overViewData = [ + { + title: 'Push Integrations', + value: 534, + size: 60, + }, + { + title: 'Chats Sent', + value: 44, + size: 51, + }, + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + ]; + + return ( + + + Live Blocks + + + + BLOCK HASH + VALIDATOR + TX + AGE + + + {overViewData.map((data, index) => ( + + 0xjhd..dd5325 + 0xj3d..dd325 + 878 + 4s ago + + ))} + + ) +} diff --git a/components/Home/LiveBlocks/liveblocks.styles.ts b/components/Home/LiveBlocks/liveblocks.styles.ts new file mode 100644 index 0000000..560b4d5 --- /dev/null +++ b/components/Home/LiveBlocks/liveblocks.styles.ts @@ -0,0 +1,17 @@ +// External Library imports +import styled from 'styled-components'; + +export const OverviewItem = styled.div` + border-radius: 28px; + padding: ${props => props.padding || '25px 30px 22px 40px'}; + display: flex; + flex: 1 1 0; + justify-content: space-between; + align-items: center; + height: 114px; + min-width: 285px; + @media (max-width: 480px) { + margin-bottom: 0px; + width: 100%; + } +`; diff --git a/components/Home/LiveTransactions/index.tsx b/components/Home/LiveTransactions/index.tsx new file mode 100644 index 0000000..76cfe3a --- /dev/null +++ b/components/Home/LiveTransactions/index.tsx @@ -0,0 +1,95 @@ +// React, NextJS imports +import React from 'react'; +import Image from 'next/image'; + +// External Library imports +import { useTheme } from 'styled-components'; +import { useMediaQuery, useScrollTrigger } from '@mui/material'; + +// Internal Components imports +import { OverviewItem } from './livetransactions.styles'; +import { Text } from '../../Reusables/SharedStyling'; +import { useTheme as getTheme } from '../../../contexts/ThemeContext'; +import { ItemHV2, ItemVV2 } from '../../Reusables/SharedStyling'; +import { ThemeType } from '../../../types/theme'; +import { OverviewLoader } from '../../Loader/OverviewLoader'; + +export default function LiveBlocks() { + const isMobile = useMediaQuery('(max-width:480px)'); + const { isDarkMode } = getTheme(); + + const theme = useTheme() as ThemeType; + + const overViewData = [ + { + title: 'Push Integrations', + value: 534, + size: 60, + }, + { + title: 'Chats Sent', + value: 44, + size: 51, + }, + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + ]; + + return ( + + + Live Transactions + + + + STATUS + TX HASH + FROM + TO + AGE + + {overViewData.map((data, index) => ( + + SUCCESS + 0xw34..5h33 + 0xd324..45h54 + 0xd32..h54 + 2s ago + + ))} + + ) +} diff --git a/components/Home/LiveTransactions/livetransactions.styles.ts b/components/Home/LiveTransactions/livetransactions.styles.ts new file mode 100644 index 0000000..560b4d5 --- /dev/null +++ b/components/Home/LiveTransactions/livetransactions.styles.ts @@ -0,0 +1,17 @@ +// External Library imports +import styled from 'styled-components'; + +export const OverviewItem = styled.div` + border-radius: 28px; + padding: ${props => props.padding || '25px 30px 22px 40px'}; + display: flex; + flex: 1 1 0; + justify-content: space-between; + align-items: center; + height: 114px; + min-width: 285px; + @media (max-width: 480px) { + margin-bottom: 0px; + width: 100%; + } +`; diff --git a/components/Home/OverViewSet/index.tsx b/components/Home/OverViewSet/index.tsx new file mode 100644 index 0000000..6a4ee0f --- /dev/null +++ b/components/Home/OverViewSet/index.tsx @@ -0,0 +1,69 @@ +// React, NextJS imports +import React from 'react'; +import Image from 'next/image'; + +// External Library imports +import { useTheme } from 'styled-components'; +import { useMediaQuery, useScrollTrigger } from '@mui/material'; + +// Internal Components imports +import { OverviewItem } from './overview.styles'; +import { Text } from '../../Reusables/SharedStyling'; +import { useData } from '../../../contexts/DataContext'; +import { useTheme as getTheme } from '../../../contexts/ThemeContext'; +import { ItemHV2, ItemVV2 } from '../../Reusables/SharedStyling'; +import { ThemeType } from '../../../types/theme'; +import { OverviewLoader } from '../../Loader/OverviewLoader'; + +export default function OverViewSet() { + const isMobile = useMediaQuery('(max-width:480px)'); + const { isDarkMode } = getTheme(); + + const theme = useTheme() as ThemeType; + + const overViewData = [ + { + title: 'Push Integrations', + value: 534, + size: 60, + }, + { + title: 'Chats Sent', + value: 44, + size: 51, + }, + { + title: 'Notifications Sent', + value: 333, + size: 41, + }, + ]; + + return ( + + + {overViewData.map((data, index) => ( + + + ))} + + + ) +} diff --git a/components/Home/OverViewSet/overview.styles.ts b/components/Home/OverViewSet/overview.styles.ts new file mode 100644 index 0000000..560b4d5 --- /dev/null +++ b/components/Home/OverViewSet/overview.styles.ts @@ -0,0 +1,17 @@ +// External Library imports +import styled from 'styled-components'; + +export const OverviewItem = styled.div` + border-radius: 28px; + padding: ${props => props.padding || '25px 30px 22px 40px'}; + display: flex; + flex: 1 1 0; + justify-content: space-between; + align-items: center; + height: 114px; + min-width: 285px; + @media (max-width: 480px) { + margin-bottom: 0px; + width: 100%; + } +`; diff --git a/components/Home/Search/index.tsx b/components/Home/Search/index.tsx new file mode 100644 index 0000000..6d10621 --- /dev/null +++ b/components/Home/Search/index.tsx @@ -0,0 +1,63 @@ +// React, NextJS imports +import React from 'react'; +import Image from 'next/image'; + +// External Library imports +import { useTheme } from 'styled-components'; +import { useMediaQuery, useScrollTrigger } from '@mui/material'; + +// Internal Components imports +import { SearchItem } from './search.styles'; +import { Text } from '../../Reusables/SharedStyling'; +import { useData } from '../../../contexts/DataContext'; +import { useTheme as getTheme } from '../../../contexts/ThemeContext'; +import { ItemVV2 } from '../../Reusables/SharedStyling'; +import { ThemeType } from '../../../types/theme'; +import { OverviewLoader } from '../../Loader/OverviewLoader'; + +export default function Search() { + const { + pushIntegrations, + setChatSent, + setChatUsers, + setNotificationsSent, + chatSent, + notifiactionsSent, + overViewLoading, + setOverviewLoading, + } = useData(); + const { isDarkMode } = getTheme(); + const isMobile = useMediaQuery('(max-width:480px)'); + + const theme = useTheme() as ThemeType; + + return ( + + + Push Blockchain Explorer + + + {/* + + + { + if (timeOutRef.current) clearTimeout(timeOutRef.current); + timeOutRef.current = setTimeout(() => { + setSearchInputValue(e.target.value); + }, 500); + }} + type="text" + placeholder="Search..." + /> + + + */} + + + ); +} diff --git a/components/Home/Search/search.styles.ts b/components/Home/Search/search.styles.ts new file mode 100644 index 0000000..d965fda --- /dev/null +++ b/components/Home/Search/search.styles.ts @@ -0,0 +1,17 @@ +// External Library imports +import styled from 'styled-components'; + +export const SearchItem = styled.div` + border-radius: 28px; + padding: ${props => props.padding || '25px 30px 22px 40px'}; + display: flex; + flex: 1 1 0; + justify-content: space-between; + align-items: center; + height: 114px; + min-width: 285px; + @media (max-width: 480px) { + margin-bottom: 0px; + width: 100%; + } +`; diff --git a/components/Loader/HomeLoader.tsx b/components/Loader/HomeLoader.tsx new file mode 100644 index 0000000..114793b --- /dev/null +++ b/components/Loader/HomeLoader.tsx @@ -0,0 +1,28 @@ +// React, NextJS imports +import React from 'react'; + +// External Library imports +import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; +import 'react-loading-skeleton/dist/skeleton.css'; +import styled, { useTheme } from 'styled-components'; +import { Grid } from '@mui/material'; + +// Internal Components imports +import { ItemVV2, ItemHV2 } from '../Reusables/SharedStyling'; +import { DashBoardContainer } from '../Reusables/SharedStyling'; +import { ThemeType } from '../../types/theme'; + +export const HomeLoader = () => { + const theme = useTheme() as ThemeType; + + return ( + + + + + + ); +}; \ No newline at end of file diff --git a/components/Reusables/SharedStyling/index.ts b/components/Reusables/SharedStyling/index.ts index f52bb3a..08bb26d 100644 --- a/components/Reusables/SharedStyling/index.ts +++ b/components/Reusables/SharedStyling/index.ts @@ -247,6 +247,20 @@ export const DashBoardContainer = styled(ItemVV2)` } `; +export const HomeContainer = styled(ItemVV2)` + width: 100%; + height: auto; + justify-content: flex-start; + + @media (min-width: 310px) { + padding: 0px 24px !important; + } + @media (min-width: 1024px) { + padding: 0px 70px !important; + } +`; + + export const Text = styled.p` font-size: ${(props) => props.size || '15px'}; font-weight: ${(props) => props.weight || 400}; diff --git a/package-lock.json b/package-lock.json index 4ada826..8ee14e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,10 @@ "@emotion/styled": "^11.10.5", "@mui/icons-material": "^5.10.9", "@mui/material": "^5.10.12", + "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-dropdown-menu": "^2.1.1", + "@radix-ui/react-switch": "^1.1.0", + "@radix-ui/react-tooltip": "^1.1.1", "apexcharts": "^3.36.3", "axios": "^1.1.3", "date-fns": "^2.29.3", @@ -2190,6 +2194,40 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", + "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", + "dependencies": { + "@floating-ui/utils": "^0.2.5" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", + "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.5" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", + "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -2809,27 +2847,648 @@ "node": ">= 8" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.6", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", + "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", + "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", + "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz", + "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.7" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", + "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz", + "integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-menu": "2.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz", + "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", + "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-menu": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz", + "integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.7" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", + "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz", + "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", + "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", + "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.0.tgz", + "integrity": "sha512-OBzy5WAj641k0AOSpKQtreDMe+isX0MQJ1IVyF03ucdF3DunOnROVrjWs8zsXUxC3zfZ6JL9HFVCUlMghz9dJw==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz", + "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "dependencies": { + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", + "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "@radix-ui/react-primitive": "2.0.0" }, - "engines": { - "node": ">= 8" + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@popperjs/core": { - "version": "2.11.6", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", - "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" }, "node_modules/@react-native-community/cli": { "version": "9.2.1", @@ -3505,7 +4164,7 @@ "version": "18.0.8", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.8.tgz", "integrity": "sha512-C3GYO0HLaOkk9dDAz3Dl4sbe4AKUGTCfFIZsz3n/82dPNN8Du533HzKatDxeUYWu24wJgMP1xICqkWk1YOLOIw==", - "dev": true, + "devOptional": true, "dependencies": { "@types/react": "*" } @@ -3838,6 +4497,17 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/aria-query": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", @@ -5081,6 +5751,11 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -6409,6 +7084,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -6833,7 +7516,6 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "peer": true, "dependencies": { "loose-envify": "^1.0.0" } @@ -9703,6 +10385,51 @@ "node": ">=0.10.0" } }, + "node_modules/react-remove-scroll": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz", + "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.4", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", + "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-shallow-renderer": { "version": "16.15.0", "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", @@ -9865,6 +10592,28 @@ "object-assign": "^4.1.1" } }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-toastify": { "version": "9.0.8", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.8.tgz", @@ -11927,6 +12676,47 @@ "node": ">=0.10.0" } }, + "node_modules/use-callback-ref": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", + "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", @@ -13768,6 +14558,36 @@ "strip-json-comments": "^3.1.1" } }, + "@floating-ui/core": { + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", + "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", + "requires": { + "@floating-ui/utils": "^0.2.5" + } + }, + "@floating-ui/dom": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", + "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", + "requires": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.5" + } + }, + "@floating-ui/react-dom": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", + "requires": { + "@floating-ui/dom": "^1.0.0" + } + }, + "@floating-ui/utils": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", + "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" + }, "@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -14117,6 +14937,307 @@ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz", "integrity": "sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==" }, + "@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + }, + "@radix-ui/react-arrow": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", + "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "requires": { + "@radix-ui/react-primitive": "2.0.0" + } + }, + "@radix-ui/react-collection": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", + "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "requires": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" + } + }, + "@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "requires": {} + }, + "@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "requires": {} + }, + "@radix-ui/react-dialog": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz", + "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==", + "requires": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.7" + } + }, + "@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "requires": {} + }, + "@radix-ui/react-dismissable-layer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", + "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", + "requires": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + } + }, + "@radix-ui/react-dropdown-menu": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz", + "integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==", + "requires": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-menu": "2.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + } + }, + "@radix-ui/react-focus-guards": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz", + "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==", + "requires": {} + }, + "@radix-ui/react-focus-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", + "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", + "requires": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0" + } + }, + "@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "requires": { + "@radix-ui/react-use-layout-effect": "1.1.0" + } + }, + "@radix-ui/react-menu": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz", + "integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==", + "requires": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.7" + } + }, + "@radix-ui/react-popper": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", + "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "requires": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + } + }, + "@radix-ui/react-portal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz", + "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==", + "requires": { + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + } + }, + "@radix-ui/react-presence": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", + "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", + "requires": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + } + }, + "@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "requires": { + "@radix-ui/react-slot": "1.1.0" + } + }, + "@radix-ui/react-roving-focus": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", + "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", + "requires": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + } + }, + "@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "requires": { + "@radix-ui/react-compose-refs": "1.1.0" + } + }, + "@radix-ui/react-switch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.0.tgz", + "integrity": "sha512-OBzy5WAj641k0AOSpKQtreDMe+isX0MQJ1IVyF03ucdF3DunOnROVrjWs8zsXUxC3zfZ6JL9HFVCUlMghz9dJw==", + "requires": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + } + }, + "@radix-ui/react-tooltip": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz", + "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==", + "requires": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.0" + } + }, + "@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "requires": {} + }, + "@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "requires": { + "@radix-ui/react-use-callback-ref": "1.1.0" + } + }, + "@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "requires": { + "@radix-ui/react-use-callback-ref": "1.1.0" + } + }, + "@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "requires": {} + }, + "@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "requires": {} + }, + "@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "requires": { + "@radix-ui/rect": "1.1.0" + } + }, + "@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "requires": { + "@radix-ui/react-use-layout-effect": "1.1.0" + } + }, + "@radix-ui/react-visually-hidden": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", + "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", + "requires": { + "@radix-ui/react-primitive": "2.0.0" + } + }, + "@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" + }, "@react-native-community/cli": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-9.2.1.tgz", @@ -14684,7 +15805,7 @@ "version": "18.0.8", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.8.tgz", "integrity": "sha512-C3GYO0HLaOkk9dDAz3Dl4sbe4AKUGTCfFIZsz3n/82dPNN8Du533HzKatDxeUYWu24wJgMP1xICqkWk1YOLOIw==", - "dev": true, + "devOptional": true, "requires": { "@types/react": "*" } @@ -14935,6 +16056,14 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "requires": { + "tslib": "^2.0.0" + } + }, "aria-query": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", @@ -15883,6 +17012,11 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "peer": true }, + "detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -16926,6 +18060,11 @@ "has-symbols": "^1.0.3" } }, + "get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -17239,7 +18378,6 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "peer": true, "requires": { "loose-envify": "^1.0.0" } @@ -19472,6 +20610,27 @@ "integrity": "sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA==", "peer": true }, + "react-remove-scroll": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz", + "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==", + "requires": { + "react-remove-scroll-bar": "^2.3.4", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + } + }, + "react-remove-scroll-bar": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz", + "integrity": "sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==", + "requires": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + } + }, "react-shallow-renderer": { "version": "16.15.0", "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", @@ -19604,6 +20763,16 @@ } } }, + "react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "requires": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + } + }, "react-toastify": { "version": "9.0.8", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.8.tgz", @@ -21215,6 +22384,23 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "peer": true }, + "use-callback-ref": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz", + "integrity": "sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==", + "requires": { + "tslib": "^2.0.0" + } + }, + "use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "requires": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + } + }, "use-sync-external-store": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", diff --git a/package.json b/package.json index a2bf206..72e828b 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,12 @@ "react-toastify": "^9.0.8", "react-toggle-dark-mode": "^1.1.0", "react-use": "^17.4.0", + "react-router-dom": "^6.9.0", + "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-dropdown-menu": "^2.1.1", + "@radix-ui/react-switch": "^1.1.0", + "@radix-ui/react-tooltip": "^1.1.1", + "@reach/tabs": "^0.18.0", "styled-components": "^5.3.6" }, "devDependencies": { diff --git a/pages/home/index.tsx b/pages/home/index.tsx new file mode 100644 index 0000000..9f9bbd9 --- /dev/null +++ b/pages/home/index.tsx @@ -0,0 +1,26 @@ +// React, NextJS imports +import React from 'react'; +import Head from 'next/head'; +import dynamic from 'next/dynamic'; + +// Internal Components imports +import { HomeLoader } from '../../components/Loader/HomeLoader'; + +const HomeView = dynamic(() => import('../../sections/Home'), { + loading: () => , +}); + +const Layout = dynamic(() => import('../../layout')); + +export default function Home() { + return ( + <> + + Push Scan + + + + + + ); +} diff --git a/pages/index.tsx b/pages/index.tsx index eada268..a7837ee 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -7,7 +7,9 @@ import { ROUTES } from '../utils/constants'; export default function Home() { const router = useRouter(); + useEffect(() => { router.push(ROUTES.DASHBOARD, undefined, { shallow: true }); - }); + router.push(ROUTES.HOME, undefined, { shallow: true }); + }, [router]); } diff --git a/sections/Home/home.styles.ts b/sections/Home/home.styles.ts new file mode 100644 index 0000000..e69de29 diff --git a/sections/Home/index.tsx b/sections/Home/index.tsx new file mode 100644 index 0000000..5649e53 --- /dev/null +++ b/sections/Home/index.tsx @@ -0,0 +1,38 @@ +// React, NextJS imports +import React from 'react'; + +// External Library imports +import { Grid, useMediaQuery } from '@mui/material'; + +// Internal Components imports +import { + HomeContainer +} from '../../components/Reusables/SharedStyling'; +import Search from '../../components/Home/Search'; +import LiveBlocks from '../../components/Home/LiveBlocks'; +import LiveTransactions from '../../components/Home/LiveTransactions'; +import OverViewSet from '../../components/Home/OverViewSet'; + +import { Box, Skeleton, Text } from '../../blocks'; + +const Home = () => { + const isMobile = useMediaQuery('(max-width:480px)'); + return ( + + + + + + + + + ); +}; + +export default Home; \ No newline at end of file diff --git a/theme/globalStyles.ts b/theme/globalStyles.ts index ddaeae1..cef2cd1 100644 --- a/theme/globalStyles.ts +++ b/theme/globalStyles.ts @@ -1,5 +1,6 @@ // External Library imports import { createGlobalStyle } from 'styled-components'; +import { blocksColors, getBlocksCSSVariables } from '../blocks'; export const GlobalStyles = createGlobalStyle` @font-face { @@ -27,7 +28,7 @@ export const GlobalStyles = createGlobalStyle` font-family: 'Strawford', Helvetica, sans-serif; transition: all 0.2s linear; } - *{ - + :root { + ${(props) => getBlocksCSSVariables(props.theme.blocksTheme)} } `; diff --git a/theme/palette.ts b/theme/palette.ts index 1743750..800f7d7 100644 --- a/theme/palette.ts +++ b/theme/palette.ts @@ -1,8 +1,12 @@ // Define what props.theme will look like +import { blocksTheme } from '../blocks/theme/Theme'; export const themeLight = { scheme: 'light', + // theme for the new blocks design system + blocksTheme: blocksTheme.light, + // Default Background Theme defaultBG: '#FFFFFF', @@ -64,7 +68,9 @@ export const themeLight = { export const themeDark = { scheme: 'dark', - + // theme for the new blocks design system + blocksTheme: blocksTheme.dark, + // Default Background Theme defaultBG: '#2F3137', diff --git a/utils/constants.js b/utils/constants.js index 0f2c32d..a5be05c 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -9,7 +9,7 @@ import FuseIcon from '../public/static/fuse.svg'; import CyberIcon from '../public/static/cyber.svg'; export const ROUTES = { - HOME: '/', + HOME: '/home', LOGIN: '/login', ERROR: '*', ADMIN: '/admin', diff --git a/yarn.lock b/yarn.lock index 5cdd25e..2fad001 100644 --- a/yarn.lock +++ b/yarn.lock @@ -277,6 +277,33 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@floating-ui/core@^1.6.0": + version "1.6.5" + resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz" + integrity sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA== + dependencies: + "@floating-ui/utils" "^0.2.5" + +"@floating-ui/dom@^1.0.0": + version "1.6.8" + resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz" + integrity sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q== + dependencies: + "@floating-ui/core" "^1.6.0" + "@floating-ui/utils" "^0.2.5" + +"@floating-ui/react-dom@^2.0.0": + version "2.1.1" + resolved "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz" + integrity sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg== + dependencies: + "@floating-ui/dom" "^1.0.0" + +"@floating-ui/utils@^0.2.5": + version "0.2.5" + resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz" + integrity sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ== + "@humanwhocodes/config-array@^0.11.6": version "0.11.6" resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.6.tgz" @@ -445,7 +472,7 @@ "@next/swc-darwin-arm64@13.0.0": version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.0.0.tgz#caf262fb5cb8bb335f6f344fd67a44dc8bf6a084" + resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.0.0.tgz" integrity sha512-APA26nps1j4qyhOIzkclW/OmgotVHj1jBxebSpMCPw2rXfiNvKNY9FA0TcuwPmUCNqaTnm703h6oW4dvp73A4Q== "@next/swc-darwin-x64@13.0.0": @@ -495,7 +522,7 @@ "@next/swc-win32-x64-msvc@13.0.0": version "13.0.0" - resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.0.0.tgz" + resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.0.0.tgz#c54a5a739dee04b20338d305226a2acdf701f67f" integrity sha512-FFOGGWwTCRMu9W7MF496Urefxtuo2lttxF1vwS+1rIRsKvuLrWhVaVTj3T8sf2EBL6gtJbmh4TYlizS+obnGKA== "@nodelib/fs.scandir@2.1.5": @@ -524,6 +551,313 @@ resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz" integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw== +"@radix-ui/primitive@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz" + integrity sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA== + +"@radix-ui/react-arrow@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz" + integrity sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw== + dependencies: + "@radix-ui/react-primitive" "2.0.0" + +"@radix-ui/react-collection@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz" + integrity sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-slot" "1.1.0" + +"@radix-ui/react-compose-refs@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz" + integrity sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw== + +"@radix-ui/react-context@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz" + integrity sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A== + +"@radix-ui/react-dialog@^1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz" + integrity sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-dismissable-layer" "1.1.0" + "@radix-ui/react-focus-guards" "1.1.0" + "@radix-ui/react-focus-scope" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-portal" "1.1.1" + "@radix-ui/react-presence" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-slot" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.7" + +"@radix-ui/react-direction@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz" + integrity sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg== + +"@radix-ui/react-dismissable-layer@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz" + integrity sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + "@radix-ui/react-use-escape-keydown" "1.1.0" + +"@radix-ui/react-dropdown-menu@^2.1.1": + version "2.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz" + integrity sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-menu" "2.1.1" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + +"@radix-ui/react-focus-guards@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz" + integrity sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw== + +"@radix-ui/react-focus-scope@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz" + integrity sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + +"@radix-ui/react-id@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz" + integrity sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-menu@2.1.1": + version "2.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz" + integrity sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-collection" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-direction" "1.1.0" + "@radix-ui/react-dismissable-layer" "1.1.0" + "@radix-ui/react-focus-guards" "1.1.0" + "@radix-ui/react-focus-scope" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-popper" "1.2.0" + "@radix-ui/react-portal" "1.1.1" + "@radix-ui/react-presence" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-roving-focus" "1.1.0" + "@radix-ui/react-slot" "1.1.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.7" + +"@radix-ui/react-popper@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz" + integrity sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg== + dependencies: + "@floating-ui/react-dom" "^2.0.0" + "@radix-ui/react-arrow" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + "@radix-ui/react-use-layout-effect" "1.1.0" + "@radix-ui/react-use-rect" "1.1.0" + "@radix-ui/react-use-size" "1.1.0" + "@radix-ui/rect" "1.1.0" + +"@radix-ui/react-portal@1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz" + integrity sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g== + dependencies: + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-presence@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz" + integrity sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-primitive@2.0.0": + version "2.0.0" + resolved "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz" + integrity sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw== + dependencies: + "@radix-ui/react-slot" "1.1.0" + +"@radix-ui/react-roving-focus@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz" + integrity sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-collection" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-direction" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-callback-ref" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + +"@radix-ui/react-slot@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz" + integrity sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw== + dependencies: + "@radix-ui/react-compose-refs" "1.1.0" + +"@radix-ui/react-switch@^1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.0.tgz" + integrity sha512-OBzy5WAj641k0AOSpKQtreDMe+isX0MQJ1IVyF03ucdF3DunOnROVrjWs8zsXUxC3zfZ6JL9HFVCUlMghz9dJw== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + "@radix-ui/react-use-previous" "1.1.0" + "@radix-ui/react-use-size" "1.1.0" + +"@radix-ui/react-tooltip@^1.1.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz" + integrity sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w== + dependencies: + "@radix-ui/primitive" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.0" + "@radix-ui/react-context" "1.1.0" + "@radix-ui/react-dismissable-layer" "1.1.0" + "@radix-ui/react-id" "1.1.0" + "@radix-ui/react-popper" "1.2.0" + "@radix-ui/react-portal" "1.1.1" + "@radix-ui/react-presence" "1.1.0" + "@radix-ui/react-primitive" "2.0.0" + "@radix-ui/react-slot" "1.1.0" + "@radix-ui/react-use-controllable-state" "1.1.0" + "@radix-ui/react-visually-hidden" "1.1.0" + +"@radix-ui/react-use-callback-ref@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz" + integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw== + +"@radix-ui/react-use-controllable-state@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz" + integrity sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.0" + +"@radix-ui/react-use-escape-keydown@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz" + integrity sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.0" + +"@radix-ui/react-use-layout-effect@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz" + integrity sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w== + +"@radix-ui/react-use-previous@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz" + integrity sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og== + +"@radix-ui/react-use-rect@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz" + integrity sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ== + dependencies: + "@radix-ui/rect" "1.1.0" + +"@radix-ui/react-use-size@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz" + integrity sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.0" + +"@radix-ui/react-visually-hidden@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz" + integrity sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ== + dependencies: + "@radix-ui/react-primitive" "2.0.0" + +"@radix-ui/rect@1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz" + integrity sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg== + +"@reach/auto-id@0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@reach/auto-id/-/auto-id-0.18.0.tgz#4b97085cd1cf1360a9bedc6e9c78e97824014f0d" + integrity sha512-XwY1IwhM7mkHZFghhjiqjQ6dstbOdpbFLdggeke75u8/8icT8uEHLbovFUgzKjy9qPvYwZIB87rLiR8WdtOXCg== + dependencies: + "@reach/utils" "0.18.0" + +"@reach/descendants@0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@reach/descendants/-/descendants-0.18.0.tgz#16fe52a5154da262994b0b8768baff4f670922d1" + integrity sha512-GXUxnM6CfrX5URdnipPIl3Tlc6geuz4xb4n61y4tVWXQX1278Ra9Jz9DMRN8x4wheHAysvrYwnR/SzAlxQzwtA== + dependencies: + "@reach/utils" "0.18.0" + +"@reach/polymorphic@0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@reach/polymorphic/-/polymorphic-0.18.0.tgz#2fe42007a774e06cdbc8e13e0d46f2dc30f2f1ed" + integrity sha512-N9iAjdMbE//6rryZZxAPLRorzDcGBnluf7YQij6XDLiMtfCj1noa7KyLpEc/5XCIB/EwhX3zCluFAwloBKdblA== + +"@reach/tabs@^0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@reach/tabs/-/tabs-0.18.0.tgz#f2e789d445d61a371eace9415841502729d099c9" + integrity sha512-gTRJzStWJJtgMhn9FDEmKogAJMcqNaGZx0i1SGoTdVM+D29DBhVeRdO8qEg+I2l2k32DkmuZxG/Mrh+GZTjczQ== + dependencies: + "@reach/auto-id" "0.18.0" + "@reach/descendants" "0.18.0" + "@reach/polymorphic" "0.18.0" + "@reach/utils" "0.18.0" + +"@reach/utils@0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.18.0.tgz#4f3cebe093dd436eeaff633809bf0f68f4f9d2ee" + integrity sha512-KdVMdpTgDyK8FzdKO9SCpiibuy/kbv3pwgfXshTI6tEcQT1OOwj7BAksnzGC0rPz0UholwC+AgkqEl3EJX3M1A== + "@react-spring/animated@~9.5.5": version "9.5.5" resolved "https://registry.npmjs.org/@react-spring/animated/-/animated-9.5.5.tgz" @@ -610,6 +944,11 @@ "@react-spring/shared" "~9.5.5" "@react-spring/types" "~9.5.5" +"@remix-run/router@1.19.0": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.19.0.tgz#745dbffbce67f05386d57ca22c51dfd85c979593" + integrity sha512-zDICCLKEwbVYTS6TjYaWtHXxkdoUvD/QXvyVZjGCsWz5vyH7aFeONlPffPdW+Y/t6KT0MgXb2Mfjun9YpWN1dA== + "@rushstack/eslint-patch@^1.1.3": version "1.2.0" resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz" @@ -809,6 +1148,13 @@ argparse@^2.0.1: resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +aria-hidden@^1.1.1: + version "1.2.4" + resolved "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz" + integrity sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A== + dependencies: + tslib "^2.0.0" + aria-query@^4.2.2: version "4.2.2" resolved "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz" @@ -1133,6 +1479,11 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" @@ -1596,6 +1947,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@ has "^1.0.3" has-symbols "^1.0.3" +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" @@ -1772,6 +2128,13 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" +invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" @@ -1985,7 +2348,7 @@ lodash@^4.17.11, lodash@^4.17.21: resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -2338,6 +2701,40 @@ react-loading-skeleton@^3.3.1: resolved "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.3.1.tgz" integrity sha512-NilqqwMh2v9omN7LteiDloEVpFyMIa0VGqF+ukqp0ncVlYu1sKYbYGX9JEl+GtOT9TKsh04zCHAbavnQ2USldA== +react-remove-scroll-bar@^2.3.4: + version "2.3.6" + resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz" + integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g== + dependencies: + react-style-singleton "^2.2.1" + tslib "^2.0.0" + +react-remove-scroll@2.5.7: + version "2.5.7" + resolved "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz" + integrity sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA== + dependencies: + react-remove-scroll-bar "^2.3.4" + react-style-singleton "^2.2.1" + tslib "^2.1.0" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" + +react-router-dom@^6.9.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.26.0.tgz#8debe13295c58605c04f93018d659a763245e58c" + integrity sha512-RRGUIiDtLrkX3uYcFiCIxKFWMcWQGMojpYZfcstc63A1+sSnVgILGIm9gNUA6na3Fm1QuPGSBQH2EMbAZOnMsQ== + dependencies: + "@remix-run/router" "1.19.0" + react-router "6.26.0" + +react-router@6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.26.0.tgz#d5af4c46835b202348ef2b7ddacd32a2db539fde" + integrity sha512-wVQq0/iFYd3iZ9H2l3N3k4PL8EEHcb0XlU2Na8nEwmiXgIUElEH6gaJDtUQxJ+JFzmIXaQjfdpcGWaM6IoQGxg== + dependencies: + "@remix-run/router" "1.19.0" + react-spring@^9.0.0-rc.3: version "9.5.5" resolved "https://registry.npmjs.org/react-spring/-/react-spring-9.5.5.tgz" @@ -2350,6 +2747,15 @@ react-spring@^9.0.0-rc.3: "@react-spring/web" "~9.5.5" "@react-spring/zdog" "~9.5.5" +react-style-singleton@^2.2.1: + version "2.2.1" + resolved "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz" + integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== + dependencies: + get-nonce "^1.0.0" + invariant "^2.2.4" + tslib "^2.0.0" + react-toastify@^9.0.8: version "9.0.8" resolved "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.8.tgz" @@ -2815,7 +3221,7 @@ tslib@^1.8.1: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.1.0, tslib@^2.4.0: +tslib@^2.0.0, tslib@^2.1.0, tslib@^2.4.0: version "2.4.0" resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== @@ -2861,6 +3267,21 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +use-callback-ref@^1.3.0: + version "1.3.2" + resolved "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz" + integrity sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA== + dependencies: + tslib "^2.0.0" + +use-sidecar@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz" + integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== + dependencies: + detect-node-es "^1.1.0" + tslib "^2.0.0" + use-sync-external-store@1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" From 4c2c33cde9dbee1c0d16e3ca368f54d10903a548 Mon Sep 17 00:00:00 2001 From: rozaso Date: Tue, 6 Aug 2024 18:09:00 -0700 Subject: [PATCH 02/42] Landing page and transaction details pages UI. --- blocks/icons/Icons.types.ts | 2 +- blocks/textInput/TextInput.tsx | 2 +- blocks/theme/variables/variables.spacing.ts | 1 + common/hooks/index.ts | 3 +- .../Home/BlocksContainer/LiveBlocks/index.tsx | 137 +++++++++ .../LiveBlocks/liveblocks.styles.ts | 0 .../LiveTransactions/index.tsx | 148 ++++++++++ .../livetransactions.styles.ts | 0 .../blocks.styles.ts} | 0 components/Home/BlocksContainer/index.tsx | 34 +++ components/Home/LiveBlocks/index.tsx | 93 ------- components/Home/LiveTransactions/index.tsx | 95 ------- components/Home/OverViewSet/index.tsx | 69 ----- components/Home/Search/index.tsx | 63 ----- .../Home/SearchContainer/OverViewSet.tsx | 71 +++++ components/Home/SearchContainer/SearchBar.tsx | 62 +++++ components/Home/SearchContainer/index.tsx | 41 +++ .../search.styles.ts} | 2 +- components/Loader/HomeLoader.tsx | 3 - components/Loader/TransactionLoader.tsx | 22 ++ components/Navbar/index.tsx | 13 + components/Reusables/SharedStyling/index.ts | 14 - index.html | 37 +++ package.json | 13 +- pages/index.tsx | 3 + pages/transactions/index.tsx | 26 ++ sections/Home/index.tsx | 42 +-- sections/Transactions/index.tsx | 259 ++++++++++++++++++ theme/Theme.tsx | 1 + theme/palette.ts | 4 +- utils/constants.js | 4 +- yarn.lock | 55 +++- 32 files changed, 936 insertions(+), 383 deletions(-) create mode 100644 components/Home/BlocksContainer/LiveBlocks/index.tsx rename components/Home/{ => BlocksContainer}/LiveBlocks/liveblocks.styles.ts (100%) create mode 100644 components/Home/BlocksContainer/LiveTransactions/index.tsx rename components/Home/{ => BlocksContainer}/LiveTransactions/livetransactions.styles.ts (100%) rename components/Home/{Search/search.styles.ts => BlocksContainer/blocks.styles.ts} (100%) create mode 100644 components/Home/BlocksContainer/index.tsx delete mode 100644 components/Home/LiveBlocks/index.tsx delete mode 100644 components/Home/LiveTransactions/index.tsx delete mode 100644 components/Home/OverViewSet/index.tsx delete mode 100644 components/Home/Search/index.tsx create mode 100644 components/Home/SearchContainer/OverViewSet.tsx create mode 100644 components/Home/SearchContainer/SearchBar.tsx create mode 100644 components/Home/SearchContainer/index.tsx rename components/Home/{OverViewSet/overview.styles.ts => SearchContainer/search.styles.ts} (89%) create mode 100644 components/Loader/TransactionLoader.tsx create mode 100644 index.html create mode 100644 pages/transactions/index.tsx create mode 100644 sections/Transactions/index.tsx diff --git a/blocks/icons/Icons.types.ts b/blocks/icons/Icons.types.ts index 371e88a..32beb37 100644 --- a/blocks/icons/Icons.types.ts +++ b/blocks/icons/Icons.types.ts @@ -1,4 +1,4 @@ -import { IconColors } from 'blocks/theme/Theme.types'; +import { IconColors } from './../../blocks/theme/Theme.types'; export type IconProps = { /** Set icon fill color from design system */ diff --git a/blocks/textInput/TextInput.tsx b/blocks/textInput/TextInput.tsx index 3e3f75f..6dd72e1 100644 --- a/blocks/textInput/TextInput.tsx +++ b/blocks/textInput/TextInput.tsx @@ -182,7 +182,6 @@ export const TextInput = forwardRef( success={success} > - {icon} ( onChange={onChange} value={value} /> + {icon} {onClear && onClear?.()} />} diff --git a/blocks/theme/variables/variables.spacing.ts b/blocks/theme/variables/variables.spacing.ts index 2108365..a54f984 100644 --- a/blocks/theme/variables/variables.spacing.ts +++ b/blocks/theme/variables/variables.spacing.ts @@ -9,4 +9,5 @@ export const spacingVariables = { 'spacing-xl': '40px', 'spacing-xxl': '48px', 'spacing-xxxl': '64px', + 'spacing-xxxxl': '120px', }; diff --git a/common/hooks/index.ts b/common/hooks/index.ts index 7bbc6ac..d81bc37 100644 --- a/common/hooks/index.ts +++ b/common/hooks/index.ts @@ -1,2 +1 @@ -export { useIsVisible } from './useIsVisible'; -// export { usePushStakingStats } from './usePushStakingStats'; +export { useIsVisible } from './useIsVisible'; \ No newline at end of file diff --git a/components/Home/BlocksContainer/LiveBlocks/index.tsx b/components/Home/BlocksContainer/LiveBlocks/index.tsx new file mode 100644 index 0000000..4b5f30e --- /dev/null +++ b/components/Home/BlocksContainer/LiveBlocks/index.tsx @@ -0,0 +1,137 @@ +// React, NextJS imports +import React from 'react'; + +// External Library imports +import { useTheme } from 'styled-components'; +import { Divider, useMediaQuery } from '@mui/material'; +import { ThemeType } from '../../../../types/theme'; + +// Internal Components imports +import { OverviewItem } from './liveblocks.styles'; +import { useTheme as getTheme } from '../../../../contexts/ThemeContext'; +import { Box, Text, ArrowUpRight } from '../../../../blocks'; + +export default function LiveBlocks() { + const isMobile = useMediaQuery('(max-width:480px)'); + const { isDarkMode } = getTheme(); + + const theme = useTheme() as ThemeType; + + const overViewData = [ + { + blockHash: '0556ba4acd62f....', + validator: '0556b...96e5659bf', + tx: 460, + age: '2s ago' + }, + { + blockHash: '0556ba4acd62f....', + validator: '0556b...96e5659bf', + tx: 660, + age: '6s ago' + }, + { + blockHash: '0556ba4acd62f....', + validator: '0556b...96e5659bf', + tx: 660, + age: '9s ago' + }, + { + blockHash: '0556ba4acd62f....', + validator: '0556b...96e5659bf', + tx: 605, + age: '2m ago' + }, + { + blockHash: '0556ba4acd62f....', + validator: '0556b...96e5659bf', + tx: 60, + age: '33m ago' + }, + { + blockHash: '0556ba4acd62f....', + validator: '0556b...96e5659bf', + tx: 234, + age: '45m ago' + }, + + { + blockHash: '0556ba4acd62f....', + validator: '0556b...96e5659bf', + tx: 2, + age: '48m ago' + }, + { + blockHash: '0556ba4acd62f....', + validator: '0556b...96e5659bf', + tx: 789, + age: '52m ago' + }, + ]; + + return ( + + + Live Blocks + + + BLOCK HASH + VALIDATOR + TX + AGE + + {overViewData.map((dt) => + + + {dt.blockHash} + {dt.validator} + {dt.tx} + {dt.age} + + + + )} + + + + View All Blocks + + + + ) +} diff --git a/components/Home/LiveBlocks/liveblocks.styles.ts b/components/Home/BlocksContainer/LiveBlocks/liveblocks.styles.ts similarity index 100% rename from components/Home/LiveBlocks/liveblocks.styles.ts rename to components/Home/BlocksContainer/LiveBlocks/liveblocks.styles.ts diff --git a/components/Home/BlocksContainer/LiveTransactions/index.tsx b/components/Home/BlocksContainer/LiveTransactions/index.tsx new file mode 100644 index 0000000..fbbdf66 --- /dev/null +++ b/components/Home/BlocksContainer/LiveTransactions/index.tsx @@ -0,0 +1,148 @@ +// React, NextJS imports +import React from 'react'; + +// External Library imports +import { useTheme } from 'styled-components'; +import { Divider, useMediaQuery } from '@mui/material'; +import { ThemeType } from '../../../../types/theme'; + +// Internal Components imports +import { useTheme as getTheme } from '../../../../contexts/ThemeContext'; +import { Box, Text, ArrowUpRight } from '../../../../blocks'; + +export default function LiveTransactions() { + const isMobile = useMediaQuery('(max-width:480px)'); + const { isDarkMode } = getTheme(); + + const theme = useTheme() as ThemeType; + + const overViewData = [ + { + status: "Success", + txHash: '0556ba4acd62f....', + from: '0556b...96e5659bf', + to: '0556b...96e5659bf', + age: '2s ago' + }, + { + status: "Success", + txHash: '0556ba4acd62f....', + from: '0556b...96e5659bf', + to: '0556b...96e5659bf', + age: '2s ago' + }, + { + status: "Success", + txHash: '0556ba4acd62f....', + from: '0556b...96e5659bf', + to: '0556b...96e5659bf', + age: '2s ago' + }, + { + status: "Success", + txHash: '0556ba4acd62f....', + from: '0556b...96e5659bf', + to: '0556b...96e5659bf', + age: '2s ago' + }, + { + status: "Success", + txHash: '0556ba4acd62f....', + from: '0556b...96e5659bf', + to: '0556b...96e5659bf', + age: '2s ago' + }, + { + status: "Success", + txHash: '0556ba4acd62f....', + from: '0556b...96e5659bf', + to: '0556b...96e5659bf', + age: '2s ago' + }, + { + status: "Success", + txHash: '0556ba4acd62f....', + from: '0556b...96e5659bf', + to: '0556b...96e5659bf', + age: '2s ago' + }, + { + status: "Success", + txHash: '0556ba4acd62f....', + from: '0556b...96e5659bf', + to: '0556b...96e5659bf', + age: '2s ago' + }, + ]; + + return ( + + + Live Transactions + + + STATUS + Tx HASH + FROM + TO + AGE + + {overViewData.map((dt) => + + + {dt.status} + {dt.txHash} + {dt.from} + {dt.to} + {dt.age} + + + + + + )} + + + + View All Transactions + + + + ) +} diff --git a/components/Home/LiveTransactions/livetransactions.styles.ts b/components/Home/BlocksContainer/LiveTransactions/livetransactions.styles.ts similarity index 100% rename from components/Home/LiveTransactions/livetransactions.styles.ts rename to components/Home/BlocksContainer/LiveTransactions/livetransactions.styles.ts diff --git a/components/Home/Search/search.styles.ts b/components/Home/BlocksContainer/blocks.styles.ts similarity index 100% rename from components/Home/Search/search.styles.ts rename to components/Home/BlocksContainer/blocks.styles.ts diff --git a/components/Home/BlocksContainer/index.tsx b/components/Home/BlocksContainer/index.tsx new file mode 100644 index 0000000..ad84642 --- /dev/null +++ b/components/Home/BlocksContainer/index.tsx @@ -0,0 +1,34 @@ +// React, NextJS imports +import React from 'react'; +import Image from 'next/image'; + +// External Library imports +import { useTheme } from 'styled-components'; +import { useMediaQuery, useScrollTrigger } from '@mui/material'; + +// Internal Components imports +import { useTheme as getTheme } from '../../../contexts/ThemeContext'; +import { ThemeType } from '../../../types/theme'; +import { Box } from '../../../blocks'; +import LiveBlocks from './LiveBlocks' +import LiveTransactions from './LiveTransactions' + +export default function BlocksContainer() { + const { isDarkMode } = getTheme(); + const isMobile = useMediaQuery('(max-width:480px)'); + + const theme = useTheme() as ThemeType; + + return ( + + + + + ); +} diff --git a/components/Home/LiveBlocks/index.tsx b/components/Home/LiveBlocks/index.tsx deleted file mode 100644 index 90bd20b..0000000 --- a/components/Home/LiveBlocks/index.tsx +++ /dev/null @@ -1,93 +0,0 @@ -// React, NextJS imports -import React from 'react'; -import Image from 'next/image'; - -// External Library imports -import { useTheme } from 'styled-components'; -import { useMediaQuery } from '@mui/material'; - -// Internal Components imports -import { OverviewItem } from './liveblocks.styles'; -import { Text } from '../../Reusables/SharedStyling'; -import { useTheme as getTheme } from '../../../contexts/ThemeContext'; -import { ItemHV2, ItemVV2 } from '../../Reusables/SharedStyling'; -import { ThemeType } from '../../../types/theme'; - -export default function LiveBlocks() { - const isMobile = useMediaQuery('(max-width:480px)'); - const { isDarkMode } = getTheme(); - - const theme = useTheme() as ThemeType; - - const overViewData = [ - { - title: 'Push Integrations', - value: 534, - size: 60, - }, - { - title: 'Chats Sent', - value: 44, - size: 51, - }, - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - ]; - - return ( - - - Live Blocks - - - - BLOCK HASH - VALIDATOR - TX - AGE - - - {overViewData.map((data, index) => ( - - 0xjhd..dd5325 - 0xj3d..dd325 - 878 - 4s ago - - ))} - - ) -} diff --git a/components/Home/LiveTransactions/index.tsx b/components/Home/LiveTransactions/index.tsx deleted file mode 100644 index 76cfe3a..0000000 --- a/components/Home/LiveTransactions/index.tsx +++ /dev/null @@ -1,95 +0,0 @@ -// React, NextJS imports -import React from 'react'; -import Image from 'next/image'; - -// External Library imports -import { useTheme } from 'styled-components'; -import { useMediaQuery, useScrollTrigger } from '@mui/material'; - -// Internal Components imports -import { OverviewItem } from './livetransactions.styles'; -import { Text } from '../../Reusables/SharedStyling'; -import { useTheme as getTheme } from '../../../contexts/ThemeContext'; -import { ItemHV2, ItemVV2 } from '../../Reusables/SharedStyling'; -import { ThemeType } from '../../../types/theme'; -import { OverviewLoader } from '../../Loader/OverviewLoader'; - -export default function LiveBlocks() { - const isMobile = useMediaQuery('(max-width:480px)'); - const { isDarkMode } = getTheme(); - - const theme = useTheme() as ThemeType; - - const overViewData = [ - { - title: 'Push Integrations', - value: 534, - size: 60, - }, - { - title: 'Chats Sent', - value: 44, - size: 51, - }, - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - ]; - - return ( - - - Live Transactions - - - - STATUS - TX HASH - FROM - TO - AGE - - {overViewData.map((data, index) => ( - - SUCCESS - 0xw34..5h33 - 0xd324..45h54 - 0xd32..h54 - 2s ago - - ))} - - ) -} diff --git a/components/Home/OverViewSet/index.tsx b/components/Home/OverViewSet/index.tsx deleted file mode 100644 index 6a4ee0f..0000000 --- a/components/Home/OverViewSet/index.tsx +++ /dev/null @@ -1,69 +0,0 @@ -// React, NextJS imports -import React from 'react'; -import Image from 'next/image'; - -// External Library imports -import { useTheme } from 'styled-components'; -import { useMediaQuery, useScrollTrigger } from '@mui/material'; - -// Internal Components imports -import { OverviewItem } from './overview.styles'; -import { Text } from '../../Reusables/SharedStyling'; -import { useData } from '../../../contexts/DataContext'; -import { useTheme as getTheme } from '../../../contexts/ThemeContext'; -import { ItemHV2, ItemVV2 } from '../../Reusables/SharedStyling'; -import { ThemeType } from '../../../types/theme'; -import { OverviewLoader } from '../../Loader/OverviewLoader'; - -export default function OverViewSet() { - const isMobile = useMediaQuery('(max-width:480px)'); - const { isDarkMode } = getTheme(); - - const theme = useTheme() as ThemeType; - - const overViewData = [ - { - title: 'Push Integrations', - value: 534, - size: 60, - }, - { - title: 'Chats Sent', - value: 44, - size: 51, - }, - { - title: 'Notifications Sent', - value: 333, - size: 41, - }, - ]; - - return ( - - - {overViewData.map((data, index) => ( - - - ))} - - - ) -} diff --git a/components/Home/Search/index.tsx b/components/Home/Search/index.tsx deleted file mode 100644 index 6d10621..0000000 --- a/components/Home/Search/index.tsx +++ /dev/null @@ -1,63 +0,0 @@ -// React, NextJS imports -import React from 'react'; -import Image from 'next/image'; - -// External Library imports -import { useTheme } from 'styled-components'; -import { useMediaQuery, useScrollTrigger } from '@mui/material'; - -// Internal Components imports -import { SearchItem } from './search.styles'; -import { Text } from '../../Reusables/SharedStyling'; -import { useData } from '../../../contexts/DataContext'; -import { useTheme as getTheme } from '../../../contexts/ThemeContext'; -import { ItemVV2 } from '../../Reusables/SharedStyling'; -import { ThemeType } from '../../../types/theme'; -import { OverviewLoader } from '../../Loader/OverviewLoader'; - -export default function Search() { - const { - pushIntegrations, - setChatSent, - setChatUsers, - setNotificationsSent, - chatSent, - notifiactionsSent, - overViewLoading, - setOverviewLoading, - } = useData(); - const { isDarkMode } = getTheme(); - const isMobile = useMediaQuery('(max-width:480px)'); - - const theme = useTheme() as ThemeType; - - return ( - - - Push Blockchain Explorer - - - {/* - - - { - if (timeOutRef.current) clearTimeout(timeOutRef.current); - timeOutRef.current = setTimeout(() => { - setSearchInputValue(e.target.value); - }, 500); - }} - type="text" - placeholder="Search..." - /> - - - */} - - - ); -} diff --git a/components/Home/SearchContainer/OverViewSet.tsx b/components/Home/SearchContainer/OverViewSet.tsx new file mode 100644 index 0000000..89b7768 --- /dev/null +++ b/components/Home/SearchContainer/OverViewSet.tsx @@ -0,0 +1,71 @@ +// React, NextJS imports +import React from 'react'; + +// External Library imports +import { useTheme } from 'styled-components'; +import { Divider, useMediaQuery, useScrollTrigger } from '@mui/material'; +import { Box, Text } from '../../../blocks'; + +// Internal Components imports +import { useTheme as getTheme } from '../../../contexts/ThemeContext'; +import { ThemeType } from '../../../types/theme'; +import { HorizontalLine } from '../../Reusables/SharedStyling'; + +export default function OverViewSet() { + + const { isDarkMode } = getTheme(); + const isMobile = useMediaQuery('(max-width:480px)'); + + const theme = useTheme() as ThemeType; + + console.log("theme : ", console.log(theme)) + + return ( + + + Transactions + 245,487,099 + + + + Total Blocks + 16, 793, 950 + + + + Daily Transactions + 142, 098 + + + ) +} diff --git a/components/Home/SearchContainer/SearchBar.tsx b/components/Home/SearchContainer/SearchBar.tsx new file mode 100644 index 0000000..a601757 --- /dev/null +++ b/components/Home/SearchContainer/SearchBar.tsx @@ -0,0 +1,62 @@ +// React, NextJS imports +import React, { useCallback, useState } from 'react'; + +// External Library imports +import { useTheme } from 'styled-components'; +import { useMediaQuery, useScrollTrigger } from '@mui/material'; +import { Box, Text, TextInput, Search } from '../../../blocks'; + +// Internal Components imports +import { useTheme as getTheme } from '../../../contexts/ThemeContext'; +import { ThemeType } from '../../../types/theme'; +import { ethers } from 'ethers'; + +export default function SearchBar() { + + const theme = useTheme() as ThemeType; + const { isDarkMode } = getTheme(); + const isMobile = useMediaQuery('(max-width:480px)'); + + const [query, setQuery] = useState(''); + const [debouncedQuery, setDebouncedQuery] = useState({}); + + const getFormattedQuery = useCallback((qry: string) => { + if (!qry) return {}; + const isAddress = ethers.isAddress(qry); + const key = isAddress ? 'wallet' : 'twitter'; + const value = isAddress ? `eip155:${qry}` : qry; + return { [key]: value }; + }, []); + + + return ( + + Push Blockchain Explorer + + + + } + value={query} + onChange={(e) => setQuery(e.target.value)} + /> + + + ) +} + + + diff --git a/components/Home/SearchContainer/index.tsx b/components/Home/SearchContainer/index.tsx new file mode 100644 index 0000000..402204d --- /dev/null +++ b/components/Home/SearchContainer/index.tsx @@ -0,0 +1,41 @@ +// React, NextJS imports +import React from 'react'; +import Image from 'next/image'; + +// External Library imports +import { useTheme } from 'styled-components'; +import { useMediaQuery, useScrollTrigger } from '@mui/material'; +import { Box } from '../../../blocks'; + +// Internal Components imports +import { SearchItem } from './search.styles'; +import { Text } from '../../Reusables/SharedStyling'; +import { useData } from '../../../contexts/DataContext'; +import { useTheme as getTheme } from '../../../contexts/ThemeContext'; +import { ItemVV2 } from '../../Reusables/SharedStyling'; +import { ThemeType } from '../../../types/theme'; +import { OverviewLoader } from '../../Loader/OverviewLoader'; + +import SearchBar from './SearchBar' +import OverViewSet from './OverViewSet' +export default function SearchContainer() { + + const { isDarkMode } = getTheme(); + const isMobile = useMediaQuery('(max-width:480px)'); + + const theme = useTheme() as ThemeType; + + return ( + + + + + + ) +} diff --git a/components/Home/OverViewSet/overview.styles.ts b/components/Home/SearchContainer/search.styles.ts similarity index 89% rename from components/Home/OverViewSet/overview.styles.ts rename to components/Home/SearchContainer/search.styles.ts index 560b4d5..d965fda 100644 --- a/components/Home/OverViewSet/overview.styles.ts +++ b/components/Home/SearchContainer/search.styles.ts @@ -1,7 +1,7 @@ // External Library imports import styled from 'styled-components'; -export const OverviewItem = styled.div` +export const SearchItem = styled.div` border-radius: 28px; padding: ${props => props.padding || '25px 30px 22px 40px'}; display: flex; diff --git a/components/Loader/HomeLoader.tsx b/components/Loader/HomeLoader.tsx index 114793b..bfd355a 100644 --- a/components/Loader/HomeLoader.tsx +++ b/components/Loader/HomeLoader.tsx @@ -20,9 +20,6 @@ export const HomeLoader = () => { baseColor={theme?.background?.secondary} highlightColor={theme?.background?.default} > - - - ); }; \ No newline at end of file diff --git a/components/Loader/TransactionLoader.tsx b/components/Loader/TransactionLoader.tsx new file mode 100644 index 0000000..ac9339e --- /dev/null +++ b/components/Loader/TransactionLoader.tsx @@ -0,0 +1,22 @@ +// React, NextJS imports +import React from 'react'; + +// External Library imports +import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; +import 'react-loading-skeleton/dist/skeleton.css'; +import styled, { useTheme } from 'styled-components'; + +// Internal Components imports +import { ThemeType } from '../../types/theme'; + +export const TransactionLoader = () => { + const theme = useTheme() as ThemeType; + + return ( + + + ); +}; \ No newline at end of file diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index 1cd7ad6..b3799a6 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -103,6 +103,19 @@ export default function Navbar() { <> {showSidebar && ( + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + Show more + + + + + + + Payload Data + + + 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000006419000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024ac6824ffa0000000000000000000000000000000000000000000000000000000000c2b5a6000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000020d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020d40000000000000000000000000000000000000000000000000000000000c2f8cd0000000000000000000 + + + + + + + + ); +}; + +export default Transactions; \ No newline at end of file diff --git a/theme/Theme.tsx b/theme/Theme.tsx index a0a511c..e620a65 100644 --- a/theme/Theme.tsx +++ b/theme/Theme.tsx @@ -6,6 +6,7 @@ import { ThemeProvider } from 'styled-components'; // Internal Components imports import { themeLight, themeDark } from './palette'; + import { useTheme } from '../contexts/ThemeContext'; import { GlobalStyles } from './globalStyles'; diff --git a/theme/palette.ts b/theme/palette.ts index 800f7d7..055e921 100644 --- a/theme/palette.ts +++ b/theme/palette.ts @@ -72,12 +72,12 @@ export const themeDark = { blocksTheme: blocksTheme.dark, // Default Background Theme - defaultBG: '#2F3137', + defaultBG: '#17181B', headerIconsBg: '#282A2E', background: { - default: '#2F3137', + default: '#17181B', secondary: '#404650', tooltip: '#2F3137', timeFilter: '#404650', diff --git a/utils/constants.js b/utils/constants.js index a5be05c..5db213b 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -11,9 +11,11 @@ import CyberIcon from '../public/static/cyber.svg'; export const ROUTES = { HOME: '/home', LOGIN: '/login', - ERROR: '*', ADMIN: '/admin', DASHBOARD: '/dashboard', + TRANSACTION_DETAILS: '/transactions', + BLOCKS_DETAILS: '/blocks', + ERROR: '*', }; export const DAPP_LINKS = { diff --git a/yarn.lock b/yarn.lock index 2fad001..f59ad07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@adraffy/ens-normalize@1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": version "7.18.6" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz" @@ -525,6 +530,18 @@ resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.0.0.tgz#c54a5a739dee04b20338d305226a2acdf701f67f" integrity sha512-FFOGGWwTCRMu9W7MF496Urefxtuo2lttxF1vwS+1rIRsKvuLrWhVaVTj3T8sf2EBL6gtJbmh4TYlizS+obnGKA== +"@noble/curves@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" + integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== + dependencies: + "@noble/hashes" "1.3.2" + +"@noble/hashes@1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -989,6 +1006,11 @@ resolved "https://registry.npmjs.org/@types/node/-/node-18.11.7.tgz" integrity sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ== +"@types/node@18.15.13": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" @@ -1102,6 +1124,11 @@ acorn@^8.8.0: resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz" integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== +aes-js@4.0.0-beta.5: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" + integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== + ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" @@ -1811,6 +1838,19 @@ esutils@^2.0.2: resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +ethers@^6.13.2: + version "6.13.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.2.tgz#4b67d4b49e69b59893931a032560999e5e4419fe" + integrity sha512-9VkriTTed+/27BGuY1s0hf441kqwHJ1wtN2edksEtiRvXx+soxRX3iSXTfFqq2+YwrOqbDoTHjIhQnjJRlzKmg== + dependencies: + "@adraffy/ens-normalize" "1.10.1" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@types/node" "18.15.13" + aes-js "4.0.0-beta.5" + tslib "2.4.0" + ws "8.17.1" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" @@ -3216,16 +3256,16 @@ tslib@2.3.0: resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== +tslib@2.4.0, tslib@^2.0.0, tslib@^2.1.0, tslib@^2.4.0: + version "2.4.0" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + tslib@^1.8.1: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.1.0, tslib@^2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - tsutils@^3.21.0: version "3.21.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" @@ -3315,6 +3355,11 @@ wrappy@1: resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +ws@8.17.1: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" + integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" From d5c48c28037f6b86b57fd2849ea59732bdb72bbf Mon Sep 17 00:00:00 2001 From: rozaso Date: Tue, 6 Aug 2024 18:39:39 -0700 Subject: [PATCH 03/42] Blocks Details page. --- components/Loader/BlocksLoader.tsx | 22 ++++ pages/blocks/index.tsx | 26 +++++ sections/Blocks/index.tsx | 168 +++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 components/Loader/BlocksLoader.tsx create mode 100644 pages/blocks/index.tsx create mode 100644 sections/Blocks/index.tsx diff --git a/components/Loader/BlocksLoader.tsx b/components/Loader/BlocksLoader.tsx new file mode 100644 index 0000000..744fafb --- /dev/null +++ b/components/Loader/BlocksLoader.tsx @@ -0,0 +1,22 @@ +// React, NextJS imports +import React from 'react'; + +// External Library imports +import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; +import 'react-loading-skeleton/dist/skeleton.css'; +import styled, { useTheme } from 'styled-components'; + +// Internal Components imports +import { ThemeType } from '../../types/theme'; + +export const BlocksLoader = () => { + const theme = useTheme() as ThemeType; + + return ( + + + ); +}; \ No newline at end of file diff --git a/pages/blocks/index.tsx b/pages/blocks/index.tsx new file mode 100644 index 0000000..ef85917 --- /dev/null +++ b/pages/blocks/index.tsx @@ -0,0 +1,26 @@ +// React, NextJS imports +import React from 'react'; +import Head from 'next/head'; +import dynamic from 'next/dynamic'; + +// Internal Components imports +import { BlocksLoader } from '../../components/Loader/BlocksLoader'; + +const BlocksView = dynamic(() => import('../../sections/Blocks'), { + loading: () => , +}); + +const Layout = dynamic(() => import('../../layout')); + +export default function Home() { + return ( + <> + + Push Blocks detail + + + + + + ); +} diff --git a/sections/Blocks/index.tsx b/sections/Blocks/index.tsx new file mode 100644 index 0000000..c6f21e8 --- /dev/null +++ b/sections/Blocks/index.tsx @@ -0,0 +1,168 @@ +// React, NextJS imports +import React from 'react'; +// External Library imports +import { useMediaQuery } from '@mui/material'; +import { Box, Text, Add, CaretDown, Button } from '../../blocks'; + +const Blocks = () => { + const isMobile = useMediaQuery('(max-width:480px)'); + return ( + + Block Details + + + + Block Hash + Validator + Timestamp + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x482741Ab0442755d344Ff8BDbEcc1e7b9BeB2823 + 40 minutes ago, Sun, Jul 21 2024 18:33:47 GMT + + + + + + Transactions + Block Size + + + + 792 + 3,968,000 + + + + + Advanced + + + + + + + Consensus Info + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + Show more + + + + + + + ); +}; + +export default Blocks; \ No newline at end of file From cd96b83bd65a8d0d51470dc7cd8d8a31d41a0251 Mon Sep 17 00:00:00 2001 From: rozaso Date: Tue, 6 Aug 2024 21:20:38 -0700 Subject: [PATCH 04/42] Transactions landing page. --- pages/index.tsx | 5 +- pages/transactions/[address].tsx | 28 ++++ pages/transactions/index.tsx | 2 +- sections/Transactions/address.tsx | 263 ++++++++++++++++++++++++++++++ sections/Transactions/index.tsx | 250 ++++------------------------ utils/constants.js | 3 +- 6 files changed, 330 insertions(+), 221 deletions(-) create mode 100644 pages/transactions/[address].tsx create mode 100644 sections/Transactions/address.tsx diff --git a/pages/index.tsx b/pages/index.tsx index f554f85..5d6ac30 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -11,7 +11,10 @@ export default function Home() { useEffect(() => { router.push(ROUTES.DASHBOARD, undefined, { shallow: true }); router.push(ROUTES.HOME, undefined, { shallow: true }); - router.push(ROUTES.TRANSACTION_DETAILS, undefined, { shallow: true }); + + router.push(ROUTES.TRANSACTIONS, undefined, { shallow: true }); + router.push(ROUTES.TRANSACTIONS_DETAILS, undefined, { shallow: true }); + router.push(ROUTES.BLOCKS_DETAILS, undefined, { shallow: true }); }, [router]); diff --git a/pages/transactions/[address].tsx b/pages/transactions/[address].tsx new file mode 100644 index 0000000..c97332d --- /dev/null +++ b/pages/transactions/[address].tsx @@ -0,0 +1,28 @@ +// pages/transactions/details/[address].tsx +import React from 'react'; +import { useRouter } from 'next/router'; +import dynamic from 'next/dynamic'; +import Head from 'next/head'; + +const Layout = dynamic(() => import('../../layout')); +const TransactionDetailsView = dynamic(() => import('../../sections/Transactions/address'), { + loading: () =>

Loading...

, +}); + +const TransactionDetailsPage = () => { + const router = useRouter(); + const { address } = router.query; // Accessing the dynamic address parameter + + return ( + <> + + Transaction Details for {address} + + + + + + ); +}; + +export default TransactionDetailsPage; diff --git a/pages/transactions/index.tsx b/pages/transactions/index.tsx index cee660b..5511757 100644 --- a/pages/transactions/index.tsx +++ b/pages/transactions/index.tsx @@ -16,7 +16,7 @@ export default function Home() { return ( <> - Push Transaction detail + Push Transactions diff --git a/sections/Transactions/address.tsx b/sections/Transactions/address.tsx new file mode 100644 index 0000000..cc4ee66 --- /dev/null +++ b/sections/Transactions/address.tsx @@ -0,0 +1,263 @@ +// React, NextJS imports +import React from 'react'; +// External Library imports +import { useMediaQuery } from '@mui/material'; +import SearchContainer from '../../components/Home/SearchContainer'; +import BlocksContainer from '../../components/Home/BlocksContainer'; +import { Box, Text, Add, CaretDown, Button } from '../../blocks'; + +interface TransactionDetailsProps { + address: string | string[] | undefined; +} + +const Details = (props: TransactionDetailsProps) => { + const isMobile = useMediaQuery('(max-width:480px)'); + return ( + + Transaction Details + + + + Transaction Hash + Status + Block Hash + Category + Timestamp + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + Success + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + Notification + 40 minutes ago, Sun, Jul 21 2024 18:33:47 GMT + + + + + + From + To + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + Show more + + + + + + + + + Advanced + + + + + + + Consensus Info + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + Show more + + + + + + + Payload Data + + + 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000006419000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024ac6824ffa0000000000000000000000000000000000000000000000000000000000c2b5a6000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000020d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020d40000000000000000000000000000000000000000000000000000000000c2f8cd0000000000000000000 + + + + + + + + ); +}; + +export default Details; \ No newline at end of file diff --git a/sections/Transactions/index.tsx b/sections/Transactions/index.tsx index f691101..db4b989 100644 --- a/sections/Transactions/index.tsx +++ b/sections/Transactions/index.tsx @@ -1,11 +1,12 @@ // React, NextJS imports import React from 'react'; + // External Library imports -import { useMediaQuery } from '@mui/material'; -import SearchContainer from '../../components/Home/SearchContainer'; -import BlocksContainer from '../../components/Home/BlocksContainer'; +import { Divider, useMediaQuery } from '@mui/material'; import { Box, Text, Add, CaretDown, Button } from '../../blocks'; +const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + const Transactions = () => { const isMobile = useMediaQuery('(max-width:480px)'); return ( @@ -14,244 +15,57 @@ const Transactions = () => { display="flex" flexDirection="column" justifyContent="flex-start" - gap="spacing-sm" + gap="spacing-md" padding="spacing-xxxl" > Transaction Details - - - - Transaction Hash - Status - Block Hash - Category - Timestamp - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - Success - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - Notification - 40 minutes ago, Sun, Jul 21 2024 18:33:47 GMT - - - - - - From - To - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - Show more - - - - - - - - - Advanced - - - - - Consensus Info - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - Show more - - - + STATUS + TX HASH + BLCK HASH + FROM + TO + CATEGORY + AGE + {data.map((v) => ( - Payload Data - - 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000006419000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024ac6824ffa0000000000000000000000000000000000000000000000000000000000c2b5a6000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000020d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020d40000000000000000000000000000000000000000000000000000000000c2f8cd0000000000000000000 + Success + 0x2d2269ft... + 0x2d226953... + 0x2dw...408df + 0x2dr...508df + Notification + 2s ago - + + ))} - - ); }; diff --git a/utils/constants.js b/utils/constants.js index 5db213b..d55f089 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -13,7 +13,8 @@ export const ROUTES = { LOGIN: '/login', ADMIN: '/admin', DASHBOARD: '/dashboard', - TRANSACTION_DETAILS: '/transactions', + TRANSACTIONS: '/transactions', + TRANSACTION_DETAILS: '/transactions/address', BLOCKS_DETAILS: '/blocks', ERROR: '*', }; From 9de6eb967d4b449cd9f13501b3d466baf1d4f12c Mon Sep 17 00:00:00 2001 From: rozaso Date: Tue, 6 Aug 2024 21:31:25 -0700 Subject: [PATCH 05/42] Blocks landing page and details page. --- .../Home/BlocksContainer/LiveBlocks/index.tsx | 4 +- .../LiveTransactions/index.tsx | 4 +- pages/blocks/[address].tsx | 28 ++ pages/index.tsx | 1 + sections/Blocks/address.tsx | 263 ++++++++++++++++++ sections/Blocks/index.tsx | 158 ++--------- utils/constants.js | 3 +- 7 files changed, 327 insertions(+), 134 deletions(-) create mode 100644 pages/blocks/[address].tsx create mode 100644 sections/Blocks/address.tsx diff --git a/components/Home/BlocksContainer/LiveBlocks/index.tsx b/components/Home/BlocksContainer/LiveBlocks/index.tsx index 4b5f30e..35f4730 100644 --- a/components/Home/BlocksContainer/LiveBlocks/index.tsx +++ b/components/Home/BlocksContainer/LiveBlocks/index.tsx @@ -91,7 +91,7 @@ export default function LiveBlocks() { flexDirection="row" padding="spacing-xs" justifyContent="space-between" - gap="spacing-xxl" + gap="spacing-xs" > BLOCK HASH VALIDATOR @@ -110,7 +110,7 @@ export default function LiveBlocks() { padding="spacing-xs" justifyContent="space-between" alignItems="center" - gap="spacing-xxl" + gap="spacing-xs" > {dt.blockHash} {dt.validator} diff --git a/components/Home/BlocksContainer/LiveTransactions/index.tsx b/components/Home/BlocksContainer/LiveTransactions/index.tsx index fbbdf66..0ba984d 100644 --- a/components/Home/BlocksContainer/LiveTransactions/index.tsx +++ b/components/Home/BlocksContainer/LiveTransactions/index.tsx @@ -98,7 +98,7 @@ export default function LiveTransactions() { padding="spacing-xs" justifyContent="space-between" alignSelf="stretch" - gap="spacing-xxl" + gap="spacing-xs" > STATUS Tx HASH @@ -118,7 +118,7 @@ export default function LiveTransactions() { padding="spacing-xs" justifyContent="space-between" alignItems="center" - gap="spacing-xxl" + gap="spacing-xs" > {dt.status} {dt.txHash} diff --git a/pages/blocks/[address].tsx b/pages/blocks/[address].tsx new file mode 100644 index 0000000..c4b9f62 --- /dev/null +++ b/pages/blocks/[address].tsx @@ -0,0 +1,28 @@ +// pages/transactions/details/[address].tsx +import React from 'react'; +import { useRouter } from 'next/router'; +import dynamic from 'next/dynamic'; +import Head from 'next/head'; + +const Layout = dynamic(() => import('../../layout')); +const BlocksDetailsView = dynamic(() => import('../../sections/Blocks/address'), { + loading: () =>

Loading...

, +}); + +const BlocksDetailsPage = () => { + const router = useRouter(); + const { address } = router.query; // Accessing the dynamic address parameter + + return ( + <> + + Blocks Details for {address} + + + + + + ); +}; + +export default BlocksDetailsPage; diff --git a/pages/index.tsx b/pages/index.tsx index 5d6ac30..8262756 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -15,6 +15,7 @@ export default function Home() { router.push(ROUTES.TRANSACTIONS, undefined, { shallow: true }); router.push(ROUTES.TRANSACTIONS_DETAILS, undefined, { shallow: true }); + router.push(ROUTES.BLOCKS, undefined, { shallow: true }); router.push(ROUTES.BLOCKS_DETAILS, undefined, { shallow: true }); }, [router]); diff --git a/sections/Blocks/address.tsx b/sections/Blocks/address.tsx new file mode 100644 index 0000000..8a0979b --- /dev/null +++ b/sections/Blocks/address.tsx @@ -0,0 +1,263 @@ +// React, NextJS imports +import React from 'react'; +// External Library imports +import { useMediaQuery } from '@mui/material'; +import SearchContainer from '../../components/Home/SearchContainer'; +import BlocksContainer from '../../components/Home/BlocksContainer'; +import { Box, Text, Add, CaretDown, Button } from '../../blocks'; + +interface BlocksDetailsProps { + address: string | string[] | undefined; +} + +const Details = (props: BlocksDetailsProps) => { + const isMobile = useMediaQuery('(max-width:480px)'); + return ( + + Block Details + + + + Transaction Hash + Status + Block Hash + Category + Timestamp + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + Success + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + Notification + 40 minutes ago, Sun, Jul 21 2024 18:33:47 GMT + + + + + + From + To + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + Show more + + + + + + + + + Advanced + + + + + + + Consensus Info + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + Show more + + + + + + + Payload Data + + + 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000006419000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024ac6824ffa0000000000000000000000000000000000000000000000000000000000c2b5a6000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000020d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020d40000000000000000000000000000000000000000000000000000000000c2f8cd0000000000000000000 + + + + + + + + ); +}; + +export default Details; \ No newline at end of file diff --git a/sections/Blocks/index.tsx b/sections/Blocks/index.tsx index c6f21e8..0bb2ec6 100644 --- a/sections/Blocks/index.tsx +++ b/sections/Blocks/index.tsx @@ -1,8 +1,10 @@ // React, NextJS imports import React from 'react'; // External Library imports -import { useMediaQuery } from '@mui/material'; -import { Box, Text, Add, CaretDown, Button } from '../../blocks'; +import { Divider, useMediaQuery } from '@mui/material'; +import { Box, Text } from '../../blocks'; + +const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] const Blocks = () => { const isMobile = useMediaQuery('(max-width:480px)'); @@ -12,154 +14,52 @@ const Blocks = () => { display="flex" flexDirection="column" justifyContent="flex-start" - gap="spacing-sm" + gap="spacing-md" padding="spacing-xxxl" > - Block Details - + Blocks - - Block Hash - Validator - Timestamp - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x482741Ab0442755d344Ff8BDbEcc1e7b9BeB2823 - 40 minutes ago, Sun, Jul 21 2024 18:33:47 GMT - - - - - Transactions - Block Size + BLOCK HASH + VALIDATOR + TXN + SIZE (IN BYTES) + AGE + {data.map((v) => ( - 792 - 3,968,000 - - - - - Advanced - - - - - - - Consensus Info - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - Show more - - + 0x2d2269ft... + 0x2dw...408df + 824 + 4,565,456 + 2s ago + + ))} ); diff --git a/utils/constants.js b/utils/constants.js index d55f089..d7d15b6 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -15,7 +15,8 @@ export const ROUTES = { DASHBOARD: '/dashboard', TRANSACTIONS: '/transactions', TRANSACTION_DETAILS: '/transactions/address', - BLOCKS_DETAILS: '/blocks', + BLOCKS: '/blocks', + BLOCKS_DETAILS: '/blocks/address', ERROR: '*', }; From b2892c7bf1887b107892d9d1190d9f7b9a16d737 Mon Sep 17 00:00:00 2001 From: rozaso Date: Tue, 13 Aug 2024 19:11:03 -0700 Subject: [PATCH 06/42] Overall layout strucuture and resuable components. --- .vscode/settings.json | 2 +- blocks/icons/components/CaretLeft.tsx | 21 ++ blocks/icons/components/CaretRight.tsx | 21 ++ blocks/icons/index.ts | 2 + blocks/index.ts | 1 + blocks/select/Select.tsx | 321 ++++++++++++++++++ blocks/select/index.tsx | 1 + blocks/text/Text.constants.ts | 8 + components/Blocks/BlockView.tsx | 29 ++ components/Blocks/ListView.tsx | 42 +++ components/Dashboard/OverViewSet/index.tsx | 2 +- components/Footer/footer.styled.ts | 42 +-- components/Footer/index.tsx | 71 ++-- .../LiveBlocks/liveblocks.styles.ts | 17 - .../livetransactions.styles.ts | 17 - .../Home/BlocksContainer/blocks.styles.ts | 17 - components/Home/BlocksContainer/index.tsx | 34 -- .../LiveBlocks/index.tsx => LiveBlocks.tsx} | 54 ++- .../index.tsx => LiveTransactions.tsx} | 20 +- .../OverViewSet.tsx => OverView.tsx} | 24 +- components/Home/SearchBar.tsx | 34 ++ components/Home/SearchContainer/SearchBar.tsx | 62 ---- components/Home/SearchContainer/index.tsx | 41 --- .../Home/SearchContainer/search.styles.ts | 17 - components/Navbar/index.tsx | 188 +++++----- components/Pagination.tsx | 70 ++++ components/Reusables/Advanced.tsx | 17 + components/Reusables/ChainsDropDown.tsx | 51 +++ components/Reusables/ConsensusInfo.tsx | 158 +++++++++ components/Reusables/TxDetails.tsx | 42 +++ components/Reusables/TxTravels.tsx | 53 +++ components/Transactions/ListView.tsx | 47 +++ components/Transactions/RowView.tsx | 50 +++ contexts/NavigationContext.tsx | 17 + layout/index.tsx | 16 +- package.json | 3 +- public/static/push-icon-v1.svg | 74 ++++ sections/Blocks/address.tsx | 245 +------------ sections/Blocks/index.tsx | 52 +-- sections/Dashboard/index.tsx | 10 +- sections/Home/index.tsx | 46 ++- sections/Transactions/address.tsx | 251 +------------- sections/Transactions/index.tsx | 61 +--- utils/constants.js | 5 - yarn.lock | 48 +++ 45 files changed, 1342 insertions(+), 1062 deletions(-) create mode 100644 blocks/icons/components/CaretLeft.tsx create mode 100644 blocks/icons/components/CaretRight.tsx create mode 100644 blocks/select/Select.tsx create mode 100644 blocks/select/index.tsx create mode 100644 components/Blocks/BlockView.tsx create mode 100644 components/Blocks/ListView.tsx delete mode 100644 components/Home/BlocksContainer/LiveBlocks/liveblocks.styles.ts delete mode 100644 components/Home/BlocksContainer/LiveTransactions/livetransactions.styles.ts delete mode 100644 components/Home/BlocksContainer/blocks.styles.ts delete mode 100644 components/Home/BlocksContainer/index.tsx rename components/Home/{BlocksContainer/LiveBlocks/index.tsx => LiveBlocks.tsx} (64%) rename components/Home/{BlocksContainer/LiveTransactions/index.tsx => LiveTransactions.tsx} (86%) rename components/Home/{SearchContainer/OverViewSet.tsx => OverView.tsx} (73%) create mode 100644 components/Home/SearchBar.tsx delete mode 100644 components/Home/SearchContainer/SearchBar.tsx delete mode 100644 components/Home/SearchContainer/index.tsx delete mode 100644 components/Home/SearchContainer/search.styles.ts create mode 100644 components/Pagination.tsx create mode 100644 components/Reusables/Advanced.tsx create mode 100644 components/Reusables/ChainsDropDown.tsx create mode 100644 components/Reusables/ConsensusInfo.tsx create mode 100644 components/Reusables/TxDetails.tsx create mode 100644 components/Reusables/TxTravels.tsx create mode 100644 components/Transactions/ListView.tsx create mode 100644 components/Transactions/RowView.tsx create mode 100644 contexts/NavigationContext.tsx create mode 100644 public/static/push-icon-v1.svg diff --git a/.vscode/settings.json b/.vscode/settings.json index 576646c..551c4e4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, "eslint.validate": [ "javascript" diff --git a/blocks/icons/components/CaretLeft.tsx b/blocks/icons/components/CaretLeft.tsx new file mode 100644 index 0000000..28c7e18 --- /dev/null +++ b/blocks/icons/components/CaretLeft.tsx @@ -0,0 +1,21 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CaretLeft: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default CaretLeft; diff --git a/blocks/icons/components/CaretRight.tsx b/blocks/icons/components/CaretRight.tsx new file mode 100644 index 0000000..5892db6 --- /dev/null +++ b/blocks/icons/components/CaretRight.tsx @@ -0,0 +1,21 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CaretRight: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default CaretRight; diff --git a/blocks/icons/index.ts b/blocks/icons/index.ts index e32de6a..7ccbaee 100644 --- a/blocks/icons/index.ts +++ b/blocks/icons/index.ts @@ -18,6 +18,8 @@ export { default as CalendarBlank } from './components/CalendarBlank'; export { default as CaretDown } from './components/CaretDown'; export { default as CaretUp } from './components/CaretUp'; +export { default as CaretLeft } from './components/CaretLeft'; +export { default as CaretRight } from './components/CaretRight'; export { default as CameraFilled } from './components/CameraFilled'; diff --git a/blocks/index.ts b/blocks/index.ts index 2c3677f..c30632d 100644 --- a/blocks/index.ts +++ b/blocks/index.ts @@ -17,6 +17,7 @@ export { TextArea, type TextAreaProps } from './textarea'; export { TextInput } from './textInput'; export { ToggleSwitch } from './toggleSwtich'; export { Spinner, type SpinnerProps } from './spinner'; +export { Select } from './select' export * from './Blocks.colors'; export * from './Blocks.types'; diff --git a/blocks/select/Select.tsx b/blocks/select/Select.tsx new file mode 100644 index 0000000..4f9b250 --- /dev/null +++ b/blocks/select/Select.tsx @@ -0,0 +1,321 @@ +import React, { useRef, useState, ReactNode, useEffect } from 'react'; +import styled, { FlattenSimpleInterpolation, css } from 'styled-components'; +import { Combobox, ComboboxInput, ComboboxPopover, ComboboxList, ComboboxOption } from '@reach/combobox'; +import '@reach/combobox/styles.css'; + +import { textVariants } from '../text'; +import { Asterisk, CaretDown } from '../icons'; + +export type SelectOption = { + icon?: React.ReactNode; + label: string; + value: string; +}; + +export type SelectProps = { + /* Additional prop from styled components to apply custom css to Button */ + css?: FlattenSimpleInterpolation; + /* Description below the select field*/ + description?: string; + /* Sets button as disabled */ + disabled?: boolean; + /* Sets error state */ + error?: boolean; + /* The error message to be shown */ + errorMessage?: string; + /* Shows the label for the select field */ + label?: string; + /* Function invoked when an option is selected */ + onSelect?: (value: string) => void; + /* Select option list */ + options: SelectOption[]; + /* Placeholder to be shown when nothing is selected */ + placeholder?: string; + /* To make the field compulsory */ + required?: boolean; + /* Selected value */ + value?: string; + /* Sets success state */ + success?: boolean; + /* Action component on the top left of the Select */ + action?: ReactNode; +}; + +const Container = styled.div<{ css?: FlattenSimpleInterpolation }>` + align-items: flex-start; + display: flex; + flex-direction: column; + flex: 1 0 0; + gap: var(--spacing-xxs, 8px); + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''}; +`; + +const StyledBox = styled.div<{ + error?: boolean; + success?: boolean; + disabled?: boolean; +}>` + ${({ theme, success, error, disabled }) => { + const colors = theme?.blocksTheme?.colors; + const defaultState = error ? 'danger' : success ? 'success' : disabled ? 'disabled' : 'default'; + const focusState = error ? 'danger' : success ? 'success' : 'focus'; + + return css` + display: flex; + align-self: stretch; + cursor: pointer; + align-items: center; + justify-content: space-between; + border-radius: var(--radius-xs, 12px); + border: 1.5px solid + var(--components-inputs-stroke-${defaultState}, ${colors[`components-inputs-stroke-${defaultState}`]}); + background: var( + --components-inputs-background-${defaultState}, + ${colors[`components-inputs-background-${defaultState}`]} + ); + padding: var(--spacing-xs, 12px); + &:hover { + border: 1.5px solid var(--components-inputs-stroke-hover, #c4cbd5); + } + + &:focus-within { + border: 1.5px solid + var(--components-inputs-stroke-${focusState}, ${colors[`components-inputs-stroke-${focusState}`]}); + outline: none; + } + + [data-reach-combobox-input] { + background-color: transparent; + border: none; + color: var(--components-inputs-text-default, ${colors['components-inputs-text-default']}); + + display: flex; + + font-family: var(--font-family); + font-size: ${textVariants['bs-regular'].fontSize}; + font-style: ${textVariants['bs-regular'].fontStyle}; + font-weight: ${textVariants['bs-regular'].fontWeight}; + line-height: ${textVariants['bs-regular'].lineHeight}; + + gap: var(--spacing-none, 0px); + + &:focus { + outline: none; + } + &:hover { + outline: none; + } + &:disabled { + background-color: transparent; + cursor: not-allowed; + color: var(--components-inputs-text-disabled, ${colors['components-inputs-text-disabled']}); + } + + ::placeholder { + color: var(--components-inputs-text-placeholder, ${colors['components-inputs-text-placeholder']}); + } + } + `; + }} +`; + +const StyledPopover = styled(ComboboxPopover)` + margin: var(--spacing-sm) var(--spacing-xl) var(--spacing-none) var(--spacing-none); + padding: var(--spacing-xxs, 8px); + border-radius: var(--radius-xs, 12px); + border: var(--border-sm, 1px) solid var(--stroke-secondary, #eaebf2); + background: var(--surface-primary, #fff); + overflow: hidden auto; + max-height: 20rem; +`; + +const StyledCombobox = styled(Combobox)` + width: 100%; +`; + +const StyledInputContainer = styled.div` + display: flex; + width: 100%; + gap: var(--spacing-xxs); +`; + +const StyledInput = styled(ComboboxInput)` + width: 100%; +`; +const StyledList = styled(ComboboxList)` + display: flex; + flex-direction: column; + gap: var(--spacing-xs, 12px); +`; + +const StyledOption = styled(ComboboxOption)` + display: flex; + align-items: center; + padding: var(--spacing-xxxs, 4px); + gap: var(--spacing-xxs, 8px); + color: var(--components-dropdown-text-default, #17181b); + font-family: var(--font-family); + font-size: ${textVariants['bs-regular'].fontSize}; + font-style: ${textVariants['bs-regular'].fontStyle}; + font-weight: ${textVariants['bs-regular'].fontWeight}; + line-height: ${textVariants['bs-regular'].lineHeight}; + &:hover { + border-radius: var(--radius-xxs, 8px); + background: var(--surface-secondary, #f5f6f8); + } + [role='img'] { + width: 24px; + height: 24px; + } +`; +const LabelContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; +`; +const LabelText = styled.span<{ color: string }>` + color: var(--${({ color }) => color}); + font-family: var(--font-family); + font-size: ${textVariants['h6-semibold'].fontSize}; + font-style: ${textVariants['h6-semibold'].fontStyle}; + font-weight: ${textVariants['h6-semibold'].fontWeight}; + line-height: ${textVariants['h6-semibold'].lineHeight}; +`; + +const LabelTextContainer = styled.div` + display: flex; + align-items: flex-start; + gap: var(--spacing-xxxs, 4px); +`; +const Description = styled.span<{ color: string }>` + color: var(--${({ color }) => color}); + font-family: var(--font-family); + font-size: ${textVariants['c-regular'].fontSize}; + font-style: ${textVariants['c-regular'].fontStyle}; + font-weight: ${textVariants['c-regular'].fontWeight}; + line-height: ${textVariants['c-regular'].lineHeight}; +`; +const Select: React.FC = ({ + options, + onSelect, + css, + value, + placeholder = '', + error, + success, + label, + required, + description, + errorMessage, + action, + disabled, +}) => { + const [popoverWidth, setPopoverWidth] = useState(0); + const [viewPopover, setViewPopover] = useState(true); + const comboboxRef = useRef(null); + const parentRef = useRef(null); + const childRef = useRef(null); + + useEffect(() => { + const handleScroll = () => setViewPopover(false); + + window.addEventListener('scroll', handleScroll); + + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + + const selectedOption = options.find((option) => option.value === value); + + const handleParentFocus = () => { + childRef?.current?.focus(); + }; + + return ( + + + + + {label} + {required && } + + + {action} + + + { + onSelect?.(value); + setViewPopover(false); + }} + > + { + handleParentFocus(); + setViewPopover(true); + }} + > + + {selectedOption?.icon} + + + + + + {viewPopover && ( + + + {options.map((option, index) => ( + + {option?.icon} + {option.label} + + ))} + + + )} + + {description && ( + + {description} + + )} + {errorMessage && {errorMessage}} + + ); +}; + +Select.displayName = 'Select'; + +export { Select }; \ No newline at end of file diff --git a/blocks/select/index.tsx b/blocks/select/index.tsx new file mode 100644 index 0000000..90988f7 --- /dev/null +++ b/blocks/select/index.tsx @@ -0,0 +1 @@ +export { Select, type SelectProps } from './Select'; \ No newline at end of file diff --git a/blocks/text/Text.constants.ts b/blocks/text/Text.constants.ts index 9eaa127..01c8f90 100644 --- a/blocks/text/Text.constants.ts +++ b/blocks/text/Text.constants.ts @@ -176,6 +176,14 @@ export const textVariants = { letterSpacing: null, textTransform: null, }, + 'h4-regular-logo': { + fontSize: '20px', + fontStyle: null, + fontWeight: '400', + lineHeight: '160px', + letterSpacing: "-0.402px", + textTransform: null, + }, 'h5-regular': { fontSize: '16px', fontStyle: null, diff --git a/components/Blocks/BlockView.tsx b/components/Blocks/BlockView.tsx new file mode 100644 index 0000000..82d1a81 --- /dev/null +++ b/components/Blocks/BlockView.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { Divider } from '@mui/material'; +import { Box, Text } from '../../blocks'; + +const BlockView = () => { + return ( + + + 0x2d2269ft... + 0x2dw...408df + 824 + 4,565,456 + 2s ago + + + + ); +}; + +export default BlockView; \ No newline at end of file diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx new file mode 100644 index 0000000..575d13a --- /dev/null +++ b/components/Blocks/ListView.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { Box, Text } from '../../blocks'; +import Pagination from '../Pagination'; +import BlockView from './BlockView' + +const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] + +const Blocks = () => { + return ( + + + BLOCK HASH + VALIDATOR + TXN + SIZE (IN BYTES) + AGE + + + {data.map((v) => )} + + console.log(pageNumber)} + currentPage={1} + /> + + ); +}; + +export default Blocks; \ No newline at end of file diff --git a/components/Dashboard/OverViewSet/index.tsx b/components/Dashboard/OverViewSet/index.tsx index b51d92d..752880a 100644 --- a/components/Dashboard/OverViewSet/index.tsx +++ b/components/Dashboard/OverViewSet/index.tsx @@ -119,7 +119,7 @@ export default function OverViewSet() { return ( diff --git a/components/Footer/footer.styled.ts b/components/Footer/footer.styled.ts index 4cd0e7e..0aa06ad 100644 --- a/components/Footer/footer.styled.ts +++ b/components/Footer/footer.styled.ts @@ -4,27 +4,27 @@ import styled from 'styled-components'; // Internal Components imports import { ItemHV2 } from '../../components/Reusables/SharedStyling'; -export const FooterContainer = styled.div` - width: 100%; - display: flex; - justify-content: space-between; - align-items: center; - margin: 0; - @media (max-width: 480px) { - padding: 47px 24px 35px; - flex-direction: column; - align-items: center; - justify-content: center; - width: 100%; - gap: 30px; - } - @media (min-width: 768px) { - padding: 47px 24px 35px; - } - @media (min-width: 1024px) { - padding: 47px 70px 35px; - } -`; +// export const FooterContainer = styled.div` +// width: 100%; +// display: flex; +// justify-content: space-between; +// align-items: center; +// margin: 0; +// @media (max-width: 480px) { +// padding: 47px 24px 35px; +// flex-direction: column; +// align-items: center; +// justify-content: center; +// width: 100%; +// gap: 30px; +// } +// @media (min-width: 768px) { +// padding: 47px 24px 35px; +// } +// @media (min-width: 1024px) { +// padding: 47px 70px 35px; +// } +// `; export const LinkContainer = styled(ItemHV2)` justify-content: flex-start; diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index 30272eb..84f958d 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -4,19 +4,8 @@ import Image from 'next/image'; // External Library imports import { useTheme } from 'styled-components'; - -// Internal Components imports -import { - FooterContainer, - LinkContainer, - LeftContainer, - RightContainer, -} from './footer.styled'; import { useTheme as Theme } from '../../contexts/ThemeContext'; -import { Text } from '../Reusables/SharedStyling'; import { ThemeType } from '../../types/theme'; -import PushLogoLight from "../../public/static/push-logo-2.svg"; -import PushLogoDark from "../../public/static/push-logo-1.svg"; import TwitterIconDark from "../../public/static/twitter-dark.svg"; import TwitterIconLight from "../../public/static/twitter.svg"; import GithubIconDark from "../../public/static/github-dark.svg"; @@ -24,43 +13,25 @@ import GithubIconLight from "../../public/static/github.svg"; import DiscordIconDark from "../../public/static/discord-dark.svg"; import DiscordIconLight from "../../public/static/discord.svg"; +import { Box, Text, TickCircleFilled, TickDecoratedCircleFilled } from '../../blocks'; + export default function Footer() { const { isDarkMode } = Theme(); const theme = useTheme() as ThemeType; return ( - - - - Push Logo - - - - Terms - - - Privacy - - - Docs - - - - + + - - + + + + All systems operational + + ); } diff --git a/components/Home/BlocksContainer/LiveBlocks/liveblocks.styles.ts b/components/Home/BlocksContainer/LiveBlocks/liveblocks.styles.ts deleted file mode 100644 index 560b4d5..0000000 --- a/components/Home/BlocksContainer/LiveBlocks/liveblocks.styles.ts +++ /dev/null @@ -1,17 +0,0 @@ -// External Library imports -import styled from 'styled-components'; - -export const OverviewItem = styled.div` - border-radius: 28px; - padding: ${props => props.padding || '25px 30px 22px 40px'}; - display: flex; - flex: 1 1 0; - justify-content: space-between; - align-items: center; - height: 114px; - min-width: 285px; - @media (max-width: 480px) { - margin-bottom: 0px; - width: 100%; - } -`; diff --git a/components/Home/BlocksContainer/LiveTransactions/livetransactions.styles.ts b/components/Home/BlocksContainer/LiveTransactions/livetransactions.styles.ts deleted file mode 100644 index 560b4d5..0000000 --- a/components/Home/BlocksContainer/LiveTransactions/livetransactions.styles.ts +++ /dev/null @@ -1,17 +0,0 @@ -// External Library imports -import styled from 'styled-components'; - -export const OverviewItem = styled.div` - border-radius: 28px; - padding: ${props => props.padding || '25px 30px 22px 40px'}; - display: flex; - flex: 1 1 0; - justify-content: space-between; - align-items: center; - height: 114px; - min-width: 285px; - @media (max-width: 480px) { - margin-bottom: 0px; - width: 100%; - } -`; diff --git a/components/Home/BlocksContainer/blocks.styles.ts b/components/Home/BlocksContainer/blocks.styles.ts deleted file mode 100644 index d965fda..0000000 --- a/components/Home/BlocksContainer/blocks.styles.ts +++ /dev/null @@ -1,17 +0,0 @@ -// External Library imports -import styled from 'styled-components'; - -export const SearchItem = styled.div` - border-radius: 28px; - padding: ${props => props.padding || '25px 30px 22px 40px'}; - display: flex; - flex: 1 1 0; - justify-content: space-between; - align-items: center; - height: 114px; - min-width: 285px; - @media (max-width: 480px) { - margin-bottom: 0px; - width: 100%; - } -`; diff --git a/components/Home/BlocksContainer/index.tsx b/components/Home/BlocksContainer/index.tsx deleted file mode 100644 index ad84642..0000000 --- a/components/Home/BlocksContainer/index.tsx +++ /dev/null @@ -1,34 +0,0 @@ -// React, NextJS imports -import React from 'react'; -import Image from 'next/image'; - -// External Library imports -import { useTheme } from 'styled-components'; -import { useMediaQuery, useScrollTrigger } from '@mui/material'; - -// Internal Components imports -import { useTheme as getTheme } from '../../../contexts/ThemeContext'; -import { ThemeType } from '../../../types/theme'; -import { Box } from '../../../blocks'; -import LiveBlocks from './LiveBlocks' -import LiveTransactions from './LiveTransactions' - -export default function BlocksContainer() { - const { isDarkMode } = getTheme(); - const isMobile = useMediaQuery('(max-width:480px)'); - - const theme = useTheme() as ThemeType; - - return ( - - - - - ); -} diff --git a/components/Home/BlocksContainer/LiveBlocks/index.tsx b/components/Home/LiveBlocks.tsx similarity index 64% rename from components/Home/BlocksContainer/LiveBlocks/index.tsx rename to components/Home/LiveBlocks.tsx index 35f4730..6bd6d63 100644 --- a/components/Home/BlocksContainer/LiveBlocks/index.tsx +++ b/components/Home/LiveBlocks.tsx @@ -1,22 +1,8 @@ -// React, NextJS imports import React from 'react'; - -// External Library imports -import { useTheme } from 'styled-components'; -import { Divider, useMediaQuery } from '@mui/material'; -import { ThemeType } from '../../../../types/theme'; - -// Internal Components imports -import { OverviewItem } from './liveblocks.styles'; -import { useTheme as getTheme } from '../../../../contexts/ThemeContext'; -import { Box, Text, ArrowUpRight } from '../../../../blocks'; +import { Divider } from '@mui/material'; +import { Box, Text, Front } from '../../blocks'; export default function LiveBlocks() { - const isMobile = useMediaQuery('(max-width:480px)'); - const { isDarkMode } = getTheme(); - - const theme = useTheme() as ThemeType; - const overViewData = [ { blockHash: '0556ba4acd62f....', @@ -89,7 +75,7 @@ export default function LiveBlocks() { @@ -99,26 +85,26 @@ export default function LiveBlocks() { AGE {overViewData.map((dt) => - - {dt.blockHash} - {dt.validator} - {dt.tx} - {dt.age} + > + + {dt.blockHash} + {dt.validator} + {dt.tx} + {dt.age} + + - - )} @@ -130,7 +116,7 @@ export default function LiveBlocks() { justifyContent="flex-end" > View All Blocks - + ) diff --git a/components/Home/BlocksContainer/LiveTransactions/index.tsx b/components/Home/LiveTransactions.tsx similarity index 86% rename from components/Home/BlocksContainer/LiveTransactions/index.tsx rename to components/Home/LiveTransactions.tsx index 0ba984d..157d1b6 100644 --- a/components/Home/BlocksContainer/LiveTransactions/index.tsx +++ b/components/Home/LiveTransactions.tsx @@ -1,21 +1,11 @@ // React, NextJS imports import React from 'react'; - -// External Library imports -import { useTheme } from 'styled-components'; -import { Divider, useMediaQuery } from '@mui/material'; -import { ThemeType } from '../../../../types/theme'; +import { Divider } from '@mui/material'; // Internal Components imports -import { useTheme as getTheme } from '../../../../contexts/ThemeContext'; -import { Box, Text, ArrowUpRight } from '../../../../blocks'; +import { Box, Text, Front } from '../../blocks'; export default function LiveTransactions() { - const isMobile = useMediaQuery('(max-width:480px)'); - const { isDarkMode } = getTheme(); - - const theme = useTheme() as ThemeType; - const overViewData = [ { status: "Success", @@ -95,7 +85,7 @@ export default function LiveTransactions() { View All Transactions - + ) diff --git a/components/Home/SearchContainer/OverViewSet.tsx b/components/Home/OverView.tsx similarity index 73% rename from components/Home/SearchContainer/OverViewSet.tsx rename to components/Home/OverView.tsx index 89b7768..3edbe6f 100644 --- a/components/Home/SearchContainer/OverViewSet.tsx +++ b/components/Home/OverView.tsx @@ -1,29 +1,13 @@ -// React, NextJS imports import React from 'react'; +import { Divider, useMediaQuery } from '@mui/material'; +import { Box, Text } from '../../blocks'; -// External Library imports -import { useTheme } from 'styled-components'; -import { Divider, useMediaQuery, useScrollTrigger } from '@mui/material'; -import { Box, Text } from '../../../blocks'; - -// Internal Components imports -import { useTheme as getTheme } from '../../../contexts/ThemeContext'; -import { ThemeType } from '../../../types/theme'; -import { HorizontalLine } from '../../Reusables/SharedStyling'; - -export default function OverViewSet() { - - const { isDarkMode } = getTheme(); +export default function OverView() { const isMobile = useMediaQuery('(max-width:480px)'); - - const theme = useTheme() as ThemeType; - - console.log("theme : ", console.log(theme)) - return ( { + if (!qry) return {}; + const isAddress = ethers.isAddress(qry); + const key = isAddress ? 'wallet' : 'twitter'; + const value = isAddress ? `eip155:${qry}` : qry; + return { [key]: value }; + }, []); + + return ( + + } + value={query} + onChange={(e) => setQuery(e.target.value)} + /> + + ) +} + + + diff --git a/components/Home/SearchContainer/SearchBar.tsx b/components/Home/SearchContainer/SearchBar.tsx deleted file mode 100644 index a601757..0000000 --- a/components/Home/SearchContainer/SearchBar.tsx +++ /dev/null @@ -1,62 +0,0 @@ -// React, NextJS imports -import React, { useCallback, useState } from 'react'; - -// External Library imports -import { useTheme } from 'styled-components'; -import { useMediaQuery, useScrollTrigger } from '@mui/material'; -import { Box, Text, TextInput, Search } from '../../../blocks'; - -// Internal Components imports -import { useTheme as getTheme } from '../../../contexts/ThemeContext'; -import { ThemeType } from '../../../types/theme'; -import { ethers } from 'ethers'; - -export default function SearchBar() { - - const theme = useTheme() as ThemeType; - const { isDarkMode } = getTheme(); - const isMobile = useMediaQuery('(max-width:480px)'); - - const [query, setQuery] = useState(''); - const [debouncedQuery, setDebouncedQuery] = useState({}); - - const getFormattedQuery = useCallback((qry: string) => { - if (!qry) return {}; - const isAddress = ethers.isAddress(qry); - const key = isAddress ? 'wallet' : 'twitter'; - const value = isAddress ? `eip155:${qry}` : qry; - return { [key]: value }; - }, []); - - - return ( - - Push Blockchain Explorer - - - - } - value={query} - onChange={(e) => setQuery(e.target.value)} - /> - - - ) -} - - - diff --git a/components/Home/SearchContainer/index.tsx b/components/Home/SearchContainer/index.tsx deleted file mode 100644 index 402204d..0000000 --- a/components/Home/SearchContainer/index.tsx +++ /dev/null @@ -1,41 +0,0 @@ -// React, NextJS imports -import React from 'react'; -import Image from 'next/image'; - -// External Library imports -import { useTheme } from 'styled-components'; -import { useMediaQuery, useScrollTrigger } from '@mui/material'; -import { Box } from '../../../blocks'; - -// Internal Components imports -import { SearchItem } from './search.styles'; -import { Text } from '../../Reusables/SharedStyling'; -import { useData } from '../../../contexts/DataContext'; -import { useTheme as getTheme } from '../../../contexts/ThemeContext'; -import { ItemVV2 } from '../../Reusables/SharedStyling'; -import { ThemeType } from '../../../types/theme'; -import { OverviewLoader } from '../../Loader/OverviewLoader'; - -import SearchBar from './SearchBar' -import OverViewSet from './OverViewSet' -export default function SearchContainer() { - - const { isDarkMode } = getTheme(); - const isMobile = useMediaQuery('(max-width:480px)'); - - const theme = useTheme() as ThemeType; - - return ( - - - - - - ) -} diff --git a/components/Home/SearchContainer/search.styles.ts b/components/Home/SearchContainer/search.styles.ts deleted file mode 100644 index d965fda..0000000 --- a/components/Home/SearchContainer/search.styles.ts +++ /dev/null @@ -1,17 +0,0 @@ -// External Library imports -import styled from 'styled-components'; - -export const SearchItem = styled.div` - border-radius: 28px; - padding: ${props => props.padding || '25px 30px 22px 40px'}; - display: flex; - flex: 1 1 0; - justify-content: space-between; - align-items: center; - height: 114px; - min-width: 285px; - @media (max-width: 480px) { - margin-bottom: 0px; - width: 100%; - } -`; diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index b3799a6..05467db 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -1,10 +1,11 @@ // React, NextJS imports import React from 'react'; import { useRouter } from 'next/router'; +import Image from 'next/image'; // External Library imports import { DarkModeSwitch } from 'react-toggle-dark-mode'; -import { Box, Button, useMediaQuery } from '@mui/material'; +import { Button, useMediaQuery } from '@mui/material'; import { useTheme } from 'styled-components'; // Internal Components imports @@ -12,7 +13,6 @@ import Logo from '../Logo'; import { useTheme as Theme } from '../../contexts/ThemeContext'; import { useData } from '../../contexts/DataContext'; import { ROUTES, CREDENTIALKEYS } from '../../utils/constants'; -import { Text } from '../Reusables/SharedStyling'; import { ItemHV2, ItemVV2 } from '../../components/Reusables/SharedStyling'; import { NavBarButtons } from './NavBarButtons'; import { @@ -21,6 +21,9 @@ import { SidebarContainer, } from './navbar.styled'; import { ThemeType } from '../../types/theme'; +import { Box, Select, Text } from '../../blocks'; +import SearchBar from '../Home/SearchBar' +import ChainsDropDown from '../Reusables/ChainsDropDown' export default function Navbar() { const { isDarkMode, darkModeToggle } = Theme(); @@ -40,122 +43,85 @@ export default function Navbar() { }; return ( - - - - - - Push Snapshots - - {!isMobile && ( - - Explore trends, activity and track growth on the Push Network - - )} - - - - {asPath !== '/dashboard' && !isSmall && ( - - )} + + - + PushScan + + + + ALPHA - {asPath !== '/dashboard' && isSmall && ( - setShowSidebar(!showSidebar)} + + + + + + + { asPath !== '/home' && ( + { + router.push(ROUTES.HOME); + }} > - - - - + Home + )} - - <> - {showSidebar && ( - - - - - {isLoggedIn ? ( - - ) : null} - + { asPath !== '/dashboard' && ( + { + router.push(ROUTES.DASHBOARD); + }} + > + Analytics + )} - - + + + + { asPath !== '/home' && } + + ); } diff --git a/components/Pagination.tsx b/components/Pagination.tsx new file mode 100644 index 0000000..f6e221f --- /dev/null +++ b/components/Pagination.tsx @@ -0,0 +1,70 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import { Box, Text, Add, CaretLeft, CaretRight } from '../blocks'; + +const Pagination = ({ itemsPerPage, totalItems, paginate, currentPage }) => { + const totalPages = Math.ceil(totalItems / itemsPerPage); + let pageNumbers: number[] = []; + let startPage, endPage; + + if (totalPages <= 5) { + // less than 5 total pages so show all + startPage = 1; + endPage = totalPages; + } else { + // more than 5 total pages so calculate start and end pages + if (currentPage <= 3) { + startPage = 1; + endPage = 5; + } else if (currentPage + 2 >= totalPages) { + startPage = totalPages - 4; + endPage = totalPages; + } else { + startPage = currentPage - 2; + endPage = currentPage + 2; + } + } + + // generate page numbers to be displayed + for (let i = startPage; i <= endPage; i++) { + pageNumbers.push(i); + } + + const indexOfLastPageButton = currentPage + 3; + const indexOfFirstPageButton = currentPage - 3; + + return ( + + + currentPage > 1 && paginate(currentPage - 1)} /> + {currentPage > 3 && totalPages > 5 && ( + <> + paginate(1)}>1 + {currentPage > 4 && ...} + + )} + + {pageNumbers.map(number => ( + paginate(number)} key={number}> + {number} + + ))} + + {currentPage + 3 < totalPages && ( + <> + ... + paginate(totalPages)}>{totalPages} + + )} + currentPage < totalPages && paginate(currentPage + 1)} /> + + ); +}; + +export default Pagination; diff --git a/components/Reusables/Advanced.tsx b/components/Reusables/Advanced.tsx new file mode 100644 index 0000000..3f9cab7 --- /dev/null +++ b/components/Reusables/Advanced.tsx @@ -0,0 +1,17 @@ +import React from 'react'; +import { Box, Text, CaretDown } from '../../blocks'; + +const Advanced = () => { + return ( + + Advanced + + + ); +}; + +export default Advanced; \ No newline at end of file diff --git a/components/Reusables/ChainsDropDown.tsx b/components/Reusables/ChainsDropDown.tsx new file mode 100644 index 0000000..b78f19b --- /dev/null +++ b/components/Reusables/ChainsDropDown.tsx @@ -0,0 +1,51 @@ +// React, NextJS imports +import React, { FC, useRef, useState, ReactNode, useEffect } from 'react'; + +import { Box, Select, Text } from '../../blocks'; +import Ethereum from '../../blocks/illustrations/components/Ethereum'; +import Polygon from '../../blocks/illustrations/components/Polygon'; +import BNB from '../../blocks/illustrations/components/BNB'; +import Optimisim from '../../blocks/illustrations/components/Optimisim'; +import Arbitrum from '../../blocks/illustrations/components/Arbitrum'; +import PolygonZK from '../../blocks/illustrations/components/PolygonZK'; +import Fuse from '../../blocks/illustrations/components/Fuse'; +import Cyber from '../../blocks/illustrations/components/Cyber'; +import { CHAIN_LIST } from '../../utils/constants' +import { IllustrationProps } from '../../blocks'; + +export default function ChainsDropDown() { + + const LOGO_ALIAS_CHAIN: { [key: string]: FC } = { + "ETH_MAINNET": Ethereum, + "POLYGON_MAINNET": Polygon, + "BSC_MAINNET": BNB, + "OPTIMISM_MAINNET": Optimisim, + "ARBITRUMONE_MAINNET": Arbitrum, + "POLYGON_ZK_EVM_MAINNET": PolygonZK, + "FUSE_MAINNET": Fuse, + "CYBER_CONNECT_MAINNET": Cyber + }; + + const getSelectChains = () => { + return CHAIN_LIST?.map((chain) => { + const Component = LOGO_ALIAS_CHAIN[chain.value]; + return { + value: chain.value, + label: chain.chain, + icon: , + }; + }); + }; + + const networkOptions = getSelectChains() + + const [chain, setChain] = useState(networkOptions[0].value); + + return ( + ( onChange={onChange} value={value} /> - {icon} {onClear && onClear?.()} />} diff --git a/blocks/textarea/TextArea.tsx b/blocks/textarea/TextArea.tsx index 2cbedb7..7c8096a 100644 --- a/blocks/textarea/TextArea.tsx +++ b/blocks/textarea/TextArea.tsx @@ -1,4 +1,4 @@ -import { Asterisk } from 'blocks/icons'; +import { Asterisk } from '../../blocks/icons'; import { textVariants } from '../text'; import React, { forwardRef } from 'react'; import styled, { FlattenSimpleInterpolation, css } from 'styled-components'; diff --git a/blocks/theme/Theme.utils.ts b/blocks/theme/Theme.utils.ts index 7ec82dd..128346b 100644 --- a/blocks/theme/Theme.utils.ts +++ b/blocks/theme/Theme.utils.ts @@ -30,4 +30,4 @@ export const getBlocksCSSVariables = (theme: Theme) => .map(([key, value]) => `--${key}: ${value};`) .join('') ) - .join(''); \ No newline at end of file + .join(''); diff --git a/blocks/theme/colors/colors.semantics.ts b/blocks/theme/colors/colors.semantics.ts index e3b36b8..a392a8f 100644 --- a/blocks/theme/colors/colors.semantics.ts +++ b/blocks/theme/colors/colors.semantics.ts @@ -12,12 +12,14 @@ import { dropdownSemantics } from '../semantics/semantics.dropdown'; import { iconSemantics } from '../semantics/semantics.icon'; import { inputSemantics } from '../semantics/semantics.input'; import { modalSemantics } from '../semantics/semantics.modal'; +import { notificationsSemantics } from '../semantics/semantics.notifications'; import { progressBarSemantics } from '../semantics/semantics.progress-bar'; import { radioSemantics } from '../semantics/semantics.radio'; import { skeletonSemantics } from '../semantics/semantics.skeleton'; import { strokeSemantics } from '../semantics/semantics.stroke'; import { surfaceSemantics } from '../semantics/semantics.surface'; import { switchSemantics } from '../semantics/semantics.switch'; +import { tagSemantics } from '../semantics/semantics.tag'; import { textSemantics } from '../semantics/semantics.text'; import { textAreaSemantics } from '../semantics/semantics.textarea'; import { toastSemantics } from '../semantics/semantics.toast'; @@ -38,11 +40,13 @@ type SemanticKeys = { icon: 'icon'; input: 'components-inputs'; modal: 'components-modal'; + notifications: 'components-in-app-notification'; progressBar: 'components-progress-bar'; radio: 'components-radio-button'; surface: 'surface'; stroke: 'stroke'; skeleton: 'components-skeleton-loader'; + tag: 'components-tag'; text: 'text'; textArea: 'components-textarea'; toast: 'components-toast'; @@ -64,11 +68,13 @@ export const semanticKeys: SemanticKeys = { icon: 'icon', input: 'components-inputs', modal: 'components-modal', + notifications: 'components-in-app-notification', progressBar: 'components-progress-bar', radio: 'components-radio-button', surface: 'surface', stroke: 'stroke', skeleton: 'components-skeleton-loader', + tag: 'components-tag', text: 'text', textArea: 'components-textarea', toast: 'components-toast', @@ -90,11 +96,13 @@ export const colorSemantics = { [semanticKeys.icon]: iconSemantics, [semanticKeys.input]: inputSemantics, [semanticKeys.modal]: modalSemantics, + [semanticKeys.notifications]: notificationsSemantics, [semanticKeys.progressBar]: progressBarSemantics, [semanticKeys.radio]: radioSemantics, [semanticKeys.surface]: surfaceSemantics, [semanticKeys.stroke]: strokeSemantics, [semanticKeys.skeleton]: skeletonSemantics, + [semanticKeys.tag]: tagSemantics, [semanticKeys.text]: textSemantics, [semanticKeys.textArea]: textAreaSemantics, [semanticKeys.toast]: toastSemantics, diff --git a/blocks/theme/semantics/semantics.notifications.ts b/blocks/theme/semantics/semantics.notifications.ts new file mode 100644 index 0000000..7e0f821 --- /dev/null +++ b/blocks/theme/semantics/semantics.notifications.ts @@ -0,0 +1,15 @@ +import { iconSemantics } from './semantics.icon'; +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const notificationsSemantics = { + 'background-default': { light: surfaceSemantics['primary'].light, dark: surfaceSemantics['primary'].dark }, + 'stroke-bg': { light: strokeSemantics['secondary'].light, dark: strokeSemantics['secondary'].dark }, + 'text-default': { + light: textSemantics['primary'].light, + dark: textSemantics['primary'].dark, + }, + 'text-secondary': { light: textSemantics['tertiary'].light, dark: textSemantics['tertiary'].dark }, + 'icon-default': { light: iconSemantics['primary'].light, dark: iconSemantics['primary'].dark }, +}; diff --git a/blocks/theme/semantics/semantics.surface.ts b/blocks/theme/semantics/semantics.surface.ts index 2930a9c..be0356f 100644 --- a/blocks/theme/semantics/semantics.surface.ts +++ b/blocks/theme/semantics/semantics.surface.ts @@ -19,16 +19,16 @@ export const surfaceSemantics = { // surface states - 'state-success-subtle': { light: colorBrands['success-100'], dark: colorBrands['success-500'] }, + 'state-success-subtle': { light: colorBrands['success-100'], dark: colorBrands['success-900'] }, 'state-success-bold': { light: colorBrands['success-500'], dark: colorBrands['success-200'] }, - 'state-info-subtle': { light: colorBrands['info-100'], dark: colorBrands['info-500'] }, + 'state-info-subtle': { light: colorBrands['info-100'], dark: colorBrands['info-900'] }, 'state-info-bold': { light: colorBrands['info-500'], dark: colorBrands['info-200'] }, - 'state-warning-subtle': { light: colorBrands['warning-100'], dark: colorBrands['warning-500'] }, + 'state-warning-subtle': { light: colorBrands['warning-100'], dark: colorBrands['warning-900'] }, 'state-warning-bold': { light: colorBrands['warning-500'], dark: colorBrands['warning-200'] }, - 'state-danger-subtle': { light: colorBrands['danger-100'], dark: colorBrands['danger-800'] }, + 'state-danger-subtle': { light: colorBrands['danger-100'], dark: colorBrands['danger-900'] }, 'state-danger-bold': { light: colorBrands['danger-500'], dark: colorBrands['danger-200'] }, 'state-disabled': { light: colorBrands['neutral-200'], dark: colorBrands['neutral-800'] }, diff --git a/blocks/theme/semantics/semantics.tag.ts b/blocks/theme/semantics/semantics.tag.ts new file mode 100644 index 0000000..31a2101 --- /dev/null +++ b/blocks/theme/semantics/semantics.tag.ts @@ -0,0 +1,44 @@ +import { iconSemantics } from './semantics.icon'; +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const tagSemantics = { + 'background-default': { light: surfaceSemantics['tertiary'].light, dark: surfaceSemantics['tertiary'].dark }, + 'background-success': { + light: surfaceSemantics['state-success-subtle'].light, + dark: surfaceSemantics['state-success-subtle'].dark, + }, + 'background-danger': { + light: surfaceSemantics['state-danger-subtle'].light, + dark: surfaceSemantics['state-danger-subtle'].dark, + }, + 'background-warning': { + light: surfaceSemantics['state-warning-subtle'].light, + dark: surfaceSemantics['state-warning-subtle'].dark, + }, + 'background-info': { + light: surfaceSemantics['state-info-subtle'].light, + dark: surfaceSemantics['state-info-subtle'].dark, + }, + 'background-disabled': { + light: surfaceSemantics['state-disabled'].light, + dark: surfaceSemantics['state-disabled'].dark, + }, + + 'stroke-bg': { light: strokeSemantics['secondary'].light, dark: strokeSemantics['secondary'].dark }, + + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-success': { light: textSemantics['state-success-bold'].light, dark: textSemantics['state-success-bold'].dark }, + 'text-warning': { light: textSemantics['state-warning-bold'].light, dark: textSemantics['state-warning-bold'].dark }, + 'text-danger': { light: textSemantics['state-danger-bold'].light, dark: textSemantics['state-danger-bold'].dark }, + 'text-info': { light: textSemantics['state-info-bold'].light, dark: textSemantics['state-info-bold'].dark }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + + 'icon-default': { light: iconSemantics['primary'].light, dark: iconSemantics['primary'].dark }, + 'icon-success': { light: iconSemantics['state-success-bold'].light, dark: iconSemantics['state-success-bold'].dark }, + 'icon-warning': { light: iconSemantics['state-warning-bold'].light, dark: iconSemantics['state-warning-bold'].dark }, + 'icon-danger': { light: iconSemantics['state-danger-bold'].light, dark: iconSemantics['state-danger-bold'].dark }, + 'icon-info': { light: iconSemantics['state-info-bold'].light, dark: iconSemantics['state-info-bold'].dark }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, +}; diff --git a/blocks/theme/semantics/semantics.text.ts b/blocks/theme/semantics/semantics.text.ts index f59a2f9..41b91ba 100644 --- a/blocks/theme/semantics/semantics.text.ts +++ b/blocks/theme/semantics/semantics.text.ts @@ -26,7 +26,7 @@ export const textSemantics = { 'state-info-bold': { light: colorBrands['info-700'], dark: colorBrands['info-100'] }, 'state-warning-subtle': { light: colorBrands['warning-100'], dark: colorBrands['warning-700'] }, - 'warning-bold': { light: colorBrands['warning-700'], dark: colorBrands['warning-100'] }, + 'state-warning-bold': { light: colorBrands['warning-700'], dark: colorBrands['warning-100'] }, 'state-danger-subtle': { light: colorBrands['danger-100'], dark: colorBrands['danger-700'] }, 'state-danger-bold': { light: colorBrands['danger-700'], dark: colorBrands['danger-300'] }, diff --git a/blocks/theme/variables/variables.spacing.ts b/blocks/theme/variables/variables.spacing.ts index a54f984..2108365 100644 --- a/blocks/theme/variables/variables.spacing.ts +++ b/blocks/theme/variables/variables.spacing.ts @@ -9,5 +9,4 @@ export const spacingVariables = { 'spacing-xl': '40px', 'spacing-xxl': '48px', 'spacing-xxxl': '64px', - 'spacing-xxxxl': '120px', }; diff --git a/blocks/toggleSwtich/ToggleSwitch.tsx b/blocks/toggleSwtich/ToggleSwitch.tsx index 035bda6..23076c7 100644 --- a/blocks/toggleSwtich/ToggleSwitch.tsx +++ b/blocks/toggleSwtich/ToggleSwitch.tsx @@ -4,7 +4,7 @@ import styled, { FlattenSimpleInterpolation } from 'styled-components'; import * as Switch from '@radix-ui/react-switch'; import { TextVariants, textVariants } from '../text'; -import { ThemeColors } from 'blocks/theme/Theme.types'; +import { ThemeColors } from '../../blocks/theme/Theme.types'; export type ToggleSwitchProps = { /* Additional prop from styled components to apply custom css to Toggle switch */ diff --git a/blocks/tooltip/Tooltip.tsx b/blocks/tooltip/Tooltip.tsx index 53f6c77..6d3e755 100644 --- a/blocks/tooltip/Tooltip.tsx +++ b/blocks/tooltip/Tooltip.tsx @@ -4,7 +4,7 @@ import * as RadixTooltip from '@radix-ui/react-tooltip'; import type { TooltipProps } from './Tooltip.types'; import { getTooltipPositionalCSS } from './Tooltip.utils'; import { tooltipCSSPropsKeys } from './Tooltip.constants'; -import { useIsVisible } from '../../common'; +import { useIsVisible } from 'common'; import { textVariants } from '../text'; const RadixTooltipContent = styled(RadixTooltip.Content).withConfig({ diff --git a/components/Blocks/BlockView.tsx b/components/Blocks/BlockView.tsx index 82d1a81..e3d72cf 100644 --- a/components/Blocks/BlockView.tsx +++ b/components/Blocks/BlockView.tsx @@ -1,8 +1,13 @@ import React from 'react'; import { Divider } from '@mui/material'; import { Box, Text } from '../../blocks'; +import { useRouter } from 'next/router' +import { getValidatorNode } from '../../utils/helpers' +import moment from 'moment'; + +const BlockView = (props) => { + const router = useRouter() -const BlockView = () => { return ( { display="flex" flexDirection="row" justifyContent="space-between" + onClick={() => router.push(`/blocks/${props.block.blockHash}`)} > - 0x2d2269ft... - 0x2dw...408df - 824 - 4,565,456 - 2s ago + {props.block.blockHash} + {getValidatorNode(props.block.blockDataAsJson?.signersList)} + {props.block.totalNumberOfTxns} + {props.block.blockSize} + {moment(props.block.ts * 1000).fromNow()} diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx index 575d13a..f61ffa6 100644 --- a/components/Blocks/ListView.tsx +++ b/components/Blocks/ListView.tsx @@ -1,13 +1,17 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Box, Text } from '../../blocks'; import Pagination from '../Pagination'; import BlockView from './BlockView' - -const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] +import { useLiveBlocks } from '../../hooks/useBlocks'; +import { PerPageItems } from '../../utils/constants' const Blocks = () => { + const [page, setPage] = useState(1); + const { data, error, isLoading, isError } = useLiveBlocks(); + return ( { > BLOCK HASH VALIDATOR - TXN - SIZE (IN BYTES) - AGE + TXN + SIZE (IN BYTES) + AGE - {data.map((v) => )} + {data?.blocks?.map((block) => )} console.log(pageNumber)} - currentPage={1} + itemsPerPage={PerPageItems} + totalItems={data?.totalPages * PerPageItems} + paginate={(page) => setPage(page)} + currentPage={page} /> ); diff --git a/components/Home/LiveBlocks.tsx b/components/Home/LiveBlocks.tsx index 6bd6d63..9097265 100644 --- a/components/Home/LiveBlocks.tsx +++ b/components/Home/LiveBlocks.tsx @@ -1,60 +1,15 @@ import React from 'react'; -import { Divider } from '@mui/material'; -import { Box, Text, Front } from '../../blocks'; +import { Box, Text, Front, Separator } from '../../blocks'; +import { useRouter } from 'next/router' +import Link from 'next/link' +import { useLiveBlocks } from '../../hooks/useBlocks'; +import moment from 'moment'; +import { getValidatorNode } from '../../utils/helpers' +import { centerMaskString, rightMaskString } from '../../utils/helpers' export default function LiveBlocks() { - const overViewData = [ - { - blockHash: '0556ba4acd62f....', - validator: '0556b...96e5659bf', - tx: 460, - age: '2s ago' - }, - { - blockHash: '0556ba4acd62f....', - validator: '0556b...96e5659bf', - tx: 660, - age: '6s ago' - }, - { - blockHash: '0556ba4acd62f....', - validator: '0556b...96e5659bf', - tx: 660, - age: '9s ago' - }, - { - blockHash: '0556ba4acd62f....', - validator: '0556b...96e5659bf', - tx: 605, - age: '2m ago' - }, - { - blockHash: '0556ba4acd62f....', - validator: '0556b...96e5659bf', - tx: 60, - age: '33m ago' - }, - { - blockHash: '0556ba4acd62f....', - validator: '0556b...96e5659bf', - tx: 234, - age: '45m ago' - }, - - { - blockHash: '0556ba4acd62f....', - validator: '0556b...96e5659bf', - tx: 2, - age: '48m ago' - }, - { - blockHash: '0556ba4acd62f....', - validator: '0556b...96e5659bf', - tx: 789, - age: '52m ago' - }, - ]; - + const router = useRouter() + const { data, error, isLoading, isError } = useLiveBlocks(); return ( TX AGE - {overViewData.map((dt) => + {data?.blocks?.map((dt) => - {dt.blockHash} - {dt.validator} - {dt.tx} - {dt.age} + onClick={() => router.push(`/blocks/${dt.blockHash}`)} + > + {rightMaskString(dt.blockHash)} + {centerMaskString(getValidatorNode(dt.blockDataAsJson?.signersList))} + {dt.totalNumberOfTxns} + {moment(dt.ts * 1000).fromNow()} - + )} + - View All Blocks + + View All Blocks + diff --git a/components/Home/LiveTransactions.tsx b/components/Home/LiveTransactions.tsx index 157d1b6..6ad1024 100644 --- a/components/Home/LiveTransactions.tsx +++ b/components/Home/LiveTransactions.tsx @@ -1,69 +1,16 @@ // React, NextJS imports import React from 'react'; import { Divider } from '@mui/material'; - -// Internal Components imports -import { Box, Text, Front } from '../../blocks'; +import { Box, Text, Front, Tag, Separator } from '../../blocks'; +import { useRouter } from 'next/router' +import Link from 'next/link' +import { useLiveTransactions } from '../../hooks/useLiveTransactions'; +import moment from 'moment'; +import { centerMaskString, rightMaskString } from '../../utils/helpers' export default function LiveTransactions() { - const overViewData = [ - { - status: "Success", - txHash: '0556ba4acd62f....', - from: '0556b...96e5659bf', - to: '0556b...96e5659bf', - age: '2s ago' - }, - { - status: "Success", - txHash: '0556ba4acd62f....', - from: '0556b...96e5659bf', - to: '0556b...96e5659bf', - age: '2s ago' - }, - { - status: "Success", - txHash: '0556ba4acd62f....', - from: '0556b...96e5659bf', - to: '0556b...96e5659bf', - age: '2s ago' - }, - { - status: "Success", - txHash: '0556ba4acd62f....', - from: '0556b...96e5659bf', - to: '0556b...96e5659bf', - age: '2s ago' - }, - { - status: "Success", - txHash: '0556ba4acd62f....', - from: '0556b...96e5659bf', - to: '0556b...96e5659bf', - age: '2s ago' - }, - { - status: "Success", - txHash: '0556ba4acd62f....', - from: '0556b...96e5659bf', - to: '0556b...96e5659bf', - age: '2s ago' - }, - { - status: "Success", - txHash: '0556ba4acd62f....', - from: '0556b...96e5659bf', - to: '0556b...96e5659bf', - age: '2s ago' - }, - { - status: "Success", - txHash: '0556ba4acd62f....', - from: '0556b...96e5659bf', - to: '0556b...96e5659bf', - age: '2s ago' - }, - ]; + const router = useRouter() + const { data, error, isLoading, isError } = useLiveTransactions({ lastTs: null }); return ( STATUS Tx HASH FROM - TO - AGE + TO + AGE - {overViewData.map((dt) => - + {data?.transactions.map((dt) => + router.push(`/transactions/${dt.txhash}`)} > - {dt.status} - {dt.txHash} - {dt.from} - {dt.to} - {dt.age} - - - - + + {rightMaskString(dt.txHash)} + {centerMaskString(dt.from)} + + {centerMaskString(dt?.recipients[0])} + { dt?.recipients.length > 1 && ( { `+ ${dt?.recipients.length - 1} more`}) } + + + {moment(dt.ts * 1000).fromNow()} + + + )} @@ -128,9 +80,11 @@ export default function LiveTransactions() { flexDirection="row" gap="spacing-xxxs" color="text-brand-medium" - justifyContent="flex-end" + justifyContent={{initial: "flex-end", ml: "flex-start"}} > - View All Transactions + + View All Transactions + diff --git a/components/Home/OverView.tsx b/components/Home/OverView.tsx index 3edbe6f..1f0e082 100644 --- a/components/Home/OverView.tsx +++ b/components/Home/OverView.tsx @@ -1,55 +1,81 @@ -import React from 'react'; -import { Divider, useMediaQuery } from '@mui/material'; -import { Box, Text } from '../../blocks'; - -export default function OverView() { - const isMobile = useMediaQuery('(max-width:480px)'); - return ( - - - Transactions - 245,487,099 - - - - Total Blocks - 16, 793, 950 - - +import React, { FC } from 'react'; +import { Box, Text, Separator, Skeleton } from '../../blocks'; +import { useCounts } from '../../hooks/useCounts'; + +export type OverViewProps = {}; + +const OverView: FC = () => { + const { data, error, isLoading, isError } = useCounts(); + return ( - Daily Transactions - 142, 098 + border="border-lg solid stroke-secondary" + backgroundColor="surface-primary" + borderRadius='radius-md' + width="-webkit-fill-available" + > + + + Transactions + {data?.totalTransactions} + + + + + + + + + + + + + + Total Blocks + {data?.totalBlocks} + + + + + + + + + + + + + + Daily Transactions + {data?.dailyTransactions} + + - - ) + ) } + +export default OverView; diff --git a/components/Home/SearchBar.tsx b/components/Home/SearchBar.tsx index 954ab37..0dadc33 100644 --- a/components/Home/SearchBar.tsx +++ b/components/Home/SearchBar.tsx @@ -1,6 +1,7 @@ import React, { useCallback, useState } from 'react'; import { Box, TextInput, Search } from '../../blocks'; import { ethers } from 'ethers'; +import { useDebounce } from 'react-use'; export default function SearchBar() { const [query, setQuery] = useState(''); @@ -9,11 +10,17 @@ export default function SearchBar() { const getFormattedQuery = useCallback((qry: string) => { if (!qry) return {}; const isAddress = ethers.isAddress(qry); - const key = isAddress ? 'wallet' : 'twitter'; + console.log("isAddress: ", isAddress) + + const key = isAddress ? 'wallet' : 'transaction'; const value = isAddress ? `eip155:${qry}` : qry; + console.log("{ [key]: value } :::::", { [key]: value }) + return { [key]: value }; }, []); + useDebounce(() => setDebouncedQuery(getFormattedQuery(query)), 500, [query]); + return ( + <> - - PushScan - + + - - ALPHA + PushScan + + ALPHA + + + + - - + + { asPath !== '/dashboard' && ( + + Analytics + + )} + + + + { asPath !== '/home' && } + - { asPath !== '/home' && ( - { - router.push(ROUTES.HOME); - }} - > - Home - - )} - - { asPath !== '/dashboard' && ( - { - router.push(ROUTES.DASHBOARD); - }} + display={{ ml: "flex", dp: "none" }} + flexDirection="column" + gap="spacing-xs" + > + + - Analytics - - )} - - + + + + PushScan + + ALPHA + + + + + { asPath !== '/dashboard' && ( + + Analytics + + )} + + + + + + { asPath !== '/home' && } - + + ); } diff --git a/components/Pagination.tsx b/components/Pagination.tsx index f6e221f..2031ede 100644 --- a/components/Pagination.tsx +++ b/components/Pagination.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import axios from 'axios'; -import { Box, Text, Add, CaretLeft, CaretRight } from '../blocks'; +import { Box, Text, Add, PrevIconSlider, NextIconSlider } from '../blocks'; const Pagination = ({ itemsPerPage, totalItems, paginate, currentPage }) => { const totalPages = Math.ceil(totalItems / itemsPerPage); @@ -35,34 +35,35 @@ const Pagination = ({ itemsPerPage, totalItems, paginate, currentPage }) => { return ( - currentPage > 1 && paginate(currentPage - 1)} /> + currentPage > 1 && paginate(currentPage - 1)} /> {currentPage > 3 && totalPages > 5 && ( <> - paginate(1)}>1 - {currentPage > 4 && ...} + paginate(1)}>1 + {currentPage > 4 && ...} )} {pageNumbers.map(number => ( - paginate(number)} key={number}> + paginate(number)} key={number}> {number} ))} {currentPage + 3 < totalPages && ( <> - ... - paginate(totalPages)}>{totalPages} + ... + paginate(totalPages)}>{totalPages} )} - currentPage < totalPages && paginate(currentPage + 1)} /> + currentPage < totalPages && paginate(currentPage + 1)} /> ); }; diff --git a/components/Reusables/ChainsDropDown.tsx b/components/Reusables/ChainsDropDown.tsx index b78f19b..eb6dfff 100644 --- a/components/Reusables/ChainsDropDown.tsx +++ b/components/Reusables/ChainsDropDown.tsx @@ -1,7 +1,7 @@ // React, NextJS imports import React, { FC, useRef, useState, ReactNode, useEffect } from 'react'; -import { Box, Select, Text } from '../../blocks'; +import { Box, Text } from '../../blocks'; import Ethereum from '../../blocks/illustrations/components/Ethereum'; import Polygon from '../../blocks/illustrations/components/Polygon'; import BNB from '../../blocks/illustrations/components/BNB'; @@ -42,10 +42,12 @@ export default function ChainsDropDown() { const [chain, setChain] = useState(networkOptions[0].value); return ( - setChain(value)} + /> */} + ) } diff --git a/components/Reusables/ConsensusInfo.tsx b/components/Reusables/ConsensusInfo.tsx index 3083175..e53527c 100644 --- a/components/Reusables/ConsensusInfo.tsx +++ b/components/Reusables/ConsensusInfo.tsx @@ -1,157 +1,316 @@ import React from 'react'; -import { Box, Text, Button, Add } from '../../blocks'; +import { Box, Text, Button, Add, Ethereum } from '../../blocks'; const ConsensusInfo = () => { return ( - + <> - - Consensus Info - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - + + Consensus Info - + - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + + Show more + + - + + + + Payload Data + - - Show more + 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000006419000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024ac6824ffa0000000000000000000000000000000000000000000000000000000000c2b5a6000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000020d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020d40000000000000000000000000000000000000000000000000000000000c2f8cd0000000000000000000 - Payload Data - - 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000006419000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024ac6824ffa0000000000000000000000000000000000000000000000000000000000c2b5a6000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000020d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020d40000000000000000000000000000000000000000000000000000000000c2f8cd0000000000000000000 + + Consensus Info + + + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + + + + + Show more + + + + + Payload Data + + + 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000006419000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024ac6824ffa0000000000000000000000000000000000000000000000000000000000c2b5a6000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000020d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020d40000000000000000000000000000000000000000000000000000000000c2f8cd0000000000000000000 + + + - + ); }; diff --git a/components/Reusables/TxDetails.tsx b/components/Reusables/TxDetails.tsx index 014003b..34a8081 100644 --- a/components/Reusables/TxDetails.tsx +++ b/components/Reusables/TxDetails.tsx @@ -1,41 +1,99 @@ import React from 'react'; -import { Box, Text, CaretDown } from '../../blocks'; +import { Box, Text, Tag, CaretDown } from '../../blocks'; const TXDetails = () => { return ( - + <> - Transaction Hash - Status - Block Hash - Category - Timestamp + + Transaction Hash + Status + Block Hash + Category + Timestamp + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + Notification + 40 minutes ago, Sun, Jul 21 2024 18:33:47 GMT + - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - Success - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - Notification - 40 minutes ago, Sun, Jul 21 2024 18:33:47 GMT + + Transaction Hash + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + Status + + + + + Block Hash + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + Category + Notification + + + + Timestamp + 40 minutes ago, Sun, Jul 21 2024 18:33:47 GMT + + - + ); }; diff --git a/components/Reusables/TxTravels.tsx b/components/Reusables/TxTravels.tsx index eb84870..865ce78 100644 --- a/components/Reusables/TxTravels.tsx +++ b/components/Reusables/TxTravels.tsx @@ -1,52 +1,153 @@ import React from 'react'; -import { Box, Text, Add } from '../../blocks'; +import { Box, Text, Add, Ethereum } from '../../blocks'; const TxTravels = () => { return ( - + <> - From - To + + From + To + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + Show more + + + + - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + From - - Show more + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + To + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + Show more + + + - + ); }; diff --git a/components/Transactions/ListView.tsx b/components/Transactions/ListView.tsx index 8711991..0e586fa 100644 --- a/components/Transactions/ListView.tsx +++ b/components/Transactions/ListView.tsx @@ -1,44 +1,48 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Box, Text } from '../../blocks'; import Pagination from '../Pagination'; import RowView from './RowView' - -const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] +import { useLiveTransactions } from '../../hooks/useLiveTransactions'; +import { PerPageItems } from '../../utils/constants' const ListView = () => { + const [page, setPage] = useState(null); + const { data, error, isLoading, isError } = useLiveTransactions({ lastTs: page }); + return ( - STATUS - TX HASH - BLCK HASH - FROM - TO - CATEGORY - AGE - + STATUS + TX HASH + BLCK HASH + FROM + TO + CATEGORY + AGE - {data.map((v) => ( - + {data?.transactions.map((tx) => ( + ))} console.log(pageNumber)} - currentPage={1} + itemsPerPage={PerPageItems} + totalItems={data?.totalPages * PerPageItems} + paginate={(page) => setPage(data?.lastTs)} + currentPage={page} /> ); diff --git a/components/Transactions/RowView.tsx b/components/Transactions/RowView.tsx index bb78431..16e7a9d 100644 --- a/components/Transactions/RowView.tsx +++ b/components/Transactions/RowView.tsx @@ -1,48 +1,63 @@ import React from 'react'; -import { Divider } from '@mui/material'; -import { Box, Text, Add, CaretLeft, CaretRight, BellRingFilled, BellSimple, InboxBell, InboxBellFilled, Ethereum } from '../../blocks'; +import { Box, Text, Separator, Tag, InboxBellFilled, Ethereum } from '../../blocks'; +import { useRouter } from 'next/router' +import moment from 'moment'; +import { centerMaskString, rightMaskString } from '../../utils/helpers' + +const TransactionRowView = (props) => { + const router = useRouter() -const TransactionRowView = () => { return ( router.push(`/transactions/${props.txHash}`)} > - Success - 0x2d2269ft... - 0x2d226953... + + + {rightMaskString(props.txHash)} + {rightMaskString(props.blockHash)} - 0x2dw...408df + {centerMaskString(props.from)} - - 0x2dr...508df + + + {centerMaskString(props.recipients[0])} + + { props.recipients.length > 1 && ( { `+ ${props.recipients.length - 1} more`}) } - Notification - 2s ago + {props.category} + {moment(props.ts * 1000).fromNow()} - + ); }; diff --git a/hooks/useBlocks.ts b/hooks/useBlocks.ts new file mode 100644 index 0000000..b9709af --- /dev/null +++ b/hooks/useBlocks.ts @@ -0,0 +1,18 @@ +import { useQuery } from 'react-query'; +import { POLL_INTERVAL } from '../utils/constants' +import { makeJsonRpcRequest } from '../utils/json-rpc'; + +const RPC_ID = 1 + +export const useLiveBlocks = () => { + const getBlocks = () => makeJsonRpcRequest(RPC_ID, 'getBlocks', { + "startTime": Math.floor(Date.now() / 1000), + "direction": "DESC", + "showDetails": false, + "pageSize": 10 + }); + + return useQuery('homeLiveBlocks', getBlocks, { + refetchInterval: POLL_INTERVAL + }); +} \ No newline at end of file diff --git a/hooks/useCounts.ts b/hooks/useCounts.ts new file mode 100644 index 0000000..8fdb092 --- /dev/null +++ b/hooks/useCounts.ts @@ -0,0 +1,12 @@ +import { useQuery } from 'react-query'; +import { POLL_INTERVAL } from '../utils/constants' +import { makeJsonRpcRequest } from '../utils/json-rpc'; + +const RPC_ID = 6 + +export const useCounts = () => { + const getCounts = () => makeJsonRpcRequest(RPC_ID, 'getCounts'); + return useQuery('homeOverViewCounts', getCounts, { + refetchInterval: POLL_INTERVAL + }); +} \ No newline at end of file diff --git a/hooks/useLiveTransactions.ts b/hooks/useLiveTransactions.ts new file mode 100644 index 0000000..12d368f --- /dev/null +++ b/hooks/useLiveTransactions.ts @@ -0,0 +1,89 @@ +import { useQuery } from 'react-query'; +import { POLL_INTERVAL } from '../utils/constants' +import { makeJsonRpcRequest } from '../utils/json-rpc'; +import { PerPageItems } from '../utils/constants'; + +const RPC_ID = 3 + +type Transaction = { + txnHash: string; + ts: number; + blockHash: string; + category: string; + source: string; + status: string; + from: string; + recipients: { + recipients: { address: string }[]; + }; + txnData: string; + txnDataAsJson: { + did: string; + masterpubkey: string; + derivedpubkey: string; + derivedkeyindex: number; + encderivedprivkey: string; + }; + sig: string; +}; + +type Block = { + blockHash: string; + blockData: string; + blockDataAsJson: { + ts: number; + txobjList: any[]; + attesttoken: string; + signersList: { + sig: string; + node: string; + role: number; + }[]; + }; + blockSize: number; + ts: number; + transactions: Transaction[]; + totalNumberOfTxns: number; +}; + +type ApiResponse = { + transactions: Transaction[]; +}; + +type inputProps = { + lastTs?: number | null; +}; + +export const useLiveTransactions = (props: inputProps) => { + console.log("lastTs: ", props.lastTs) + + const getTransactions = () => makeJsonRpcRequest(RPC_ID, 'getTxs', { + "startTime": props.lastTs ?? Math.floor(Date.now() / 1000), + "direction": "DESC", + "pageSize": PerPageItems + }); + + return useQuery('homeLiveTransactions', getTransactions, { + refetchInterval: POLL_INTERVAL, + select: (data) => { + const transactions = data.blocks.flatMap(block => + block.transactions.map(tx => ({ + txHash: tx.txnHash, + ts: tx.ts, + blockHash: tx.blockHash, + category: tx.category, + status: tx.status, + source: tx.source, + from: tx.from, + recipients: tx.recipients.recipients.map(recipient => recipient.address) + })) + ); + // Sorting transactions by timestamp in descending order + return { + transactions: transactions.sort((a, b) => b.ts - a.ts), + totalPages: data.totalPages, + lastTs: data.lastTs + } + } + }); +} \ No newline at end of file diff --git a/layout/index.tsx b/layout/index.tsx index f87fd89..9b2b2fa 100644 --- a/layout/index.tsx +++ b/layout/index.tsx @@ -18,8 +18,9 @@ export default function Layout({ children }) { flexDirection="column" alignItems="center" justifyContent="space-between" - height="100vh" + height="100%" margin={`spacing-none ${isMobile ? 'spacing-xs' : 'spacing-xxxl'}`} + gap="spacing-lg" > {children} diff --git a/package.json b/package.json index c8f74a4..3744d7e 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-switch": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.1", + "@reach/combobox": "^0.18.0", "@reach/tabs": "^0.18.0", "apexcharts": "^3.36.3", "axios": "^1.1.3", @@ -33,12 +34,13 @@ "react-dom": "18.2.0", "react-loader-spinner": "^5.3.4", "react-loading-skeleton": "^3.3.1", + "react-query": "^3.39.3", "react-router-dom": "^6.9.0", "react-toastify": "^9.0.8", "react-toggle-dark-mode": "^1.1.0", "react-use": "^17.4.0", "styled-components": "^5.3.6", - "@reach/combobox": "^0.18.0" + "sonner": "^1.5.0" }, "devDependencies": { "@types/lodash": "^4.14.188", diff --git a/pages/_app.tsx b/pages/_app.tsx index 39821bf..5c23079 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -15,31 +15,36 @@ import Theme from '../theme/Theme'; import { ThemeProvider as GlobalThemeProvider } from '../contexts/ThemeContext'; import { DataProvider } from '../contexts/DataContext'; +import { QueryClient, QueryClientProvider } from 'react-query'; +const queryClient = new QueryClient(); + export default function App({ Component, pageProps }: AppProps) { return ( - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + ); } diff --git a/queries/baseURL.ts b/queries/baseURL.ts new file mode 100644 index 0000000..6ac4796 --- /dev/null +++ b/queries/baseURL.ts @@ -0,0 +1,17 @@ + +export const getBaseURL = () => { + switch (process.env.APP_ENV) { + case 'prod': + return `https://us-east1-push-prod-apps.cloudfunctions.net/pushpointsrewardsystem`; + case 'staging': + return `https://us-east1-push-stage-apps.cloudfunctions.net/pushpointsrewardsystem`; + case 'dev': + return `https://us-east1-push-dev-apps.cloudfunctions.net/helloWorld`; + case 'local': + return `http://localhost:3000/rpc` + default: + return `https://us-east1-push-dev-apps.cloudfunctions.net/helloWorld`; + } +}; + +export const analyticsBaseURL = 'https://backend.epns.io/apis/v1'; diff --git a/queries/getCounts.ts b/queries/getCounts.ts new file mode 100644 index 0000000..c5aeae6 --- /dev/null +++ b/queries/getCounts.ts @@ -0,0 +1,9 @@ +import axios from 'axios'; +import { getBaseURL } from './baseURL'; +import { getRewardsActivityModelCreator } from 'queries/models'; + +export const getMetrics = (userId: string, activityId: string) => + axios({ + method: 'GET', + url: `${getBaseURL()}/users/${userId}/activity/${activityId}`, + }).then((response) => getRewardsActivityModelCreator(response.data)); diff --git a/sections/Blocks/index.tsx b/sections/Blocks/index.tsx index d85002e..edf22a1 100644 --- a/sections/Blocks/index.tsx +++ b/sections/Blocks/index.tsx @@ -5,7 +5,7 @@ import BlocksListView from '../../components/Blocks/ListView'; const Blocks = () => { return ( { return ( { flexDirection="column" justifyContent="flex-start" alignItems="flex-start" - gap="spacing-xxxl" - width="100%" + gap={{ ml: "spacing-lg", initial: "spacing-xxxl" }} > Push Blockchain Explorer @@ -38,9 +36,9 @@ const Home = () => { diff --git a/sections/Transactions/address.tsx b/sections/Transactions/address.tsx index 73fc5c5..9f55497 100644 --- a/sections/Transactions/address.tsx +++ b/sections/Transactions/address.tsx @@ -16,7 +16,7 @@ const Details = (props: TransactionDetailsProps) => { display="flex" flexDirection="column" justifyContent="flex-start" - gap="spacing-sm" + gap={{initial: "spacing-sm", ml: "spacing-md"}} > Transaction Details diff --git a/sections/Transactions/index.tsx b/sections/Transactions/index.tsx index 083bb7a..bd684fb 100644 --- a/sections/Transactions/index.tsx +++ b/sections/Transactions/index.tsx @@ -2,18 +2,38 @@ import React from 'react'; import { Box, Text } from '../../blocks'; import ListView from '../../components/Transactions/ListView'; -const Transactions = () => { +const Transactions = (props) => { return ( + - Transactions - + + { props.address && ( + Address {props.address} + Transactions for {props.address} + )} + + + Transactions + + + ); }; diff --git a/utils/constants.js b/utils/constants.js index 84d7b46..fd5c10e 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -8,6 +8,9 @@ import ArbitrumIcon from '../public/static/arbitrum.svg'; import FuseIcon from '../public/static/fuse.svg'; import CyberIcon from '../public/static/cyber.svg'; +export const POLL_INTERVAL = 30 * 1000 // 30 seconds +export const PerPageItems = 10 + export const ROUTES = { HOME: '/home', LOGIN: '/login', diff --git a/utils/helpers.ts b/utils/helpers.ts index 73691f8..51bdb7f 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -3,6 +3,12 @@ import { format, formatDistanceToNow } from 'date-fns'; import { replace } from 'lodash'; import numeral from 'numeral'; +type Signer = { + sig: string; + node: string; + role: number; +}; + export function fDate(date) { return format(new Date(date), 'dd MMMM yyyy'); } @@ -65,3 +71,34 @@ export default function getDatesArray({ return dateArray; } + +export function isErrorWithMessage(error: unknown): error is { message: string } { + return typeof error === 'object' && error !== null && 'message' in error; +} + +export function getValidatorNode(signers: Signer[]) { + const signer = signers.find(signer => signer.role === 1); + return signer?.node +} + +export function centerMaskString(str) { + // Check if the string length is more than 2 to mask characters + if (str.length > 14) { + const start = str.substring(0, 10); + const end = str.substring(str.length - 7); + return start + '...' + end; + } + // If the string is too short, return it as is + return str; +} + +export function rightMaskString(str) { + // Check if the string length is more than 15 to mask the remaining characters + if (str.length > 15) { + const visiblePart = str.substring(0, 15); + const maskedPart = '...'; + return visiblePart + maskedPart; + } + // If the string is too short to mask after 15 characters, return it as is + return str; +} \ No newline at end of file diff --git a/utils/json-rpc.ts b/utils/json-rpc.ts new file mode 100644 index 0000000..4f51652 --- /dev/null +++ b/utils/json-rpc.ts @@ -0,0 +1,19 @@ +import axios from 'axios'; + +const API_BASE = 'http://localhost:3000/rpc'; + +export const makeJsonRpcRequest = async (id, method, params = {}) => { + const data = { + jsonrpc: '2.0', + method: `RpcService.${method}`, + params: params, + id + }; + + try { + const response = await axios.post(API_BASE, data); + return response.data.result; + } catch (error) { + throw new Error('JSON-RPC Error: ' + error.message); + } +}; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index bf08912..7291f7a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -115,6 +115,13 @@ dependencies: regenerator-runtime "^0.13.10" +"@babel/runtime@^7.23.8", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb" + integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.18.10": version "7.18.10" resolved "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz" @@ -1328,6 +1335,11 @@ balanced-match@^1.0.0: resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +big-integer@^1.6.16: + version "1.6.52" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" + integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" @@ -1343,6 +1355,20 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" +broadcast-channel@^3.4.1: + version "3.7.0" + resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.7.0.tgz#2dfa5c7b4289547ac3f6705f9c00af8723889937" + integrity sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg== + dependencies: + "@babel/runtime" "^7.7.2" + detect-node "^2.1.0" + js-sha3 "0.8.0" + microseconds "0.2.0" + nano-time "1.0.0" + oblivious-set "1.0.0" + rimraf "3.0.2" + unload "2.2.0" + call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" @@ -1554,6 +1580,11 @@ detect-node-es@^1.1.0: resolved "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz" integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== +detect-node@^2.0.4, detect-node@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" @@ -2342,6 +2373,11 @@ js-sdsl@^4.1.4: resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz" integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q== +js-sha3@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" @@ -2445,6 +2481,14 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +match-sorter@^6.0.2: + version "6.3.4" + resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.4.tgz#afa779d8e922c81971fbcb4781c7003ace781be7" + integrity sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg== + dependencies: + "@babel/runtime" "^7.23.8" + remove-accents "0.5.0" + mdn-data@2.0.14: version "2.0.14" resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" @@ -2463,6 +2507,11 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" +microseconds@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39" + integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== + mime-db@1.52.0: version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" @@ -2516,6 +2565,13 @@ nano-css@^5.3.1: stacktrace-js "^2.0.2" stylis "^4.0.6" +nano-time@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef" + integrity sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA== + dependencies: + big-integer "^1.6.16" + nanoid@^3.3.4: version "3.3.4" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz" @@ -2617,6 +2673,11 @@ object.values@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" +oblivious-set@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/oblivious-set/-/oblivious-set-1.0.0.tgz#c8316f2c2fb6ff7b11b6158db3234c49f733c566" + integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw== + once@^1.3.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" @@ -2784,6 +2845,15 @@ react-loading-skeleton@^3.3.1: resolved "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.3.1.tgz" integrity sha512-NilqqwMh2v9omN7LteiDloEVpFyMIa0VGqF+ukqp0ncVlYu1sKYbYGX9JEl+GtOT9TKsh04zCHAbavnQ2USldA== +react-query@^3.39.3: + version "3.39.3" + resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.39.3.tgz#4cea7127c6c26bdea2de5fb63e51044330b03f35" + integrity sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g== + dependencies: + "@babel/runtime" "^7.5.5" + broadcast-channel "^3.4.1" + match-sorter "^6.0.2" + react-remove-scroll-bar@^2.3.4: version "2.3.6" resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz" @@ -2900,6 +2970,11 @@ regenerator-runtime@^0.13.10: resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz" integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw== +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3: version "1.4.3" resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz" @@ -2914,6 +2989,11 @@ regexpp@^3.2.0: resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== +remove-accents@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.5.0.tgz#77991f37ba212afba162e375b627631315bed687" + integrity sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A== + resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz" @@ -2947,7 +3027,7 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^3.0.2: +rimraf@3.0.2, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -3042,6 +3122,11 @@ slash@^3.0.0: resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +sonner@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/sonner/-/sonner-1.5.0.tgz#af359f817063318415326b33aab54c5d17c747b7" + integrity sha512-FBjhG/gnnbN6FY0jaNnqZOMmB73R+5IiyYAw8yBj7L54ER7HB3fOSE5OFiQiE2iXWxeXKvg6fIP4LtVppHEdJA== + source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" @@ -3348,6 +3433,14 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +unload@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7" + integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA== + dependencies: + "@babel/runtime" "^7.6.2" + detect-node "^2.0.4" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" From 30c1ddf401dc930ce40a988c3dbd8037c4e43c48 Mon Sep 17 00:00:00 2001 From: rozaso Date: Mon, 26 Aug 2024 21:00:38 -0700 Subject: [PATCH 08/42] Integrating Table component and listing blocks and transactions. --- blocks/index.ts | 1 + blocks/table/Table.tsx | 175 ++++++++++ blocks/table/Table.types.ts | 16 + blocks/table/index.ts | 1 + blocks/tag/Tag.tsx | 2 +- blocks/theme/colors/colors.semantics.ts | 4 + blocks/theme/semantics/semantics.table.ts | 14 + components/Blocks/BlockTxDetails.tsx | 73 ++++ components/Blocks/BlockView.tsx | 35 -- .../{Reusables => Blocks}/ConsensusInfo.tsx | 17 +- components/Blocks/Details.tsx | 87 +++++ components/Blocks/ListView.tsx | 77 ++++- components/Home/LiveBlocks.tsx | 100 +++--- components/Home/LiveTransactions.tsx | 140 ++++---- components/Home/SearchBar.tsx | 36 +- components/Reusables/TxTravels.tsx | 154 --------- components/Transactions/ConsensusInfo.tsx | 324 ++++++++++++++++++ components/Transactions/ListView.tsx | 114 ++++-- components/Transactions/RowView.tsx | 65 ---- .../{Reusables => Transactions}/TxDetails.tsx | 43 ++- components/Transactions/TxTravels.tsx | 137 ++++++++ hooks/useLiveBlockByHash.ts | 43 +++ hooks/useLiveTxByHash.ts | 37 ++ hooks/useSearchByAddress.ts | 44 +++ layout/index.tsx | 4 +- package.json | 4 +- .../blocks/{[address].tsx => [blockHash].tsx} | 8 +- .../{[address].tsx => [txHash].tsx} | 10 +- pages/transactions/search/[txHash].tsx | 48 +++ sections/Blocks/address.tsx | 34 -- sections/Blocks/blockHash.tsx | 39 +++ sections/Blocks/index.tsx | 3 +- sections/Home/index.tsx | 5 +- sections/Transactions/address.tsx | 30 -- sections/Transactions/index.tsx | 2 - sections/Transactions/txHash.tsx | 39 +++ types/block.ts | 31 ++ types/transaction.ts | 21 ++ utils/helpers.ts | 16 +- yarn.lock | 39 +++ 40 files changed, 1525 insertions(+), 547 deletions(-) create mode 100644 blocks/table/Table.tsx create mode 100644 blocks/table/Table.types.ts create mode 100644 blocks/table/index.ts create mode 100644 blocks/theme/semantics/semantics.table.ts create mode 100644 components/Blocks/BlockTxDetails.tsx delete mode 100644 components/Blocks/BlockView.tsx rename components/{Reusables => Blocks}/ConsensusInfo.tsx (88%) create mode 100644 components/Blocks/Details.tsx delete mode 100644 components/Reusables/TxTravels.tsx create mode 100644 components/Transactions/ConsensusInfo.tsx delete mode 100644 components/Transactions/RowView.tsx rename components/{Reusables => Transactions}/TxDetails.tsx (77%) create mode 100644 components/Transactions/TxTravels.tsx create mode 100644 hooks/useLiveBlockByHash.ts create mode 100644 hooks/useLiveTxByHash.ts create mode 100644 hooks/useSearchByAddress.ts rename pages/blocks/{[address].tsx => [blockHash].tsx} (72%) rename pages/transactions/{[address].tsx => [txHash].tsx} (71%) create mode 100644 pages/transactions/search/[txHash].tsx delete mode 100644 sections/Blocks/address.tsx create mode 100644 sections/Blocks/blockHash.tsx delete mode 100644 sections/Transactions/address.tsx create mode 100644 sections/Transactions/txHash.tsx create mode 100644 types/block.ts create mode 100644 types/transaction.ts diff --git a/blocks/index.ts b/blocks/index.ts index 15f33c6..a0c6f46 100644 --- a/blocks/index.ts +++ b/blocks/index.ts @@ -19,6 +19,7 @@ export { TextArea, type TextAreaProps } from './textarea'; export { TextInput } from './textInput'; export { ToggleSwitch } from './toggleSwtich'; export { Spinner, type SpinnerProps } from './spinner'; +export { Table, type TableProps } from './table'; export * from './Blocks.colors'; export * from './Blocks.types'; diff --git a/blocks/table/Table.tsx b/blocks/table/Table.tsx new file mode 100644 index 0000000..873fda3 --- /dev/null +++ b/blocks/table/Table.tsx @@ -0,0 +1,175 @@ +import React, { FC, useMemo } from 'react'; +import { + Table as ReactTable, + Header, + HeaderRow, + Body, + Row, + HeaderCell, + Cell, +} from '@table-library/react-table-library/table'; +import { useTheme } from '@table-library/react-table-library/theme'; +import styled from 'styled-components'; +import { textVariants } from '../text'; +import { SurfaceColors } from '../theme/Theme.types'; +import { Column, DataSource } from './Table.types'; + +export type TableProps = { + columns: Column[]; + dataSource: DataSource[]; + fixedHeader?: boolean; + backgroundColor?: SurfaceColors; +}; + +const StyledHeaderCell = styled(HeaderCell)<{ headerAlignment?: Column['headerAlignment'] }>` + ${({ headerAlignment }) => + headerAlignment + ? ` + div { + display: flex; + justify-content: ${headerAlignment}; + } + ` + : ''} +`; + +const StyledRowCell = styled(Cell)<{ cellAlignment?: Column['cellAlignment'] }>` + ${({ cellAlignment }) => + cellAlignment + ? ` + div { + display: flex; + justify-content: ${cellAlignment}; + } + ` + : ''} +`; + +const Table: FC = ({ backgroundColor = 'surface-secondary', columns, dataSource, fixedHeader = false }) => { + const columnData = useMemo(() => { + const columnWidths = columns.map((col) => col.width || `${100 / columns.length}%`); + + const leftRightPositionCSS = columns + .map((col, index) => { + if (col?.fixed == 'left') { + return ` + &:nth-of-type(${index + 1}) { + left: ${index === 0 ? '0px' : columnWidths[index]}; + }; + `; + } + if (col?.fixed == 'right') { + return ` + &:nth-of-type(${index + 1}) { + right: ${index + 1 === columns.length ? '0px' : columnWidths[index]}; + }; + `; + } + + return ''; + }) + .join(''); + + return { + columnWidthCSS: columnWidths.join(' '), + leftRightPositionCSS, + }; + }, [columns]); + + const theme = useTheme({ + Table: ` + --data-table-library_grid-template-columns: ${columnData.columnWidthCSS}; + `, + BaseCell: ` + ${columnData.leftRightPositionCSS} + `, + Cell: ` + align-items: center; + align-self: stretch; + border-bottom: var(--border-sm) solid var(--components-table-stroke-default); + color: var(--components-table-text-default); + display: flex; + flex: 1 0 0; + font-family: var(--font-family); + font-size: ${textVariants['bs-semibold'].fontSize}; + font-style: ${textVariants['bs-semibold'].fontStyle}; + font-weight: ${textVariants['bs-semibold'].fontWeight}; + line-height: ${textVariants['bs-semibold'].lineHeight}; + gap: var(--spacing-xxs); + height: 56px; + padding: var(--spacing-xxxs); + `, + Row: ` + background: var(--${backgroundColor}); + `, + HeaderRow: ` + background: var(--${backgroundColor}); + `, + HeaderCell: ` + align-items: center; + color: var(--components-table-text-heading); + display: flex; + font-family: var(--font-family); + font-size: ${textVariants['c-bold'].fontSize}; + font-style: ${textVariants['c-bold'].fontStyle}; + font-weight: ${textVariants['c-bold'].fontWeight}; + line-height: ${textVariants['c-bold'].lineHeight}; + padding: var(--spacing-xxs) var(--spacing-xxxs); + gap: 10px; + `, + }); + + return ( + + {(tableList: DataSource[]) => ( + <> +
+ + {columns.map((column, index) => ( + + {column.title} + + ))} + +
+ + + {tableList.map((record) => ( + + {columns.map((column) => { + const cellValue = `${record?.[column.dataIndex] || ''}`; + return ( + + {column.render ? column.render(cellValue, record) : cellValue} + + ); + })} + + ))} + + + )} +
+ ); +}; + +export { Table }; diff --git a/blocks/table/Table.types.ts b/blocks/table/Table.types.ts new file mode 100644 index 0000000..9938dfd --- /dev/null +++ b/blocks/table/Table.types.ts @@ -0,0 +1,16 @@ +import { CSSProperties, ReactNode } from 'react'; + +export type Column = { + title: string; + dataIndex: string; + cellAlignment?: CSSProperties['justifyContent']; + headerAlignment?: CSSProperties['justifyContent']; + render?: (text: string | string[], record: any) => ReactNode; + width?: string; + fixed?: 'left' | 'right'; +}; + +export type DataSource = { + id: string; + [key: string]: any; +}; diff --git a/blocks/table/index.ts b/blocks/table/index.ts new file mode 100644 index 0000000..75193ad --- /dev/null +++ b/blocks/table/index.ts @@ -0,0 +1 @@ +export * from './Table'; diff --git a/blocks/tag/Tag.tsx b/blocks/tag/Tag.tsx index 6613f92..cfcbba9 100644 --- a/blocks/tag/Tag.tsx +++ b/blocks/tag/Tag.tsx @@ -15,7 +15,7 @@ const StyledTagContainer = styled.div<{ variant: TagVariant }>` background: var(--components-tag-background-${({ variant }) => variant}); display: flex; gap: var(--spacing-xxxs); - padding: var(--spacing-none) var(--spacing-xxxs); + padding: var(--spacing-xxxs) var(--spacing-xxs); width: max-content; `; diff --git a/blocks/theme/colors/colors.semantics.ts b/blocks/theme/colors/colors.semantics.ts index a392a8f..43a8075 100644 --- a/blocks/theme/colors/colors.semantics.ts +++ b/blocks/theme/colors/colors.semantics.ts @@ -25,6 +25,7 @@ import { textAreaSemantics } from '../semantics/semantics.textarea'; import { toastSemantics } from '../semantics/semantics.toast'; import { tooltipSemantics } from '../semantics/semantics.tooltip'; import { spinnerSemantics } from '../semantics/semantics.spinner'; +import { tableSemantics } from '../semantics/semantics.table'; // TODO: find a better way to do this in future type SemanticKeys = { @@ -46,6 +47,7 @@ type SemanticKeys = { surface: 'surface'; stroke: 'stroke'; skeleton: 'components-skeleton-loader'; + table: 'components-table', tag: 'components-tag'; text: 'text'; textArea: 'components-textarea'; @@ -74,6 +76,7 @@ export const semanticKeys: SemanticKeys = { surface: 'surface', stroke: 'stroke', skeleton: 'components-skeleton-loader', + table: 'components-table', tag: 'components-tag', text: 'text', textArea: 'components-textarea', @@ -109,4 +112,5 @@ export const colorSemantics = { [semanticKeys.toggle]: switchSemantics, [semanticKeys.tooltip]: tooltipSemantics, [semanticKeys.spinner]: spinnerSemantics, + [semanticKeys.table]: tableSemantics }; diff --git a/blocks/theme/semantics/semantics.table.ts b/blocks/theme/semantics/semantics.table.ts new file mode 100644 index 0000000..ccdaed4 --- /dev/null +++ b/blocks/theme/semantics/semantics.table.ts @@ -0,0 +1,14 @@ +import { iconSemantics } from './semantics.icon'; +import { strokeSemantics } from './semantics.stroke'; +import { textSemantics } from './semantics.text'; + +export const tableSemantics = { + 'stroke-default': { light: strokeSemantics['tertiary'].light, dark: strokeSemantics['tertiary'].dark }, + + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-heading': { light: textSemantics['tertiary'].light, dark: textSemantics['tertiary'].dark }, + 'text-disabled': { light: textSemantics['state-disabled'].light, dark: textSemantics['state-disabled'].dark }, + + 'icon-default': { light: iconSemantics['primary'].light, dark: iconSemantics['primary'].dark }, + 'icon-disabled': { light: iconSemantics['state-disabled'].light, dark: iconSemantics['state-disabled'].dark }, +}; diff --git a/components/Blocks/BlockTxDetails.tsx b/components/Blocks/BlockTxDetails.tsx new file mode 100644 index 0000000..e0b55a1 --- /dev/null +++ b/components/Blocks/BlockTxDetails.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import { Box, Text } from '../../blocks'; +import { BlockDetails } from '../../types/block' + +interface IProps { + data: BlockDetails | null | undefined, + isLoading: boolean +} + +const BlockTXDetails = (props: IProps) => { + return ( + <> + + + Transactions + Block Size + + + + { props.data?.totalNumberOfTxns } + { props.data?.blockSize } + + + + + + Transactions + { props.data?.totalNumberOfTxns } + + + + + Block Size + { props.data?.blockSize } + + + + ); +}; + +export default BlockTXDetails; \ No newline at end of file diff --git a/components/Blocks/BlockView.tsx b/components/Blocks/BlockView.tsx deleted file mode 100644 index e3d72cf..0000000 --- a/components/Blocks/BlockView.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react'; -import { Divider } from '@mui/material'; -import { Box, Text } from '../../blocks'; -import { useRouter } from 'next/router' -import { getValidatorNode } from '../../utils/helpers' -import moment from 'moment'; - -const BlockView = (props) => { - const router = useRouter() - - return ( - - router.push(`/blocks/${props.block.blockHash}`)} - > - {props.block.blockHash} - {getValidatorNode(props.block.blockDataAsJson?.signersList)} - {props.block.totalNumberOfTxns} - {props.block.blockSize} - {moment(props.block.ts * 1000).fromNow()} - - - - ); -}; - -export default BlockView; \ No newline at end of file diff --git a/components/Reusables/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx similarity index 88% rename from components/Reusables/ConsensusInfo.tsx rename to components/Blocks/ConsensusInfo.tsx index e53527c..0899653 100644 --- a/components/Reusables/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -1,7 +1,14 @@ import React from 'react'; import { Box, Text, Button, Add, Ethereum } from '../../blocks'; +import { BlockDetails } from '../../types/block' -const ConsensusInfo = () => { +interface IProps { + data: BlockDetails | null | undefined, + isLoading: boolean +} + +const ConsensusInfo = (props: IProps) => { + return ( <> { Consensus Info @@ -139,7 +146,7 @@ const ConsensusInfo = () => { Payload Data @@ -149,7 +156,7 @@ const ConsensusInfo = () => { padding="spacing-sm" width="68vw" > - 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000006419000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024ac6824ffa0000000000000000000000000000000000000000000000000000000000c2b5a6000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000020d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020d40000000000000000000000000000000000000000000000000000000000c2f8cd0000000000000000000 + {props.data?.blockData} @@ -305,7 +312,7 @@ const ConsensusInfo = () => { padding="spacing-sm" width="88vw" > - 0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000006419000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024ac6824ffa0000000000000000000000000000000000000000000000000000000000c2b5a6000000000000000000000000000000000000000000000000000000000000017f00000000000000000000000000000000000000000000000000000000000020d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020d40000000000000000000000000000000000000000000000000000000000c2f8cd0000000000000000000 + {props.data?.blockData} diff --git a/components/Blocks/Details.tsx b/components/Blocks/Details.tsx new file mode 100644 index 0000000..8e3bd35 --- /dev/null +++ b/components/Blocks/Details.tsx @@ -0,0 +1,87 @@ +import React from 'react'; +import { Box, Text } from '../../blocks'; +import moment from 'moment'; +import { BlockDetails } from '../../types/block' +import { getValidatorNode } from '../../utils/helpers' + +interface IProps { + data: BlockDetails | null | undefined, + isLoading: boolean +} + +const Details = (props: IProps) => { + return ( + <> + + + Block Hash + Validator + Timestamp + + + + { props.data?.blockHash } + { getValidatorNode(props.data?.signers) } + { props.data?.ts && moment(props.data.ts * 1000).fromNow() } + + + + + + Block Hash + { props.data?.blockHash } + + + + + Validator + { getValidatorNode(props.data?.signers) } + + + + Timestamp + { props.data?.ts && moment(props.data.ts * 1000).fromNow() } + + + + + ); +}; + +export default Details; \ No newline at end of file diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx index f61ffa6..f19e252 100644 --- a/components/Blocks/ListView.tsx +++ b/components/Blocks/ListView.tsx @@ -1,37 +1,76 @@ import React, { useState } from 'react'; -import { Box, Text } from '../../blocks'; +import { Box, Text, Table } from '../../blocks'; import Pagination from '../Pagination'; -import BlockView from './BlockView' import { useLiveBlocks } from '../../hooks/useBlocks'; import { PerPageItems } from '../../utils/constants' +import { useRouter } from 'next/router' +import moment from 'moment'; +import { getValidatorNode } from '../../utils/helpers' const Blocks = () => { + const router = useRouter() const [page, setPage] = useState(1); const { data, error, isLoading, isError } = useLiveBlocks(); + const columns = [ + { + title: 'BLOCK HASH', + dataIndex: 'blockHash', + render: (text) => router.push(`/blocks/${text}`)}>{text}, + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', + width: '35%' + }, + { + title: 'VALIDATOR', + dataIndex: 'validator', + render: (text) => {text}, + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', + width: '35%' + }, + { + title: 'TXN', + dataIndex: 'totalNumberOfTxns', + render: (text) => {text}, + cellAlignment: 'center', + headerAlignment: 'center', + width: '10%' + }, + { + title: 'SIZE', + dataIndex: 'blockSize', + render: (text) => {text}, + cellAlignment: 'center', + headerAlignment: 'center', + width: '10%' + }, + { + title: 'AGE', + dataIndex: 'ts', + render: (text) => {moment(text * 1000).fromNow()}, + cellAlignment: 'flex-end', + headerAlignment: 'flex-end', + width: '10%' + }, + ]; + + const dataSource = data?.blocks?.map(block => ({ + id: block.blockHash, + blockHash: block.blockHash, + validator: getValidatorNode(block.blockDataAsJson?.signersList), // Define this function or update data mapping accordingly + totalNumberOfTxns: block.totalNumberOfTxns, + blockSize: block.blockSize, + ts: block.ts + })) || []; + return ( - - BLOCK HASH - VALIDATOR - TXN - SIZE (IN BYTES) - AGE - - - {data?.blocks?.map((block) => )} + router.push(`/blocks/${text}`)}>{text}, + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', + width: '35%' + }, + { + title: 'VALIDATOR', + dataIndex: 'validator', + render: (text) => {text}, + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', + width: '35%' + }, + { + title: 'TX', + dataIndex: 'totalNumberOfTxns', + render: (text) => {text}, + cellAlignment: 'center', + headerAlignment: 'center', + width: '15%' + }, + { + title: 'AGE', + dataIndex: 'ts', + render: (text) => {moment(text * 1000).fromNow()}, + cellAlignment: 'flex-end', + headerAlignment: 'flex-end', + width: '15%' + }, + ]; + + const dataSource = data?.blocks?.map(block => ({ + id: block.blockHash, + blockHash: block.blockHash, + validator: getValidatorNode(block.blockDataAsJson?.signersList), // Define this function or update data mapping accordingly + totalNumberOfTxns: block.totalNumberOfTxns, + ts: block.ts + })) || []; + return ( - - Live Blocks - - - BLOCK HASH - VALIDATOR - TX - AGE - - {data?.blocks?.map((dt) => - - router.push(`/blocks/${dt.blockHash}`)} - > - {rightMaskString(dt.blockHash)} - {centerMaskString(getValidatorNode(dt.blockDataAsJson?.signersList))} - {dt.totalNumberOfTxns} - {moment(dt.ts * 1000).fromNow()} - - - - )} - - + Live Blocks +
, + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', + width: '10%' + }, + { + title: 'Tx HASH', + dataIndex: 'txHash', + render: (txHash: string) => router.push(`/transactions/${txHash}`)}>{rightMaskString(txHash)}, + cellAlignment: 'center', + headerAlignment: 'center', + width: '25%' + }, + { + title: 'FROM', + dataIndex: 'from', + render: (from: string) => {centerMaskString(from)}, + cellAlignment: 'center', + headerAlignment: 'center', + width: '25%' + }, + { + title: 'TO', + dataIndex: 'recipients', + render: (recipients: string) => { + const reci = recipients.split(',') + return ( + + {centerMaskString(reci[0])} + { reci.length > 1 && {`+ ${reci.length - 1} more`}} + + )}, + cellAlignment: 'center', + headerAlignment: 'center', + width: '30%' + }, + { + title: 'AGE', + dataIndex: 'ts', + render: (ts: number) => {moment(ts * 1000).fromNow()}, + cellAlignment: 'flex-end', + headerAlignment: 'flex-end', + width: '10%' + }, + ]; + + const dataSource = data?.transactions.map((dt) => ({ + id: dt.txHash, + status: dt.status, + txHash: dt.txHash, + from: dt.from, + recipients: dt.recipients, + ts: dt.ts, + })) || []; + return ( - Live Transactions +
- - STATUS - Tx HASH - FROM - TO - AGE - - {data?.transactions.map((dt) => - - router.push(`/transactions/${dt.txhash}`)} - > - - {rightMaskString(dt.txHash)} - {centerMaskString(dt.from)} - - {centerMaskString(dt?.recipients[0])} - { dt?.recipients.length > 1 && ( { `+ ${dt?.recipients.length - 1} more`}) } - - - {moment(dt.ts * 1000).fromNow()} - - - - - )} + + View All Transactions + + - - - - View All Transactions - - - ) } diff --git a/components/Home/SearchBar.tsx b/components/Home/SearchBar.tsx index 0dadc33..a7faba5 100644 --- a/components/Home/SearchBar.tsx +++ b/components/Home/SearchBar.tsx @@ -1,39 +1,33 @@ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; import { Box, TextInput, Search } from '../../blocks'; import { ethers } from 'ethers'; import { useDebounce } from 'react-use'; +import { useRouter } from 'next/router' export default function SearchBar() { + const router = useRouter() + const [query, setQuery] = useState(''); - const [debouncedQuery, setDebouncedQuery] = useState({}); + const [debouncedQuery, setDebouncedQuery] = useState(''); const getFormattedQuery = useCallback((qry: string) => { - if (!qry) return {}; + if (!qry) return ''; const isAddress = ethers.isAddress(qry); - console.log("isAddress: ", isAddress) - - const key = isAddress ? 'wallet' : 'transaction'; const value = isAddress ? `eip155:${qry}` : qry; - console.log("{ [key]: value } :::::", { [key]: value }) + console.log(" Search Value: ", value) - return { [key]: value }; + return value; }, []); useDebounce(() => setDebouncedQuery(getFormattedQuery(query)), 500, [query]); - + return ( - - } - value={query} - onChange={(e) => setQuery(e.target.value)} - /> - + router.push(`/transactions/search/${debouncedQuery}`)}/>} + value={query} + onChange={(e) => setQuery(e.target.value)} + /> ) } diff --git a/components/Reusables/TxTravels.tsx b/components/Reusables/TxTravels.tsx deleted file mode 100644 index 865ce78..0000000 --- a/components/Reusables/TxTravels.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import React from 'react'; -import { Box, Text, Add, Ethereum } from '../../blocks'; - -const TxTravels = () => { - return ( - <> - - - From - To - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - Show more - - - - - - - - - From - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - - To - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - Show more - - - - - - ); -}; - -export default TxTravels; \ No newline at end of file diff --git a/components/Transactions/ConsensusInfo.tsx b/components/Transactions/ConsensusInfo.tsx new file mode 100644 index 0000000..10a9959 --- /dev/null +++ b/components/Transactions/ConsensusInfo.tsx @@ -0,0 +1,324 @@ +import React from 'react'; +import { Box, Text, Button, Add, Ethereum } from '../../blocks'; +import { Transaction } from '../../types/transaction'; + +interface IProps { + data: Transaction | null | undefined, + isLoading: boolean +} + +const ConsensusInfo = (props: IProps) => { + + return ( + <> + + + + Consensus Info + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + + Show more + + + + + + + Payload Data + + + {props.data?.txnData} + + + + + + + + + Consensus Info + + + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + + + + + + 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + + + + + + + + Show more + + + + + + + Payload Data + + + {props.data?.txnData} + + + + + + ); +}; + +export default ConsensusInfo; \ No newline at end of file diff --git a/components/Transactions/ListView.tsx b/components/Transactions/ListView.tsx index 0e586fa..4ed860b 100644 --- a/components/Transactions/ListView.tsx +++ b/components/Transactions/ListView.tsx @@ -1,43 +1,107 @@ import React, { useState } from 'react'; -import { Box, Text } from '../../blocks'; +import { Box, Text, Tag, Table } from '../../blocks'; import Pagination from '../Pagination'; -import RowView from './RowView' import { useLiveTransactions } from '../../hooks/useLiveTransactions'; import { PerPageItems } from '../../utils/constants' +import { capitalizeStr } from '../../utils/helpers' +import { useRouter } from 'next/router' +import moment from 'moment'; +import { TagVariant } from '../../blocks/tag'; const ListView = () => { + const router = useRouter() + const [page, setPage] = useState(null); const { data, error, isLoading, isError } = useLiveTransactions({ lastTs: page }); + const columns = [ + { + title: 'STATUS', + dataIndex: 'status', + render: (status: string) => , + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', + width: '10%' + }, + { + title: 'TX HASH', + dataIndex: 'txHash', + render: (txHash: string) => router.push(`/transactions/${txHash}`)}>{txHash}, + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', + width: '15%' + }, + { + title: 'BLOCK HASH', + dataIndex: 'blockHash', + render: (blockHash: string) => router.push(`/transactions/${txHash}`)}>{blockHash}, + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', + width: '15%' + }, + { + title: 'FROM', + dataIndex: 'from', + render: (from: string) => {from}, + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', + width: '20%' + }, + { + title: 'TO', + dataIndex: 'recipients', + render: (recipients: string) => { + const reci = recipients.split(',') + return ( + + {reci[0]} + { reci.length > 1 && {`+ ${reci.length - 1} more`}} + + )}, + cellAlignment: 'center', + headerAlignment: 'center', + width: '25%' + }, + { + title: 'CATEGORY', + dataIndex: 'category', + render: (category: string) => {category}, + cellAlignment: 'center', + headerAlignment: 'center', + width: '10%' + }, + { + title: 'AGE', + dataIndex: 'ts', + render: (ts: number) => {moment(ts * 1000).fromNow()}, + cellAlignment: 'flex-end', + headerAlignment: 'flex-end', + width: '5%' + }, + ]; + + const dataSource = data?.transactions.map((dt) => ({ + id: dt.txHash, + status: dt.status, + txHash: dt.txHash, + blockHash: dt.blockHash, + category: dt.category, + from: dt.from, + recipients: dt.recipients, + ts: dt.ts, + })) || []; + + return ( - - STATUS - TX HASH - BLCK HASH - FROM - TO - CATEGORY - AGE - - - {data?.transactions.map((tx) => ( - - ))} - +
{ - const router = useRouter() - - return ( - - router.push(`/transactions/${props.txHash}`)} - > - - - {rightMaskString(props.txHash)} - {rightMaskString(props.blockHash)} - - - - {centerMaskString(props.from)} - - - - - - {centerMaskString(props.recipients[0])} - - { props.recipients.length > 1 && ( { `+ ${props.recipients.length - 1} more`}) } - - - {props.category} - {moment(props.ts * 1000).fromNow()} - - - - ); -}; - -export default TransactionRowView; \ No newline at end of file diff --git a/components/Reusables/TxDetails.tsx b/components/Transactions/TxDetails.tsx similarity index 77% rename from components/Reusables/TxDetails.tsx rename to components/Transactions/TxDetails.tsx index 34a8081..85135fa 100644 --- a/components/Reusables/TxDetails.tsx +++ b/components/Transactions/TxDetails.tsx @@ -1,7 +1,21 @@ import React from 'react'; -import { Box, Text, Tag, CaretDown } from '../../blocks'; +import { Box, Text, Tag } from '../../blocks'; +import { Transaction } from '../../types/transaction'; +import moment from 'moment'; +import { TagVariant } from '../../blocks/tag'; + +interface IProps { + data: Transaction | null | undefined, + isLoading: boolean +} + +const TXDetails = (props: IProps) => { + let status: TagVariant = "default" + + if (props.data?.status) { + status = props.data.status.toLowerCase() as TagVariant + } -const TXDetails = () => { return ( <> { alignItems="flex-start" borderRadius="radius-sm" backgroundColor="surface-primary" - gap="spacing-xxxxl" + gap="spacing-xxxl" padding="spacing-md" > { flexDirection="column" gap="spacing-sm" > - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - Notification - 40 minutes ago, Sun, Jul 21 2024 18:33:47 GMT + {props.data?.txnHash} + + {props.data?.blockHash} + {props.data?.category} + { props.data?.ts && moment(props.data.ts * 1000).fromNow() } @@ -53,7 +67,7 @@ const TXDetails = () => { gap="spacing-xxxs" > Transaction Hash - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + {props.data?.txnHash} { flexDirection="column" gap="spacing-xxxs" > - Status - + Status + { gap="spacing-xxxs" > Block Hash - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + {props.data?.blockHash} { gap="spacing-xxxs" > Category - Notification + {props.data?.category} { gap="spacing-xxxs" > Timestamp - 40 minutes ago, Sun, Jul 21 2024 18:33:47 GMT - + { props.data?.ts && moment(props.data.ts * 1000).fromNow() } diff --git a/components/Transactions/TxTravels.tsx b/components/Transactions/TxTravels.tsx new file mode 100644 index 0000000..3080149 --- /dev/null +++ b/components/Transactions/TxTravels.tsx @@ -0,0 +1,137 @@ +import React, { useState } from 'react'; +import { Box, Text, Ethereum } from '../../blocks'; +import { Transaction } from '../../types/transaction'; + +const MAX_DISPLAY = 5; + +interface IProps { + data: Transaction | null | undefined, + isLoading: boolean +} + +const TxTravels = (props: IProps) => { + const [showAll, setShowAll] = useState(false); + + const toggleShowAll = () => { + setShowAll(!showAll); + }; + + const recipients = props.data?.recipients?.recipients || []; + const displayedRecipients = showAll ? recipients : recipients.slice(0, MAX_DISPLAY); + const showMoreButton = recipients.length > MAX_DISPLAY; + + return ( + <> + + + From + To + + + + {props.data?.from} + + {displayedRecipients.map((recipient, index) => ( + {recipient.address} + ))} + + {showMoreButton && ( + + + {showAll ? 'Show Less' : 'Show More'} + + + )} + + + + + + + From + + + {props.data?.from} + + + + + To + + {displayedRecipients.map((recipient, index) => ( + {recipient.address} + ))} + + {showMoreButton && ( + + + {showAll ? 'Show Less' : 'Show More'} + + + )} + + + + + ); +}; + +export default TxTravels; \ No newline at end of file diff --git a/hooks/useLiveBlockByHash.ts b/hooks/useLiveBlockByHash.ts new file mode 100644 index 0000000..0d8ef05 --- /dev/null +++ b/hooks/useLiveBlockByHash.ts @@ -0,0 +1,43 @@ +import { useQuery } from 'react-query'; +import { POLL_INTERVAL } from '../utils/constants' +import { makeJsonRpcRequest } from '../utils/json-rpc'; +import { BlockDetails } from '../types/block'; + +const RPC_ID = 2 + +export interface BlockDetailsProps { + blockHash: string | string[] | undefined; +} + +export const useLiveBlockByHash = (params: BlockDetailsProps) => { + const getBlockByHash = () => makeJsonRpcRequest(RPC_ID, 'getBlockByHash', { + "blockHash": params.blockHash, + "showDetails": true + }); + + return useQuery('getBlockByHashDetails', getBlockByHash, { + refetchInterval: POLL_INTERVAL, + select: (data) => { + if (data.blocks && data.blocks.length > 0) { + const { blocks } = data; + // Creating a summary of the block details + const blockDetails: BlockDetails = { + blockData: blocks[0].blockData, + blockHash: blocks[0].blockHash, + blockSize: blocks[0].blockSize, + totalNumberOfTxns: blocks[0].totalNumberOfTxns, + signers: blocks[0].blockDataAsJson?.signersList, + ts: blocks[0].ts + }; + + return { + blockDetails + } + } + + return { + blockDetails: null + } + } + }); +} \ No newline at end of file diff --git a/hooks/useLiveTxByHash.ts b/hooks/useLiveTxByHash.ts new file mode 100644 index 0000000..0318f79 --- /dev/null +++ b/hooks/useLiveTxByHash.ts @@ -0,0 +1,37 @@ +import { useQuery } from 'react-query'; +import { POLL_INTERVAL } from '../utils/constants' +import { makeJsonRpcRequest } from '../utils/json-rpc'; +import { Transaction } from '../types/transaction'; + +const RPC_ID = 5 + +export interface TxDetailsProps { + txHash: string | string[] | undefined; + search?: boolean; +} + +export const useLiveTxByHash = (params: TxDetailsProps) => { + const getTxByHash = () => makeJsonRpcRequest(RPC_ID, 'getTxByHash', { + "transactionHash": params.txHash, + "showDetails": true + }); + + return useQuery('getTxByHashDetails', getTxByHash, { + refetchInterval: POLL_INTERVAL, + select: (data) => { + if (data.blocks && data.blocks.length > 0) { + const { blocks } = data; + // Creating a summary of the block details + const transaction: Transaction = blocks[0].transactions[0] + + return { + transaction + } + } + + return { + transaction: null + } + } + }); +} \ No newline at end of file diff --git a/hooks/useSearchByAddress.ts b/hooks/useSearchByAddress.ts new file mode 100644 index 0000000..9e4e6cd --- /dev/null +++ b/hooks/useSearchByAddress.ts @@ -0,0 +1,44 @@ +import { useQuery } from 'react-query'; +import { makeJsonRpcRequest } from '../utils/json-rpc'; +import { Transaction } from '../types/transaction'; +import { POLL_INTERVAL } from '../utils/constants' + +const RPC_ID = 7 + +export interface searchProps { + address: string | string[] | undefined; +} + +export const useSearchByAddress = (params: searchProps) => { + + console.log("useSearchByAddress hook params : ", params.address) + + const searchByAddress = () => makeJsonRpcRequest(RPC_ID, 'searchByAddress', { + "searchTerm": params.address, + "startTime": Math.floor(Date.now() / 1000), + "direction": "DESC", + "pageSize": 10, + "showDetails": true + }); + + return useQuery('searchByAddressDetailswee', searchByAddress, { + cacheTime: 0, + staleTime: 0, + refetchInterval: 5000, + select: (data) => { + if (data.blocks && data.blocks.length > 0) { + const { blocks } = data; + // Creating a summary of the block details + const transaction: Transaction = blocks[0].transactions[0] + + return { + transaction + } + } + + return { + transaction: null + } + } + }); +} \ No newline at end of file diff --git a/layout/index.tsx b/layout/index.tsx index 9b2b2fa..750fa3e 100644 --- a/layout/index.tsx +++ b/layout/index.tsx @@ -2,8 +2,8 @@ import React from 'react'; // External Library imports -import { Box, Text, Add, CaretLeft, CaretRight } from '../blocks'; -import { useMediaQuery, useScrollTrigger } from '@mui/material'; +import { Box } from '../blocks'; +import { useMediaQuery } from '@mui/material'; // Internal Components imports import FooterSection from '../sections/Footer'; diff --git a/package.json b/package.json index 3744d7e..ce7ad30 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,9 @@ "react-toggle-dark-mode": "^1.1.0", "react-use": "^17.4.0", "styled-components": "^5.3.6", - "sonner": "^1.5.0" + "sonner": "^1.5.0", + "@table-library/react-table-library": "^4.1.7" + }, "devDependencies": { "@types/lodash": "^4.14.188", diff --git a/pages/blocks/[address].tsx b/pages/blocks/[blockHash].tsx similarity index 72% rename from pages/blocks/[address].tsx rename to pages/blocks/[blockHash].tsx index c4b9f62..f3a922a 100644 --- a/pages/blocks/[address].tsx +++ b/pages/blocks/[blockHash].tsx @@ -5,21 +5,21 @@ import dynamic from 'next/dynamic'; import Head from 'next/head'; const Layout = dynamic(() => import('../../layout')); -const BlocksDetailsView = dynamic(() => import('../../sections/Blocks/address'), { +const BlocksDetailsView = dynamic(() => import('../../sections/Blocks/blockHash'), { loading: () =>

Loading...

, }); const BlocksDetailsPage = () => { const router = useRouter(); - const { address } = router.query; // Accessing the dynamic address parameter + const { blockHash } = router.query; return ( <> - Blocks Details for {address} + Blocks Details for {blockHash} - + ); diff --git a/pages/transactions/[address].tsx b/pages/transactions/[txHash].tsx similarity index 71% rename from pages/transactions/[address].tsx rename to pages/transactions/[txHash].tsx index c97332d..452f487 100644 --- a/pages/transactions/[address].tsx +++ b/pages/transactions/[txHash].tsx @@ -5,21 +5,21 @@ import dynamic from 'next/dynamic'; import Head from 'next/head'; const Layout = dynamic(() => import('../../layout')); -const TransactionDetailsView = dynamic(() => import('../../sections/Transactions/address'), { +const TransactionDetailsView = dynamic(() => import('../../sections/Transactions/txHash'), { loading: () =>

Loading...

, }); const TransactionDetailsPage = () => { const router = useRouter(); - const { address } = router.query; // Accessing the dynamic address parameter - + const { txHash } = router.query; // Accessing the dynamic address parameter + return ( <> - Transaction Details for {address} + Transaction Details for {txHash} - + ); diff --git a/pages/transactions/search/[txHash].tsx b/pages/transactions/search/[txHash].tsx new file mode 100644 index 0000000..30029b4 --- /dev/null +++ b/pages/transactions/search/[txHash].tsx @@ -0,0 +1,48 @@ +// React, NextJS imports +import React, { useEffect, useState } from 'react'; +import Head from 'next/head'; +import dynamic from 'next/dynamic'; +import { useRouter } from 'next/router'; +import { useSearchByAddress } from '../../../hooks/useSearchByAddress' +import { TransactionLoader } from '../../../components/Loader/TransactionLoader'; + +const TransactionView = dynamic(() => import('../../../sections/Transactions'), { + loading: () => , +}); + +const TransactionDetailsView = dynamic(() => import('../../../sections/Transactions/txHash'), { + loading: () =>

Loading...

, + }); + +const Layout = dynamic(() => import('../../../layout')); + +export default function Transactions() { + const router = useRouter(); + const { txHash } = router.query; // Accessing the dynamic address parameter + const [address, setAddress] = useState(''); + + useEffect(() => { + if (router.isReady && txHash && typeof txHash === 'string') { + setAddress(txHash); // Ensuring txHash is treated as a string + } + }, [router.isReady, txHash]); + + console.log(" address : ", address) + const { data, error, isLoading, isError } = useSearchByAddress({ address }); + console.log(" data : ", data) + + if (!address) { + return ; // Render a loading state or placeholder until address is defined + } + + return ( + <> + + Push Transactions + + + + + + ); +} diff --git a/sections/Blocks/address.tsx b/sections/Blocks/address.tsx deleted file mode 100644 index 1f3b375..0000000 --- a/sections/Blocks/address.tsx +++ /dev/null @@ -1,34 +0,0 @@ -// React, NextJS imports -import React from 'react'; -// External Library imports -import { useMediaQuery } from '@mui/material'; -import { Box, Text, Add, CaretDown, Button } from '../../blocks'; -import Advanced from '../../components/Reusables/Advanced'; -import ConsensusInfo from '../../components/Reusables/ConsensusInfo'; -import TXDetails from '../../components/Reusables/TxDetails' -import TxTravels from '../../components/Reusables/TxTravels' - -interface BlocksDetailsProps { - address: string | string[] | undefined; -} - -const Details = (props: BlocksDetailsProps) => { - const isMobile = useMediaQuery('(max-width:480px)'); - return ( - - Block Details - - - - - - ); -}; - -export default Details; \ No newline at end of file diff --git a/sections/Blocks/blockHash.tsx b/sections/Blocks/blockHash.tsx new file mode 100644 index 0000000..924640e --- /dev/null +++ b/sections/Blocks/blockHash.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { Box, Text } from '../../blocks'; +import Advanced from '../../components/Reusables/Advanced'; +import ConsensusInfo from '../../components/Blocks/ConsensusInfo'; +import BlockDetails from '../../components/Blocks/Details' +import BlockTxDetails from '../../components/Blocks/BlockTxDetails' +import { useLiveBlockByHash, BlockDetailsProps } from '../../hooks/useLiveBlockByHash'; + +const Details = (props: BlockDetailsProps) => { + + const { data, error, isLoading, isError } = useLiveBlockByHash({ blockHash: props.blockHash }); + + return ( + + Block Details + + + + + + ); +}; + +export default Details; \ No newline at end of file diff --git a/sections/Blocks/index.tsx b/sections/Blocks/index.tsx index edf22a1..dc1700e 100644 --- a/sections/Blocks/index.tsx +++ b/sections/Blocks/index.tsx @@ -5,10 +5,9 @@ import BlocksListView from '../../components/Blocks/ListView'; const Blocks = () => { return ( Blocks diff --git a/sections/Home/index.tsx b/sections/Home/index.tsx index ef9df82..3566653 100644 --- a/sections/Home/index.tsx +++ b/sections/Home/index.tsx @@ -12,7 +12,8 @@ const Home = () => { display="flex" flexDirection="column" gap="spacing-xxxl" - > + + > { width="100%" display="flex" flexDirection={{ initial: "row", ml: "column" }} + gap={{ initial: "spacing-xxxl", ml: "spacing-xxl" }} justifyContent="space-between" - gap={{ initial: "spacing-sm", ml: "spacing-xxl" }} > diff --git a/sections/Transactions/address.tsx b/sections/Transactions/address.tsx deleted file mode 100644 index 9f55497..0000000 --- a/sections/Transactions/address.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import { Box, Text } from '../../blocks'; -import Advanced from '../../components/Reusables/Advanced'; -import ConsensusInfo from '../../components/Reusables/ConsensusInfo'; -import TXDetails from '../../components/Reusables/TxDetails' -import TxTravels from '../../components/Reusables/TxTravels' - -interface TransactionDetailsProps { - address: string | string[] | undefined; -} - -const Details = (props: TransactionDetailsProps) => { - return ( - - Transaction Details - - - - - - ); -}; - -export default Details; \ No newline at end of file diff --git a/sections/Transactions/index.tsx b/sections/Transactions/index.tsx index bd684fb..ce4af59 100644 --- a/sections/Transactions/index.tsx +++ b/sections/Transactions/index.tsx @@ -23,10 +23,8 @@ const Transactions = (props) => { )} Transactions diff --git a/sections/Transactions/txHash.tsx b/sections/Transactions/txHash.tsx new file mode 100644 index 0000000..96bceeb --- /dev/null +++ b/sections/Transactions/txHash.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import { Box, Text } from '../../blocks'; +import Advanced from '../../components/Reusables/Advanced'; +import ConsensusInfo from '../../components/Transactions/ConsensusInfo'; +import TXDetails from '../../components/Transactions/TxDetails' +import TxTravels from '../../components/Transactions/TxTravels' +import { useLiveTxByHash, TxDetailsProps } from '../../hooks/useLiveTxByHash'; + +const Details = (props: TxDetailsProps) => { + + const { data, error, isLoading, isError } = useLiveTxByHash({ txHash: props.txHash }); + + return ( + + Transaction Details + + + + + + ); +}; + +export default Details; \ No newline at end of file diff --git a/types/block.ts b/types/block.ts new file mode 100644 index 0000000..7e10936 --- /dev/null +++ b/types/block.ts @@ -0,0 +1,31 @@ + +import { Transaction } from './transaction' + +export interface Signer { + sig: string; + node: string; + role: number; +} +export interface Block { + blockHash: string; + blockData: string; + blockDataAsJson: { + ts: number; + txobjList: any[]; + attesttoken: string; + signersList: Signer[]; + }; + blockSize: number; + ts: number; + transactions: Transaction[]; + totalNumberOfTxns: number; +}; + +export interface BlockDetails { + blockData: string, + blockHash: string, + blockSize: number, + totalNumberOfTxns: number, + signers: Signer[], + ts: number +} \ No newline at end of file diff --git a/types/transaction.ts b/types/transaction.ts new file mode 100644 index 0000000..434a090 --- /dev/null +++ b/types/transaction.ts @@ -0,0 +1,21 @@ +export interface Transaction { + txnHash: string; + ts: number; + blockHash: string; + category: string; + source: string; + status: string; + from: string; + recipients: { + recipients: { address: string }[]; + }; + txnData: string; + txnDataAsJson: { + did: string; + masterpubkey: string; + derivedpubkey: string; + derivedkeyindex: number; + encderivedprivkey: string; + }; + sig: string; +}; \ No newline at end of file diff --git a/utils/helpers.ts b/utils/helpers.ts index 51bdb7f..ecf6fd3 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -2,12 +2,7 @@ import { format, formatDistanceToNow } from 'date-fns'; import { replace } from 'lodash'; import numeral from 'numeral'; - -type Signer = { - sig: string; - node: string; - role: number; -}; +import { Signer } from '../types/block' export function fDate(date) { return format(new Date(date), 'dd MMMM yyyy'); @@ -76,8 +71,8 @@ export function isErrorWithMessage(error: unknown): error is { message: string } return typeof error === 'object' && error !== null && 'message' in error; } -export function getValidatorNode(signers: Signer[]) { - const signer = signers.find(signer => signer.role === 1); +export function getValidatorNode(signers: Signer[] | undefined) { + const signer = signers?.find(signer => signer.role === 1); return signer?.node } @@ -101,4 +96,9 @@ export function rightMaskString(str) { } // If the string is too short to mask after 15 characters, return it as is return str; +} + +export function capitalizeStr(string) { + if (!string) return ''; + return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 7291f7a..5f50d74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -108,6 +108,13 @@ core-js-pure "^3.25.1" regenerator-runtime "^0.13.10" +"@babel/runtime@^7.0.0": + version "7.25.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.4.tgz#6ef37d678428306e7d75f054d5b1bdb8cf8aa8ee" + integrity sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.19.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": version "7.20.0" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.0.tgz" @@ -1028,6 +1035,15 @@ dependencies: tslib "^2.4.0" +"@table-library/react-table-library@^4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@table-library/react-table-library/-/react-table-library-4.1.7.tgz#90b71f959228f420d2deffeecc9eace879cb4c2e" + integrity sha512-KKFjdACvEUeD9yhgXBjZUJSdE9pxUbJdou4Pp71FW8dxQWc7LcMcSxpveSfGXw8KlcWY0hThJOwyjQb+UKOmnw== + dependencies: + clsx "1.1.1" + react-virtualized-auto-sizer "1.0.7" + react-window "1.8.7" + "@types/hoist-non-react-statics@*": version "3.3.1" resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz" @@ -1414,6 +1430,11 @@ client-only@0.0.1: resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== +clsx@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" + integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== + clsx@^1.1.1, clsx@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" @@ -2494,6 +2515,11 @@ mdn-data@2.0.14: resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== +"memoize-one@>=3.1.1 <6": + version "5.2.1" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" + integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== + merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" @@ -2958,6 +2984,19 @@ react-use@^17.4.0: ts-easing "^0.2.0" tslib "^2.1.0" +react-virtualized-auto-sizer@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.7.tgz#bfb8414698ad1597912473de3e2e5f82180c1195" + integrity sha512-Mxi6lwOmjwIjC1X4gABXMJcKHsOo0xWl3E3ugOgufB8GJU+MqrtY35aBuvCYv/razQ1Vbp7h1gWJjGjoNN5pmA== + +react-window@1.8.7: + version "1.8.7" + resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.7.tgz#5e9fd0d23f48f432d7022cdb327219353a15f0d4" + integrity sha512-JHEZbPXBpKMmoNO1bNhoXOOLg/ujhL/BU4IqVU9r8eQPcy5KQnGHIHDRkJ0ns9IM5+Aq5LNwt3j8t3tIrePQzA== + dependencies: + "@babel/runtime" "^7.0.0" + memoize-one ">=3.1.1 <6" + react@18.2.0: version "18.2.0" resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" From ce00e90c73a8daa55471ab67da9793b52ba41147 Mon Sep 17 00:00:00 2001 From: rozaso Date: Tue, 27 Aug 2024 06:06:52 -0700 Subject: [PATCH 09/42] Support search by addresss. --- components/Home/LiveTransactions.tsx | 4 +-- components/Transactions/ListView.tsx | 29 ++++++++++++++--- hooks/useLiveTransactions.ts | 44 +++++++++++++++++++++----- hooks/useSearchByAddress.ts | 29 ++++++++++------- pages/transactions/search/[txHash].tsx | 12 ++++--- sections/Transactions/index.tsx | 16 +++++++++- 6 files changed, 102 insertions(+), 32 deletions(-) diff --git a/components/Home/LiveTransactions.tsx b/components/Home/LiveTransactions.tsx index 7854e8f..f520c25 100644 --- a/components/Home/LiveTransactions.tsx +++ b/components/Home/LiveTransactions.tsx @@ -1,6 +1,6 @@ // React, NextJS imports import React from 'react'; -import { Box, Text, Front, Tag, Separator, Table } from '../../blocks'; +import { Box, Text, Front, Tag, Separator, Table, Ethereum } from '../../blocks'; import { useRouter } from 'next/router' import Link from 'next/link' import { useLiveTransactions } from '../../hooks/useLiveTransactions'; @@ -32,7 +32,7 @@ export default function LiveTransactions() { { title: 'FROM', dataIndex: 'from', - render: (from: string) => {centerMaskString(from)}, + render: (from: string) => {centerMaskString(from)}, cellAlignment: 'center', headerAlignment: 'center', width: '25%' diff --git a/components/Transactions/ListView.tsx b/components/Transactions/ListView.tsx index 4ed860b..8c00e5b 100644 --- a/components/Transactions/ListView.tsx +++ b/components/Transactions/ListView.tsx @@ -7,12 +7,33 @@ import { capitalizeStr } from '../../utils/helpers' import { useRouter } from 'next/router' import moment from 'moment'; import { TagVariant } from '../../blocks/tag'; +import { Transaction } from '../../types/transaction'; -const ListView = () => { +interface dataProps { + transactions: Transaction[], + totalPages: number, + lastTs: number +} +interface IProps { + data?: dataProps, + search?: true, + address?: string +} + +const ListView = (props) => { const router = useRouter() - const [page, setPage] = useState(null); - const { data, error, isLoading, isError } = useLiveTransactions({ lastTs: page }); + const [page, setPage] = useState(1); + + + let data; + + if (props.search) { + data = props.data; + } else { + const { data: liveData, error, isLoading, isError } = useLiveTransactions({ page }); + data = liveData; + } const columns = [ { @@ -105,7 +126,7 @@ const ListView = () => { setPage(data?.lastTs)} + paginate={(page) => setPage(page)} currentPage={page} /> diff --git a/hooks/useLiveTransactions.ts b/hooks/useLiveTransactions.ts index 12d368f..f90d06a 100644 --- a/hooks/useLiveTransactions.ts +++ b/hooks/useLiveTransactions.ts @@ -51,20 +51,22 @@ type ApiResponse = { }; type inputProps = { - lastTs?: number | null; + page?: number | null; }; export const useLiveTransactions = (props: inputProps) => { - console.log("lastTs: ", props.lastTs) - + console.log("props : ", props) + const getTransactions = () => makeJsonRpcRequest(RPC_ID, 'getTxs', { - "startTime": props.lastTs ?? Math.floor(Date.now() / 1000), + "startTime": Math.floor(Date.now() / 1000), "direction": "DESC", - "pageSize": PerPageItems + "pageSize": PerPageItems, + "page": props.page }); - return useQuery('homeLiveTransactions', getTransactions, { - refetchInterval: POLL_INTERVAL, + return useQuery({ + queryKey: ['homeLiveTransactions', props], + queryFn: getTransactions, select: (data) => { const transactions = data.blocks.flatMap(block => block.transactions.map(tx => ({ @@ -85,5 +87,31 @@ export const useLiveTransactions = (props: inputProps) => { lastTs: data.lastTs } } - }); + }); + + + // return useQuery('homeLiveTransactions', getTransactions, { + // cacheTime: 0, + // staleTime: 0, + // select: (data) => { + // const transactions = data.blocks.flatMap(block => + // block.transactions.map(tx => ({ + // txHash: tx.txnHash, + // ts: tx.ts, + // blockHash: tx.blockHash, + // category: tx.category, + // status: tx.status, + // source: tx.source, + // from: tx.from, + // recipients: tx.recipients.recipients.map(recipient => recipient.address) + // })) + // ); + // // Sorting transactions by timestamp in descending order + // return { + // transactions: transactions.sort((a, b) => b.ts - a.ts), + // totalPages: data.totalPages, + // lastTs: data.lastTs + // } + // } + // }); } \ No newline at end of file diff --git a/hooks/useSearchByAddress.ts b/hooks/useSearchByAddress.ts index 9e4e6cd..a7ea072 100644 --- a/hooks/useSearchByAddress.ts +++ b/hooks/useSearchByAddress.ts @@ -24,20 +24,25 @@ export const useSearchByAddress = (params: searchProps) => { return useQuery('searchByAddressDetailswee', searchByAddress, { cacheTime: 0, staleTime: 0, - refetchInterval: 5000, + refetchInterval: 1000, select: (data) => { - if (data.blocks && data.blocks.length > 0) { - const { blocks } = data; - // Creating a summary of the block details - const transaction: Transaction = blocks[0].transactions[0] - - return { - transaction - } - } - + const transactions = data.blocks.flatMap(block => + block.transactions.map(tx => ({ + txHash: tx.txnHash, + ts: tx.ts, + blockHash: tx.blockHash, + category: tx.category, + status: tx.status, + source: tx.source, + from: tx.from, + recipients: tx.recipients.recipients.map(recipient => recipient.address) + })) + ); + // Sorting transactions by timestamp in descending order return { - transaction: null + transactions: transactions.sort((a, b) => b.ts - a.ts), + totalPages: data.totalPages, + lastTs: data.lastTs } } }); diff --git a/pages/transactions/search/[txHash].tsx b/pages/transactions/search/[txHash].tsx index 30029b4..f163a86 100644 --- a/pages/transactions/search/[txHash].tsx +++ b/pages/transactions/search/[txHash].tsx @@ -10,7 +10,7 @@ const TransactionView = dynamic(() => import('../../../sections/Transactions'), loading: () => , }); -const TransactionDetailsView = dynamic(() => import('../../../sections/Transactions/txHash'), { +const TransactionsView = dynamic(() => import('../../../sections/Transactions'), { loading: () =>

Loading...

, }); @@ -27,11 +27,13 @@ export default function Transactions() { } }, [router.isReady, txHash]); - console.log(" address : ", address) + const { data, error, isLoading, isError } = useSearchByAddress({ address }); - console.log(" data : ", data) + + - if (!address) { + + if (!address || data?.transactions.length == 0) { return ; // Render a loading state or placeholder until address is defined } @@ -41,7 +43,7 @@ export default function Transactions() { Push Transactions - + ); diff --git a/sections/Transactions/index.tsx b/sections/Transactions/index.tsx index ce4af59..1049c1a 100644 --- a/sections/Transactions/index.tsx +++ b/sections/Transactions/index.tsx @@ -1,6 +1,20 @@ import React from 'react'; import { Box, Text } from '../../blocks'; import ListView from '../../components/Transactions/ListView'; +import { Transaction } from '../../types/transaction'; + + +interface dataProps { + transactions: Transaction[], + totalPages: number, + lastTs: number +} + +interface IProps { + data?: dataProps, + search?: true, + address?: string +} const Transactions = (props) => { return ( @@ -28,7 +42,7 @@ const Transactions = (props) => { gap="spacing-md" > Transactions - +
From 9dd57517178344d7c222871857243a2b421b250e Mon Sep 17 00:00:00 2001 From: rozaso Date: Mon, 2 Sep 2024 07:00:04 -0700 Subject: [PATCH 10/42] Pagination component integration. --- blocks/icons/components/CaretLeft.tsx | 32 ++ blocks/icons/components/CaretRight.tsx | 32 ++ blocks/icons/index.ts | 3 + blocks/illustrations/index.ts | 4 +- blocks/index.ts | 1 + blocks/pagination/Pagination.tsx | 140 ++++++++ blocks/pagination/Pagination.types.ts | 12 + blocks/pagination/index.ts | 2 + blocks/table/Table.types.ts | 2 +- blocks/theme/colors/colors.semantics.ts | 4 + .../theme/semantics/semantics.pagination.ts | 14 + blocks/tooltip/Tooltip.tsx | 4 +- components/Blocks/ConsensusInfo.tsx | 299 +++++----------- components/Blocks/ListView.tsx | 25 +- components/Home/LiveBlocks.tsx | 2 +- components/Home/LiveTransactions.tsx | 29 +- components/Navbar/index.tsx | 19 +- components/Pagination.tsx | 71 ---- components/Transactions/ConsensusInfo.tsx | 322 ++++++------------ components/Transactions/ListView.tsx | 53 ++- components/Transactions/TxTravels.tsx | 23 +- hooks/useBlocks.ts | 18 +- hooks/useLiveTransactions.ts | 28 +- hooks/useLiveTxByHash.ts | 14 + hooks/useSearchByAddress.ts | 16 +- package.json | 4 +- pages/home/index.tsx | 5 +- sections/Blocks/blockHash.tsx | 2 +- sections/Transactions/index.tsx | 44 ++- sections/Transactions/txHash.tsx | 5 +- yarn.lock | 24 +- 31 files changed, 646 insertions(+), 607 deletions(-) create mode 100644 blocks/icons/components/CaretLeft.tsx create mode 100644 blocks/icons/components/CaretRight.tsx create mode 100644 blocks/pagination/Pagination.tsx create mode 100644 blocks/pagination/Pagination.types.ts create mode 100644 blocks/pagination/index.ts create mode 100644 blocks/theme/semantics/semantics.pagination.ts delete mode 100644 components/Pagination.tsx diff --git a/blocks/icons/components/CaretLeft.tsx b/blocks/icons/components/CaretLeft.tsx new file mode 100644 index 0000000..66d011b --- /dev/null +++ b/blocks/icons/components/CaretLeft.tsx @@ -0,0 +1,32 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CaretLeft: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default CaretLeft; diff --git a/blocks/icons/components/CaretRight.tsx b/blocks/icons/components/CaretRight.tsx new file mode 100644 index 0000000..b436b3d --- /dev/null +++ b/blocks/icons/components/CaretRight.tsx @@ -0,0 +1,32 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CaretRight: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default CaretRight; diff --git a/blocks/icons/index.ts b/blocks/icons/index.ts index e32de6a..1976cde 100644 --- a/blocks/icons/index.ts +++ b/blocks/icons/index.ts @@ -19,6 +19,9 @@ export { default as CalendarBlank } from './components/CalendarBlank'; export { default as CaretDown } from './components/CaretDown'; export { default as CaretUp } from './components/CaretUp'; +export { default as CaretRight } from './components/CaretRight'; +export { default as CaretLeft } from './components/CaretLeft'; + export { default as CameraFilled } from './components/CameraFilled'; export { default as Channel } from './components/Channel'; diff --git a/blocks/illustrations/index.ts b/blocks/illustrations/index.ts index f518202..912fb51 100644 --- a/blocks/illustrations/index.ts +++ b/blocks/illustrations/index.ts @@ -12,7 +12,9 @@ export { default as Discord } from './components/Discord'; export { default as EarnOnPush } from './components/EarnOnPush'; export { default as Ethereum } from './components/Ethereum'; - +export { default as Polygon } from './components/Polygon'; +export { default as BNB } from './components/BNB'; + export { default as PushAlpha } from './components/PushAlpha'; export { default as PushBot } from './components/PushBot'; diff --git a/blocks/index.ts b/blocks/index.ts index a0c6f46..42f611c 100644 --- a/blocks/index.ts +++ b/blocks/index.ts @@ -8,6 +8,7 @@ export { Lozenge, type LozengeProps } from './lozenge'; export { Menu, type MenuProps, MenuItem, type MenuItemComponentProps } from './menu'; export { Modal, type ModalProps, modal } from './modal'; export { notification } from './notification'; +export { Pagination, type PaginationProps } from './pagination'; export { ProgressBar, type ProgressBarProps } from './progressBar'; export { Separator, type SeparatorProps } from './separator'; export { Skeleton, type SkeletonProps } from './skeleton'; diff --git a/blocks/pagination/Pagination.tsx b/blocks/pagination/Pagination.tsx new file mode 100644 index 0000000..e8d54af --- /dev/null +++ b/blocks/pagination/Pagination.tsx @@ -0,0 +1,140 @@ +import RCPagination from 'rc-pagination'; +import styled from 'styled-components'; +import 'rc-pagination/assets/index.css'; +import { FC } from 'react'; +import { CaretLeft, CaretRight } from '../icons'; +import { getTextVariantStyles } from '../Blocks.utils'; +import { PaginationProps } from './Pagination.types'; +import enUS from 'rc-pagination/lib/locale/en_US'; + +const StyledPagination = styled(RCPagination)<{ disabled?: PaginationProps['disabled'] }>` + display: flex; + justify-content: center; + align-items: center; + + .rc-pagination-item { + display: flex; + justify-content: center; + align-items: center; + border: none !important; + background: transparent !important; + margin: var(--spacing-none) var(--spacing-xxxs) !important; + padding: 0; + height: 24px; + min-width: 18px !important; + max-width: 18px !important; + line-height: 24px; + font-family: var(--font-family); + ${({ disabled }) => + getTextVariantStyles( + 'bes-semibold', + disabled ? 'components-pagination-text-disabled' : 'components-pagination-text-default' + )}; + + &-active { + font-weight: bold; + color: ${({ disabled }) => + disabled ? 'var(--components-pagination-text-disabled)' : 'var(--components-pagination-text-selected)'}; + } + + a { + color: inherit !important; + padding: 0px; + text-decoration: none; + } + } + + .rc-pagination-jump-prev, + .rc-pagination-jump-next { + display: flex; + justify-content: center; + align-items: center; + border: none !important; + background: transparent !important; + min-width: 18px !important; + max-width: 18px !important; + margin: var(--spacing-none) var(--spacing-xxxs) !important; + padding: 0; + + /* Hide the original ellipsis content */ + & > * { + display: none; + } + + &::before { + content: '...'; + color: ${({ disabled }) => + disabled ? 'var(--components-pagination-text-disabled)' : 'var(--components-pagination-text-default)'}; + display: inline-block; + line-height: 24px; + vertical-align: middle; + margin-bottom: var(--spacing-xxxs); + } + + &:hover::before { + color: var(--components-pagination-text-default); + } + } + + .rc-pagination-prev, + .rc-pagination-next { + display: flex; + justify-content: center; + align-items: center; + border: none !important; + background: transparent !important; + margin: 0 !important; + padding: 0; + } + + .rc-pagination-prev:focus-visible, + .rc-pagination-next:focus-visible, + .rc-pagination-item:focus-visible { + outline: none !important; + box-shadow: none !important; + } +`; + +const CaretIcon = styled.div` + background: var(--components-pagination-background-default); + width: 24px; + height: 24px; + display: flex; + justify-content: center; + align-items: center; + border-radius: var(--radius-xxs); + + &:hover { + background: var(--components-pagination-background-hover); + } + + span { + height: 10px; + width: 10px; + } +`; + +const Pagination: FC = ({ current = 1, total, disabled = false, onChange, pageSize }) => { + return ( + + + + } + nextIcon={ + + + + } + /> + ); +}; + +export { Pagination }; diff --git a/blocks/pagination/Pagination.types.ts b/blocks/pagination/Pagination.types.ts new file mode 100644 index 0000000..7a3b921 --- /dev/null +++ b/blocks/pagination/Pagination.types.ts @@ -0,0 +1,12 @@ +export type PaginationProps = { + /* Called when the page is changed, and it takes the resulting page number as argument */ + onChange: (page: number) => void; + /* Number of data items per page */ + pageSize: number; + /* Default initial page number */ + current: number; + /* Total number of data items */ + total: number; + /* Disable pagination item */ + disabled?: boolean; +}; diff --git a/blocks/pagination/index.ts b/blocks/pagination/index.ts new file mode 100644 index 0000000..bfd2b96 --- /dev/null +++ b/blocks/pagination/index.ts @@ -0,0 +1,2 @@ +export * from './Pagination'; +export * from './Pagination.types'; diff --git a/blocks/table/Table.types.ts b/blocks/table/Table.types.ts index 9938dfd..c7641a9 100644 --- a/blocks/table/Table.types.ts +++ b/blocks/table/Table.types.ts @@ -5,7 +5,7 @@ export type Column = { dataIndex: string; cellAlignment?: CSSProperties['justifyContent']; headerAlignment?: CSSProperties['justifyContent']; - render?: (text: string | string[], record: any) => ReactNode; + render?: (text: string, record: any) => ReactNode; width?: string; fixed?: 'left' | 'right'; }; diff --git a/blocks/theme/colors/colors.semantics.ts b/blocks/theme/colors/colors.semantics.ts index 43a8075..553a6bc 100644 --- a/blocks/theme/colors/colors.semantics.ts +++ b/blocks/theme/colors/colors.semantics.ts @@ -13,6 +13,7 @@ import { iconSemantics } from '../semantics/semantics.icon'; import { inputSemantics } from '../semantics/semantics.input'; import { modalSemantics } from '../semantics/semantics.modal'; import { notificationsSemantics } from '../semantics/semantics.notifications'; +import { paginationSemantics } from '../semantics/semantics.pagination'; import { progressBarSemantics } from '../semantics/semantics.progress-bar'; import { radioSemantics } from '../semantics/semantics.radio'; import { skeletonSemantics } from '../semantics/semantics.skeleton'; @@ -42,6 +43,7 @@ type SemanticKeys = { input: 'components-inputs'; modal: 'components-modal'; notifications: 'components-in-app-notification'; + pagination: 'components-pagination'; progressBar: 'components-progress-bar'; radio: 'components-radio-button'; surface: 'surface'; @@ -71,6 +73,7 @@ export const semanticKeys: SemanticKeys = { input: 'components-inputs', modal: 'components-modal', notifications: 'components-in-app-notification', + pagination: 'components-pagination', progressBar: 'components-progress-bar', radio: 'components-radio-button', surface: 'surface', @@ -100,6 +103,7 @@ export const colorSemantics = { [semanticKeys.input]: inputSemantics, [semanticKeys.modal]: modalSemantics, [semanticKeys.notifications]: notificationsSemantics, + [semanticKeys.pagination]: paginationSemantics, [semanticKeys.progressBar]: progressBarSemantics, [semanticKeys.radio]: radioSemantics, [semanticKeys.surface]: surfaceSemantics, diff --git a/blocks/theme/semantics/semantics.pagination.ts b/blocks/theme/semantics/semantics.pagination.ts new file mode 100644 index 0000000..ec10b53 --- /dev/null +++ b/blocks/theme/semantics/semantics.pagination.ts @@ -0,0 +1,14 @@ +import { colorBrands } from '../colors/colors.brands'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const paginationSemantics = { + 'background-default': { light: surfaceSemantics['tertiary'].light, dark: surfaceSemantics['tertiary'].dark }, + 'background-hover': { light: colorBrands['neutral-300'], dark: colorBrands['neutral-300'] }, + 'text-selected': { + light: textSemantics['primary'].light, + dark: textSemantics['primary'].dark, + }, + 'text-default': { light: textSemantics['tertiary'].light, dark: textSemantics['tertiary'].dark }, + 'text-disabled': { light: textSemantics['secondary-inverse'].light, dark: textSemantics['secondary-inverse'].dark }, +}; diff --git a/blocks/tooltip/Tooltip.tsx b/blocks/tooltip/Tooltip.tsx index 6d3e755..70c510b 100644 --- a/blocks/tooltip/Tooltip.tsx +++ b/blocks/tooltip/Tooltip.tsx @@ -1,10 +1,10 @@ -import { type FC, useRef, useState } from 'react'; +import React, { type FC, useRef, useState } from 'react'; import styled from 'styled-components'; import * as RadixTooltip from '@radix-ui/react-tooltip'; import type { TooltipProps } from './Tooltip.types'; import { getTooltipPositionalCSS } from './Tooltip.utils'; import { tooltipCSSPropsKeys } from './Tooltip.constants'; -import { useIsVisible } from 'common'; +import { useIsVisible } from '../../common'; import { textVariants } from '../text'; const RadixTooltipContent = styled(RadixTooltip.Content).withConfig({ diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index 0899653..5a982df 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Box, Text, Button, Add, Ethereum } from '../../blocks'; import { BlockDetails } from '../../types/block' @@ -7,8 +7,29 @@ interface IProps { isLoading: boolean } +const MAX_DISPLAY_NODES = 5 +const MAX_DISPLAY_CHARS = 700; + const ConsensusInfo = (props: IProps) => { - + const [showAll, setShowAll] = useState(false); + const [showAllPayload, setShowAllPayload] = useState(false); + + const toggleShowAll = () => { + setShowAll(!showAll); + }; + + const toggleShowAllPayload = () => { + setShowAllPayload(!showAllPayload); + }; + + const nodes = props.data?.signers.map((signer) => signer.node) || [] + const displayedNodes = showAll ? nodes : nodes.slice(0, MAX_DISPLAY_NODES); + const showMoreButton = nodes.length > MAX_DISPLAY_NODES; + + const payload = props.data?.blockData || ""; + const displayedPayload = showAllPayload ? payload : payload.substring(0, MAX_DISPLAY_CHARS); + const showMorePayloadButton = payload.length > MAX_DISPLAY_CHARS; + return ( <> { flexDirection="column" gap="spacing-xs" > - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - + {displayedNodes.map((node, index) => ( + {node} + ))} - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - - Show more - - + + {showAll ? 'Show Less' : 'Show More'} + + + )} @@ -155,10 +88,23 @@ const ConsensusInfo = (props: IProps) => { borderRadius="radius-xs" padding="spacing-sm" width="68vw" - > - {props.data?.blockData} - - + > + {displayedPayload} + {showMorePayloadButton && ( + + + {showAllPayload ? 'Show Less' : 'Show More'} + + + )} + @@ -185,117 +131,24 @@ const ConsensusInfo = (props: IProps) => { flexDirection="column" gap="spacing-xs" > - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - + {displayedNodes.map((node, index) => ( + {node} + ))} - + {showMoreButton && ( - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + {showAll ? 'Show Less' : 'Show More'} + - - - - - - - - Show more - - + )} @@ -312,7 +165,21 @@ const ConsensusInfo = (props: IProps) => { padding="spacing-sm" width="88vw" > - {props.data?.blockData} + {displayedPayload} + {showMorePayloadButton && ( + + + {showAllPayload ? 'Show Less' : 'Show More'} + + + )} diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx index f19e252..6b1e9b1 100644 --- a/components/Blocks/ListView.tsx +++ b/components/Blocks/ListView.tsx @@ -1,6 +1,5 @@ import React, { useState } from 'react'; -import { Box, Text, Table } from '../../blocks'; -import Pagination from '../Pagination'; +import { Box, Text, Table, Pagination } from '../../blocks'; import { useLiveBlocks } from '../../hooks/useBlocks'; import { PerPageItems } from '../../utils/constants' import { useRouter } from 'next/router' @@ -10,7 +9,7 @@ import { getValidatorNode } from '../../utils/helpers' const Blocks = () => { const router = useRouter() const [page, setPage] = useState(1); - const { data, error, isLoading, isError } = useLiveBlocks(); + const { data, error, isLoading, isError } = useLiveBlocks({ page }); const columns = [ { @@ -71,13 +70,19 @@ const Blocks = () => { gap="spacing-xs" >
- - setPage(page)} - currentPage={page} - /> + + setPage(page)} + /> + ); }; diff --git a/components/Home/LiveBlocks.tsx b/components/Home/LiveBlocks.tsx index 0f86396..5d8e9a4 100644 --- a/components/Home/LiveBlocks.tsx +++ b/components/Home/LiveBlocks.tsx @@ -9,7 +9,7 @@ import { centerMaskString, rightMaskString } from '../../utils/helpers' export default function LiveBlocks() { const router = useRouter() - const { data, error, isLoading, isError } = useLiveBlocks(); + const { data, error, isLoading, isError } = useLiveBlocks({ page: 1 }); const columns = [ { diff --git a/components/Home/LiveTransactions.tsx b/components/Home/LiveTransactions.tsx index f520c25..724a869 100644 --- a/components/Home/LiveTransactions.tsx +++ b/components/Home/LiveTransactions.tsx @@ -1,6 +1,6 @@ // React, NextJS imports import React from 'react'; -import { Box, Text, Front, Tag, Separator, Table, Ethereum } from '../../blocks'; +import { Box, Text, Front, Tag, Separator, Table, Ethereum, Polygon, BNB } from '../../blocks'; import { useRouter } from 'next/router' import Link from 'next/link' import { useLiveTransactions } from '../../hooks/useLiveTransactions'; @@ -10,7 +10,20 @@ import { TagVariant } from '../../blocks/tag'; export default function LiveTransactions() { const router = useRouter() - const { data, error, isLoading, isError } = useLiveTransactions({ lastTs: null }); + const { data, error, isLoading, isError } = useLiveTransactions({ page: 1 }); + + function getChainIcon(source) { + switch(source) { + case 'ETH_MAINNET': + return + case 'POLYGON_MAINNET': + return + case 'BSC_MAINNET': + return + default: + return + } + } const columns = [ { @@ -32,7 +45,15 @@ export default function LiveTransactions() { { title: 'FROM', dataIndex: 'from', - render: (from: string) => {centerMaskString(from)}, + render: (params) => { + const from = JSON.parse(params) + return ( + + { getChainIcon(from.source) } + {centerMaskString(from.from)} + + ) + }, cellAlignment: 'center', headerAlignment: 'center', width: '25%' @@ -69,7 +90,7 @@ export default function LiveTransactions() { id: dt.txHash, status: dt.status, txHash: dt.txHash, - from: dt.from, + from: JSON.stringify({ from: dt.from, source: dt.source }), recipients: dt.recipients, ts: dt.ts, })) || []; diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index d05e05d..a34f5c2 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -21,7 +21,7 @@ import { SidebarContainer, } from './navbar.styled'; import { ThemeType } from '../../types/theme'; -import { Box, Select, Text, Lozenge } from '../../blocks'; +import { Box, Select, Text, Lozenge, PushLogo } from '../../blocks'; import SearchBar from '../Home/SearchBar' import ChainsDropDown from '../Reusables/ChainsDropDown' import Link from 'next/link' @@ -51,6 +51,7 @@ export default function Navbar() { display={{ ml: "none", dp: "flex" }} flexDirection="row" justifyContent="space-between" + css={'margin-top: 20px'} > - - + PushScan - - + PushScan diff --git a/components/Pagination.tsx b/components/Pagination.tsx deleted file mode 100644 index 2031ede..0000000 --- a/components/Pagination.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import axios from 'axios'; -import { Box, Text, Add, PrevIconSlider, NextIconSlider } from '../blocks'; - -const Pagination = ({ itemsPerPage, totalItems, paginate, currentPage }) => { - const totalPages = Math.ceil(totalItems / itemsPerPage); - let pageNumbers: number[] = []; - let startPage, endPage; - - if (totalPages <= 5) { - // less than 5 total pages so show all - startPage = 1; - endPage = totalPages; - } else { - // more than 5 total pages so calculate start and end pages - if (currentPage <= 3) { - startPage = 1; - endPage = 5; - } else if (currentPage + 2 >= totalPages) { - startPage = totalPages - 4; - endPage = totalPages; - } else { - startPage = currentPage - 2; - endPage = currentPage + 2; - } - } - - // generate page numbers to be displayed - for (let i = startPage; i <= endPage; i++) { - pageNumbers.push(i); - } - - const indexOfLastPageButton = currentPage + 3; - const indexOfFirstPageButton = currentPage - 3; - - return ( - - - currentPage > 1 && paginate(currentPage - 1)} /> - {currentPage > 3 && totalPages > 5 && ( - <> - paginate(1)}>1 - {currentPage > 4 && ...} - - )} - - {pageNumbers.map(number => ( - paginate(number)} key={number}> - {number} - - ))} - - {currentPage + 3 < totalPages && ( - <> - ... - paginate(totalPages)}>{totalPages} - - )} - currentPage < totalPages && paginate(currentPage + 1)} /> - - ); -}; - -export default Pagination; diff --git a/components/Transactions/ConsensusInfo.tsx b/components/Transactions/ConsensusInfo.tsx index 10a9959..8954e9a 100644 --- a/components/Transactions/ConsensusInfo.tsx +++ b/components/Transactions/ConsensusInfo.tsx @@ -1,14 +1,37 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Box, Text, Button, Add, Ethereum } from '../../blocks'; import { Transaction } from '../../types/transaction'; +import { BlockDetails } from '../../types/block'; interface IProps { - data: Transaction | null | undefined, + blockDetails: BlockDetails | null | undefined, + transaction: Transaction | null | undefined, isLoading: boolean } +const MAX_DISPLAY_NODES = 5;4 +const MAX_DISPLAY_CHARS = 700; + const ConsensusInfo = (props: IProps) => { - + const [showAll, setShowAll] = useState(false); + const [showAllPayload, setShowAllPayload] = useState(false); + + const toggleShowAll = () => { + setShowAll(!showAll); + }; + + const toggleShowAllPayload = () => { + setShowAllPayload(!showAllPayload); + }; + + const nodes = props.blockDetails?.signers.map((signer) => signer.node) || [] + const displayedNodes = showAll ? nodes : nodes.slice(0, MAX_DISPLAY_NODES); + const showMoreButton = nodes.length > MAX_DISPLAY_NODES; + + const payload = props.transaction?.txnData || ""; + const displayedPayload = showAllPayload ? payload : payload.substring(0, MAX_DISPLAY_CHARS); + const showMorePayloadButton = payload.length > MAX_DISPLAY_CHARS; + return ( <> { Consensus Info - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - + {node} + + + ))} - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - - Show more - - + + {showAll ? 'Show Less' : 'Show More'} + + + )} @@ -149,16 +97,28 @@ const ConsensusInfo = (props: IProps) => { gap="spacing-xxxl" > Payload Data - - {props.data?.txnData} + > + {displayedPayload} + {showMorePayloadButton && ( + + + {showAllPayload ? 'Show Less' : 'Show More'} + + + )} - @@ -179,123 +139,43 @@ const ConsensusInfo = (props: IProps) => { Consensus Info - - + {displayedNodes.map((node, index) => ( - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + {node} + - - - - + ))} - + {showMoreButton && ( - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df + + {showAll ? 'Show Less' : 'Show More'} + - - - - - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - - - - - - 0x2d2269c5863cc504fef489cca963f3f2beb197b6a80cd1820357d6b5447408df - - - - - - - - - Show more - - + )} @@ -305,16 +185,28 @@ const ConsensusInfo = (props: IProps) => { gap="spacing-xs" > Payload Data - - {props.data?.txnData} + {displayedPayload} + {showMorePayloadButton && ( + + + {showAllPayload ? 'Show Less' : 'Show More'} + + + )} - diff --git a/components/Transactions/ListView.tsx b/components/Transactions/ListView.tsx index 8c00e5b..89468db 100644 --- a/components/Transactions/ListView.tsx +++ b/components/Transactions/ListView.tsx @@ -1,9 +1,8 @@ import React, { useState } from 'react'; -import { Box, Text, Tag, Table } from '../../blocks'; -import Pagination from '../Pagination'; +import { Box, Text, Tag, Table, Pagination, Ethereum, Polygon, BNB } from '../../blocks'; import { useLiveTransactions } from '../../hooks/useLiveTransactions'; import { PerPageItems } from '../../utils/constants' -import { capitalizeStr } from '../../utils/helpers' +import { capitalizeStr, centerMaskString } from '../../utils/helpers' import { useRouter } from 'next/router' import moment from 'moment'; import { TagVariant } from '../../blocks/tag'; @@ -35,6 +34,19 @@ const ListView = (props) => { data = liveData; } + function getChainIcon(source) { + switch(source) { + case 'ETH_MAINNET': + return + case 'POLYGON_MAINNET': + return + case 'BSC_MAINNET': + return + default: + return + } + } + const columns = [ { title: 'STATUS', @@ -63,9 +75,17 @@ const ListView = (props) => { { title: 'FROM', dataIndex: 'from', - render: (from: string) => {from}, - cellAlignment: 'flex-start', - headerAlignment: 'flex-start', + render: (params) => { + const from = JSON.parse(params) + return ( + + { getChainIcon(from.source) } + {centerMaskString(from.from)} + + ) + }, + cellAlignment: 'center', + headerAlignment: 'center', width: '20%' }, { @@ -110,7 +130,7 @@ const ListView = (props) => { txHash: dt.txHash, blockHash: dt.blockHash, category: dt.category, - from: dt.from, + from: JSON.stringify({ from: dt.from, source: dt.source }), recipients: dt.recipients, ts: dt.ts, })) || []; @@ -123,12 +143,19 @@ const ListView = (props) => { gap="spacing-xs" >
- setPage(page)} - currentPage={page} - /> + + setPage(page)} + /> + ); }; diff --git a/components/Transactions/TxTravels.tsx b/components/Transactions/TxTravels.tsx index 3080149..3c45141 100644 --- a/components/Transactions/TxTravels.tsx +++ b/components/Transactions/TxTravels.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Box, Text, Ethereum } from '../../blocks'; +import { Box, Text, Ethereum, Polygon, BNB } from '../../blocks'; import { Transaction } from '../../types/transaction'; const MAX_DISPLAY = 5; @@ -20,6 +20,19 @@ const TxTravels = (props: IProps) => { const displayedRecipients = showAll ? recipients : recipients.slice(0, MAX_DISPLAY); const showMoreButton = recipients.length > MAX_DISPLAY; + function getChainIcon(source) { + switch(source) { + case 'ETH_MAINNET': + return + case 'POLYGON_MAINNET': + return + case 'BSC_MAINNET': + return + default: + return + } + } + return ( <> { flexDirection="column" gap="spacing-sm" > - {props.data?.from} + + { getChainIcon(props.data?.source) } + {props.data?.from} + + { flexDirection="row" gap="spacing-xxxs" > - + { getChainIcon(props.data?.source) } {props.data?.from} diff --git a/hooks/useBlocks.ts b/hooks/useBlocks.ts index b9709af..965fcbf 100644 --- a/hooks/useBlocks.ts +++ b/hooks/useBlocks.ts @@ -1,18 +1,28 @@ import { useQuery } from 'react-query'; import { POLL_INTERVAL } from '../utils/constants' import { makeJsonRpcRequest } from '../utils/json-rpc'; +import { PerPageItems } from '../utils/constants'; const RPC_ID = 1 -export const useLiveBlocks = () => { +type inputProps = { + page?: number | null; +}; + +export const useLiveBlocks = (props: inputProps) => { + console.log("props : ", props) + const getBlocks = () => makeJsonRpcRequest(RPC_ID, 'getBlocks', { "startTime": Math.floor(Date.now() / 1000), "direction": "DESC", "showDetails": false, - "pageSize": 10 + "pageSize": PerPageItems, + "page": props.page }); - return useQuery('homeLiveBlocks', getBlocks, { + return useQuery({ + queryKey: ['homeLiveBlocks', props], + queryFn: getBlocks, refetchInterval: POLL_INTERVAL - }); + }); } \ No newline at end of file diff --git a/hooks/useLiveTransactions.ts b/hooks/useLiveTransactions.ts index f90d06a..639abdb 100644 --- a/hooks/useLiveTransactions.ts +++ b/hooks/useLiveTransactions.ts @@ -87,31 +87,5 @@ export const useLiveTransactions = (props: inputProps) => { lastTs: data.lastTs } } - }); - - - // return useQuery('homeLiveTransactions', getTransactions, { - // cacheTime: 0, - // staleTime: 0, - // select: (data) => { - // const transactions = data.blocks.flatMap(block => - // block.transactions.map(tx => ({ - // txHash: tx.txnHash, - // ts: tx.ts, - // blockHash: tx.blockHash, - // category: tx.category, - // status: tx.status, - // source: tx.source, - // from: tx.from, - // recipients: tx.recipients.recipients.map(recipient => recipient.address) - // })) - // ); - // // Sorting transactions by timestamp in descending order - // return { - // transactions: transactions.sort((a, b) => b.ts - a.ts), - // totalPages: data.totalPages, - // lastTs: data.lastTs - // } - // } - // }); + }); } \ No newline at end of file diff --git a/hooks/useLiveTxByHash.ts b/hooks/useLiveTxByHash.ts index 0318f79..ab3087b 100644 --- a/hooks/useLiveTxByHash.ts +++ b/hooks/useLiveTxByHash.ts @@ -1,6 +1,8 @@ import { useQuery } from 'react-query'; import { POLL_INTERVAL } from '../utils/constants' import { makeJsonRpcRequest } from '../utils/json-rpc'; +import { BlockDetails } from '../types/block' + import { Transaction } from '../types/transaction'; const RPC_ID = 5 @@ -21,15 +23,27 @@ export const useLiveTxByHash = (params: TxDetailsProps) => { select: (data) => { if (data.blocks && data.blocks.length > 0) { const { blocks } = data; + + const blockDetails: BlockDetails = { + blockData: blocks[0].blockData, + blockHash: blocks[0].blockHash, + blockSize: blocks[0].blockSize, + totalNumberOfTxns: blocks[0].totalNumberOfTxns, + signers: blocks[0].blockDataAsJson?.signersList, + ts: blocks[0].ts + }; + // Creating a summary of the block details const transaction: Transaction = blocks[0].transactions[0] return { + blockDetails, transaction } } return { + blockDetails: null, transaction: null } } diff --git a/hooks/useSearchByAddress.ts b/hooks/useSearchByAddress.ts index a7ea072..49b1e40 100644 --- a/hooks/useSearchByAddress.ts +++ b/hooks/useSearchByAddress.ts @@ -2,6 +2,7 @@ import { useQuery } from 'react-query'; import { makeJsonRpcRequest } from '../utils/json-rpc'; import { Transaction } from '../types/transaction'; import { POLL_INTERVAL } from '../utils/constants' +import { PerPageItems } from '../utils/constants'; const RPC_ID = 7 @@ -10,21 +11,18 @@ export interface searchProps { } export const useSearchByAddress = (params: searchProps) => { - - console.log("useSearchByAddress hook params : ", params.address) - const searchByAddress = () => makeJsonRpcRequest(RPC_ID, 'searchByAddress', { "searchTerm": params.address, "startTime": Math.floor(Date.now() / 1000), "direction": "DESC", - "pageSize": 10, + "pageSize": PerPageItems, + "page": 1, "showDetails": true }); - return useQuery('searchByAddressDetailswee', searchByAddress, { - cacheTime: 0, - staleTime: 0, - refetchInterval: 1000, + return useQuery({ + queryKey: ['searchByAddressDetailswee', params], + queryFn: searchByAddress, select: (data) => { const transactions = data.blocks.flatMap(block => block.transactions.map(tx => ({ @@ -45,5 +43,5 @@ export const useSearchByAddress = (params: searchProps) => { lastTs: data.lastTs } } - }); + }); } \ No newline at end of file diff --git a/package.json b/package.json index ce7ad30..49b618f 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,8 @@ "react-use": "^17.4.0", "styled-components": "^5.3.6", "sonner": "^1.5.0", - "@table-library/react-table-library": "^4.1.7" - + "@table-library/react-table-library": "^4.1.7", + "rc-pagination": "^4.2.0" }, "devDependencies": { "@types/lodash": "^4.14.188", diff --git a/pages/home/index.tsx b/pages/home/index.tsx index 9f9bbd9..0c52b9a 100644 --- a/pages/home/index.tsx +++ b/pages/home/index.tsx @@ -6,10 +6,7 @@ import dynamic from 'next/dynamic'; // Internal Components imports import { HomeLoader } from '../../components/Loader/HomeLoader'; -const HomeView = dynamic(() => import('../../sections/Home'), { - loading: () => , -}); - +const HomeView = dynamic(() => import('../../sections/Home')); const Layout = dynamic(() => import('../../layout')); export default function Home() { diff --git a/sections/Blocks/blockHash.tsx b/sections/Blocks/blockHash.tsx index 924640e..416e3c4 100644 --- a/sections/Blocks/blockHash.tsx +++ b/sections/Blocks/blockHash.tsx @@ -28,7 +28,7 @@ const Details = (props: BlockDetailsProps) => { isLoading={isLoading} /> - diff --git a/sections/Transactions/index.tsx b/sections/Transactions/index.tsx index 1049c1a..ac13f12 100644 --- a/sections/Transactions/index.tsx +++ b/sections/Transactions/index.tsx @@ -1,8 +1,8 @@ -import React from 'react'; -import { Box, Text } from '../../blocks'; +import React, { useState } from 'react'; +import { Box, Text, Copy, Tooltip } from '../../blocks'; import ListView from '../../components/Transactions/ListView'; import { Transaction } from '../../types/transaction'; - +import { centerMaskString } from '../../utils/helpers'; interface dataProps { transactions: Transaction[], @@ -17,12 +17,26 @@ interface IProps { } const Transactions = (props) => { + const [tooltipText, setToolTipText] = useState('Copy Address'); + + const copyAddress = () => { + if (props.address) { + navigator.clipboard.writeText(props.address); + setToolTipText('Copied'); + } + setTimeout(() => { + setToolTipText('Copy Address'); + }, 1000); + }; + + return ( { props.address && ( { justifyContent="flex-start" gap="spacing-md" > - Address {props.address} - Transactions for {props.address} + + Address {props.address} + + + + + + + + Transactions for {centerMaskString(props.address)} )} { flexDirection="column" gap="spacing-md" > - Transactions + {!props.search && Transactions} diff --git a/sections/Transactions/txHash.tsx b/sections/Transactions/txHash.tsx index 96bceeb..4e28b53 100644 --- a/sections/Transactions/txHash.tsx +++ b/sections/Transactions/txHash.tsx @@ -28,8 +28,9 @@ const Details = (props: TxDetailsProps) => { isLoading={isLoading} /> - diff --git a/yarn.lock b/yarn.lock index 5f50d74..b914693 100644 --- a/yarn.lock +++ b/yarn.lock @@ -108,7 +108,7 @@ core-js-pure "^3.25.1" regenerator-runtime "^0.13.10" -"@babel/runtime@^7.0.0": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1": version "7.25.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.4.tgz#6ef37d678428306e7d75f054d5b1bdb8cf8aa8ee" integrity sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w== @@ -1425,6 +1425,11 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +classnames@^2.3.2: + version "2.5.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" + integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== + client-only@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" @@ -2832,6 +2837,23 @@ queue-microtask@^1.2.2: resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +rc-pagination@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-4.2.0.tgz#b7222b429dec38f6c74e139a30ae7765e9a0b8a6" + integrity sha512-V6qeANJsT6tmOcZ4XiUmj8JXjRLbkusuufpuoBw2GiAn94fIixYjFLmbruD1Sbhn8fPLDnWawPp4CN37zQorvw== + dependencies: + "@babel/runtime" "^7.10.1" + classnames "^2.3.2" + rc-util "^5.38.0" + +rc-util@^5.38.0: + version "5.43.0" + resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.43.0.tgz#bba91fbef2c3e30ea2c236893746f3e9b05ecc4c" + integrity sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw== + dependencies: + "@babel/runtime" "^7.18.3" + react-is "^18.2.0" + react-apexcharts@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.0.tgz" From 19e93d69c97c84350a39dd705f46fc6f10d7bd23 Mon Sep 17 00:00:00 2001 From: rozaso Date: Tue, 3 Sep 2024 08:33:13 -0700 Subject: [PATCH 11/42] Search results View. --- components/Blocks/ConsensusInfo.tsx | 23 ++++++- components/Footer/index.tsx | 8 +-- components/Home/LiveBlocks.tsx | 23 ++++--- components/Home/LiveTransactions.tsx | 35 ++++++---- components/Home/SearchBar.tsx | 2 +- components/Loader/BlocksLoader.tsx | 22 ------ components/Loader/HomeLoader.tsx | 25 ------- components/Loader/TransactionLoader.tsx | 22 ------ components/Navbar/index.tsx | 8 ++- components/Transactions/ListView.tsx | 51 +++----------- hooks/useLiveBlockByHash.ts | 7 +- hooks/useLiveTransactions.ts | 2 - hooks/useLiveTxByHash.ts | 7 +- hooks/useSearchByAddress.ts | 11 +-- layout/index.tsx | 13 +--- pages/blocks/[blockHash].tsx | 13 ++-- pages/blocks/index.tsx | 6 +- pages/home/index.tsx | 8 +-- pages/search/[txHash].tsx | 24 +++++++ pages/transactions/[txHash].tsx | 13 ++-- pages/transactions/index.tsx | 7 +- pages/transactions/search/[txHash].tsx | 50 -------------- sections/Blocks/blockHash.tsx | 22 ++++-- sections/Home/index.tsx | 5 +- sections/Search/index.tsx | 92 +++++++++++++++++++++++++ sections/Transactions/index.tsx | 91 +++++++----------------- sections/Transactions/txHash.tsx | 20 ++++-- utils/helpers.ts | 11 ++- utils/json-rpc.ts | 8 ++- 29 files changed, 291 insertions(+), 338 deletions(-) delete mode 100644 components/Loader/BlocksLoader.tsx delete mode 100644 components/Loader/HomeLoader.tsx delete mode 100644 components/Loader/TransactionLoader.tsx create mode 100644 pages/search/[txHash].tsx delete mode 100644 pages/transactions/search/[txHash].tsx create mode 100644 sections/Search/index.tsx diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index 5a982df..036bb83 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Box, Text, Button, Add, Ethereum } from '../../blocks'; +import { Box, Text, Button, Add, Ethereum, Tooltip, Copy } from '../../blocks'; import { BlockDetails } from '../../types/block' interface IProps { @@ -13,6 +13,7 @@ const MAX_DISPLAY_CHARS = 700; const ConsensusInfo = (props: IProps) => { const [showAll, setShowAll] = useState(false); const [showAllPayload, setShowAllPayload] = useState(false); + const [tooltipText, setToolTipText] = useState('Copy Payload'); const toggleShowAll = () => { setShowAll(!showAll); @@ -30,6 +31,16 @@ const ConsensusInfo = (props: IProps) => { const displayedPayload = showAllPayload ? payload : payload.substring(0, MAX_DISPLAY_CHARS); const showMorePayloadButton = payload.length > MAX_DISPLAY_CHARS; + const copyPayload = () => { + if (payload) { + navigator.clipboard.writeText(payload); + setToolTipText('Copied'); + } + setTimeout(() => { + setToolTipText('Copy Payload'); + }, 1000); + }; + return ( <> { )} + + + + + diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index 84f958d..1c1a17b 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -3,9 +3,7 @@ import React from 'react'; import Image from 'next/image'; // External Library imports -import { useTheme } from 'styled-components'; import { useTheme as Theme } from '../../contexts/ThemeContext'; -import { ThemeType } from '../../types/theme'; import TwitterIconDark from "../../public/static/twitter-dark.svg"; import TwitterIconLight from "../../public/static/twitter.svg"; import GithubIconDark from "../../public/static/github-dark.svg"; @@ -13,11 +11,10 @@ import GithubIconLight from "../../public/static/github.svg"; import DiscordIconDark from "../../public/static/discord-dark.svg"; import DiscordIconLight from "../../public/static/discord.svg"; -import { Box, Text, TickCircleFilled, TickDecoratedCircleFilled } from '../../blocks'; +import { Box, Text, TickCircleFilled } from '../../blocks'; export default function Footer() { const { isDarkMode } = Theme(); - const theme = useTheme() as ThemeType; return ( - + All systems operational diff --git a/components/Home/LiveBlocks.tsx b/components/Home/LiveBlocks.tsx index 5d8e9a4..30a412a 100644 --- a/components/Home/LiveBlocks.tsx +++ b/components/Home/LiveBlocks.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Box, Text, Front, Separator, Table } from '../../blocks'; +import { Box, Text, Front, Skeleton, Table } from '../../blocks'; import { useRouter } from 'next/router' import Link from 'next/link' import { useLiveBlocks } from '../../hooks/useBlocks'; @@ -15,18 +15,18 @@ export default function LiveBlocks() { { title: 'BLOCK HASH', dataIndex: 'blockHash', - render: (text) => router.push(`/blocks/${text}`)}>{text}, + render: (text) => router.push(`/blocks/${text}`)}>{rightMaskString(text)}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '35%' + width: '30%' }, { title: 'VALIDATOR', dataIndex: 'validator', - render: (text) => {text}, + render: (text) => {centerMaskString(text)}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '35%' + width: '30%' }, { title: 'TX', @@ -34,7 +34,7 @@ export default function LiveBlocks() { render: (text) => {text}, cellAlignment: 'center', headerAlignment: 'center', - width: '15%' + width: '20%' }, { title: 'AGE', @@ -42,7 +42,7 @@ export default function LiveBlocks() { render: (text) => {moment(text * 1000).fromNow()}, cellAlignment: 'flex-end', headerAlignment: 'flex-end', - width: '15%' + width: '20%' }, ]; @@ -56,14 +56,15 @@ export default function LiveBlocks() { return ( Live Blocks -
- + +
+ View All Blocks - + ) diff --git a/components/Home/LiveTransactions.tsx b/components/Home/LiveTransactions.tsx index 724a869..abbc5c8 100644 --- a/components/Home/LiveTransactions.tsx +++ b/components/Home/LiveTransactions.tsx @@ -1,6 +1,6 @@ // React, NextJS imports import React from 'react'; -import { Box, Text, Front, Tag, Separator, Table, Ethereum, Polygon, BNB } from '../../blocks'; +import { Box, Text, Front, Tag, Skeleton, Table, Ethereum, Polygon, BNB } from '../../blocks'; import { useRouter } from 'next/router' import Link from 'next/link' import { useLiveTransactions } from '../../hooks/useLiveTransactions'; @@ -15,13 +15,13 @@ export default function LiveTransactions() { function getChainIcon(source) { switch(source) { case 'ETH_MAINNET': - return + return case 'POLYGON_MAINNET': - return + return case 'BSC_MAINNET': - return + return default: - return + return } } @@ -32,7 +32,7 @@ export default function LiveTransactions() { render: (status: string) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '10%' + width: '15%' }, { title: 'Tx HASH', @@ -40,7 +40,7 @@ export default function LiveTransactions() { render: (txHash: string) => router.push(`/transactions/${txHash}`)}>{rightMaskString(txHash)}, cellAlignment: 'center', headerAlignment: 'center', - width: '25%' + width: '20%' }, { title: 'FROM', @@ -68,13 +68,18 @@ export default function LiveTransactions() { display="flex" flexDirection="column" > - {centerMaskString(reci[0])} - { reci.length > 1 && {`+ ${reci.length - 1} more`}} + + + { getChainIcon('ETH_MAINNET') } + {centerMaskString(reci[0])} + + { reci.length > 1 && {`+ ${reci.length - 1} more`}} + )}, cellAlignment: 'center', headerAlignment: 'center', - width: '30%' + width: '25%' }, { title: 'AGE', @@ -82,7 +87,7 @@ export default function LiveTransactions() { render: (ts: number) => {moment(ts * 1000).fromNow()}, cellAlignment: 'flex-end', headerAlignment: 'flex-end', - width: '10%' + width: '15%' }, ]; @@ -97,13 +102,15 @@ export default function LiveTransactions() { return ( Live Transactions -
+ +
+ View All Transactions - + ) diff --git a/components/Home/SearchBar.tsx b/components/Home/SearchBar.tsx index a7faba5..4811cd5 100644 --- a/components/Home/SearchBar.tsx +++ b/components/Home/SearchBar.tsx @@ -24,7 +24,7 @@ export default function SearchBar() { return ( router.push(`/transactions/search/${debouncedQuery}`)}/>} + icon={ router.push(`/search/${debouncedQuery}`)}/>} value={query} onChange={(e) => setQuery(e.target.value)} /> diff --git a/components/Loader/BlocksLoader.tsx b/components/Loader/BlocksLoader.tsx deleted file mode 100644 index 744fafb..0000000 --- a/components/Loader/BlocksLoader.tsx +++ /dev/null @@ -1,22 +0,0 @@ -// React, NextJS imports -import React from 'react'; - -// External Library imports -import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; -import 'react-loading-skeleton/dist/skeleton.css'; -import styled, { useTheme } from 'styled-components'; - -// Internal Components imports -import { ThemeType } from '../../types/theme'; - -export const BlocksLoader = () => { - const theme = useTheme() as ThemeType; - - return ( - - - ); -}; \ No newline at end of file diff --git a/components/Loader/HomeLoader.tsx b/components/Loader/HomeLoader.tsx deleted file mode 100644 index bfd355a..0000000 --- a/components/Loader/HomeLoader.tsx +++ /dev/null @@ -1,25 +0,0 @@ -// React, NextJS imports -import React from 'react'; - -// External Library imports -import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; -import 'react-loading-skeleton/dist/skeleton.css'; -import styled, { useTheme } from 'styled-components'; -import { Grid } from '@mui/material'; - -// Internal Components imports -import { ItemVV2, ItemHV2 } from '../Reusables/SharedStyling'; -import { DashBoardContainer } from '../Reusables/SharedStyling'; -import { ThemeType } from '../../types/theme'; - -export const HomeLoader = () => { - const theme = useTheme() as ThemeType; - - return ( - - - ); -}; \ No newline at end of file diff --git a/components/Loader/TransactionLoader.tsx b/components/Loader/TransactionLoader.tsx deleted file mode 100644 index ac9339e..0000000 --- a/components/Loader/TransactionLoader.tsx +++ /dev/null @@ -1,22 +0,0 @@ -// React, NextJS imports -import React from 'react'; - -// External Library imports -import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; -import 'react-loading-skeleton/dist/skeleton.css'; -import styled, { useTheme } from 'styled-components'; - -// Internal Components imports -import { ThemeType } from '../../types/theme'; - -export const TransactionLoader = () => { - const theme = useTheme() as ThemeType; - - return ( - - - ); -}; \ No newline at end of file diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index a34f5c2..9cab17b 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -51,7 +51,6 @@ export default function Navbar() { display={{ ml: "none", dp: "flex" }} flexDirection="row" justifyContent="space-between" - css={'margin-top: 20px'} > PushScan + - + PushScan diff --git a/components/Transactions/ListView.tsx b/components/Transactions/ListView.tsx index 89468db..94a4b4a 100644 --- a/components/Transactions/ListView.tsx +++ b/components/Transactions/ListView.tsx @@ -1,7 +1,5 @@ -import React, { useState } from 'react'; -import { Box, Text, Tag, Table, Pagination, Ethereum, Polygon, BNB } from '../../blocks'; -import { useLiveTransactions } from '../../hooks/useLiveTransactions'; -import { PerPageItems } from '../../utils/constants' +import React from 'react'; +import { Box, Text, Tag, Table, Ethereum, Polygon, BNB } from '../../blocks'; import { capitalizeStr, centerMaskString } from '../../utils/helpers' import { useRouter } from 'next/router' import moment from 'moment'; @@ -14,25 +12,13 @@ interface dataProps { lastTs: number } interface IProps { - data?: dataProps, - search?: true, - address?: string + data?: dataProps } -const ListView = (props) => { +const ListView = (props: IProps) => { const router = useRouter() - const [page, setPage] = useState(1); - - - let data; - - if (props.search) { - data = props.data; - } else { - const { data: liveData, error, isLoading, isError } = useLiveTransactions({ page }); - data = liveData; - } + let data = props.data; function getChainIcon(source) { switch(source) { @@ -67,7 +53,7 @@ const ListView = (props) => { { title: 'BLOCK HASH', dataIndex: 'blockHash', - render: (blockHash: string) => router.push(`/transactions/${txHash}`)}>{blockHash}, + render: (blockHash: string) => router.push(`/blocks/${blockHash}`)}>{blockHash}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '15%' @@ -125,9 +111,9 @@ const ListView = (props) => { ]; const dataSource = data?.transactions.map((dt) => ({ - id: dt.txHash, + id: dt.txnHash, status: dt.status, - txHash: dt.txHash, + txHash: dt.txnHash, blockHash: dt.blockHash, category: dt.category, from: JSON.stringify({ from: dt.from, source: dt.source }), @@ -137,26 +123,7 @@ const ListView = (props) => { return ( - -
- - setPage(page)} - /> - - +
); }; diff --git a/hooks/useLiveBlockByHash.ts b/hooks/useLiveBlockByHash.ts index 0d8ef05..04c5a8c 100644 --- a/hooks/useLiveBlockByHash.ts +++ b/hooks/useLiveBlockByHash.ts @@ -15,8 +15,9 @@ export const useLiveBlockByHash = (params: BlockDetailsProps) => { "showDetails": true }); - return useQuery('getBlockByHashDetails', getBlockByHash, { - refetchInterval: POLL_INTERVAL, + return useQuery({ + queryKey: ['getBlockByHashDetails', params], + queryFn: getBlockByHash, select: (data) => { if (data.blocks && data.blocks.length > 0) { const { blocks } = data; @@ -39,5 +40,5 @@ export const useLiveBlockByHash = (params: BlockDetailsProps) => { blockDetails: null } } - }); + }); } \ No newline at end of file diff --git a/hooks/useLiveTransactions.ts b/hooks/useLiveTransactions.ts index 639abdb..ecfb01e 100644 --- a/hooks/useLiveTransactions.ts +++ b/hooks/useLiveTransactions.ts @@ -55,8 +55,6 @@ type inputProps = { }; export const useLiveTransactions = (props: inputProps) => { - console.log("props : ", props) - const getTransactions = () => makeJsonRpcRequest(RPC_ID, 'getTxs', { "startTime": Math.floor(Date.now() / 1000), "direction": "DESC", diff --git a/hooks/useLiveTxByHash.ts b/hooks/useLiveTxByHash.ts index ab3087b..b810957 100644 --- a/hooks/useLiveTxByHash.ts +++ b/hooks/useLiveTxByHash.ts @@ -18,8 +18,9 @@ export const useLiveTxByHash = (params: TxDetailsProps) => { "showDetails": true }); - return useQuery('getTxByHashDetails', getTxByHash, { - refetchInterval: POLL_INTERVAL, + return useQuery({ + queryKey: ['getTxByHashDetails', params], + queryFn: getTxByHash, select: (data) => { if (data.blocks && data.blocks.length > 0) { const { blocks } = data; @@ -47,5 +48,5 @@ export const useLiveTxByHash = (params: TxDetailsProps) => { transaction: null } } - }); + }); } \ No newline at end of file diff --git a/hooks/useSearchByAddress.ts b/hooks/useSearchByAddress.ts index 49b1e40..327e6e6 100644 --- a/hooks/useSearchByAddress.ts +++ b/hooks/useSearchByAddress.ts @@ -8,6 +8,7 @@ const RPC_ID = 7 export interface searchProps { address: string | string[] | undefined; + page: number } export const useSearchByAddress = (params: searchProps) => { @@ -16,7 +17,7 @@ export const useSearchByAddress = (params: searchProps) => { "startTime": Math.floor(Date.now() / 1000), "direction": "DESC", "pageSize": PerPageItems, - "page": 1, + "page": params.page, "showDetails": true }); @@ -26,13 +27,7 @@ export const useSearchByAddress = (params: searchProps) => { select: (data) => { const transactions = data.blocks.flatMap(block => block.transactions.map(tx => ({ - txHash: tx.txnHash, - ts: tx.ts, - blockHash: tx.blockHash, - category: tx.category, - status: tx.status, - source: tx.source, - from: tx.from, + ...tx, recipients: tx.recipients.recipients.map(recipient => recipient.address) })) ); diff --git a/layout/index.tsx b/layout/index.tsx index 750fa3e..89b181a 100644 --- a/layout/index.tsx +++ b/layout/index.tsx @@ -1,25 +1,14 @@ -// React, NextJS imports import React from 'react'; - -// External Library imports import { Box } from '../blocks'; -import { useMediaQuery } from '@mui/material'; - -// Internal Components imports import FooterSection from '../sections/Footer'; import HeaderSection from '../sections/Header'; export default function Layout({ children }) { - const isMobile = useMediaQuery('(max-width:480px)'); - return ( diff --git a/pages/blocks/[blockHash].tsx b/pages/blocks/[blockHash].tsx index f3a922a..53d78c3 100644 --- a/pages/blocks/[blockHash].tsx +++ b/pages/blocks/[blockHash].tsx @@ -1,25 +1,22 @@ -// pages/transactions/details/[address].tsx import React from 'react'; -import { useRouter } from 'next/router'; import dynamic from 'next/dynamic'; import Head from 'next/head'; +import { Spinner } from '../../blocks' const Layout = dynamic(() => import('../../layout')); + const BlocksDetailsView = dynamic(() => import('../../sections/Blocks/blockHash'), { - loading: () =>

Loading...

, + loading: () => , }); const BlocksDetailsPage = () => { - const router = useRouter(); - const { blockHash } = router.query; - return ( <> - Blocks Details for {blockHash} + Blocks Details - + ); diff --git a/pages/blocks/index.tsx b/pages/blocks/index.tsx index ef85917..fb75278 100644 --- a/pages/blocks/index.tsx +++ b/pages/blocks/index.tsx @@ -2,12 +2,10 @@ import React from 'react'; import Head from 'next/head'; import dynamic from 'next/dynamic'; - -// Internal Components imports -import { BlocksLoader } from '../../components/Loader/BlocksLoader'; +import { Spinner } from '../../blocks' const BlocksView = dynamic(() => import('../../sections/Blocks'), { - loading: () => , + loading: () => , }); const Layout = dynamic(() => import('../../layout')); diff --git a/pages/home/index.tsx b/pages/home/index.tsx index 0c52b9a..a6d706a 100644 --- a/pages/home/index.tsx +++ b/pages/home/index.tsx @@ -1,12 +1,12 @@ -// React, NextJS imports import React from 'react'; import Head from 'next/head'; import dynamic from 'next/dynamic'; +import { Spinner } from '../../blocks' -// Internal Components imports -import { HomeLoader } from '../../components/Loader/HomeLoader'; +const HomeView = dynamic(() => import('../../sections/Home'), { + loading: () => , +}); -const HomeView = dynamic(() => import('../../sections/Home')); const Layout = dynamic(() => import('../../layout')); export default function Home() { diff --git a/pages/search/[txHash].tsx b/pages/search/[txHash].tsx new file mode 100644 index 0000000..074a0f2 --- /dev/null +++ b/pages/search/[txHash].tsx @@ -0,0 +1,24 @@ +// React, NextJS imports +import React, { useEffect, useState } from 'react'; +import Head from 'next/head'; +import dynamic from 'next/dynamic'; +import { Spinner, Box } from '../../blocks'; + +const SearchView = dynamic(() => import('../../sections/Search'), { + loading: () => + }); + +const Layout = dynamic(() => import('../../layout')); + +export default function Transactions() { + return ( + <> + + Push Transactions + + + + + + ); +} diff --git a/pages/transactions/[txHash].tsx b/pages/transactions/[txHash].tsx index 452f487..9b752e8 100644 --- a/pages/transactions/[txHash].tsx +++ b/pages/transactions/[txHash].tsx @@ -1,25 +1,22 @@ -// pages/transactions/details/[address].tsx import React from 'react'; -import { useRouter } from 'next/router'; import dynamic from 'next/dynamic'; import Head from 'next/head'; +import { Spinner } from '../../blocks' const Layout = dynamic(() => import('../../layout')); + const TransactionDetailsView = dynamic(() => import('../../sections/Transactions/txHash'), { - loading: () =>

Loading...

, + loading: () => , }); const TransactionDetailsPage = () => { - const router = useRouter(); - const { txHash } = router.query; // Accessing the dynamic address parameter - return ( <> - Transaction Details for {txHash} + Transaction Details - + ); diff --git a/pages/transactions/index.tsx b/pages/transactions/index.tsx index 5511757..f801b90 100644 --- a/pages/transactions/index.tsx +++ b/pages/transactions/index.tsx @@ -1,13 +1,10 @@ -// React, NextJS imports import React from 'react'; import Head from 'next/head'; import dynamic from 'next/dynamic'; - -// Internal Components imports -import { TransactionLoader } from '../../components/Loader/TransactionLoader'; +import { Spinner } from '../../blocks' const TransactionView = dynamic(() => import('../../sections/Transactions'), { - loading: () => , + loading: () => , }); const Layout = dynamic(() => import('../../layout')); diff --git a/pages/transactions/search/[txHash].tsx b/pages/transactions/search/[txHash].tsx deleted file mode 100644 index f163a86..0000000 --- a/pages/transactions/search/[txHash].tsx +++ /dev/null @@ -1,50 +0,0 @@ -// React, NextJS imports -import React, { useEffect, useState } from 'react'; -import Head from 'next/head'; -import dynamic from 'next/dynamic'; -import { useRouter } from 'next/router'; -import { useSearchByAddress } from '../../../hooks/useSearchByAddress' -import { TransactionLoader } from '../../../components/Loader/TransactionLoader'; - -const TransactionView = dynamic(() => import('../../../sections/Transactions'), { - loading: () => , -}); - -const TransactionsView = dynamic(() => import('../../../sections/Transactions'), { - loading: () =>

Loading...

, - }); - -const Layout = dynamic(() => import('../../../layout')); - -export default function Transactions() { - const router = useRouter(); - const { txHash } = router.query; // Accessing the dynamic address parameter - const [address, setAddress] = useState(''); - - useEffect(() => { - if (router.isReady && txHash && typeof txHash === 'string') { - setAddress(txHash); // Ensuring txHash is treated as a string - } - }, [router.isReady, txHash]); - - - const { data, error, isLoading, isError } = useSearchByAddress({ address }); - - - - - if (!address || data?.transactions.length == 0) { - return ; // Render a loading state or placeholder until address is defined - } - - return ( - <> - - Push Transactions - - - - - - ); -} diff --git a/sections/Blocks/blockHash.tsx b/sections/Blocks/blockHash.tsx index 416e3c4..4754c3a 100644 --- a/sections/Blocks/blockHash.tsx +++ b/sections/Blocks/blockHash.tsx @@ -1,14 +1,26 @@ import React from 'react'; -import { Box, Text } from '../../blocks'; +import { Box, Text, Spinner } from '../../blocks'; import Advanced from '../../components/Reusables/Advanced'; import ConsensusInfo from '../../components/Blocks/ConsensusInfo'; import BlockDetails from '../../components/Blocks/Details' import BlockTxDetails from '../../components/Blocks/BlockTxDetails' -import { useLiveBlockByHash, BlockDetailsProps } from '../../hooks/useLiveBlockByHash'; +import { useLiveBlockByHash } from '../../hooks/useLiveBlockByHash'; +import { useRouter } from 'next/router'; -const Details = (props: BlockDetailsProps) => { - - const { data, error, isLoading, isError } = useLiveBlockByHash({ blockHash: props.blockHash }); +const Details = () => { + const router = useRouter(); + const { blockHash } = router.query; + + const { data, isLoading } = useLiveBlockByHash({ blockHash }); + const showLoading = !blockHash || isLoading + + if (showLoading) { + return ( + + + + ) + } return ( { display="flex" flexDirection="column" gap="spacing-xxxl" - - > + > { + const router = useRouter(); + const { txHash } = router.query; + + const [tooltipText, setToolTipText] = useState('Copy Address'); + const [page, setPage] = useState(1); + + const copyAddress = () => { + if (txHash) { + navigator.clipboard.writeText(Array.isArray(txHash) ? txHash[0] : txHash); + setToolTipText('Copied'); + } + setTimeout(() => { + setToolTipText('Copy Address'); + }, 1000); + }; + + const { data, isLoading } = useSearchByAddress({ address: txHash, page: page }) + + const showLoading = !txHash || isLoading + + if (showLoading) { + return ( + + + + ) + } + + return ( + + + + Address {txHash} + + + + + + + + Transactions for {centerMaskString(txHash)} + + + + setPage(page)} + /> + + + + ); +}; + +export default Search; \ No newline at end of file diff --git a/sections/Transactions/index.tsx b/sections/Transactions/index.tsx index ac13f12..27f3a3b 100644 --- a/sections/Transactions/index.tsx +++ b/sections/Transactions/index.tsx @@ -1,83 +1,44 @@ import React, { useState } from 'react'; -import { Box, Text, Copy, Tooltip } from '../../blocks'; +import { Box, Text, Spinner, Pagination } from '../../blocks'; import ListView from '../../components/Transactions/ListView'; -import { Transaction } from '../../types/transaction'; -import { centerMaskString } from '../../utils/helpers'; - -interface dataProps { - transactions: Transaction[], - totalPages: number, - lastTs: number -} - -interface IProps { - data?: dataProps, - search?: true, - address?: string -} - -const Transactions = (props) => { - const [tooltipText, setToolTipText] = useState('Copy Address'); - - const copyAddress = () => { - if (props.address) { - navigator.clipboard.writeText(props.address); - setToolTipText('Copied'); - } - setTimeout(() => { - setToolTipText('Copy Address'); - }, 1000); - }; - +import { useLiveTransactions } from '../../hooks/useLiveTransactions'; +import { PerPageItems } from '../../utils/constants' + +const Transactions = () => { + const [page, setPage] = useState(1); + const { data, isLoading } = useLiveTransactions({ page }); + + if (isLoading) { + return ( + + + + ) + } return ( - - - { props.address && ( - - Address {props.address} - - - - - - - - Transactions for {centerMaskString(props.address)} - )} - + > + Transactions + - {!props.search && Transactions} - + setPage(page)} + /> - ); }; diff --git a/sections/Transactions/txHash.tsx b/sections/Transactions/txHash.tsx index 4e28b53..08d6b83 100644 --- a/sections/Transactions/txHash.tsx +++ b/sections/Transactions/txHash.tsx @@ -1,14 +1,26 @@ import React from 'react'; -import { Box, Text } from '../../blocks'; +import { Box, Text, Spinner } from '../../blocks'; import Advanced from '../../components/Reusables/Advanced'; import ConsensusInfo from '../../components/Transactions/ConsensusInfo'; import TXDetails from '../../components/Transactions/TxDetails' import TxTravels from '../../components/Transactions/TxTravels' -import { useLiveTxByHash, TxDetailsProps } from '../../hooks/useLiveTxByHash'; +import { useLiveTxByHash } from '../../hooks/useLiveTxByHash'; +import { useRouter } from 'next/router'; -const Details = (props: TxDetailsProps) => { +const Details = () => { + const router = useRouter(); + const { txHash } = router.query; + + const { data, isLoading } = useLiveTxByHash({ txHash }); + const showLoading = !txHash || isLoading - const { data, error, isLoading, isError } = useLiveTxByHash({ txHash: props.txHash }); + if (showLoading) { + return ( + + + + ) + } return ( 14) { +export function centerMaskString(str, len = 15) { + if (str.length > 15) { const start = str.substring(0, 10); const end = str.substring(str.length - 7); return start + '...' + end; @@ -87,10 +86,10 @@ export function centerMaskString(str) { return str; } -export function rightMaskString(str) { +export function rightMaskString(str, len = 15) { // Check if the string length is more than 15 to mask the remaining characters - if (str.length > 15) { - const visiblePart = str.substring(0, 15); + if (str.length > len) { + const visiblePart = str.substring(0, len); const maskedPart = '...'; return visiblePart + maskedPart; } diff --git a/utils/json-rpc.ts b/utils/json-rpc.ts index 4f51652..d4ac30d 100644 --- a/utils/json-rpc.ts +++ b/utils/json-rpc.ts @@ -2,6 +2,8 @@ import axios from 'axios'; const API_BASE = 'http://localhost:3000/rpc'; +const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + export const makeJsonRpcRequest = async (id, method, params = {}) => { const data = { jsonrpc: '2.0', @@ -11,7 +13,11 @@ export const makeJsonRpcRequest = async (id, method, params = {}) => { }; try { - const response = await axios.post(API_BASE, data); + const response = await axios.post(API_BASE, data); + if (response.data.error) { + throw new Error('JSON-RPC Error: ' + response.data.error.message); + } + return response.data.result; } catch (error) { throw new Error('JSON-RPC Error: ' + error.message); From 04d6b87dabdd78e0a04c9d8b342a913c61b1eb12 Mon Sep 17 00:00:00 2001 From: rozaso Date: Fri, 6 Sep 2024 07:47:10 -0700 Subject: [PATCH 12/42] Integrate latest block components and fix UI issues. --- blocks/alert/Alert.tsx | 2 + blocks/illustrations/components/PushLogo.tsx | 2 +- blocks/spinner/Spinner.tsx | 25 ++- blocks/spinner/Spinner.types.ts | 2 +- blocks/spinner/Spinner.utils.ts | 11 + blocks/table/Table.tsx | 205 ++++++++++++++----- blocks/theme/semantics/semantics.spinner.ts | 2 +- components/Blocks/ConsensusInfo.tsx | 10 + components/Blocks/ListView.tsx | 9 +- components/Home/LiveBlocks.tsx | 14 +- components/Home/LiveTransactions.tsx | 36 ++-- components/Home/SearchBar.tsx | 16 +- components/Navbar/index.tsx | 36 +--- components/Reusables/Advanced.tsx | 12 +- components/Transactions/ConsensusInfo.tsx | 67 ++++-- components/Transactions/ListView.tsx | 6 +- components/Transactions/TxTravels.tsx | 17 +- hooks/useCounts.ts | 7 +- hooks/useLiveTransactions.ts | 8 +- layout/index.tsx | 2 +- pages/index.tsx | 8 - sections/Blocks/blockHash.tsx | 16 +- sections/Transactions/index.tsx | 2 +- sections/Transactions/txHash.tsx | 18 +- utils/constants.js | 5 +- utils/json-rpc.ts | 1 + 26 files changed, 365 insertions(+), 174 deletions(-) diff --git a/blocks/alert/Alert.tsx b/blocks/alert/Alert.tsx index 9f5599d..5bc304e 100644 --- a/blocks/alert/Alert.tsx +++ b/blocks/alert/Alert.tsx @@ -77,10 +77,12 @@ const RightContainer = styled.div` `; const Heading = styled.p` + white-space: break-spaces; ${() => getTextVariantStyles('h5-semibold', 'components-alert-text-default')} `; const Description = styled.p` + white-space: break-spaces; ${() => getTextVariantStyles('bs-regular', 'components-alert-text-body')} `; diff --git a/blocks/illustrations/components/PushLogo.tsx b/blocks/illustrations/components/PushLogo.tsx index 53ac3f2..33d21b1 100644 --- a/blocks/illustrations/components/PushLogo.tsx +++ b/blocks/illustrations/components/PushLogo.tsx @@ -1,4 +1,4 @@ -import { FC } from 'react'; +import React , { FC } from 'react'; import { IllustrationWrapper } from '../IllustrationWrapper'; import { IllustrationProps } from '../Illustrations.types'; diff --git a/blocks/spinner/Spinner.tsx b/blocks/spinner/Spinner.tsx index 9d93ec3..31eb925 100644 --- a/blocks/spinner/Spinner.tsx +++ b/blocks/spinner/Spinner.tsx @@ -1,9 +1,8 @@ import React from 'react'; import styled, { FlattenSimpleInterpolation, keyframes } from 'styled-components'; import { SpinnerSize, SpinnerVariant } from './Spinner.types'; -import { getSpinnerSize } from './Spinner.utils'; +import { getSpinnerSize, getSpinnerColor } from './Spinner.utils'; import { Ellipse } from '../icons'; - export type SpinnerProps = { /* Additional prop from styled components to apply custom css to Spinner */ css?: FlattenSimpleInterpolation; @@ -12,7 +11,6 @@ export type SpinnerProps = { /* Variants for the Spinner */ variant?: SpinnerVariant; }; - const spin = keyframes` from { transform:rotate(0deg); @@ -21,8 +19,7 @@ const spin = keyframes` transform:rotate(360deg); } `; - -const Container = styled.div<{ css?: FlattenSimpleInterpolation; size: SpinnerSize }>` +const Container = styled.div<{ css?: FlattenSimpleInterpolation; size: SpinnerSize; variant?: SpinnerVariant }>` display: flex; align-items: center; justify-content: center; @@ -34,23 +31,31 @@ const Container = styled.div<{ css?: FlattenSimpleInterpolation; size: SpinnerSi width: ${getSpinnerSize(size)}px; height: ${getSpinnerSize(size)}px; `} - + ${({ variant }) => ` + ${ + variant + ? ` + [role='img'] { + color: var(--${getSpinnerColor(variant)}); + } + ` + : '' + } + `} /* Custom CSS applied via styled component css prop */ ${(props) => props.css || ''}; `; - -const Spinner: React.FC = ({ size = 'small', css }) => { +const Spinner: React.FC = ({ size = 'small', css, variant }) => { return ( ); }; - Spinner.displayName = 'Spinner'; - export { Spinner }; diff --git a/blocks/spinner/Spinner.types.ts b/blocks/spinner/Spinner.types.ts index a2a7433..c5d1f7f 100644 --- a/blocks/spinner/Spinner.types.ts +++ b/blocks/spinner/Spinner.types.ts @@ -1,2 +1,2 @@ export type SpinnerSize = 'small' | 'medium' | 'large' | 'extraLarge'; -export type SpinnerVariant = 'default' | 'secondary'; +export type SpinnerVariant = 'primary' | 'secondary'; diff --git a/blocks/spinner/Spinner.utils.ts b/blocks/spinner/Spinner.utils.ts index ebac408..c53413a 100644 --- a/blocks/spinner/Spinner.utils.ts +++ b/blocks/spinner/Spinner.utils.ts @@ -1,5 +1,16 @@ import { SpinnerSize, SpinnerVariant } from './Spinner.types'; +export const getSpinnerColor = (variant: SpinnerVariant) => { + switch (variant) { + case 'primary': + return 'components-spinner-icon-primary'; + case 'secondary': + return 'components-spinner-icon-secondary'; + default: + return ''; + } +}; + export const getSpinnerSize = (size: SpinnerSize) => { switch (size) { case 'small': diff --git a/blocks/table/Table.tsx b/blocks/table/Table.tsx index 873fda3..2f58001 100644 --- a/blocks/table/Table.tsx +++ b/blocks/table/Table.tsx @@ -1,4 +1,4 @@ -import React, { FC, useMemo } from 'react'; +import { FC, useMemo } from 'react'; import { Table as ReactTable, Header, @@ -10,15 +10,24 @@ import { } from '@table-library/react-table-library/table'; import { useTheme } from '@table-library/react-table-library/theme'; import styled from 'styled-components'; +import { Button } from '../button'; +import { getTextVariantStyles } from '../Blocks.utils'; +import { ErrorFilled, Refresh, Search } from '../icons'; +import { Spinner } from '../spinner'; import { textVariants } from '../text'; import { SurfaceColors } from '../theme/Theme.types'; import { Column, DataSource } from './Table.types'; export type TableProps = { + backgroundColor?: SurfaceColors; columns: Column[]; dataSource: DataSource[]; + error?: boolean; fixedHeader?: boolean; - backgroundColor?: SurfaceColors; + loading?: boolean; + onRetry?: () => void; + onRow?: { onClick: (record: any, rowIndex: number) => void }; + retrying?: boolean; }; const StyledHeaderCell = styled(HeaderCell)<{ headerAlignment?: Column['headerAlignment'] }>` @@ -45,7 +54,64 @@ const StyledRowCell = styled(Cell)<{ cellAlignment?: Column['cellAlignment'] }>` : ''} `; -const Table: FC = ({ backgroundColor = 'surface-secondary', columns, dataSource, fixedHeader = false }) => { +const OverlayContainer = styled.div<{ blur?: boolean }>` + position: absolute; + z-index: 100; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + flex-direction: column; + gap: var(--spacing-xs); + opacity: ${({ blur }) => (blur ? '0.5' : '1')}; +`; + +const NullStateContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; + gap: var(--spacing-xs); + flex-direction: column; +`; + +const NullStateTextContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; + gap: var(--spacing-xxxs); + flex-direction: column; +`; + +const NullStateHeading = styled.span` + ${() => getTextVariantStyles('bm-semibold', 'text-primary')} +`; + +const NullStateDescription = styled.span` + ${() => getTextVariantStyles('bes-regular', 'text-tertiary')} +`; + +const LoadingText = styled.span` + ${() => getTextVariantStyles('bm-semibold', 'text-tertiary')} +`; + +const TableContainer = styled.div` + width: inherit; + height: inherit; + position: relative; +`; + +const Table: FC = ({ + backgroundColor = 'surface-secondary', + columns, + dataSource, + error = false, + fixedHeader = false, + loading = false, + onRetry, + onRow, + retrying = false, +}) => { const columnData = useMemo(() => { const columnWidths = columns.map((col) => col.width || `${100 / columns.length}%`); @@ -116,59 +182,98 @@ const Table: FC = ({ backgroundColor = 'surface-secondary', columns, line-height: ${textVariants['c-bold'].lineHeight}; padding: var(--spacing-xxs) var(--spacing-xxxs); gap: 10px; + height: fit-content; + opacity: ${loading ? '0.5' : '1'}; `, }); return ( - - {(tableList: DataSource[]) => ( - <> -
- - {columns.map((column, index) => ( - - {column.title} - - ))} - -
- - - {tableList.map((record) => ( - + {loading && !error && ( + + + Loading + + )} + {!loading && !dataSource.length && ( + + + {error ? : } + + {error ? 'Trouble Fetching Data' : 'No Results Found'} + + {error + ? 'Please try again in a few minutes or reload the page.' + : 'Try adjusting your search or filter to find what you’re looking for'} + + + {error && onRetry && ( + + )} + + )} -
+ + {(tableList: DataSource[]) => ( + <> +
+ + {columns.map((column, index) => ( + + {column.title} + + ))} + +
+ + + {tableList.map((record, recordIndex) => ( + onRow?.onClick?.(record, recordIndex)} + > + {columns.map((column) => { + const cellValue = `${record?.[column.dataIndex] || ''}`; + return ( + + {column.render ? column.render(cellValue, record) : cellValue} + + ); + })} + + ))} + + + )} +
+ ); }; diff --git a/blocks/theme/semantics/semantics.spinner.ts b/blocks/theme/semantics/semantics.spinner.ts index 785380a..ba2be66 100644 --- a/blocks/theme/semantics/semantics.spinner.ts +++ b/blocks/theme/semantics/semantics.spinner.ts @@ -1,6 +1,6 @@ import { colorBrands } from '../colors/colors.brands'; export const spinnerSemantics = { - 'icon-default': { light: colorBrands['primary-500'], dark: colorBrands['primary-500'] }, + 'icon-primary': { light: colorBrands['primary-500'], dark: colorBrands['primary-500'] }, 'icon-secondary': { light: colorBrands['neutral-1000'], dark: colorBrands['neutral-100'] }, }; diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index 036bb83..9cb08e6 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -201,6 +201,16 @@ const ConsensusInfo = (props: IProps) => {
)} + + + + +
diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx index 6b1e9b1..744614a 100644 --- a/components/Blocks/ListView.tsx +++ b/components/Blocks/ListView.tsx @@ -5,11 +5,15 @@ import { PerPageItems } from '../../utils/constants' import { useRouter } from 'next/router' import moment from 'moment'; import { getValidatorNode } from '../../utils/helpers' +import { useTheme } from 'styled-components'; const Blocks = () => { const router = useRouter() const [page, setPage] = useState(1); - const { data, error, isLoading, isError } = useLiveBlocks({ page }); + const { data, error, isLoading, isError } = useLiveBlocks({ page }); + + const theme = useTheme(); + const isDarkMode = theme.scheme === 'dark'; const columns = [ { @@ -63,13 +67,14 @@ const Blocks = () => { ts: block.ts })) || []; + return ( -
+
Live Blocks - -
- +
+ + { const reci = recipients.split(',') return ( - - - - { getChainIcon('ETH_MAINNET') } - {centerMaskString(reci[0])} + + + + { getChainIcon('ETH_MAINNET') } + {centerMaskString(reci[0])} + + { reci.length > 1 && {`+ ${reci.length - 1} more`}} - { reci.length > 1 && {`+ ${reci.length - 1} more`}} - )}, cellAlignment: 'center', headerAlignment: 'center', @@ -92,9 +96,9 @@ export default function LiveTransactions() { ]; const dataSource = data?.transactions.map((dt) => ({ - id: dt.txHash, + id: dt.txnHash, status: dt.status, - txHash: dt.txHash, + txHash: dt.txnHash, from: JSON.stringify({ from: dt.from, source: dt.source }), recipients: dt.recipients, ts: dt.ts, @@ -108,9 +112,7 @@ export default function LiveTransactions() { gap="spacing-sm" > Live Transactions - -
- +
setDebouncedQuery(getFormattedQuery(query)), 500, [query]); return ( - router.push(`/search/${debouncedQuery}`)}/>} - value={query} - onChange={(e) => setQuery(e.target.value)} - /> + + router.push(`/search/${debouncedQuery}`)}/>} + value={query} + onChange={(e) => setQuery(e.target.value)} + /> + ) } diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index 9cab17b..0c82255 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -9,19 +9,11 @@ import { Button, useMediaQuery } from '@mui/material'; import { useTheme } from 'styled-components'; // Internal Components imports -import Logo from '../Logo'; import { useTheme as Theme } from '../../contexts/ThemeContext'; import { useData } from '../../contexts/DataContext'; import { ROUTES, CREDENTIALKEYS } from '../../utils/constants'; -import { ItemHV2, ItemVV2 } from '../../components/Reusables/SharedStyling'; -import { NavBarButtons } from './NavBarButtons'; -import { - NavbarContainer, - HamburgerLine, - SidebarContainer, -} from './navbar.styled'; import { ThemeType } from '../../types/theme'; -import { Box, Select, Text, Lozenge, PushLogo } from '../../blocks'; +import { Box, Text, Lozenge, PushLogo } from '../../blocks'; import SearchBar from '../Home/SearchBar' import ChainsDropDown from '../Reusables/ChainsDropDown' import Link from 'next/link' @@ -103,7 +95,6 @@ export default function Navbar() { - - - - PushScan - - ALPHA - + + PushScan + + ALPHA { +interface IProps { + showConsensusInfo: boolean + toggleConsensusInfo: (value: boolean) => void +} + +const Advanced = ({ showConsensusInfo, toggleConsensusInfo }: IProps) => { return ( toggleConsensusInfo(!showConsensusInfo)} > Advanced - + { showConsensusInfo ? : } ); }; diff --git a/components/Transactions/ConsensusInfo.tsx b/components/Transactions/ConsensusInfo.tsx index 8954e9a..78e85fc 100644 --- a/components/Transactions/ConsensusInfo.tsx +++ b/components/Transactions/ConsensusInfo.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Box, Text, Button, Add, Ethereum } from '../../blocks'; +import { Box, Text, Button, Add, Ethereum, Tooltip, Copy } from '../../blocks'; import { Transaction } from '../../types/transaction'; import { BlockDetails } from '../../types/block'; @@ -15,6 +15,7 @@ const MAX_DISPLAY_CHARS = 700; const ConsensusInfo = (props: IProps) => { const [showAll, setShowAll] = useState(false); const [showAllPayload, setShowAllPayload] = useState(false); + const [tooltipText, setToolTipText] = useState('Copy Payload'); const toggleShowAll = () => { setShowAll(!showAll); @@ -32,6 +33,16 @@ const ConsensusInfo = (props: IProps) => { const displayedPayload = showAllPayload ? payload : payload.substring(0, MAX_DISPLAY_CHARS); const showMorePayloadButton = payload.length > MAX_DISPLAY_CHARS; + const copyPayload = () => { + if (payload) { + navigator.clipboard.writeText(payload); + setToolTipText('Copied'); + } + setTimeout(() => { + setToolTipText('Copy Payload'); + }, 1000); + }; + return ( <> { gap="spacing-lg" > {node} - + ))} @@ -118,6 +128,16 @@ const ConsensusInfo = (props: IProps) => { )} + + + + + @@ -149,16 +169,23 @@ const ConsensusInfo = (props: IProps) => { display="flex" flexDirection="row" gap="spacing-lg" - > - {node} - + + ))} @@ -206,6 +233,16 @@ const ConsensusInfo = (props: IProps) => { )} + + + + + diff --git a/components/Transactions/ListView.tsx b/components/Transactions/ListView.tsx index 94a4b4a..0745614 100644 --- a/components/Transactions/ListView.tsx +++ b/components/Transactions/ListView.tsx @@ -5,6 +5,7 @@ import { useRouter } from 'next/router' import moment from 'moment'; import { TagVariant } from '../../blocks/tag'; import { Transaction } from '../../types/transaction'; +import { useTheme } from 'styled-components'; interface dataProps { transactions: Transaction[], @@ -18,6 +19,9 @@ interface IProps { const ListView = (props: IProps) => { const router = useRouter() + const theme = useTheme(); + const isDarkMode = theme.scheme === 'dark'; + let data = props.data; function getChainIcon(source) { @@ -123,7 +127,7 @@ const ListView = (props: IProps) => { return ( -
+
); }; diff --git a/components/Transactions/TxTravels.tsx b/components/Transactions/TxTravels.tsx index 3c45141..06a7e51 100644 --- a/components/Transactions/TxTravels.tsx +++ b/components/Transactions/TxTravels.tsx @@ -105,13 +105,16 @@ const TxTravels = (props: IProps) => { gap="spacing-xxxs" > From + { getChainIcon(props.data?.source) } - {props.data?.from} + + {props.data?.from} + @@ -127,7 +130,17 @@ const TxTravels = (props: IProps) => { gap="spacing-xs" > {displayedRecipients.map((recipient, index) => ( - {recipient.address} + + { getChainIcon(props.data?.source) } + + {recipient.address} + + ))} {showMoreButton && ( diff --git a/hooks/useCounts.ts b/hooks/useCounts.ts index 8fdb092..71c7364 100644 --- a/hooks/useCounts.ts +++ b/hooks/useCounts.ts @@ -6,7 +6,10 @@ const RPC_ID = 6 export const useCounts = () => { const getCounts = () => makeJsonRpcRequest(RPC_ID, 'getCounts'); - return useQuery('homeOverViewCounts', getCounts, { + + return useQuery({ + queryKey: ['homeOverViewCounts'], + queryFn: getCounts, refetchInterval: POLL_INTERVAL - }); + }); } \ No newline at end of file diff --git a/hooks/useLiveTransactions.ts b/hooks/useLiveTransactions.ts index ecfb01e..02e2561 100644 --- a/hooks/useLiveTransactions.ts +++ b/hooks/useLiveTransactions.ts @@ -68,13 +68,7 @@ export const useLiveTransactions = (props: inputProps) => { select: (data) => { const transactions = data.blocks.flatMap(block => block.transactions.map(tx => ({ - txHash: tx.txnHash, - ts: tx.ts, - blockHash: tx.blockHash, - category: tx.category, - status: tx.status, - source: tx.source, - from: tx.from, + ...tx, recipients: tx.recipients.recipients.map(recipient => recipient.address) })) ); diff --git a/layout/index.tsx b/layout/index.tsx index 89b181a..5bf33eb 100644 --- a/layout/index.tsx +++ b/layout/index.tsx @@ -8,7 +8,7 @@ export default function Layout({ children }) { diff --git a/pages/index.tsx b/pages/index.tsx index 8262756..fd63a7c 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -9,14 +9,6 @@ export default function Home() { const router = useRouter(); useEffect(() => { - router.push(ROUTES.DASHBOARD, undefined, { shallow: true }); router.push(ROUTES.HOME, undefined, { shallow: true }); - - router.push(ROUTES.TRANSACTIONS, undefined, { shallow: true }); - router.push(ROUTES.TRANSACTIONS_DETAILS, undefined, { shallow: true }); - - router.push(ROUTES.BLOCKS, undefined, { shallow: true }); - router.push(ROUTES.BLOCKS_DETAILS, undefined, { shallow: true }); - }, [router]); } diff --git a/sections/Blocks/blockHash.tsx b/sections/Blocks/blockHash.tsx index 4754c3a..31e527c 100644 --- a/sections/Blocks/blockHash.tsx +++ b/sections/Blocks/blockHash.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Box, Text, Spinner } from '../../blocks'; import Advanced from '../../components/Reusables/Advanced'; import ConsensusInfo from '../../components/Blocks/ConsensusInfo'; @@ -11,6 +11,8 @@ const Details = () => { const router = useRouter(); const { blockHash } = router.query; + const [showConsensusInfo, setConsensusInfo] = useState(true); + const { data, isLoading } = useLiveBlockByHash({ blockHash }); const showLoading = !blockHash || isLoading @@ -39,11 +41,13 @@ const Details = () => { data={data?.blockDetails} isLoading={isLoading} /> - - + + + { showConsensusInfo && + } ); }; diff --git a/sections/Transactions/index.tsx b/sections/Transactions/index.tsx index 27f3a3b..d12f070 100644 --- a/sections/Transactions/index.tsx +++ b/sections/Transactions/index.tsx @@ -7,7 +7,7 @@ import { PerPageItems } from '../../utils/constants' const Transactions = () => { const [page, setPage] = useState(1); const { data, isLoading } = useLiveTransactions({ page }); - + if (isLoading) { return ( diff --git a/sections/Transactions/txHash.tsx b/sections/Transactions/txHash.tsx index 08d6b83..c914627 100644 --- a/sections/Transactions/txHash.tsx +++ b/sections/Transactions/txHash.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { Box, Text, Spinner } from '../../blocks'; import Advanced from '../../components/Reusables/Advanced'; import ConsensusInfo from '../../components/Transactions/ConsensusInfo'; @@ -11,6 +11,8 @@ const Details = () => { const router = useRouter(); const { txHash } = router.query; + const [showConsensusInfo, setConsensusInfo] = useState(true); + const { data, isLoading } = useLiveTxByHash({ txHash }); const showLoading = !txHash || isLoading @@ -39,12 +41,14 @@ const Details = () => { data={data?.transaction} isLoading={isLoading} /> - - + + { showConsensusInfo && + + } ); }; diff --git a/utils/constants.js b/utils/constants.js index fd5c10e..7421fec 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -17,9 +17,10 @@ export const ROUTES = { ADMIN: '/admin', DASHBOARD: '/dashboard', TRANSACTIONS: '/transactions', - TRANSACTION_DETAILS: '/transactions/address', + TRANSACTION_DETAILS: '/transactions/:address', BLOCKS: '/blocks', - BLOCKS_DETAILS: '/blocks/address', + BLOCKS_DETAILS: '/blocks/:address', + SEARCH: '/search/:address', ERROR: '*', }; diff --git a/utils/json-rpc.ts b/utils/json-rpc.ts index d4ac30d..a332817 100644 --- a/utils/json-rpc.ts +++ b/utils/json-rpc.ts @@ -13,6 +13,7 @@ export const makeJsonRpcRequest = async (id, method, params = {}) => { }; try { + // await delay(500000); const response = await axios.post(API_BASE, data); if (response.data.error) { throw new Error('JSON-RPC Error: ' + response.data.error.message); From 243e0f630731701718824202162b568b1712e68a Mon Sep 17 00:00:00 2001 From: rozaso Date: Tue, 10 Sep 2024 17:38:55 -0700 Subject: [PATCH 13/42] Fix styling issues. --- components/Home/LiveBlocks.tsx | 2 +- components/Home/SearchBar.tsx | 16 +++---- components/Navbar/index.tsx | 85 +++++++++++++--------------------- sections/Home/index.tsx | 10 ---- 4 files changed, 39 insertions(+), 74 deletions(-) diff --git a/components/Home/LiveBlocks.tsx b/components/Home/LiveBlocks.tsx index 7818968..59f2aec 100644 --- a/components/Home/LiveBlocks.tsx +++ b/components/Home/LiveBlocks.tsx @@ -69,7 +69,7 @@ export default function LiveBlocks() { -
+
console.log("Clicked !!!") }} loading={isLoading} columns={columns} dataSource={dataSource} backgroundColor={isDarkMode ? 'surface-secondary' : 'surface-primary'} /> setDebouncedQuery(getFormattedQuery(query)), 500, [query]); return ( - - router.push(`/search/${debouncedQuery}`)}/>} - value={query} - onChange={(e) => setQuery(e.target.value)} - /> - + router.push(`/search/${debouncedQuery}`)}/>} + value={query} + onChange={(e) => setQuery(e.target.value)} + /> ) } diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index 0c82255..dccd7cd 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -36,11 +36,15 @@ export default function Navbar() { }; return ( - <> + @@ -55,6 +59,8 @@ export default function Navbar() { flexDirection="row" alignItems="center" gap="spacing-xxxs" + css={'cursor: pointer'} + onClick={() => router.push('/home')} > PushScan @@ -78,7 +84,7 @@ export default function Navbar() { > { asPath !== '/dashboard' && ( - Analytics + Analytics )} @@ -90,65 +96,38 @@ export default function Navbar() { moonColor="#FFFFFF" /> - { asPath !== '/home' && } + { asPath !== '/home' && ( + + + + )} + { asPath === '/home' && Push Blockchain Explorer - TESTS!!!!!!!!!!!! } + HELLO TEST!!!! + + + + { asPath === '/home' && ( - - - PushScan - - ALPHA - - - - { asPath !== '/dashboard' && ( - - Analytics - - )} - - - + Push Blockchain Explorer + - - - - { asPath !== '/home' && } - - - + )} + ); } diff --git a/sections/Home/index.tsx b/sections/Home/index.tsx index 3ce1a79..fe0a8ff 100644 --- a/sections/Home/index.tsx +++ b/sections/Home/index.tsx @@ -20,16 +20,6 @@ const Home = () => { alignItems="flex-start" gap={{ ml: "spacing-lg", initial: "spacing-xxl" }} > - - Push Blockchain Explorer - - - From d015e78e238e4b9cfac0ba77459bb40c6ecfddad Mon Sep 17 00:00:00 2001 From: rozaso Date: Wed, 11 Sep 2024 10:11:24 -0700 Subject: [PATCH 14/42] Fix DQA issues. --- blocks/theme/variables/variables.spacing.ts | 1 + common/components/ContentLayout.tsx | 34 ++++++++++++++ common/components/index.ts | 1 + common/index.ts | 3 +- components/Blocks/ListView.tsx | 10 ++--- components/Footer/index.tsx | 3 +- components/Home/LiveBlocks.tsx | 12 ++--- components/Home/LiveTransactions.tsx | 28 ++++++------ components/Home/OverView.tsx | 40 +++++++---------- components/Home/SearchBar.tsx | 1 + components/Navbar/index.tsx | 19 ++------ hooks/useBlocks.ts | 3 +- hooks/useLiveTransactions.ts | 3 +- layout/index.tsx | 9 ++-- public/static/fonts/FKGroteskNeue-Bold.woff | Bin 0 -> 74140 bytes public/static/fonts/FKGroteskNeue-Bold.woff2 | Bin 0 -> 53696 bytes public/static/fonts/FKGroteskNeue-Medium.woff | Bin 0 -> 74236 bytes .../static/fonts/FKGroteskNeue-Medium.woff2 | Bin 0 -> 53764 bytes .../static/fonts/FKGroteskNeue-Regular.woff | Bin 0 -> 74792 bytes .../static/fonts/FKGroteskNeue-Regular.woff2 | Bin 0 -> 54380 bytes .../{fonts => fonts_old}/Strawford-Black.eot | Bin .../{fonts => fonts_old}/Strawford-Black.svg | 0 .../{fonts => fonts_old}/Strawford-Black.ttf | Bin .../{fonts => fonts_old}/Strawford-Black.woff | Bin .../Strawford-Black.woff2 | Bin .../{fonts => fonts_old}/Strawford-Bold.eot | Bin .../{fonts => fonts_old}/Strawford-Bold.svg | 0 .../{fonts => fonts_old}/Strawford-Bold.ttf | Bin .../{fonts => fonts_old}/Strawford-Bold.woff | Bin .../{fonts => fonts_old}/Strawford-Bold.woff2 | Bin .../Strawford-ExtraLight.otf | Bin .../Strawford-ExtraLight.ttf | Bin .../Strawford-ExtraLight.woff2 | Bin .../{fonts => fonts_old}/Strawford-Light.otf | Bin .../{fonts => fonts_old}/Strawford-Light.ttf | Bin .../Strawford-Light.woff2 | Bin .../{fonts => fonts_old}/Strawford-Medium.otf | Bin .../{fonts => fonts_old}/Strawford-Medium.ttf | Bin .../Strawford-Medium.woff2 | Bin .../Strawford-Regular.eot | Bin .../Strawford-Regular.otf | Bin .../Strawford-Regular.ttf | Bin .../Strawford-Regular.woff | Bin .../Strawford-Regular.woff2 | Bin sections/Home/index.tsx | 12 ++++- styles/globals.css | 10 ++--- theme/globalStyles.ts | 42 +++++++++++------- utils/constants.js | 2 +- utils/helpers.ts | 19 ++++++-- 49 files changed, 151 insertions(+), 101 deletions(-) create mode 100644 common/components/ContentLayout.tsx create mode 100644 common/components/index.ts create mode 100644 public/static/fonts/FKGroteskNeue-Bold.woff create mode 100644 public/static/fonts/FKGroteskNeue-Bold.woff2 create mode 100644 public/static/fonts/FKGroteskNeue-Medium.woff create mode 100644 public/static/fonts/FKGroteskNeue-Medium.woff2 create mode 100644 public/static/fonts/FKGroteskNeue-Regular.woff create mode 100644 public/static/fonts/FKGroteskNeue-Regular.woff2 rename public/static/{fonts => fonts_old}/Strawford-Black.eot (100%) rename public/static/{fonts => fonts_old}/Strawford-Black.svg (100%) rename public/static/{fonts => fonts_old}/Strawford-Black.ttf (100%) rename public/static/{fonts => fonts_old}/Strawford-Black.woff (100%) rename public/static/{fonts => fonts_old}/Strawford-Black.woff2 (100%) rename public/static/{fonts => fonts_old}/Strawford-Bold.eot (100%) rename public/static/{fonts => fonts_old}/Strawford-Bold.svg (100%) rename public/static/{fonts => fonts_old}/Strawford-Bold.ttf (100%) rename public/static/{fonts => fonts_old}/Strawford-Bold.woff (100%) rename public/static/{fonts => fonts_old}/Strawford-Bold.woff2 (100%) rename public/static/{fonts => fonts_old}/Strawford-ExtraLight.otf (100%) rename public/static/{fonts => fonts_old}/Strawford-ExtraLight.ttf (100%) rename public/static/{fonts => fonts_old}/Strawford-ExtraLight.woff2 (100%) rename public/static/{fonts => fonts_old}/Strawford-Light.otf (100%) rename public/static/{fonts => fonts_old}/Strawford-Light.ttf (100%) rename public/static/{fonts => fonts_old}/Strawford-Light.woff2 (100%) rename public/static/{fonts => fonts_old}/Strawford-Medium.otf (100%) rename public/static/{fonts => fonts_old}/Strawford-Medium.ttf (100%) rename public/static/{fonts => fonts_old}/Strawford-Medium.woff2 (100%) rename public/static/{fonts => fonts_old}/Strawford-Regular.eot (100%) rename public/static/{fonts => fonts_old}/Strawford-Regular.otf (100%) rename public/static/{fonts => fonts_old}/Strawford-Regular.ttf (100%) rename public/static/{fonts => fonts_old}/Strawford-Regular.woff (100%) rename public/static/{fonts => fonts_old}/Strawford-Regular.woff2 (100%) diff --git a/blocks/theme/variables/variables.spacing.ts b/blocks/theme/variables/variables.spacing.ts index 2108365..c310741 100644 --- a/blocks/theme/variables/variables.spacing.ts +++ b/blocks/theme/variables/variables.spacing.ts @@ -9,4 +9,5 @@ export const spacingVariables = { 'spacing-xl': '40px', 'spacing-xxl': '48px', 'spacing-xxxl': '64px', + 'spacing-xxxxl': '168px' }; diff --git a/common/components/ContentLayout.tsx b/common/components/ContentLayout.tsx new file mode 100644 index 0000000..41b5c3e --- /dev/null +++ b/common/components/ContentLayout.tsx @@ -0,0 +1,34 @@ +// React and other libraries +import React, { FC, ReactNode } from 'react'; + +// third party libraries +import { css } from 'styled-components'; + +//components +import { Box } from '../../blocks'; + +type ContentLayoutProps = { + children: ReactNode; +}; + +const ContentLayout: FC = ({ children }) => { + return ( + + {children} + + ); +}; +export { ContentLayout }; diff --git a/common/components/index.ts b/common/components/index.ts new file mode 100644 index 0000000..18f74fc --- /dev/null +++ b/common/components/index.ts @@ -0,0 +1 @@ +export * from './ContentLayout'; \ No newline at end of file diff --git a/common/index.ts b/common/index.ts index abd99c5..dba93b5 100644 --- a/common/index.ts +++ b/common/index.ts @@ -1 +1,2 @@ -export * from './hooks'; \ No newline at end of file +export * from './hooks'; +export * from './components'; \ No newline at end of file diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx index 744614a..a4e65d8 100644 --- a/components/Blocks/ListView.tsx +++ b/components/Blocks/ListView.tsx @@ -41,20 +41,20 @@ const Blocks = () => { width: '10%' }, { - title: 'SIZE', + title: 'SIZE (IN BYTES)', dataIndex: 'blockSize', render: (text) => {text}, cellAlignment: 'center', headerAlignment: 'center', - width: '10%' + width: '15%' }, { title: 'AGE', dataIndex: 'ts', render: (text) => {moment(text * 1000).fromNow()}, - cellAlignment: 'flex-end', - headerAlignment: 'flex-end', - width: '10%' + cellAlignment: 'center', + headerAlignment: 'center', + width: '5%' }, ]; diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index 1c1a17b..aed768c 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -17,11 +17,10 @@ export default function Footer() { const { isDarkMode } = Theme(); return ( {centerMaskString(text)}, + render: (text) => {centerMaskString(convertCaipToAddress(text))}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '30%' @@ -44,8 +44,8 @@ export default function LiveBlocks() { title: 'AGE', dataIndex: 'ts', render: (text) => {moment(text * 1000).fromNow()}, - cellAlignment: 'flex-end', - headerAlignment: 'flex-end', + cellAlignment: 'center', + headerAlignment: 'center', width: '20%' }, ]; @@ -60,7 +60,7 @@ export default function LiveBlocks() { return ( router.push(`/transactions/${txHash}`)}>{rightMaskString(txHash)}, - cellAlignment: 'center', - headerAlignment: 'center', + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', width: '20%' }, { @@ -54,12 +54,12 @@ export default function LiveTransactions() { return ( { getChainIcon(from.source) } - {centerMaskString(from.from)} + {centerMaskString(convertCaipToAddress(from.from))} ) }, - cellAlignment: 'center', - headerAlignment: 'center', + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', width: '25%' }, { @@ -75,22 +75,22 @@ export default function LiveTransactions() { { getChainIcon('ETH_MAINNET') } - {centerMaskString(reci[0])} + {centerMaskString(convertCaipToAddress(reci[0]))} { reci.length > 1 && {`+ ${reci.length - 1} more`}} )}, - cellAlignment: 'center', - headerAlignment: 'center', + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', width: '25%' }, { title: 'AGE', dataIndex: 'ts', render: (ts: number) => {moment(ts * 1000).fromNow()}, - cellAlignment: 'flex-end', - headerAlignment: 'flex-end', + cellAlignment: 'center', + headerAlignment: 'center', width: '15%' }, ]; @@ -106,7 +106,7 @@ export default function LiveTransactions() { return ( = () => { - const { data, error, isLoading, isError } = useCounts(); + const { data, isLoading } = useCounts(); return ( Transactions {data?.totalTransactions} - - - - - - - - + Total Blocks {data?.totalBlocks} - - - - - - - - Daily Transactions {data?.dailyTransactions} diff --git a/components/Home/SearchBar.tsx b/components/Home/SearchBar.tsx index aa93165..7d22a4f 100644 --- a/components/Home/SearchBar.tsx +++ b/components/Home/SearchBar.tsx @@ -23,6 +23,7 @@ export default function SearchBar() { return ( router.push(`/search/${debouncedQuery}`)}/>} value={query} diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index dccd7cd..f49d886 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -40,9 +40,9 @@ export default function Navbar() { display="flex" flexDirection="column" gap={{initial: "spacing-lg", ml: "spacing-sm" }} + margin="spacing-lg spacing-xxxxl spacing-none spacing-xxxxl" > @@ -112,22 +114,9 @@ export default function Navbar() { gap="spacing-xs" width="-webkit-fill-available" > - { asPath === '/home' && Push Blockchain Explorer - TESTS!!!!!!!!!!!! } - HELLO TEST!!!! + { asPath === '/home' && Push Blockchain Explorer } - - { asPath === '/home' && ( - - Push Blockchain Explorer - - - )} ); } diff --git a/hooks/useBlocks.ts b/hooks/useBlocks.ts index 965fcbf..9aa5ef1 100644 --- a/hooks/useBlocks.ts +++ b/hooks/useBlocks.ts @@ -7,6 +7,7 @@ const RPC_ID = 1 type inputProps = { page?: number | null; + perPageItems?: number | null; }; export const useLiveBlocks = (props: inputProps) => { @@ -16,7 +17,7 @@ export const useLiveBlocks = (props: inputProps) => { "startTime": Math.floor(Date.now() / 1000), "direction": "DESC", "showDetails": false, - "pageSize": PerPageItems, + "pageSize": props.perPageItems || PerPageItems, "page": props.page }); diff --git a/hooks/useLiveTransactions.ts b/hooks/useLiveTransactions.ts index 02e2561..62cc74a 100644 --- a/hooks/useLiveTransactions.ts +++ b/hooks/useLiveTransactions.ts @@ -52,13 +52,14 @@ type ApiResponse = { type inputProps = { page?: number | null; + perPageItems?: number | null; }; export const useLiveTransactions = (props: inputProps) => { const getTransactions = () => makeJsonRpcRequest(RPC_ID, 'getTxs', { "startTime": Math.floor(Date.now() / 1000), "direction": "DESC", - "pageSize": PerPageItems, + "pageSize": props.perPageItems || PerPageItems, "page": props.page }); diff --git a/layout/index.tsx b/layout/index.tsx index 5bf33eb..f38cb18 100644 --- a/layout/index.tsx +++ b/layout/index.tsx @@ -2,17 +2,20 @@ import React from 'react'; import { Box } from '../blocks'; import FooterSection from '../sections/Footer'; import HeaderSection from '../sections/Header'; +import { ContentLayout } from '../common' export default function Layout({ children }) { return ( - {children} + + {children} + ); diff --git a/public/static/fonts/FKGroteskNeue-Bold.woff b/public/static/fonts/FKGroteskNeue-Bold.woff new file mode 100644 index 0000000000000000000000000000000000000000..6fba5378d2b5ae689f87efe59223d7a695078f5b GIT binary patch literal 74140 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 IZ7#$B00dIbqW}N^ literal 0 HcmV?d00001 diff --git a/public/static/fonts/FKGroteskNeue-Bold.woff2 b/public/static/fonts/FKGroteskNeue-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..33b6152df7b9bcd053adb3159da6ed109c1798df GIT binary patch literal 53696 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 literal 0 HcmV?d00001 diff --git a/public/static/fonts/FKGroteskNeue-Medium.woff b/public/static/fonts/FKGroteskNeue-Medium.woff new file mode 100644 index 0000000000000000000000000000000000000000..2cb54f7a01c38c1c9a60f4e682fc041ecdc342c4 GIT binary patch literal 74236 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 literal 0 HcmV?d00001 diff --git a/public/static/fonts/FKGroteskNeue-Medium.woff2 b/public/static/fonts/FKGroteskNeue-Medium.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..29f7b709c9a796dbeb2edb182300e759b677696f GIT binary patch literal 53764 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
}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', @@ -73,10 +57,7 @@ export default function LiveTransactions() { flexDirection="column" > - - { getChainIcon('ETH_MAINNET') } - {centerMaskString(convertCaipToAddress(reci[0]))} - +
{ reci.length > 1 && {`+ ${reci.length - 1} more`}} @@ -88,7 +69,7 @@ export default function LiveTransactions() { { title: 'AGE', dataIndex: 'ts', - render: (ts: number) => {moment(ts * 1000).fromNow()}, + render: (ts: number) => {fromNow(ts * 1000)}, cellAlignment: 'center', headerAlignment: 'center', width: '15%' diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index f49d886..0dd45e9 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -40,7 +40,7 @@ export default function Navbar() { display="flex" flexDirection="column" gap={{initial: "spacing-lg", ml: "spacing-sm" }} - margin="spacing-lg spacing-xxxxl spacing-none spacing-xxxxl" + margin="spacing-lg spacing-xxxxxl spacing-none spacing-xxxxxl" > { + const [isHovered, setIsHovered] = useState(false); + + const handleMouseEnter = () => setIsHovered(true); + const handleMouseLeave = () => setIsHovered(false); + + function getChainIcon(chainId) { + try { + if (!chainId) { + return + } + + switch(Number(chainId)) { + case 1: + return + case 137: + return + case 56: + return + default: + return + } + } catch (err) { + return + } + } + + const { result } = convertCaipToObject(address) + + return ( + + { getChainIcon(result.chainId) } + {isHovered ? ( + + + {centerMaskString(result.address)} + + + ) : ( + + {centerMaskString(result.address)} + + )} + + ); +}; + +export default Address; diff --git a/components/Reusables/BlockHashLink.tsx b/components/Reusables/BlockHashLink.tsx new file mode 100644 index 0000000..5798b0a --- /dev/null +++ b/components/Reusables/BlockHashLink.tsx @@ -0,0 +1,38 @@ +import React, { useState } from 'react'; +import { Box, Text } from '../../blocks'; +import { rightMaskString } from '../../utils/helpers'; +import Link from 'next/link'; + +const BlockHashLink = ({ blockHash, masking = false }) => { + const [isHovered, setIsHovered] = useState(false); + + const handleMouseEnter = () => setIsHovered(true); + const handleMouseLeave = () => setIsHovered(false); + + const maskedBlockHash = masking ? rightMaskString(blockHash) : blockHash; + + return ( + + {isHovered ? ( + + + {maskedBlockHash} + + + ) : ( + + {maskedBlockHash} + + )} + + ); +}; + +export default BlockHashLink; diff --git a/components/Reusables/TxHashLink.tsx b/components/Reusables/TxHashLink.tsx new file mode 100644 index 0000000..9c95386 --- /dev/null +++ b/components/Reusables/TxHashLink.tsx @@ -0,0 +1,43 @@ +import React, { useState } from 'react'; +import { Box, Text } from '../../blocks'; +import { rightMaskString } from '../../utils/helpers' +import Link from 'next/link' + +const TxHashLink = ({ txHash }) => { + const [isHovered, setIsHovered] = useState(false); + + const handleMouseEnter = () => setIsHovered(true); + const handleMouseLeave = () => setIsHovered(false); + + return ( + + {isHovered ? ( + + + {rightMaskString(txHash)} + + + + ) : ( + + {rightMaskString(txHash)} + + )} + + ); +}; + +export default TxHashLink; diff --git a/components/Transactions/ConsensusInfo.tsx b/components/Transactions/ConsensusInfo.tsx index 78e85fc..6d2997d 100644 --- a/components/Transactions/ConsensusInfo.tsx +++ b/components/Transactions/ConsensusInfo.tsx @@ -1,7 +1,8 @@ import React, { useState } from 'react'; -import { Box, Text, Button, Add, Ethereum, Tooltip, Copy } from '../../blocks'; +import { Box, Text, Button, Add, Ethereum, Tooltip, Copy, Tag } from '../../blocks'; import { Transaction } from '../../types/transaction'; import { BlockDetails } from '../../types/block'; +import { Tick } from '../../blocks/icons' interface IProps { blockDetails: BlockDetails | null | undefined, @@ -57,9 +58,11 @@ const ConsensusInfo = (props: IProps) => { - + Consensus Info { gap="spacing-lg" > {node} - - Accepted - + }label={'Accepted'} variant='success'> + ))} @@ -104,15 +102,15 @@ const ConsensusInfo = (props: IProps) => { - Payload Data + gap="spacing-xxxxl" + > + Payload Data + width="52vw" + > {displayedPayload} {showMorePayloadButton && ( { let data = props.data; - function getChainIcon(source) { - switch(source) { - case 'ETH_MAINNET': - return - case 'POLYGON_MAINNET': - return - case 'BSC_MAINNET': - return - default: - return + function getChainIcon(address) { + try { + const { result } = convertCaipToObject(address); + if (!result.chainId) { + return + } + + switch(Number(result.chainId)) { + case 1: + return + case 137: + return + case 56: + return + default: + return + } + } catch (err) { + return } } @@ -41,7 +55,7 @@ const ListView = (props: IProps) => { { title: 'STATUS', dataIndex: 'status', - render: (status: string) => , + render: (status: string) => } label={capitalizeStr(status)} variant={status.toLowerCase() as TagVariant}>, cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '10%' @@ -49,7 +63,7 @@ const ListView = (props: IProps) => { { title: 'TX HASH', dataIndex: 'txHash', - render: (txHash: string) => router.push(`/transactions/${txHash}`)}>{txHash}, + render: (txHash: string) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '15%' @@ -57,7 +71,7 @@ const ListView = (props: IProps) => { { title: 'BLOCK HASH', dataIndex: 'blockHash', - render: (blockHash: string) => router.push(`/blocks/${blockHash}`)}>{blockHash}, + render: (blockHash: string) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '15%' @@ -66,16 +80,11 @@ const ListView = (props: IProps) => { title: 'FROM', dataIndex: 'from', render: (params) => { - const from = JSON.parse(params) - return ( - - { getChainIcon(from.source) } - {centerMaskString(from.from)} - - ) + const from = JSON.parse(params); + return
}, - cellAlignment: 'center', - headerAlignment: 'center', + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', width: '20%' }, { @@ -88,29 +97,29 @@ const ListView = (props: IProps) => { display="flex" flexDirection="column" > - {reci[0]} +
{ reci.length > 1 && {`+ ${reci.length - 1} more`}} )}, - cellAlignment: 'center', - headerAlignment: 'center', - width: '25%' + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', + width: '20%' }, { title: 'CATEGORY', dataIndex: 'category', render: (category: string) => {category}, - cellAlignment: 'center', - headerAlignment: 'center', - width: '10%' + cellAlignment: 'flex-start', + headerAlignment: 'flex-start', + width: '14%' }, { title: 'AGE', dataIndex: 'ts', - render: (ts: number) => {moment(ts * 1000).fromNow()}, - cellAlignment: 'flex-end', - headerAlignment: 'flex-end', - width: '5%' + render: (ts: number) => {fromNow(ts * 1000)}, + cellAlignment: 'center', + headerAlignment: 'center', + width: '6%' }, ]; diff --git a/components/Transactions/TxDetails.tsx b/components/Transactions/TxDetails.tsx index 85135fa..f3c6f8c 100644 --- a/components/Transactions/TxDetails.tsx +++ b/components/Transactions/TxDetails.tsx @@ -3,6 +3,8 @@ import { Box, Text, Tag } from '../../blocks'; import { Transaction } from '../../types/transaction'; import moment from 'moment'; import { TagVariant } from '../../blocks/tag'; +import { Tick } from '../../blocks/icons' +import BlockHashLink from '../Reusables/BlockHashLink' interface IProps { data: Transaction | null | undefined, @@ -24,10 +26,11 @@ const TXDetails = (props: IProps) => { alignItems="flex-start" borderRadius="radius-sm" backgroundColor="surface-primary" - gap="spacing-xxxl" + gap="spacing-xxxxl" padding="spacing-md" > { gap="spacing-sm" > {props.data?.txnHash} - - {props.data?.blockHash} + } label={status} variant={status}> + {props.data?.category} { props.data?.ts && moment(props.data.ts * 1000).fromNow() } diff --git a/components/Transactions/TxTravels.tsx b/components/Transactions/TxTravels.tsx index 06a7e51..a61d286 100644 --- a/components/Transactions/TxTravels.tsx +++ b/components/Transactions/TxTravels.tsx @@ -1,6 +1,8 @@ import React, { useState } from 'react'; import { Box, Text, Ethereum, Polygon, BNB } from '../../blocks'; import { Transaction } from '../../types/transaction'; +import { convertCaipToObject } from '../../utils/helpers' +import { EtheriumMonotone, BnbMonotone, PolygonMonotone, PushMonotone } from '../../blocks/icons' const MAX_DISPLAY = 5; @@ -20,18 +22,27 @@ const TxTravels = (props: IProps) => { const displayedRecipients = showAll ? recipients : recipients.slice(0, MAX_DISPLAY); const showMoreButton = recipients.length > MAX_DISPLAY; - function getChainIcon(source) { - switch(source) { - case 'ETH_MAINNET': - return - case 'POLYGON_MAINNET': - return - case 'BSC_MAINNET': - return - default: - return + function getChainIcon(address) { + try { + const { result } = convertCaipToObject(address); + if (!result.chainId) { + return + } + + switch(Number(result.chainId)) { + case 1: + return + case 137: + return + case 56: + return + default: + return + } + } catch (err) { + return } - } + } return ( <> @@ -41,10 +52,11 @@ const TxTravels = (props: IProps) => { alignItems="flex-start" borderRadius="radius-sm" backgroundColor="surface-primary" - gap="spacing-xxxl" + gap="spacing-xxxxl" padding="spacing-md" > { gap="spacing-sm" > - { getChainIcon(props.data?.source) } + { getChainIcon(props.data?.from) } {props.data?.from} @@ -69,7 +81,10 @@ const TxTravels = (props: IProps) => { gap="spacing-xxs" > {displayedRecipients.map((recipient, index) => ( - {recipient.address} + + { getChainIcon(recipient.address) } + {recipient.address} + ))} {showMoreButton && ( diff --git a/layout/index.tsx b/layout/index.tsx index f38cb18..546da4e 100644 --- a/layout/index.tsx +++ b/layout/index.tsx @@ -10,7 +10,7 @@ export default function Layout({ children }) { display="flex" flexDirection="column" gap={{ initial: "spacing-xxxl", ml: "spacing-lg" }} - + minHeight="100vh" > diff --git a/package.json b/package.json index 49b618f..bb62f8c 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "styled-components": "^5.3.6", "sonner": "^1.5.0", "@table-library/react-table-library": "^4.1.7", - "rc-pagination": "^4.2.0" + "rc-pagination": "^4.2.0", + "react-slider": "^2.0.6" }, "devDependencies": { "@types/lodash": "^4.14.188", diff --git a/public/static/X-dark.svg b/public/static/X-dark.svg new file mode 100644 index 0000000..5aa134b --- /dev/null +++ b/public/static/X-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/X.svg b/public/static/X.svg new file mode 100644 index 0000000..e6e7c15 --- /dev/null +++ b/public/static/X.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/static/discord-dark.svg b/public/static/discord-dark.svg index 1fafcfe..7b3081f 100644 --- a/public/static/discord-dark.svg +++ b/public/static/discord-dark.svg @@ -1,3 +1,12 @@ - - + + + + + + + + + + + diff --git a/public/static/github-dark.svg b/public/static/github-dark.svg index 16ffea0..f2c1eb4 100644 --- a/public/static/github-dark.svg +++ b/public/static/github-dark.svg @@ -1,3 +1,10 @@ - - + + + + + + + + + diff --git a/public/static/github.svg b/public/static/github.svg index 4b8788a..f2c1eb4 100644 --- a/public/static/github.svg +++ b/public/static/github.svg @@ -1,3 +1,10 @@ - - + + + + + + + + + diff --git a/public/static/telegram-dark.svg b/public/static/telegram-dark.svg new file mode 100644 index 0000000..78e1d57 --- /dev/null +++ b/public/static/telegram-dark.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/static/telegram.svg b/public/static/telegram.svg new file mode 100644 index 0000000..6ac7ab0 --- /dev/null +++ b/public/static/telegram.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/sections/Blocks/blockHash.tsx b/sections/Blocks/blockHash.tsx index 31e527c..98a8074 100644 --- a/sections/Blocks/blockHash.tsx +++ b/sections/Blocks/blockHash.tsx @@ -11,7 +11,7 @@ const Details = () => { const router = useRouter(); const { blockHash } = router.query; - const [showConsensusInfo, setConsensusInfo] = useState(true); + const [showConsensusInfo, setConsensusInfo] = useState(false); const { data, isLoading } = useLiveBlockByHash({ blockHash }); const showLoading = !blockHash || isLoading diff --git a/sections/Transactions/txHash.tsx b/sections/Transactions/txHash.tsx index c914627..1768144 100644 --- a/sections/Transactions/txHash.tsx +++ b/sections/Transactions/txHash.tsx @@ -11,7 +11,7 @@ const Details = () => { const router = useRouter(); const { txHash } = router.query; - const [showConsensusInfo, setConsensusInfo] = useState(true); + const [showConsensusInfo, setConsensusInfo] = useState(false); const { data, isLoading } = useLiveTxByHash({ txHash }); const showLoading = !txHash || isLoading diff --git a/styles/globals.css b/styles/globals.css index 31972ae..217b5b3 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -1,20 +1,3 @@ -@font-face { - font-family: 'Strawford'; - font-display: swap; - src: url('../public/static/fonts/FKGroteskNeue-Regular.woff2') format('woff2'), - url('../public/static/fonts/FKGroteskNeue-Regular.woff') format('woff'); - font-weight: 400; - font-style: regular; -} - -@font-face { - font-family: 'Strawford'; - font-display: swap; - src: url('../public/static/fonts/FKGroteskNeue-Regular.woff2') format('woff2'); - font-weight: 500 600 700; - font-style: medium; -} - html, body { padding: 0; diff --git a/theme/globalStyles.ts b/theme/globalStyles.ts index a552298..9043163 100644 --- a/theme/globalStyles.ts +++ b/theme/globalStyles.ts @@ -5,16 +5,16 @@ import { blocksColors, getBlocksCSSVariables } from '../blocks'; export const GlobalStyles = createGlobalStyle` @font-face { font-family: 'FK Grotesk Neu'; - src: url('./static/fonts/FKGroteskNeue-Regular.woff2') format('woff2'), - url('./static/fonts/FKGroteskNeue-Regular.woff') format('woff'); + src: url('../static/fonts/FKGroteskNeue-Regular.woff2') format('woff2'), + url('../static/fonts/FKGroteskNeue-Regular.woff') format('woff'); font-weight: 100 400; font-style: normal; } @font-face { font-family: 'FK Grotesk Neu'; - src: url('./static/fonts/FKGroteskNeue-Medium.woff2') format('woff2'), - url('./static/fonts/FKGroteskNeu-Medium.woff') format('woff'); + src: url('../static/fonts/FKGroteskNeue-Medium.woff2') format('woff2'), + url('../static/fonts/FKGroteskNeu-Medium.woff') format('woff'); font-weight: 500 600; font-style: normal; @@ -22,8 +22,8 @@ export const GlobalStyles = createGlobalStyle` @font-face { font-family: 'FK Grotesk Neu'; - src: url('./static/fonts/FKGroteskNeue-Bold.woff2') format('woff2'), - url('./static/fonts/FKGroteskNeue-Bold.woff') format('woff'); + src: url('../static/fonts/FKGroteskNeue-Bold.woff2') format('woff2'), + url('../static/fonts/FKGroteskNeue-Bold.woff') format('woff'); font-weight: 700 800; font-style: normal; font-display: swap; diff --git a/utils/helpers.ts b/utils/helpers.ts index 931e0a3..8f856bf 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -3,6 +3,7 @@ import { format, formatDistanceToNow } from 'date-fns'; import { replace } from 'lodash'; import numeral from 'numeral'; import { Signer } from '../types/block' +import { ethers } from 'ethers' export function fDate(date) { return format(new Date(date), 'dd MMMM yyyy'); @@ -77,7 +78,7 @@ export function getValidatorNode(signers: Signer[] | undefined) { } export function centerMaskString(str, len = 15) { - if (str.length > 15) { + if (str && str.length > 15) { const start = str.substring(0, 7); const end = str.substring(str.length - 7); return start + '...' + end; @@ -88,7 +89,7 @@ export function centerMaskString(str, len = 15) { export function rightMaskString(str, len = 13) { // Check if the string length is more than 15 to mask the remaining characters - if (str.length > len) { + if (str && str.length > len) { const visiblePart = str.substring(0, len); const maskedPart = '...'; return visiblePart + maskedPart; @@ -102,15 +103,101 @@ export function capitalizeStr(string) { return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); } -export const convertCaipToAddress = function (addressinCAIP: string): string { +export const convertCaipToAddress = function (addressinCAIP: string): string | null { const addressComponent = addressinCAIP.split(':') if ( + addressComponent.length === 3 && + addressComponent[0] === 'eip155' + ) { + return addressComponent[2] + } + // Wallet can be in the new caip10 format used in w2w: eip155:walletAddress + else if ( addressComponent.length === 2 && - addressComponent[0] === 'eip155' && - addressComponent[1] + addressComponent[0] === 'eip155' ) { return addressComponent[1] } else { return addressinCAIP } } + +export function isValidAddress(address: string): boolean { + return ethers.isAddress(address.toLowerCase()) +} + +export const caip10ToWallet = (wallet: string) => { + if (wallet.split(':').length === 2) { + wallet = wallet.replace('eip155:', '') + return isValidAddress(wallet) ? wallet : null + } else { + return null + } +} + +export const convertCaipToObject = (addressinCAIP: string): { + result: { chainId: string | null; chain: string; address: string } +} => { + if (!addressinCAIP) { + throw new Error('CAIP address cannot be null or empty'); + } + + const addressComponent = addressinCAIP.split(':'); + + if (addressComponent.length === 3 && isValidAddress(addressComponent[2])) { + return { + result: { + chain: addressComponent[0], + chainId: addressComponent[1], + address: addressComponent[2], + }, + }; + } else if (addressComponent.length === 2 && isValidAddress(addressComponent[1])) { + return { + result: { + chain: addressComponent[0], + chainId: null, + address: addressComponent[1], + }, + }; + } else { + throw new Error('Invalid CAIP Format'); + } +}; + +export const fromNow = (timestamp: number): string => { + const now = Date.now(); + const diffInSeconds = Math.floor((now - timestamp) / 1000); + + if (diffInSeconds < 60) { + return `${diffInSeconds}s ago`; + } + + const diffInMinutes = Math.floor(diffInSeconds / 60); + if (diffInMinutes < 60) { + return `${diffInMinutes}m ago`; + } + + const diffInHours = Math.floor(diffInMinutes / 60); + if (diffInHours < 24) { + return `${diffInHours}h ago`; + } + + const diffInDays = Math.floor(diffInHours / 24); + if (diffInDays < 7) { + return `${diffInDays}d ago`; + } + + const diffInWeeks = Math.floor(diffInDays / 7); + if (diffInWeeks < 4) { + return `${diffInWeeks}w ago`; + } + + const diffInMonths = Math.floor(diffInDays / 30); + if (diffInMonths < 12) { + return `${diffInMonths}m ago`; + } + + const diffInYears = Math.floor(diffInMonths / 12); + return `${diffInYears}y ago`; +} diff --git a/yarn.lock b/yarn.lock index b914693..093747e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2936,6 +2936,13 @@ react-router@6.26.0: dependencies: "@remix-run/router" "1.19.0" +react-slider@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/react-slider/-/react-slider-2.0.6.tgz#8c7ff0301211f7c3ff32aa0163b33bdab6258559" + integrity sha512-gJxG1HwmuMTJ+oWIRCmVWvgwotNCbByTwRkFZC6U4MBsHqJBmxwbYRJUmxy4Tke1ef8r9jfXjgkmY/uHOCEvbA== + dependencies: + prop-types "^15.8.1" + react-spring@^9.0.0-rc.3: version "9.5.5" resolved "https://registry.npmjs.org/react-spring/-/react-spring-9.5.5.tgz" From 534e84c285eca2e2671140ee736bc2ad71a5103c Mon Sep 17 00:00:00 2001 From: rozaso Date: Sun, 15 Sep 2024 23:02:54 -0700 Subject: [PATCH 16/42] Health Check API. --- components/Blocks/ConsensusInfo.tsx | 2 +- components/Blocks/Details.tsx | 12 +++- components/Footer/index.tsx | 27 +++++-- components/Home/LiveTransactions.tsx | 1 + components/Home/SearchBar.tsx | 56 +++++++++++---- components/Navbar/index.tsx | 20 ++---- components/Reusables/AddressComponent.tsx | 13 ++-- components/Transactions/ConsensusInfo.tsx | 4 +- components/Transactions/ListView.tsx | 24 +------ components/Transactions/TxDetails.tsx | 13 +++- components/Transactions/TxTravels.tsx | 66 +++-------------- hooks/useGetTransactionsByUser.ts | 40 +++++++++++ hooks/useSearchByAddress.ts | 22 ++---- package.json | 4 +- .../[txHash].tsx => users/[address].tsx} | 4 +- sections/{Search => User}/index.tsx | 72 +++++++++++++------ utils/api.ts | 10 +++ yarn.lock | 10 +++ 18 files changed, 235 insertions(+), 165 deletions(-) create mode 100644 hooks/useGetTransactionsByUser.ts rename pages/{search/[txHash].tsx => users/[address].tsx} (81%) rename sections/{Search => User}/index.tsx (52%) diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index 3526a1a..30ea82a 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -116,7 +116,7 @@ const ConsensusInfo = (props: IProps) => { )} - + { + + let dateTime = '' + if (props.data?.ts) { + const timestamp = props.data?.ts + const formattedTime = moment.unix(timestamp).utc().fromNow(); // "40 minutes ago" + const detailedTime = moment.unix(timestamp).utc().format('ddd, MMM DD YYYY HH:mm:ss [GMT]'); // "Sun, Jul 21 2024 18:33:47 GMT" + dateTime = `${formattedTime}, ${detailedTime}` + } + + return ( <> { > { props.data?.blockHash } { getValidatorNode(props.data?.signers) } - { props.data?.ts && moment(props.data.ts * 1000).fromNow() } + { dateTime } diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index 7065540..4b28806 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -1,5 +1,5 @@ // React, NextJS imports -import React from 'react'; +import React, { useEffect, useState } from 'react'; import Image from 'next/image'; // External Library imports @@ -12,11 +12,28 @@ import TelegramIconDark from "../../public/static/telegram-dark.svg"; import TelegramIconLight from "../../public/static/telegram.svg"; import DiscordIconDark from "../../public/static/discord-dark.svg"; import DiscordIconLight from "../../public/static/discord.svg"; - -import { Box, Text, TickCircleFilled, Link } from '../../blocks'; +import { getHeathCheck } from '../../utils/api'; +import { Box, Text, TickCircleFilled, CrossFilled, Link } from '../../blocks'; export default function Footer() { const { isDarkMode } = Theme(); + const [data, setData] = useState(true); + const [isLoading, setIsLoading] = React.useState(false); + + useEffect(() => { + (async () => { + setIsLoading(true); + try { + const res = await getHeathCheck(); + setData(res.status === "OK"); + } catch (e) { + console.log('Error occured', e); + } + setIsLoading(false); + })(); + }, []); + + return ( - - All systems operational + { data ? : } + { data ? 'All systems operational' : 'Not all system are operational' } ); diff --git a/components/Home/LiveTransactions.tsx b/components/Home/LiveTransactions.tsx index f24be35..c733ef9 100644 --- a/components/Home/LiveTransactions.tsx +++ b/components/Home/LiveTransactions.tsx @@ -5,6 +5,7 @@ import { Tick } from '../../blocks/icons' import { useRouter } from 'next/router' import Link from 'next/link' import { useLiveTransactions } from '../../hooks/useLiveTransactions'; +import moment from 'moment'; import { fromNow, capitalizeStr } from '../../utils/helpers' import { TagVariant } from '../../blocks/tag'; import { useTheme } from 'styled-components'; diff --git a/components/Home/SearchBar.tsx b/components/Home/SearchBar.tsx index 7d22a4f..45030ab 100644 --- a/components/Home/SearchBar.tsx +++ b/components/Home/SearchBar.tsx @@ -1,7 +1,8 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { Box, TextInput, Search } from '../../blocks'; +import React, { useCallback, useState, useEffect } from 'react'; +import { TextInput, Search } from '../../blocks'; import { ethers } from 'ethers'; import { useDebounce } from 'react-use'; +import { useSearchByAddress } from '../../hooks/useSearchByAddress'; import { useRouter } from 'next/router' export default function SearchBar() { @@ -11,26 +12,53 @@ export default function SearchBar() { const [debouncedQuery, setDebouncedQuery] = useState(''); const getFormattedQuery = useCallback((qry: string) => { - if (!qry) return ''; + if (!qry) return ''; // Return empty string if the query is empty const isAddress = ethers.isAddress(qry); - const value = isAddress ? `eip155:${qry}` : qry; - console.log(" Search Value: ", value) - - return value; + return isAddress ? `eip155:${qry}` : qry; }, []); - useDebounce(() => setDebouncedQuery(getFormattedQuery(query)), 500, [query]); - + // Debounce the query + useDebounce(() => { + setDebouncedQuery(query); + }, 500, [query]) + + // Conditionally call the useSearchByAddress hook if debouncedQuery is not empty + const { data, isLoading } = useSearchByAddress({ + address: debouncedQuery || '', + page: 1, + }) + + // Log the data or loading state + useEffect(() => { + if (debouncedQuery) { + if (!isLoading && data) { + + const blocks = data?.blocks + const transactions = blocks.map((block) => block.transactions) + + const isSearchedTransaction = transactions.find((tx) => tx.txnHash === debouncedQuery) + if (isSearchedTransaction) { + router.push(`/transactions/${debouncedQuery}`) + return + } + + const isSearchedBlock = blocks && blocks.length > 0 && blocks.map((block) => block.blockHash === debouncedQuery) + if (isSearchedBlock) { + router.push(`/blocks/${debouncedQuery}`) + return + } + + } + } + }, [debouncedQuery, data, isLoading]); + return ( router.push(`/search/${debouncedQuery}`)}/>} + icon={} value={query} onChange={(e) => setQuery(e.target.value)} /> - ) + ); } - - - diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index 0dd45e9..b667a8f 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -13,7 +13,7 @@ import { useTheme as Theme } from '../../contexts/ThemeContext'; import { useData } from '../../contexts/DataContext'; import { ROUTES, CREDENTIALKEYS } from '../../utils/constants'; import { ThemeType } from '../../types/theme'; -import { Box, Text, Lozenge, PushLogo } from '../../blocks'; +import { Box, Text, Lozenge, MoonFilled, PushLogo } from '../../blocks'; import SearchBar from '../Home/SearchBar' import ChainsDropDown from '../Reusables/ChainsDropDown' import Link from 'next/link' @@ -40,7 +40,8 @@ export default function Navbar() { display="flex" flexDirection="column" gap={{initial: "spacing-lg", ml: "spacing-sm" }} - margin="spacing-lg spacing-xxxxxl spacing-none spacing-xxxxxl" + margin={{initial: "spacing-lg spacing-xxxxxl spacing-none spacing-xxxxxl", ml: "spacing-sm" }} + > ALPHA - - - - + { asPath !== '/dashboard' && ( - Analytics + Analytics )} - + { asPath !== '/home' && ( { +const Address = ({ address, wrap = false, masking = true }) => { const [isHovered, setIsHovered] = useState(false); const handleMouseEnter = () => setIsHovered(true); const handleMouseLeave = () => setIsHovered(false); + function getChainIcon(chainId) { try { if (!chainId) { @@ -32,6 +33,8 @@ const Address = ({ address }) => { } const { result } = convertCaipToObject(address) + + const maskedAddress = masking ? centerMaskString(result.address) : result.address; return ( { - - {centerMaskString(result.address)} + + {maskedAddress} ) : ( - - {centerMaskString(result.address)} + + {maskedAddress} )} diff --git a/components/Transactions/ConsensusInfo.tsx b/components/Transactions/ConsensusInfo.tsx index 6d2997d..66419f5 100644 --- a/components/Transactions/ConsensusInfo.tsx +++ b/components/Transactions/ConsensusInfo.tsx @@ -74,11 +74,11 @@ const ConsensusInfo = (props: IProps) => { {node} }label={'Accepted'} variant='success'> - ))} @@ -127,7 +127,7 @@ const ConsensusInfo = (props: IProps) => { )} - + { let data = props.data; - function getChainIcon(address) { - try { - const { result } = convertCaipToObject(address); - if (!result.chainId) { - return - } - - switch(Number(result.chainId)) { - case 1: - return - case 137: - return - case 56: - return - default: - return - } - } catch (err) { - return - } - } - const columns = [ { title: 'STATUS', @@ -111,7 +89,7 @@ const ListView = (props: IProps) => { render: (category: string) => {category}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '14%' + width: '13%' }, { title: 'AGE', diff --git a/components/Transactions/TxDetails.tsx b/components/Transactions/TxDetails.tsx index f3c6f8c..98848e7 100644 --- a/components/Transactions/TxDetails.tsx +++ b/components/Transactions/TxDetails.tsx @@ -5,6 +5,7 @@ import moment from 'moment'; import { TagVariant } from '../../blocks/tag'; import { Tick } from '../../blocks/icons' import BlockHashLink from '../Reusables/BlockHashLink' +import { capitalizeStr } from '../../utils/helpers' interface IProps { data: Transaction | null | undefined, @@ -18,6 +19,14 @@ const TXDetails = (props: IProps) => { status = props.data.status.toLowerCase() as TagVariant } + let dateTime = '' + if (props.data?.ts) { + const timestamp = props.data?.ts + const formattedTime = moment.unix(timestamp).utc().fromNow(); // "40 minutes ago" + const detailedTime = moment.unix(timestamp).utc().format('ddd, MMM DD YYYY HH:mm:ss [GMT]'); // "Sun, Jul 21 2024 18:33:47 GMT" + dateTime = `${formattedTime}, ${detailedTime}` + } + return ( <> { gap="spacing-sm" > {props.data?.txnHash} - } label={status} variant={status}> + } label={capitalizeStr(status)} variant={status}> {props.data?.category} - { props.data?.ts && moment(props.data.ts * 1000).fromNow() } + {dateTime} diff --git a/components/Transactions/TxTravels.tsx b/components/Transactions/TxTravels.tsx index a61d286..586aafa 100644 --- a/components/Transactions/TxTravels.tsx +++ b/components/Transactions/TxTravels.tsx @@ -1,8 +1,7 @@ import React, { useState } from 'react'; -import { Box, Text, Ethereum, Polygon, BNB } from '../../blocks'; +import { Add, Box, Text } from '../../blocks'; import { Transaction } from '../../types/transaction'; -import { convertCaipToObject } from '../../utils/helpers' -import { EtheriumMonotone, BnbMonotone, PolygonMonotone, PushMonotone } from '../../blocks/icons' +import Address from '../Reusables/AddressComponent' const MAX_DISPLAY = 5; @@ -22,28 +21,6 @@ const TxTravels = (props: IProps) => { const displayedRecipients = showAll ? recipients : recipients.slice(0, MAX_DISPLAY); const showMoreButton = recipients.length > MAX_DISPLAY; - function getChainIcon(address) { - try { - const { result } = convertCaipToObject(address); - if (!result.chainId) { - return - } - - switch(Number(result.chainId)) { - case 1: - return - case 137: - return - case 56: - return - default: - return - } - } catch (err) { - return - } - } - return ( <> { flexDirection="column" gap="spacing-sm" > - - { getChainIcon(props.data?.from) } - {props.data?.from} - - +
{displayedRecipients.map((recipient, index) => ( - - { getChainIcon(recipient.address) } - {recipient.address} - +
))} {showMoreButton && ( @@ -96,6 +66,7 @@ const TxTravels = (props: IProps) => { cursor="pointer" onClick={toggleShowAll} > + {showAll ? 'Show Less' : 'Show More'} @@ -120,17 +91,7 @@ const TxTravels = (props: IProps) => { gap="spacing-xxxs" > From - - - { getChainIcon(props.data?.source) } - - {props.data?.from} - - +
{ gap="spacing-xs" > {displayedRecipients.map((recipient, index) => ( - - { getChainIcon(props.data?.source) } - - {recipient.address} - - +
))} {showMoreButton && ( @@ -167,6 +118,7 @@ const TxTravels = (props: IProps) => { cursor="pointer" onClick={toggleShowAll} > + {showAll ? 'Show Less' : 'Show More'} diff --git a/hooks/useGetTransactionsByUser.ts b/hooks/useGetTransactionsByUser.ts new file mode 100644 index 0000000..4577bc3 --- /dev/null +++ b/hooks/useGetTransactionsByUser.ts @@ -0,0 +1,40 @@ +import { useQuery } from 'react-query'; +import { makeJsonRpcRequest } from '../utils/json-rpc'; +import { PerPageItems } from '../utils/constants'; + +const RPC_ID = 9 + +export interface searchProps { + address: string | string[] | undefined; + page: number +} + +export const useGetTransactionsByUser = (params: searchProps) => { + const getTransactionsByUser = () => makeJsonRpcRequest(RPC_ID, 'getTransactionsByUser', { + "searchTerm": params.address, + "startTime": Math.floor(Date.now() / 1000), + "direction": "DESC", + "pageSize": PerPageItems, + "page": params.page, + "showDetails": false + }); + + return useQuery({ + queryKey: ['getTransactionsByUserDetails', params], + queryFn: getTransactionsByUser, + select: (data) => { + const transactions = data.blocks.flatMap(block => + block.transactions.map(tx => ({ + ...tx, + recipients: tx.recipients.recipients.map(recipient => recipient.address) + })) + ); + // Sorting transactions by timestamp in descending order + return { + transactions: transactions.sort((a, b) => b.ts - a.ts), + totalPages: data.totalPages, + lastTs: data.lastTs + } + } + }); +} \ No newline at end of file diff --git a/hooks/useSearchByAddress.ts b/hooks/useSearchByAddress.ts index 327e6e6..a7659f1 100644 --- a/hooks/useSearchByAddress.ts +++ b/hooks/useSearchByAddress.ts @@ -11,32 +11,18 @@ export interface searchProps { page: number } -export const useSearchByAddress = (params: searchProps) => { +export const useSearchByAddress = (params: searchProps) => { const searchByAddress = () => makeJsonRpcRequest(RPC_ID, 'searchByAddress', { "searchTerm": params.address, "startTime": Math.floor(Date.now() / 1000), "direction": "DESC", "pageSize": PerPageItems, "page": params.page, - "showDetails": true + "showDetails": false }); return useQuery({ - queryKey: ['searchByAddressDetailswee', params], - queryFn: searchByAddress, - select: (data) => { - const transactions = data.blocks.flatMap(block => - block.transactions.map(tx => ({ - ...tx, - recipients: tx.recipients.recipients.map(recipient => recipient.address) - })) - ); - // Sorting transactions by timestamp in descending order - return { - transactions: transactions.sort((a, b) => b.ts - a.ts), - totalPages: data.totalPages, - lastTs: data.lastTs - } - } + queryKey: [`searchByAddressDetails-${params.address}`, params], + queryFn: searchByAddress }); } \ No newline at end of file diff --git a/package.json b/package.json index bb62f8c..f5b7055 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,9 @@ "sonner": "^1.5.0", "@table-library/react-table-library": "^4.1.7", "rc-pagination": "^4.2.0", - "react-slider": "^2.0.6" + "react-slider": "^2.0.6", + "blockies": "0.0.2", + "blockies-react-svg": "^0.0.13" }, "devDependencies": { "@types/lodash": "^4.14.188", diff --git a/pages/search/[txHash].tsx b/pages/users/[address].tsx similarity index 81% rename from pages/search/[txHash].tsx rename to pages/users/[address].tsx index 074a0f2..4bd6d38 100644 --- a/pages/search/[txHash].tsx +++ b/pages/users/[address].tsx @@ -4,7 +4,7 @@ import Head from 'next/head'; import dynamic from 'next/dynamic'; import { Spinner, Box } from '../../blocks'; -const SearchView = dynamic(() => import('../../sections/Search'), { +const UserTransactionsView = dynamic(() => import('../../sections/User'), { loading: () => }); @@ -17,7 +17,7 @@ export default function Transactions() { Push Transactions - + ); diff --git a/sections/Search/index.tsx b/sections/User/index.tsx similarity index 52% rename from sections/Search/index.tsx rename to sections/User/index.tsx index e19af29..4858677 100644 --- a/sections/Search/index.tsx +++ b/sections/User/index.tsx @@ -1,21 +1,24 @@ import React, { useState } from 'react'; import { Box, Text, Copy, Tooltip, Spinner, Pagination } from '../../blocks'; import ListView from '../../components/Transactions/ListView'; -import { centerMaskString } from '../../utils/helpers'; -import { useSearchByAddress } from '../../hooks/useSearchByAddress' +import { centerMaskString, convertCaipToObject } from '../../utils/helpers'; +import { useGetTransactionsByUser } from '../../hooks/useGetTransactionsByUser' import { useRouter } from 'next/router'; import { PerPageItems } from '../../utils/constants' +import BlockiesSvg from 'blockies-react-svg'; const Search = () => { const router = useRouter(); - const { txHash } = router.query; + let { address } = router.query; const [tooltipText, setToolTipText] = useState('Copy Address'); const [page, setPage] = useState(1); + address = Array.isArray(address) ? address[0] : address + const copyAddress = () => { - if (txHash) { - navigator.clipboard.writeText(Array.isArray(txHash) ? txHash[0] : txHash); + if (address) { + navigator.clipboard.writeText(address); setToolTipText('Copied'); } setTimeout(() => { @@ -23,9 +26,10 @@ const Search = () => { }, 1000); }; - const { data, isLoading } = useSearchByAddress({ address: txHash, page: page }) + const { data, isLoading } = useGetTransactionsByUser({ address, page: page }) + + const showLoading = !address || isLoading - const showLoading = !txHash || isLoading if (showLoading) { return ( @@ -35,6 +39,14 @@ const Search = () => { ) } + console.log("::::: Address: ", address) + + address = address && convertCaipToObject(address).result.address + + if (!address) { + return null + } + return ( { - Address {txHash} - - - + Address + + + + - + {address} + + + + + + - - Transactions for {centerMaskString(txHash)} + Transactions for {centerMaskString(address)} { try { @@ -128,3 +129,12 @@ export const getUsers = async () => { console.log('error', e); } }; + +export const getHeathCheck = async () => { + try { + const res = await axios.get(`${API_ANODE_BASE}/health`); + return res.data; + } catch (e) { + console.log('Error occured in health-check', e); + } +}; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 093747e..a9be4aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1356,6 +1356,16 @@ big-integer@^1.6.16: resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== +blockies-react-svg@^0.0.13: + version "0.0.13" + resolved "https://registry.yarnpkg.com/blockies-react-svg/-/blockies-react-svg-0.0.13.tgz#785500bebdbe5e4aea8e094b3241f73669470b00" + integrity sha512-w3Upvq5xnO2m0KEf4QhExLDpPMlJZes0Oi5e1EaILTpU+TtDGipoqxJuGGMhFHl2Qg7cuw4P1pAgEMy+Y3nZrg== + +blockies@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/blockies/-/blockies-0.0.2.tgz#22ad58da4f6b382bc79bf4386c5820c70047e4ed" + integrity sha512-D9kUW071jJxjp+8w99Bcf7TxJAnhoNfglLHAVHn2dmacbZcULCq4Zi2w8/NZpPQ8lsiX1E+LiEhZITJhxNmo6g== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" From 1053167a501773c27ae5940ebc1468683fd3731a Mon Sep 17 00:00:00 2001 From: rozaso Date: Mon, 16 Sep 2024 08:44:29 -0700 Subject: [PATCH 17/42] Style updates. --- components/Blocks/BlockTxDetails.tsx | 2 ++ components/Blocks/ConsensusInfo.tsx | 4 +++- components/Blocks/Details.tsx | 4 +++- components/Footer/index.tsx | 4 ++-- components/Home/OverView.tsx | 2 +- components/Navbar/index.tsx | 3 +-- components/Transactions/ConsensusInfo.tsx | 4 +++- components/Transactions/TxDetails.tsx | 9 ++++++--- components/Transactions/TxTravels.tsx | 2 ++ layout/index.tsx | 2 +- 10 files changed, 24 insertions(+), 12 deletions(-) diff --git a/components/Blocks/BlockTxDetails.tsx b/components/Blocks/BlockTxDetails.tsx index de66179..fa33072 100644 --- a/components/Blocks/BlockTxDetails.tsx +++ b/components/Blocks/BlockTxDetails.tsx @@ -15,6 +15,7 @@ const BlockTXDetails = (props: IProps) => { flexDirection="row" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" gap="spacing-xxxxxl" padding="spacing-md" @@ -44,6 +45,7 @@ const BlockTXDetails = (props: IProps) => { flexDirection="column" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" gap="spacing-md" padding="spacing-xs" diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index 30ea82a..7acc818 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -48,6 +48,7 @@ const ConsensusInfo = (props: IProps) => { flexDirection="column" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" padding="spacing-md" gap="spacing-md" @@ -134,6 +135,7 @@ const ConsensusInfo = (props: IProps) => { flexDirection="column" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" gap="spacing-md" padding="spacing-xs" @@ -202,7 +204,7 @@ const ConsensusInfo = (props: IProps) => { )} - + { flexDirection="row" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" gap="spacing-xxxxxl" padding="spacing-md" @@ -58,6 +59,7 @@ const Details = (props: IProps) => { flexDirection="column" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" gap="spacing-md" padding="spacing-xs" @@ -87,7 +89,7 @@ const Details = (props: IProps) => { gap="spacing-xxxs" > Timestamp - { props.data?.ts && moment(props.data.ts * 1000).fromNow() } + { dateTime } diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index 4b28806..c3a3c85 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -39,7 +39,7 @@ export default function Footer() { display="flex" flexDirection="row" justifyContent="space-between" - margin="spacing-none spacing-xxxxxl spacing-lg spacing-xxxxxl" + margin={{ initial: "spacing-none spacing-xxxxxl spacing-md spacing-xxxxxl", ml: "spacing-sm" }} > diff --git a/components/Home/OverView.tsx b/components/Home/OverView.tsx index b2ef990..4a7d289 100644 --- a/components/Home/OverView.tsx +++ b/components/Home/OverView.tsx @@ -14,7 +14,7 @@ const OverView: FC = () => { alignItems="center" gap="spacing-xxxs" padding="spacing-sm" - border="border-lg solid stroke-secondary" + border="border-xmd solid stroke-secondary" backgroundColor="surface-primary" borderRadius='radius-md' width="100%" diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index b667a8f..119df04 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -40,8 +40,7 @@ export default function Navbar() { display="flex" flexDirection="column" gap={{initial: "spacing-lg", ml: "spacing-sm" }} - margin={{initial: "spacing-lg spacing-xxxxxl spacing-none spacing-xxxxxl", ml: "spacing-sm" }} - + margin={{initial: "spacing-sm spacing-xxxxxl spacing-sm spacing-xxxxxl", ml: "spacing-sm" }} > { flexDirection="column" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" padding="spacing-md" gap="spacing-md" @@ -145,6 +146,7 @@ const ConsensusInfo = (props: IProps) => { flexDirection="column" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" gap="spacing-md" padding="spacing-xs" @@ -232,7 +234,7 @@ const ConsensusInfo = (props: IProps) => { )} - + { flexDirection="row" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" gap="spacing-xxxxl" padding="spacing-md" @@ -69,6 +70,7 @@ const TXDetails = (props: IProps) => { flexDirection="column" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" gap="spacing-md" padding="spacing-xs" @@ -88,7 +90,8 @@ const TXDetails = (props: IProps) => { gap="spacing-xxxs" > Status - + } label={capitalizeStr(status)} variant={status}> + { gap="spacing-xxxs" > Block Hash - {props.data?.blockHash} + { gap="spacing-xxxs" > Timestamp - { props.data?.ts && moment(props.data.ts * 1000).fromNow() } + { dateTime } diff --git a/components/Transactions/TxTravels.tsx b/components/Transactions/TxTravels.tsx index 586aafa..d362616 100644 --- a/components/Transactions/TxTravels.tsx +++ b/components/Transactions/TxTravels.tsx @@ -28,6 +28,7 @@ const TxTravels = (props: IProps) => { flexDirection="row" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" gap="spacing-xxxxl" padding="spacing-md" @@ -81,6 +82,7 @@ const TxTravels = (props: IProps) => { flexDirection="column" alignItems="flex-start" borderRadius="radius-sm" + border="border-xs solid stroke-secondary" backgroundColor="surface-primary" gap="spacing-md" padding="spacing-xs" diff --git a/layout/index.tsx b/layout/index.tsx index 546da4e..e6d9df6 100644 --- a/layout/index.tsx +++ b/layout/index.tsx @@ -9,7 +9,7 @@ export default function Layout({ children }) { From ee49d042696b237bcc28a6a2834ca1ab34b56006 Mon Sep 17 00:00:00 2001 From: rozaso Date: Wed, 18 Sep 2024 09:21:06 -0700 Subject: [PATCH 18/42] Style fixes and backend dev server. --- .../theme/variables/variables.borderSize.ts | 1 + components/Blocks/ConsensusInfo.tsx | 46 +++++----- components/Blocks/ListView.tsx | 45 ++++++---- components/Home/LiveBlocks.tsx | 40 +++++---- components/Home/LiveTransactions.tsx | 38 ++++----- components/Home/OverView.tsx | 53 ++++++++++-- components/Navbar/index.tsx | 1 - components/Reusables/BlockHashLink.tsx | 23 ++++- components/Transactions/ConsensusInfo.tsx | 44 +++++----- components/Transactions/ListView.tsx | 29 ++++--- components/Transactions/TxDetails.tsx | 43 +++++++++- components/Transactions/TxTravels.tsx | 85 +++++++++++++++++-- sections/Home/index.tsx | 2 +- sections/Transactions/index.tsx | 38 +++++---- utils/helpers.ts | 11 ++- utils/json-rpc.ts | 4 +- 16 files changed, 355 insertions(+), 148 deletions(-) diff --git a/blocks/theme/variables/variables.borderSize.ts b/blocks/theme/variables/variables.borderSize.ts index 574f3a4..c2690bf 100644 --- a/blocks/theme/variables/variables.borderSize.ts +++ b/blocks/theme/variables/variables.borderSize.ts @@ -1,4 +1,5 @@ export const borderSizeVariables = { + 'border-none': '0px', 'border-xs': '0.5px', 'border-sm': '1px', 'border-xmd': '1.5px', diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index 7acc818..42724dd 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -116,16 +116,18 @@ const ConsensusInfo = (props: IProps) => { )} - - - - - + + + + + + + @@ -203,18 +205,20 @@ const ConsensusInfo = (props: IProps) => { )} - - - - - - + + + + + + + + diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx index 08dc101..a70be4a 100644 --- a/components/Blocks/ListView.tsx +++ b/components/Blocks/ListView.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { Box, Text, Table, Pagination } from '../../blocks'; import { useLiveBlocks } from '../../hooks/useBlocks'; import { PerPageItems } from '../../utils/constants' @@ -10,7 +10,9 @@ import BlockHashLink from '../Reusables/BlockHashLink' const Blocks = () => { const router = useRouter() const [page, setPage] = useState(1); - const { data, error, isLoading, isError } = useLiveBlocks({ page, perPageItems: 15 }); + const [cachedTotalPages, setCachedTotalPages] = useState(0); // State for caching totalPages + + const { data, isLoading } = useLiveBlocks({ page, perPageItems: 15 }); const theme = useTheme(); const isDarkMode = theme.scheme === 'dark'; @@ -22,7 +24,7 @@ const Blocks = () => { render: (text) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '25%' + width: '310px' }, { title: 'VALIDATOR', @@ -30,7 +32,7 @@ const Blocks = () => { render: (text) => {centerMaskString(text)}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '25%' + width: '310px' }, { title: 'TXN', @@ -38,7 +40,7 @@ const Blocks = () => { render: (text) => {text}, cellAlignment: 'center', headerAlignment: 'center', - width: '19%' + width: '200px' }, { title: 'SIZE (IN BYTES)', @@ -46,7 +48,7 @@ const Blocks = () => { render: (text) => {text}, cellAlignment: 'center', headerAlignment: 'center', - width: '25%' + width: '200px' }, { title: 'AGE', @@ -54,7 +56,7 @@ const Blocks = () => { render: (text) => {fromNow(text * 1000)}, cellAlignment: 'center', headerAlignment: 'center', - width: '6%' + width: '80px' }, ]; @@ -67,26 +69,39 @@ const Blocks = () => { ts: block.ts })) || []; - + // Cache totalPages when new data is fetched + useEffect(() => { + if (data?.totalPages) { + setCachedTotalPages(data.totalPages); + } + }, [data?.totalPages]); + + // Use the cached totalPages when data is loading + const totalPages = data?.totalPages ?? cachedTotalPages; + return ( -

f7i52VPyGpZT0$=Bx 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 literal 0 HcmV?d00001 diff --git a/public/static/fonts/FKGroteskNeue-Regular.woff2 b/public/static/fonts/FKGroteskNeue-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..db41f0671d23563d1193de85e6d241208b84b9cc GIT binary patch literal 54380 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 H_^tu~n>q`9 literal 0 HcmV?d00001 diff --git a/public/static/fonts/Strawford-Black.eot b/public/static/fonts_old/Strawford-Black.eot similarity index 100% rename from public/static/fonts/Strawford-Black.eot rename to public/static/fonts_old/Strawford-Black.eot diff --git a/public/static/fonts/Strawford-Black.svg b/public/static/fonts_old/Strawford-Black.svg similarity index 100% rename from public/static/fonts/Strawford-Black.svg rename to public/static/fonts_old/Strawford-Black.svg diff --git a/public/static/fonts/Strawford-Black.ttf b/public/static/fonts_old/Strawford-Black.ttf similarity index 100% rename from public/static/fonts/Strawford-Black.ttf rename to public/static/fonts_old/Strawford-Black.ttf diff --git a/public/static/fonts/Strawford-Black.woff b/public/static/fonts_old/Strawford-Black.woff similarity index 100% rename from public/static/fonts/Strawford-Black.woff rename to public/static/fonts_old/Strawford-Black.woff diff --git a/public/static/fonts/Strawford-Black.woff2 b/public/static/fonts_old/Strawford-Black.woff2 similarity index 100% rename from public/static/fonts/Strawford-Black.woff2 rename to public/static/fonts_old/Strawford-Black.woff2 diff --git a/public/static/fonts/Strawford-Bold.eot b/public/static/fonts_old/Strawford-Bold.eot similarity index 100% rename from public/static/fonts/Strawford-Bold.eot rename to public/static/fonts_old/Strawford-Bold.eot diff --git a/public/static/fonts/Strawford-Bold.svg b/public/static/fonts_old/Strawford-Bold.svg similarity index 100% rename from public/static/fonts/Strawford-Bold.svg rename to public/static/fonts_old/Strawford-Bold.svg diff --git a/public/static/fonts/Strawford-Bold.ttf b/public/static/fonts_old/Strawford-Bold.ttf similarity index 100% rename from public/static/fonts/Strawford-Bold.ttf rename to public/static/fonts_old/Strawford-Bold.ttf diff --git a/public/static/fonts/Strawford-Bold.woff b/public/static/fonts_old/Strawford-Bold.woff similarity index 100% rename from public/static/fonts/Strawford-Bold.woff rename to public/static/fonts_old/Strawford-Bold.woff diff --git a/public/static/fonts/Strawford-Bold.woff2 b/public/static/fonts_old/Strawford-Bold.woff2 similarity index 100% rename from public/static/fonts/Strawford-Bold.woff2 rename to public/static/fonts_old/Strawford-Bold.woff2 diff --git a/public/static/fonts/Strawford-ExtraLight.otf b/public/static/fonts_old/Strawford-ExtraLight.otf similarity index 100% rename from public/static/fonts/Strawford-ExtraLight.otf rename to public/static/fonts_old/Strawford-ExtraLight.otf diff --git a/public/static/fonts/Strawford-ExtraLight.ttf b/public/static/fonts_old/Strawford-ExtraLight.ttf similarity index 100% rename from public/static/fonts/Strawford-ExtraLight.ttf rename to public/static/fonts_old/Strawford-ExtraLight.ttf diff --git a/public/static/fonts/Strawford-ExtraLight.woff2 b/public/static/fonts_old/Strawford-ExtraLight.woff2 similarity index 100% rename from public/static/fonts/Strawford-ExtraLight.woff2 rename to public/static/fonts_old/Strawford-ExtraLight.woff2 diff --git a/public/static/fonts/Strawford-Light.otf b/public/static/fonts_old/Strawford-Light.otf similarity index 100% rename from public/static/fonts/Strawford-Light.otf rename to public/static/fonts_old/Strawford-Light.otf diff --git a/public/static/fonts/Strawford-Light.ttf b/public/static/fonts_old/Strawford-Light.ttf similarity index 100% rename from public/static/fonts/Strawford-Light.ttf rename to public/static/fonts_old/Strawford-Light.ttf diff --git a/public/static/fonts/Strawford-Light.woff2 b/public/static/fonts_old/Strawford-Light.woff2 similarity index 100% rename from public/static/fonts/Strawford-Light.woff2 rename to public/static/fonts_old/Strawford-Light.woff2 diff --git a/public/static/fonts/Strawford-Medium.otf b/public/static/fonts_old/Strawford-Medium.otf similarity index 100% rename from public/static/fonts/Strawford-Medium.otf rename to public/static/fonts_old/Strawford-Medium.otf diff --git a/public/static/fonts/Strawford-Medium.ttf b/public/static/fonts_old/Strawford-Medium.ttf similarity index 100% rename from public/static/fonts/Strawford-Medium.ttf rename to public/static/fonts_old/Strawford-Medium.ttf diff --git a/public/static/fonts/Strawford-Medium.woff2 b/public/static/fonts_old/Strawford-Medium.woff2 similarity index 100% rename from public/static/fonts/Strawford-Medium.woff2 rename to public/static/fonts_old/Strawford-Medium.woff2 diff --git a/public/static/fonts/Strawford-Regular.eot b/public/static/fonts_old/Strawford-Regular.eot similarity index 100% rename from public/static/fonts/Strawford-Regular.eot rename to public/static/fonts_old/Strawford-Regular.eot diff --git a/public/static/fonts/Strawford-Regular.otf b/public/static/fonts_old/Strawford-Regular.otf similarity index 100% rename from public/static/fonts/Strawford-Regular.otf rename to public/static/fonts_old/Strawford-Regular.otf diff --git a/public/static/fonts/Strawford-Regular.ttf b/public/static/fonts_old/Strawford-Regular.ttf similarity index 100% rename from public/static/fonts/Strawford-Regular.ttf rename to public/static/fonts_old/Strawford-Regular.ttf diff --git a/public/static/fonts/Strawford-Regular.woff b/public/static/fonts_old/Strawford-Regular.woff similarity index 100% rename from public/static/fonts/Strawford-Regular.woff rename to public/static/fonts_old/Strawford-Regular.woff diff --git a/public/static/fonts/Strawford-Regular.woff2 b/public/static/fonts_old/Strawford-Regular.woff2 similarity index 100% rename from public/static/fonts/Strawford-Regular.woff2 rename to public/static/fonts_old/Strawford-Regular.woff2 diff --git a/sections/Home/index.tsx b/sections/Home/index.tsx index fe0a8ff..236b464 100644 --- a/sections/Home/index.tsx +++ b/sections/Home/index.tsx @@ -13,6 +13,15 @@ const Home = () => { flexDirection="column" gap="spacing-xxxl" > + + Push Blockchain Explorer + + + { diff --git a/styles/globals.css b/styles/globals.css index 9d8f8ab..31972ae 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -1,10 +1,8 @@ @font-face { font-family: 'Strawford'; font-display: swap; - src: url('../public/static/fonts/Strawford-Regular.woff2') format('woff2'), - url('../public/static/fonts/Strawford-Regular.woff') format('woff'), - url('../public/static/fonts/Strawford-Regular.eot') format('eot'), - url('../public/static/fonts/Strawford-Regular.ttf') format('ttf'); + src: url('../public/static/fonts/FKGroteskNeue-Regular.woff2') format('woff2'), + url('../public/static/fonts/FKGroteskNeue-Regular.woff') format('woff'); font-weight: 400; font-style: regular; } @@ -12,9 +10,7 @@ @font-face { font-family: 'Strawford'; font-display: swap; - src: url('../public/static/fonts/Strawford-Medium.woff2') format('woff2'), - url('../public/static/fonts/Strawford-Medium.otf') format('otf'), - url('../public/static/fonts/Strawford-Medium.ttf') format('ttf'); + src: url('../public/static/fonts/FKGroteskNeue-Regular.woff2') format('woff2'); font-weight: 500 600 700; font-style: medium; } diff --git a/theme/globalStyles.ts b/theme/globalStyles.ts index cef2cd1..a552298 100644 --- a/theme/globalStyles.ts +++ b/theme/globalStyles.ts @@ -4,23 +4,30 @@ import { blocksColors, getBlocksCSSVariables } from '../blocks'; export const GlobalStyles = createGlobalStyle` @font-face { - font-family: 'Strawford'; - src: url('./static/fonts/Strawford-Regular.woff2') format('woff2'), - url('./static/fonts/Strawford-Regular.woff') format('woff'), - url('./static/fonts/Strawford-Regular.eot') format('eot'), - url('./static/fonts/Strawford-Regular.ttf') format('ttf'); - font-weight: 400; - font-style: regular; - }; + font-family: 'FK Grotesk Neu'; + src: url('./static/fonts/FKGroteskNeue-Regular.woff2') format('woff2'), + url('./static/fonts/FKGroteskNeue-Regular.woff') format('woff'); + font-weight: 100 400; + font-style: normal; +} - @font-face { - font-family: 'Strawford'; - src: url('./static/fonts/Strawford-Medium.woff2') format('woff2'), - url('./static/fonts/Strawford-Medium.otf') format('otf'), - url('./static/fonts/Strawford-Medium.ttf') format('ttf'); - font-weight:500 600 700; - font-style: medium; - }; +@font-face { + font-family: 'FK Grotesk Neu'; + src: url('./static/fonts/FKGroteskNeue-Medium.woff2') format('woff2'), + url('./static/fonts/FKGroteskNeu-Medium.woff') format('woff'); + + font-weight: 500 600; + font-style: normal; +} + +@font-face { + font-family: 'FK Grotesk Neu'; + src: url('./static/fonts/FKGroteskNeue-Bold.woff2') format('woff2'), + url('./static/fonts/FKGroteskNeue-Bold.woff') format('woff'); + font-weight: 700 800; + font-style: normal; + font-display: swap; +} body { background: ${({ theme }) => theme.background.default}; @@ -29,6 +36,9 @@ export const GlobalStyles = createGlobalStyle` transition: all 0.2s linear; } :root { + /* Font Family */ + --font-family: 'FK Grotesk Neu'; + ${(props) => getBlocksCSSVariables(props.theme.blocksTheme)} } `; diff --git a/utils/constants.js b/utils/constants.js index 7421fec..e868e20 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -9,7 +9,7 @@ import FuseIcon from '../public/static/fuse.svg'; import CyberIcon from '../public/static/cyber.svg'; export const POLL_INTERVAL = 30 * 1000 // 30 seconds -export const PerPageItems = 10 +export const PerPageItems = 15 export const ROUTES = { HOME: '/home', diff --git a/utils/helpers.ts b/utils/helpers.ts index 9bcbb65..931e0a3 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -78,7 +78,7 @@ export function getValidatorNode(signers: Signer[] | undefined) { export function centerMaskString(str, len = 15) { if (str.length > 15) { - const start = str.substring(0, 10); + const start = str.substring(0, 7); const end = str.substring(str.length - 7); return start + '...' + end; } @@ -86,7 +86,7 @@ export function centerMaskString(str, len = 15) { return str; } -export function rightMaskString(str, len = 15) { +export function rightMaskString(str, len = 13) { // Check if the string length is more than 15 to mask the remaining characters if (str.length > len) { const visiblePart = str.substring(0, len); @@ -100,4 +100,17 @@ export function rightMaskString(str, len = 15) { export function capitalizeStr(string) { if (!string) return ''; return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); -} \ No newline at end of file +} + +export const convertCaipToAddress = function (addressinCAIP: string): string { + const addressComponent = addressinCAIP.split(':') + if ( + addressComponent.length === 2 && + addressComponent[0] === 'eip155' && + addressComponent[1] + ) { + return addressComponent[1] + } else { + return addressinCAIP + } +} From ab96298ae519c63a0e4cabaa0ca219984f7a7a76 Mon Sep 17 00:00:00 2001 From: rozaso Date: Thu, 12 Sep 2024 23:07:16 -0700 Subject: [PATCH 15/42] DQA fixes. --- blocks/fileUpload/FileUpload.tsx | 48 +++ blocks/fileUpload/index.ts | 1 + blocks/icons/components/ArbitrumMonotone.tsx | 46 +++ blocks/icons/components/BellSimpleSlash.tsx | 47 +++ blocks/icons/components/BnbMonotone.tsx | 48 +++ blocks/icons/components/CircleFilled.tsx | 27 ++ blocks/icons/components/CloudUpload.tsx | 47 +++ blocks/icons/components/CrownSimple.tsx | 40 +++ blocks/icons/components/Cube.tsx | 39 +++ blocks/icons/components/EtheriumMonotone.tsx | 46 +++ blocks/icons/components/OptimismMonotone.tsx | 48 +++ blocks/icons/components/Pencil.tsx | 40 +++ blocks/icons/components/PolygonMonotone.tsx | 44 +++ blocks/icons/components/PushMonotone.tsx | 48 +++ blocks/icons/components/index.ts | 179 ++++++++++ blocks/icons/index.ts | 28 +- blocks/index.ts | 7 +- blocks/select/Select.tsx | 340 +++++++++++++++++++ blocks/select/index.tsx | 1 + blocks/slider/Slider.tsx | 60 ++++ blocks/slider/Slider.types.ts | 10 + blocks/slider/index.ts | 2 + blocks/tag/Tag.tsx | 30 +- blocks/theme/colors/colors.semantics.ts | 16 +- blocks/theme/semantics/semantics.listItem.ts | 37 ++ blocks/theme/semantics/semantics.slider.ts | 10 + blocks/theme/variables/variables.spacing.ts | 3 +- components/Blocks/BlockTxDetails.tsx | 3 +- components/Blocks/ConsensusInfo.tsx | 12 +- components/Blocks/Details.tsx | 3 +- components/Blocks/ListView.tsx | 22 +- components/Footer/index.tsx | 35 +- components/Home/LiveBlocks.tsx | 10 +- components/Home/LiveTransactions.tsx | 41 +-- components/Navbar/index.tsx | 2 +- components/Reusables/AddressComponent.tsx | 63 ++++ components/Reusables/BlockHashLink.tsx | 38 +++ components/Reusables/TxHashLink.tsx | 43 +++ components/Transactions/ConsensusInfo.tsx | 28 +- components/Transactions/ListView.tsx | 77 +++-- components/Transactions/TxDetails.tsx | 9 +- components/Transactions/TxTravels.tsx | 43 ++- layout/index.tsx | 2 +- package.json | 3 +- public/static/X-dark.svg | 3 + public/static/X.svg | 3 + public/static/discord-dark.svg | 13 +- public/static/github-dark.svg | 11 +- public/static/github.svg | 11 +- public/static/telegram-dark.svg | 10 + public/static/telegram.svg | 10 + sections/Blocks/blockHash.tsx | 2 +- sections/Transactions/txHash.tsx | 2 +- styles/globals.css | 17 - theme/globalStyles.ts | 12 +- utils/helpers.ts | 97 +++++- yarn.lock | 7 + 57 files changed, 1739 insertions(+), 185 deletions(-) create mode 100644 blocks/fileUpload/FileUpload.tsx create mode 100644 blocks/fileUpload/index.ts create mode 100644 blocks/icons/components/ArbitrumMonotone.tsx create mode 100644 blocks/icons/components/BellSimpleSlash.tsx create mode 100644 blocks/icons/components/BnbMonotone.tsx create mode 100644 blocks/icons/components/CircleFilled.tsx create mode 100644 blocks/icons/components/CloudUpload.tsx create mode 100644 blocks/icons/components/CrownSimple.tsx create mode 100644 blocks/icons/components/Cube.tsx create mode 100644 blocks/icons/components/EtheriumMonotone.tsx create mode 100644 blocks/icons/components/OptimismMonotone.tsx create mode 100644 blocks/icons/components/Pencil.tsx create mode 100644 blocks/icons/components/PolygonMonotone.tsx create mode 100644 blocks/icons/components/PushMonotone.tsx create mode 100644 blocks/icons/components/index.ts create mode 100644 blocks/select/Select.tsx create mode 100644 blocks/select/index.tsx create mode 100644 blocks/slider/Slider.tsx create mode 100644 blocks/slider/Slider.types.ts create mode 100644 blocks/slider/index.ts create mode 100644 blocks/theme/semantics/semantics.listItem.ts create mode 100644 blocks/theme/semantics/semantics.slider.ts create mode 100644 components/Reusables/AddressComponent.tsx create mode 100644 components/Reusables/BlockHashLink.tsx create mode 100644 components/Reusables/TxHashLink.tsx create mode 100644 public/static/X-dark.svg create mode 100644 public/static/X.svg create mode 100644 public/static/telegram-dark.svg create mode 100644 public/static/telegram.svg diff --git a/blocks/fileUpload/FileUpload.tsx b/blocks/fileUpload/FileUpload.tsx new file mode 100644 index 0000000..725c199 --- /dev/null +++ b/blocks/fileUpload/FileUpload.tsx @@ -0,0 +1,48 @@ +import { DragEventHandler, FC, forwardRef, ReactNode } from 'react'; +import styled, { FlattenSimpleInterpolation, css } from 'styled-components'; + +export type FileUploadProps = { + children?: ReactNode; + css?: FlattenSimpleInterpolation; + disabled?: boolean; + onChange?: (e: React.ChangeEvent) => void; + onDrop?: DragEventHandler; + id: string; +}; + +const Container = styled.div<{ css?: FlattenSimpleInterpolation }>` + align-items: center; + display: flex; + flex-direction: column; + flex: 1 0 0; + gap: var(--spacing-xxs, 8px); + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''}; +`; + + +export const FileUpload = forwardRef( + ({ disabled, children, onChange, onDrop, id }, ref) => { + + const handleDragOver: DragEventHandler = (e) => { + e.preventDefault(); + }; + + + return ( + + {children} + + + ); + } +); diff --git a/blocks/fileUpload/index.ts b/blocks/fileUpload/index.ts new file mode 100644 index 0000000..fca98b5 --- /dev/null +++ b/blocks/fileUpload/index.ts @@ -0,0 +1 @@ +export * from './FileUpload'; diff --git a/blocks/icons/components/ArbitrumMonotone.tsx b/blocks/icons/components/ArbitrumMonotone.tsx new file mode 100644 index 0000000..df10c1e --- /dev/null +++ b/blocks/icons/components/ArbitrumMonotone.tsx @@ -0,0 +1,46 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const ArbitrumMonotone: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default ArbitrumMonotone; diff --git a/blocks/icons/components/BellSimpleSlash.tsx b/blocks/icons/components/BellSimpleSlash.tsx new file mode 100644 index 0000000..968f1c2 --- /dev/null +++ b/blocks/icons/components/BellSimpleSlash.tsx @@ -0,0 +1,47 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const BellSimpleSlash: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + } + {...restProps} + /> + ); +}; + +export default BellSimpleSlash; diff --git a/blocks/icons/components/BnbMonotone.tsx b/blocks/icons/components/BnbMonotone.tsx new file mode 100644 index 0000000..654b4aa --- /dev/null +++ b/blocks/icons/components/BnbMonotone.tsx @@ -0,0 +1,48 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const BnbMonotone: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default BnbMonotone; diff --git a/blocks/icons/components/CircleFilled.tsx b/blocks/icons/components/CircleFilled.tsx new file mode 100644 index 0000000..b7d81bd --- /dev/null +++ b/blocks/icons/components/CircleFilled.tsx @@ -0,0 +1,27 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CircleFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default CircleFilled; diff --git a/blocks/icons/components/CloudUpload.tsx b/blocks/icons/components/CloudUpload.tsx new file mode 100644 index 0000000..a696521 --- /dev/null +++ b/blocks/icons/components/CloudUpload.tsx @@ -0,0 +1,47 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CloudUpload: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + } + {...restProps} + /> + ); +}; + +export default CloudUpload; diff --git a/blocks/icons/components/CrownSimple.tsx b/blocks/icons/components/CrownSimple.tsx new file mode 100644 index 0000000..3f18897 --- /dev/null +++ b/blocks/icons/components/CrownSimple.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CrownSimple: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default CrownSimple; diff --git a/blocks/icons/components/Cube.tsx b/blocks/icons/components/Cube.tsx new file mode 100644 index 0000000..a625f2e --- /dev/null +++ b/blocks/icons/components/Cube.tsx @@ -0,0 +1,39 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Cube: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + } + {...restProps} + /> + ); +}; + +export default Cube; diff --git a/blocks/icons/components/EtheriumMonotone.tsx b/blocks/icons/components/EtheriumMonotone.tsx new file mode 100644 index 0000000..1600bde --- /dev/null +++ b/blocks/icons/components/EtheriumMonotone.tsx @@ -0,0 +1,46 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const EtheriumMonotone: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + } + {...restProps} + /> + ); +}; + +export default EtheriumMonotone; diff --git a/blocks/icons/components/OptimismMonotone.tsx b/blocks/icons/components/OptimismMonotone.tsx new file mode 100644 index 0000000..f9471d5 --- /dev/null +++ b/blocks/icons/components/OptimismMonotone.tsx @@ -0,0 +1,48 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const OptimismMonotone: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default OptimismMonotone; diff --git a/blocks/icons/components/Pencil.tsx b/blocks/icons/components/Pencil.tsx new file mode 100644 index 0000000..a7b5235 --- /dev/null +++ b/blocks/icons/components/Pencil.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Pencil: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default Pencil; diff --git a/blocks/icons/components/PolygonMonotone.tsx b/blocks/icons/components/PolygonMonotone.tsx new file mode 100644 index 0000000..54dbfe5 --- /dev/null +++ b/blocks/icons/components/PolygonMonotone.tsx @@ -0,0 +1,44 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const PolygonMonotone: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default PolygonMonotone; diff --git a/blocks/icons/components/PushMonotone.tsx b/blocks/icons/components/PushMonotone.tsx new file mode 100644 index 0000000..6034537 --- /dev/null +++ b/blocks/icons/components/PushMonotone.tsx @@ -0,0 +1,48 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const PushMonotone: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default PushMonotone; diff --git a/blocks/icons/components/index.ts b/blocks/icons/components/index.ts new file mode 100644 index 0000000..ecb14ee --- /dev/null +++ b/blocks/icons/components/index.ts @@ -0,0 +1,179 @@ +export * from './IconWrapper'; +export * from './Icons.types'; + +export { default as Add } from './components/Add'; + +export { default as AddEmoji } from './components/AddEmoji'; + +export { default as ArbitrumMonotone } from './components/ArbitrumMonotone'; + +export { default as ArrowUpRight } from './components/ArrowUpRight'; + +export { default as Asterisk } from './components/Asterisk'; + +export { default as Back } from './components/Back'; + +export { default as BellRingFilled } from './components/BellRingFilled'; +export { default as BellSimple } from './components/BellSimple'; +export { default as BellSimpleSlash } from './components/BellSimpleSlash'; + +export { default as BnbMonotone } from './components/BnbMonotone'; + +export { default as CalendarBlank } from './components/CalendarBlank'; + +export { default as CaretDown } from './components/CaretDown'; + +export { default as CaretLeft } from './components/CaretLeft'; + +export { default as CaretRight } from './components/CaretRight'; + +export { default as CaretUp } from './components/CaretUp'; + +export { default as CameraFilled } from './components/CameraFilled'; + +export { default as Channel } from './components/Channel'; +export { default as ChannelFilled } from './components/ChannelFilled'; + +export { default as ChannelHome } from './components/ChannelHome'; +export { default as ChannelHomeFilled } from './components/ChannelHomeFilled'; + +export { default as Chat } from './components/Chat'; +export { default as ChatFilled } from './components/ChatFilled'; + +export { default as CircleFilled } from './components/CircleFilled'; +export { default as CloudUpload } from './components/CloudUpload'; + +export { default as Copy } from './components/Copy'; + +export { default as Cross } from './components/Cross'; +export { default as CrossFilled } from './components/CrossFilled'; + +export { default as CrownSimple } from './components/CrownSimple'; + +export { default as Cube } from './components/Cube'; + +export { default as Dash } from './components/Dash'; + +export { default as Dashboard } from './components/Dashboard'; + +export { default as EditProfile } from './components/EditProfile'; + +export { default as EtheriumMonotone } from './components/EtheriumMonotone'; + +export { default as Ellipse } from './components/Ellipse'; + +export { default as Envelope } from './components/Envelope'; + +export { default as ErrorFilled } from './components/ErrorFilled'; + +export { default as ExternalLink } from './components/ExternalLink'; + +export { default as Front } from './components/Front'; + +export { default as Gif } from './components/Gif'; + +export { default as InfoFilled } from './components/InfoFilled'; + +export { default as Governance } from './components/Governance'; +export { default as GovernanceFilled } from './components/GovernanceFilled'; + +export { default as Group } from './components/Group'; +export { default as GroupFilled } from './components/GroupFilled'; + +export { default as InboxBell } from './components/InboxBell'; +export { default as EmptyInbox } from './components/EmptyInbox'; +export { default as InboxBellFilled } from './components/InboxBellFilled'; + +export { default as Info } from './components/Info'; + +export { default as KebabMenuVertical } from './components/KebabMenuVertical'; +export { default as KebabMenuHorizontal } from './components/KebabMenuHorizontal'; + +export { default as LightFilled } from './components/LightFilled'; + +export { default as MaximizeRight } from './components/MaximizeRight'; +export { default as MaximizeLeft } from './components/MaximizeLeft'; + +export { default as MegaPhone } from './components/MegaPhone'; + +export { default as Moon } from './components/Moon'; +export { default as MoonFilled } from './components/MoonFilled'; + +export { default as NFTGated } from './components/NFTGated'; + +export { default as NoRewards } from './components/NoRewards'; + +export { default as NextIconSlider } from './components/NextIconSlider'; + +export { default as NotificationMobile } from './components/NotificationMobile'; + +export { default as OptOut } from './components/OptOut'; + +export { default as OptimismMonotone } from './components/OptimismMonotone'; + +export { default as Pencil } from './components/Pencil'; + +export { default as PlusCircle } from './components/PlusCircle'; +export { default as PlusCircleFilled } from './components/PlusCircleFilled'; + +export { default as PlusSquare } from './components/PlusSquare'; +export { default as PlusSquareFilled } from './components/PlusSquareFilled'; + +export { default as PrevIconSlider } from './components/PrevIconSlider'; + +export { default as Pin } from './components/Pin'; + +export { default as PolygonMonotone } from './components/PolygonMonotone'; + +export { default as PushMonotone } from './components/PushMonotone'; + +export { default as PublicChat } from './components/PublicChat'; +export { default as PrivateChat } from './components/PrivateChat'; + +export { default as QRCode } from './components/QRCode'; + +export { default as ReceiveNotification } from './components/ReceiveNotification'; +export { default as ReceiveNotificationFilled } from './components/ReceiveNotificationFilled'; + +export { default as Refresh } from './components/Refresh'; + +export { default as SealCheck } from './components/SealCheck'; +export { default as SealCheckFilled } from './components/SealCheckFilled'; + +export { default as Search } from './components/Search'; +export { default as SearchFilled } from './components/SearchFilled'; + +export { default as SendFilled } from './components/SendFilled'; + +export { default as SendNotification } from './components/SendNotification'; +export { default as SendNotificationFilled } from './components/SendNotificationFilled'; + +export { default as Smiley } from './components/Smiley'; + +export { default as Star } from './components/Star'; + +export { default as Settings } from './components/Settings'; + +export { default as Swap } from './components/Swap'; + +export { default as Tick } from './components/Tick'; +export { default as TickCircleFilled } from './components/TickCircleFilled'; +export { default as TickDecoratedCircleFilled } from './components/TickDecoratedCircleFilled'; + +export { default as UserFilled } from './components/UserFilled'; + +export { default as UserSwitch } from './components/UserSwitch'; + +export { default as VideoCamera } from './components/VideoCamera'; +export { default as VideoCameraFilled } from './components/VideoCameraFilled'; + +export { default as VideoCameraSlash } from './components/VideoCameraSlash'; +export { default as VideoCameraslashFilled } from './components/VideoCameraSlashFilled'; + +export { default as WarningCircleFilled } from './components/WarningCircleFilled'; + +export { default as Waveform } from './components/Waveform'; +export { default as WaveformFilled } from './components/WaveformFilled'; + +export { default as YieldFarming } from './components/YieldFarming'; +export { default as YieldFarmingFilled } from './components/YieldFarmingFilled'; diff --git a/blocks/icons/index.ts b/blocks/icons/index.ts index 1976cde..ecb14ee 100644 --- a/blocks/icons/index.ts +++ b/blocks/icons/index.ts @@ -5,6 +5,8 @@ export { default as Add } from './components/Add'; export { default as AddEmoji } from './components/AddEmoji'; +export { default as ArbitrumMonotone } from './components/ArbitrumMonotone'; + export { default as ArrowUpRight } from './components/ArrowUpRight'; export { default as Asterisk } from './components/Asterisk'; @@ -13,15 +15,20 @@ export { default as Back } from './components/Back'; export { default as BellRingFilled } from './components/BellRingFilled'; export { default as BellSimple } from './components/BellSimple'; +export { default as BellSimpleSlash } from './components/BellSimpleSlash'; + +export { default as BnbMonotone } from './components/BnbMonotone'; export { default as CalendarBlank } from './components/CalendarBlank'; export { default as CaretDown } from './components/CaretDown'; -export { default as CaretUp } from './components/CaretUp'; -export { default as CaretRight } from './components/CaretRight'; export { default as CaretLeft } from './components/CaretLeft'; +export { default as CaretRight } from './components/CaretRight'; + +export { default as CaretUp } from './components/CaretUp'; + export { default as CameraFilled } from './components/CameraFilled'; export { default as Channel } from './components/Channel'; @@ -33,17 +40,26 @@ export { default as ChannelHomeFilled } from './components/ChannelHomeFilled'; export { default as Chat } from './components/Chat'; export { default as ChatFilled } from './components/ChatFilled'; +export { default as CircleFilled } from './components/CircleFilled'; +export { default as CloudUpload } from './components/CloudUpload'; + export { default as Copy } from './components/Copy'; export { default as Cross } from './components/Cross'; export { default as CrossFilled } from './components/CrossFilled'; +export { default as CrownSimple } from './components/CrownSimple'; + +export { default as Cube } from './components/Cube'; + export { default as Dash } from './components/Dash'; export { default as Dashboard } from './components/Dashboard'; export { default as EditProfile } from './components/EditProfile'; +export { default as EtheriumMonotone } from './components/EtheriumMonotone'; + export { default as Ellipse } from './components/Ellipse'; export { default as Envelope } from './components/Envelope'; @@ -93,6 +109,10 @@ export { default as NotificationMobile } from './components/NotificationMobile'; export { default as OptOut } from './components/OptOut'; +export { default as OptimismMonotone } from './components/OptimismMonotone'; + +export { default as Pencil } from './components/Pencil'; + export { default as PlusCircle } from './components/PlusCircle'; export { default as PlusCircleFilled } from './components/PlusCircleFilled'; @@ -103,6 +123,10 @@ export { default as PrevIconSlider } from './components/PrevIconSlider'; export { default as Pin } from './components/Pin'; +export { default as PolygonMonotone } from './components/PolygonMonotone'; + +export { default as PushMonotone } from './components/PushMonotone'; + export { default as PublicChat } from './components/PublicChat'; export { default as PrivateChat } from './components/PrivateChat'; diff --git a/blocks/index.ts b/blocks/index.ts index 42f611c..e6cf785 100644 --- a/blocks/index.ts +++ b/blocks/index.ts @@ -12,15 +12,18 @@ export { Pagination, type PaginationProps } from './pagination'; export { ProgressBar, type ProgressBarProps } from './progressBar'; export { Separator, type SeparatorProps } from './separator'; export { Skeleton, type SkeletonProps } from './skeleton'; +export { Select, type SelectProps } from './select'; export { Tabs, type TabsProps, type TabItem } from './tabs'; -export { Tag } from './tag'; +export { Table, type TableProps } from './table'; +export { Tag, type TagProps } from './tag'; export { Text, type TextProps } from './text'; export { Tooltip, type TooltipProps } from './tooltip'; export { TextArea, type TextAreaProps } from './textarea'; export { TextInput } from './textInput'; export { ToggleSwitch } from './toggleSwtich'; +export { FileUpload } from './fileUpload'; +export { Slider, type SliderProps } from './slider'; export { Spinner, type SpinnerProps } from './spinner'; -export { Table, type TableProps } from './table'; export * from './Blocks.colors'; export * from './Blocks.types'; diff --git a/blocks/select/Select.tsx b/blocks/select/Select.tsx new file mode 100644 index 0000000..0b13f7a --- /dev/null +++ b/blocks/select/Select.tsx @@ -0,0 +1,340 @@ +import React, { useRef, useState, ReactNode, useEffect, useCallback } from 'react'; +import styled, { FlattenSimpleInterpolation, css } from 'styled-components'; +import { Combobox, ComboboxInput, ComboboxPopover, ComboboxList, ComboboxOption } from '@reach/combobox'; +import '@reach/combobox/styles.css'; + +import { textVariants } from '../text'; +import { Asterisk, CaretDown } from '../icons'; + +export type SelectOption = { + icon?: React.ReactNode; + label: string; + value: string; +}; + +export type SelectProps = { + /* Additional prop from styled components to apply custom css to Button */ + css?: FlattenSimpleInterpolation; + /* Description below the select field*/ + description?: string; + /* Sets button as disabled */ + disabled?: boolean; + /* Sets error state */ + error?: boolean; + /* The error message to be shown */ + errorMessage?: string; + /* Shows the label for the select field */ + label?: string; + /* Function invoked when an option is selected */ + onSelect?: (value: string) => void; + /* Select option list */ + options: SelectOption[]; + /* Placeholder to be shown when nothing is selected */ + placeholder?: string; + /* To make the field compulsory */ + required?: boolean; + /* Selected value */ + value?: string; + /* Sets success state */ + success?: boolean; + /* Action component on the top left of the Select */ + action?: ReactNode; +}; + +const Container = styled.div<{ css?: FlattenSimpleInterpolation }>` + align-items: flex-start; + display: flex; + flex-direction: column; + flex: 1 0 0; + gap: var(--spacing-xxs, 8px); + + /* Custom CSS applied via styled component css prop */ + ${(props) => props.css || ''}; +`; + +const StyledBox = styled.div<{ + error?: boolean; + success?: boolean; + disabled?: boolean; +}>` + ${({ theme, success, error, disabled }) => { + const colors = theme?.blocksTheme?.colors; + const defaultState = error ? 'danger' : success ? 'success' : disabled ? 'disabled' : 'default'; + const focusState = error ? 'danger' : success ? 'success' : 'focus'; + + return css` + display: flex; + align-self: stretch; + cursor: pointer; + align-items: center; + justify-content: space-between; + border-radius: var(--radius-xs, 12px); + border: 1.5px solid + var(--components-inputs-stroke-${defaultState}, ${colors[`components-inputs-stroke-${defaultState}`]}); + background: var( + --components-inputs-background-${defaultState}, + ${colors[`components-inputs-background-${defaultState}`]} + ); + padding: var(--spacing-xs, 12px); + &:hover { + border: 1.5px solid var(--components-inputs-stroke-hover, #c4cbd5); + } + + &:focus-within { + border: 1.5px solid + var(--components-inputs-stroke-${focusState}, ${colors[`components-inputs-stroke-${focusState}`]}); + outline: none; + } + + [data-reach-combobox-input] { + background-color: transparent; + border: none; + color: var(--components-inputs-text-default, ${colors['components-inputs-text-default']}); + + display: flex; + + font-family: var(--font-family); + font-size: ${textVariants['bs-regular'].fontSize}; + font-style: ${textVariants['bs-regular'].fontStyle}; + font-weight: ${textVariants['bs-regular'].fontWeight}; + line-height: ${textVariants['bs-regular'].lineHeight}; + + gap: var(--spacing-none, 0px); + + &:focus { + outline: none; + } + &:hover { + outline: none; + } + &:disabled { + background-color: transparent; + cursor: not-allowed; + color: var(--components-inputs-text-disabled, ${colors['components-inputs-text-disabled']}); + } + + ::placeholder { + color: var(--components-inputs-text-placeholder, ${colors['components-inputs-text-placeholder']}); + } + } + `; + }} +`; + +const StyledPopover = styled(ComboboxPopover)` + margin: var(--spacing-sm) var(--spacing-none) var(--spacing-none) var(--spacing-none); + padding: var(--spacing-xxs, 8px); + border-radius: var(--radius-xs, 12px); + border: var(--border-sm, 1px) solid var(--stroke-secondary, #eaebf2); + background: var(--surface-primary, #fff); + overflow: hidden auto; + max-height: 20rem; +`; + +const StyledCombobox = styled(Combobox)` + width: 100%; + position: relative; +`; + +const StyledInputContainer = styled.div` + display: flex; + width: 100%; + gap: var(--spacing-xxs); +`; + +const StyledInput = styled(ComboboxInput)` + width: 100%; +`; +const StyledList = styled(ComboboxList)` + display: flex; + flex-direction: column; + gap: var(--spacing-xs, 12px); +`; + +const StyledOption = styled(ComboboxOption)` + display: flex; + align-items: center; + padding: var(--spacing-xxxs, 4px); + gap: var(--spacing-xxs, 8px); + color: var(--components-list-item-text-default); + font-family: var(--font-family); + font-size: ${textVariants['bs-regular'].fontSize}; + font-style: ${textVariants['bs-regular'].fontStyle}; + font-weight: ${textVariants['bs-regular'].fontWeight}; + line-height: ${textVariants['bs-regular'].lineHeight}; + &:hover { + border-radius: var(--radius-xxs, 8px); + background: var(--surface-secondary, #f5f6f8); + } + [role='img'] { + width: 24px; + height: 24px; + } +`; +const LabelContainer = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; +`; +const LabelText = styled.span<{ color: string }>` + color: var(--${({ color }) => color}); + font-family: var(--font-family); + font-size: ${textVariants['h6-semibold'].fontSize}; + font-style: ${textVariants['h6-semibold'].fontStyle}; + font-weight: ${textVariants['h6-semibold'].fontWeight}; + line-height: ${textVariants['h6-semibold'].lineHeight}; +`; + +const LabelTextContainer = styled.div` + display: flex; + align-items: flex-start; + gap: var(--spacing-xxxs, 4px); +`; +const Description = styled.span<{ color: string }>` + color: var(--${({ color }) => color}); + font-family: var(--font-family); + font-size: ${textVariants['c-regular'].fontSize}; + font-style: ${textVariants['c-regular'].fontStyle}; + font-weight: ${textVariants['c-regular'].fontWeight}; + line-height: ${textVariants['c-regular'].lineHeight}; +`; +const Select: React.FC = ({ + options, + onSelect, + css, + value, + placeholder = '', + error, + success, + label, + required, + description, + errorMessage, + action, + disabled, +}) => { + const [popoverWidth, setPopoverWidth] = useState(0); + const [viewPopover, setViewPopover] = useState(true); + const [popoverLeft, setPopoverLeft] = useState(0); + const comboboxRef = useRef(null); + const parentRef = useRef(null); + const childRef = useRef(null); + + useEffect(() => { + const handleScroll = () => setViewPopover(false); + + window.addEventListener('scroll', handleScroll); + + return () => { + window.removeEventListener('scroll', handleScroll); + }; + }, []); + + const updatePopoverPosition = useCallback(() => { + if (comboboxRef.current) { + const comboboxRect = comboboxRef.current.getBoundingClientRect(); + setPopoverWidth(comboboxRect.width); + setPopoverLeft(comboboxRect.left); + } + }, []); + + useEffect(() => { + updatePopoverPosition(); + window.addEventListener('resize', updatePopoverPosition); + + return () => { + window.removeEventListener('resize', updatePopoverPosition); + }; + }, [updatePopoverPosition]); + + const selectedOption = options.find((option) => option.value === value); + + const handleParentFocus = () => { + childRef?.current?.focus(); + }; + + return ( + + + + + {label} + {required && } + + + {action} + + + { + onSelect?.(value); + setViewPopover(false); + }} + > + { + handleParentFocus(); + setViewPopover(true); + }} + > + + {selectedOption?.icon} + + + + + + {viewPopover && ( + + + {options.map((option, index) => ( + + {option?.icon} + {option.label} + + ))} + + + )} + + {description && ( + + {description} + + )} + {errorMessage && {errorMessage}} + + ); +}; + +Select.displayName = 'Select'; + +export { Select }; diff --git a/blocks/select/index.tsx b/blocks/select/index.tsx new file mode 100644 index 0000000..0b2fb0d --- /dev/null +++ b/blocks/select/index.tsx @@ -0,0 +1 @@ +export { Select, type SelectProps } from './Select'; diff --git a/blocks/slider/Slider.tsx b/blocks/slider/Slider.tsx new file mode 100644 index 0000000..ff38550 --- /dev/null +++ b/blocks/slider/Slider.tsx @@ -0,0 +1,60 @@ +import styled, { css } from 'styled-components'; + +import ReactSlider from 'react-slider'; +import { SliderProps } from './Slider.types'; +import { isArray } from 'lodash'; + +const StyledSlider = styled(ReactSlider)<{ range?: boolean }>` + .horizontal-slider-track { + height: var(--spacing-xxxs); + background-color: var(--components-slider-background-default); + border-radius: var(--border-sm); + } + + .horizontal-slider-thumb { + width: var(--spacing-sm); + height: var(--spacing-sm); + margin-top: -6px; + background-color: var(--components-slider-icon-default); + border: var(--border-sm) solid var(--components-slider-stroke-default); + border-radius: 50%; + cursor: pointer; + &:active, + &:focus { + outline: none; + } + } + + ${({ range }) => + range + ? css` + .horizontal-slider-track-1 { + background-color: var(--components-slider-background-progress); + } + ` + : css` + .horizontal-slider-track-0 { + background-color: var(--components-slider-background-progress); + } + `} +`; + +const Slider = ({ min, max, onChange, value, step }: SliderProps) => { + return ( + `Thumb value ${state.valueNow}`} + onChange={(value) => onChange(value as T)} + value={value} + range={isArray(value)} + /> + ); +}; + +Slider.displayName = 'Slider'; + +export { Slider }; diff --git a/blocks/slider/Slider.types.ts b/blocks/slider/Slider.types.ts new file mode 100644 index 0000000..91e7c30 --- /dev/null +++ b/blocks/slider/Slider.types.ts @@ -0,0 +1,10 @@ +export type SliderBaseProps = { + min: number; + max: number; + step: number; +}; + +export type SliderProps = SliderBaseProps & { + value?: T; + onChange: (value: T) => void; +}; diff --git a/blocks/slider/index.ts b/blocks/slider/index.ts new file mode 100644 index 0000000..1bf2619 --- /dev/null +++ b/blocks/slider/index.ts @@ -0,0 +1,2 @@ +export * from './Slider'; +export * from './Slider.types'; diff --git a/blocks/tag/Tag.tsx b/blocks/tag/Tag.tsx index cfcbba9..2729df4 100644 --- a/blocks/tag/Tag.tsx +++ b/blocks/tag/Tag.tsx @@ -1,15 +1,16 @@ import { getTextVariantStyles } from '../../blocks/Blocks.utils'; -import { FC } from 'react'; +import { FC, ReactNode } from 'react'; import styled from 'styled-components'; export type TagVariant = 'default' | 'success' | 'danger' | 'warning' | 'info' | 'disabled'; export type TagProps = { + icon?: ReactNode; label: string; variant?: TagVariant; }; -const StyledTagContainer = styled.div<{ variant: TagVariant }>` +const StyledTagContainer = styled.div<{ variant: TagVariant; icon: TagProps['icon'] }>` align-items: center; border-radius: var(--radius-xs); background: var(--components-tag-background-${({ variant }) => variant}); @@ -17,6 +18,22 @@ const StyledTagContainer = styled.div<{ variant: TagVariant }>` gap: var(--spacing-xxxs); padding: var(--spacing-xxxs) var(--spacing-xxs); width: max-content; + + ${({ icon }) => + icon && + ` + [role='img'] { + width: 14px; + height: 14px; + }; + `} +`; + +const IconContainer = styled.span<{ variant: TagVariant }>` + display: flex; + align-items: center; + justify-content: center; + color: var(--components-tag-text-${({ variant }) => variant}); `; const StyledTagText = styled.span<{ variant: TagVariant }>` @@ -31,10 +48,13 @@ const StyledTagIcon = styled.div<{ variant: TagVariant }>` width: 10px; `; -const Tag: FC = ({ label, variant = 'default' }) => { +const Tag: FC = ({ icon, label, variant = 'default' }) => { return ( - - + + {icon ? {icon} : } {label} ); diff --git a/blocks/theme/colors/colors.semantics.ts b/blocks/theme/colors/colors.semantics.ts index 553a6bc..1766ccc 100644 --- a/blocks/theme/colors/colors.semantics.ts +++ b/blocks/theme/colors/colors.semantics.ts @@ -8,9 +8,9 @@ import { tertiaryButtonSemantics, } from '../semantics/semantics.button'; import { checkboxSemantics } from '../semantics/semantics.checkbox'; -import { dropdownSemantics } from '../semantics/semantics.dropdown'; import { iconSemantics } from '../semantics/semantics.icon'; import { inputSemantics } from '../semantics/semantics.input'; +import { listItemSemantics } from '../semantics/semantics.listItem'; import { modalSemantics } from '../semantics/semantics.modal'; import { notificationsSemantics } from '../semantics/semantics.notifications'; import { paginationSemantics } from '../semantics/semantics.pagination'; @@ -25,6 +25,7 @@ import { textSemantics } from '../semantics/semantics.text'; import { textAreaSemantics } from '../semantics/semantics.textarea'; import { toastSemantics } from '../semantics/semantics.toast'; import { tooltipSemantics } from '../semantics/semantics.tooltip'; +import { sliderSemantics } from '../semantics/semantics.slider'; import { spinnerSemantics } from '../semantics/semantics.spinner'; import { tableSemantics } from '../semantics/semantics.table'; @@ -38,9 +39,9 @@ type SemanticKeys = { buttonDanger: 'components-button-danger'; buttonDangerSecondary: 'components-button-danger-secondary'; checkbox: 'components-checkbox'; - dropdown: 'components-dropdown'; icon: 'icon'; input: 'components-inputs'; + listItem: 'components-list-item'; modal: 'components-modal'; notifications: 'components-in-app-notification'; pagination: 'components-pagination'; @@ -49,13 +50,14 @@ type SemanticKeys = { surface: 'surface'; stroke: 'stroke'; skeleton: 'components-skeleton-loader'; - table: 'components-table', + table: 'components-table'; tag: 'components-tag'; text: 'text'; textArea: 'components-textarea'; toast: 'components-toast'; toggle: 'components-toggle-switch'; tooltip: 'components-tooltip'; + slider: 'components-slider'; spinner: 'components-spinner'; }; @@ -68,9 +70,9 @@ export const semanticKeys: SemanticKeys = { buttonDanger: 'components-button-danger', buttonDangerSecondary: 'components-button-danger-secondary', checkbox: 'components-checkbox', - dropdown: 'components-dropdown', icon: 'icon', input: 'components-inputs', + listItem: 'components-list-item', modal: 'components-modal', notifications: 'components-in-app-notification', pagination: 'components-pagination', @@ -86,6 +88,7 @@ export const semanticKeys: SemanticKeys = { toast: 'components-toast', toggle: 'components-toggle-switch', tooltip: 'components-tooltip', + slider: 'components-slider', spinner: 'components-spinner', }; @@ -98,9 +101,9 @@ export const colorSemantics = { [semanticKeys.buttonDanger]: dangerButtonSemantics, [semanticKeys.buttonDangerSecondary]: dangerSecondaryButtonSemantics, [semanticKeys.checkbox]: checkboxSemantics, - [semanticKeys.dropdown]: dropdownSemantics, [semanticKeys.icon]: iconSemantics, [semanticKeys.input]: inputSemantics, + [semanticKeys.listItem]: listItemSemantics, [semanticKeys.modal]: modalSemantics, [semanticKeys.notifications]: notificationsSemantics, [semanticKeys.pagination]: paginationSemantics, @@ -109,12 +112,13 @@ export const colorSemantics = { [semanticKeys.surface]: surfaceSemantics, [semanticKeys.stroke]: strokeSemantics, [semanticKeys.skeleton]: skeletonSemantics, + [semanticKeys.table]: tableSemantics, [semanticKeys.tag]: tagSemantics, [semanticKeys.text]: textSemantics, [semanticKeys.textArea]: textAreaSemantics, [semanticKeys.toast]: toastSemantics, [semanticKeys.toggle]: switchSemantics, [semanticKeys.tooltip]: tooltipSemantics, + [semanticKeys.slider]: sliderSemantics, [semanticKeys.spinner]: spinnerSemantics, - [semanticKeys.table]: tableSemantics }; diff --git a/blocks/theme/semantics/semantics.listItem.ts b/blocks/theme/semantics/semantics.listItem.ts new file mode 100644 index 0000000..9bfb2da --- /dev/null +++ b/blocks/theme/semantics/semantics.listItem.ts @@ -0,0 +1,37 @@ +import { iconSemantics } from './semantics.icon'; +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; +import { textSemantics } from './semantics.text'; + +export const listItemSemantics = { + 'background-default': { + light: surfaceSemantics['primary'].light, + dark: surfaceSemantics['primary'].dark + }, + 'background-hover': { + light: surfaceSemantics['secondary'].light, + dark: surfaceSemantics['secondary'].dark + }, + + 'text-default': { light: textSemantics['primary'].light, dark: textSemantics['primary'].dark }, + 'text-success': { + light: textSemantics['state-success-bold'].light, + dark: textSemantics['state-success-subtle'].dark + }, + 'text-error': { + light: textSemantics['state-danger-bold'].light, + dark: textSemantics['state-danger-bold'].dark + }, + + 'icon-default': { light: iconSemantics['primary'].light, dark: iconSemantics['primary'].dark }, + 'icon-success': { + light: iconSemantics['state-success-bold'].light, + dark: iconSemantics['state-success-bold'].dark + }, + 'icon-error': { + light: iconSemantics['state-danger-bold'].light, + dark: iconSemantics['state-danger-bold'].dark + }, + + 'stroke-default': { light: strokeSemantics['secondary'].light, dark: strokeSemantics['secondary'].dark } +}; diff --git a/blocks/theme/semantics/semantics.slider.ts b/blocks/theme/semantics/semantics.slider.ts new file mode 100644 index 0000000..24b5d2c --- /dev/null +++ b/blocks/theme/semantics/semantics.slider.ts @@ -0,0 +1,10 @@ +import { colorPrimitives } from '../colors/colors.primitives'; +import { strokeSemantics } from './semantics.stroke'; +import { surfaceSemantics } from './semantics.surface'; + +export const sliderSemantics = { + 'stroke-default': { light: strokeSemantics.secondary.light, dark: strokeSemantics.secondary.dark }, + 'icon-default': { light: colorPrimitives['white-100'], dark: colorPrimitives['white-100'] }, + 'background-default': { light: surfaceSemantics.secondary.light, dark: surfaceSemantics.secondary.dark }, + 'background-progress': { light: surfaceSemantics['brand-medium'].light, dark: surfaceSemantics['brand-medium'].dark }, +}; diff --git a/blocks/theme/variables/variables.spacing.ts b/blocks/theme/variables/variables.spacing.ts index c310741..aefd530 100644 --- a/blocks/theme/variables/variables.spacing.ts +++ b/blocks/theme/variables/variables.spacing.ts @@ -9,5 +9,6 @@ export const spacingVariables = { 'spacing-xl': '40px', 'spacing-xxl': '48px', 'spacing-xxxl': '64px', - 'spacing-xxxxl': '168px' + 'spacing-xxxxl': '128px', + 'spacing-xxxxxl': '168px', }; diff --git a/components/Blocks/BlockTxDetails.tsx b/components/Blocks/BlockTxDetails.tsx index e0b55a1..de66179 100644 --- a/components/Blocks/BlockTxDetails.tsx +++ b/components/Blocks/BlockTxDetails.tsx @@ -16,10 +16,11 @@ const BlockTXDetails = (props: IProps) => { alignItems="flex-start" borderRadius="radius-sm" backgroundColor="surface-primary" - gap="spacing-xxxl" + gap="spacing-xxxxxl" padding="spacing-md" > { - + Consensus Info @@ -90,16 +90,16 @@ const ConsensusInfo = (props: IProps) => { - Payload Data + Payload Data + width="52vw" + > {displayedPayload} {showMorePayloadButton && ( { alignItems="flex-start" borderRadius="radius-sm" backgroundColor="surface-primary" - gap="spacing-xxxl" + gap="spacing-xxxxxl" padding="spacing-md" > { const router = useRouter() const [page, setPage] = useState(1); - const { data, error, isLoading, isError } = useLiveBlocks({ page }); + const { data, error, isLoading, isError } = useLiveBlocks({ page, perPageItems: 15 }); const theme = useTheme(); const isDarkMode = theme.scheme === 'dark'; @@ -19,18 +19,18 @@ const Blocks = () => { { title: 'BLOCK HASH', dataIndex: 'blockHash', - render: (text) => router.push(`/blocks/${text}`)}>{text}, + render: (text) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '35%' + width: '25%' }, { title: 'VALIDATOR', dataIndex: 'validator', - render: (text) => {text}, + render: (text) => {centerMaskString(text)}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '35%' + width: '25%' }, { title: 'TXN', @@ -38,7 +38,7 @@ const Blocks = () => { render: (text) => {text}, cellAlignment: 'center', headerAlignment: 'center', - width: '10%' + width: '19%' }, { title: 'SIZE (IN BYTES)', @@ -46,15 +46,15 @@ const Blocks = () => { render: (text) => {text}, cellAlignment: 'center', headerAlignment: 'center', - width: '15%' + width: '25%' }, { title: 'AGE', dataIndex: 'ts', - render: (text) => {moment(text * 1000).fromNow()}, + render: (text) => {fromNow(text * 1000)}, cellAlignment: 'center', headerAlignment: 'center', - width: '5%' + width: '6%' }, ]; diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index aed768c..7065540 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -4,14 +4,16 @@ import Image from 'next/image'; // External Library imports import { useTheme as Theme } from '../../contexts/ThemeContext'; -import TwitterIconDark from "../../public/static/twitter-dark.svg"; -import TwitterIconLight from "../../public/static/twitter.svg"; +import TwitterIconDark from "../../public/static/X-dark.svg"; +import TwitterIconLight from "../../public/static/X.svg"; import GithubIconDark from "../../public/static/github-dark.svg"; import GithubIconLight from "../../public/static/github.svg"; +import TelegramIconDark from "../../public/static/telegram-dark.svg"; +import TelegramIconLight from "../../public/static/telegram.svg"; import DiscordIconDark from "../../public/static/discord-dark.svg"; import DiscordIconLight from "../../public/static/discord.svg"; -import { Box, Text, TickCircleFilled } from '../../blocks'; +import { Box, Text, TickCircleFilled, Link } from '../../blocks'; export default function Footer() { const { isDarkMode } = Theme(); @@ -20,7 +22,7 @@ export default function Footer() { display="flex" flexDirection="row" justifyContent="space-between" - margin="spacing-none spacing-xxxxl spacing-none spacing-xxxxl" + margin="spacing-none spacing-xxxxxl spacing-lg spacing-xxxxxl" > + + + + router.push(`/blocks/${text}`)}>{rightMaskString(text)}, + render: (text) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '30%' @@ -27,7 +27,7 @@ export default function LiveBlocks() { { title: 'VALIDATOR', dataIndex: 'validator', - render: (text) => {centerMaskString(convertCaipToAddress(text))}, + render: (text) => {centerMaskString(text)}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '30%' @@ -43,7 +43,7 @@ export default function LiveBlocks() { { title: 'AGE', dataIndex: 'ts', - render: (text) => {moment(text * 1000).fromNow()}, + render: (text) => {fromNow(text * 1000)}, cellAlignment: 'center', headerAlignment: 'center', width: '20%' diff --git a/components/Home/LiveTransactions.tsx b/components/Home/LiveTransactions.tsx index f164013..f24be35 100644 --- a/components/Home/LiveTransactions.tsx +++ b/components/Home/LiveTransactions.tsx @@ -1,13 +1,15 @@ // React, NextJS imports import React from 'react'; -import { Box, Text, Front, Tag, Spinner, Table, Ethereum, Polygon, BNB } from '../../blocks'; +import { Box, Text, Front, Tag, Table } from '../../blocks'; +import { Tick } from '../../blocks/icons' import { useRouter } from 'next/router' import Link from 'next/link' import { useLiveTransactions } from '../../hooks/useLiveTransactions'; -import moment from 'moment'; -import { convertCaipToAddress, centerMaskString, rightMaskString, capitalizeStr } from '../../utils/helpers' +import { fromNow, capitalizeStr } from '../../utils/helpers' import { TagVariant } from '../../blocks/tag'; import { useTheme } from 'styled-components'; +import Address from '../Reusables/AddressComponent' +import TxHashLink from '../Reusables/TxHashLink' export default function LiveTransactions() { const router = useRouter() @@ -16,24 +18,11 @@ export default function LiveTransactions() { const theme = useTheme(); const isDarkMode = theme.scheme === 'dark'; - function getChainIcon(source) { - switch(source) { - case 'ETH_MAINNET': - return - case 'POLYGON_MAINNET': - return - case 'BSC_MAINNET': - return - default: - return - } - } - const columns = [ { title: 'STATUS', dataIndex: 'status', - render: (status: string) => , + render: (status: string) => } label={capitalizeStr(status)} variant={status.toLowerCase() as TagVariant}>, cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '15%' @@ -41,7 +30,7 @@ export default function LiveTransactions() { { title: 'TX HASH', dataIndex: 'txHash', - render: (txHash: string) => router.push(`/transactions/${txHash}`)}>{rightMaskString(txHash)}, + render: (txHash: string) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '20%' @@ -50,13 +39,8 @@ export default function LiveTransactions() { title: 'FROM', dataIndex: 'from', render: (params) => { - const from = JSON.parse(params) - return ( - - { getChainIcon(from.source) } - {centerMaskString(convertCaipToAddress(from.from))} - - ) + const from = JSON.parse(params); + return

+ +
+ - setPage(page)} - /> + { + totalPages > 1 && setPage(page)} + /> + } ); diff --git a/components/Home/LiveBlocks.tsx b/components/Home/LiveBlocks.tsx index f886aa6..19f9d59 100644 --- a/components/Home/LiveBlocks.tsx +++ b/components/Home/LiveBlocks.tsx @@ -22,7 +22,7 @@ export default function LiveBlocks() { render: (text) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '30%' + width: '125px' }, { title: 'VALIDATOR', @@ -30,7 +30,7 @@ export default function LiveBlocks() { render: (text) => {centerMaskString(text)}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '30%' + width: '135px' }, { title: 'TX', @@ -38,7 +38,7 @@ export default function LiveBlocks() { render: (text) => {text}, cellAlignment: 'center', headerAlignment: 'center', - width: '20%' + width: '65px' }, { title: 'AGE', @@ -46,7 +46,7 @@ export default function LiveBlocks() { render: (text) => {fromNow(text * 1000)}, cellAlignment: 'center', headerAlignment: 'center', - width: '20%' + width: '65px' }, ]; @@ -60,29 +60,27 @@ export default function LiveBlocks() { return ( Live Blocks - -
console.log("Clicked !!!") }} loading={isLoading} columns={columns} dataSource={dataSource} backgroundColor={isDarkMode ? 'surface-secondary' : 'surface-primary'} /> - - - - View All Blocks - - + +
+ + + View All Blocks + + + ) } diff --git a/components/Home/LiveTransactions.tsx b/components/Home/LiveTransactions.tsx index c733ef9..e99c3f7 100644 --- a/components/Home/LiveTransactions.tsx +++ b/components/Home/LiveTransactions.tsx @@ -26,7 +26,7 @@ export default function LiveTransactions() { render: (status: string) => } label={capitalizeStr(status)} variant={status.toLowerCase() as TagVariant}>, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '15%' + width: '100px' }, { title: 'TX HASH', @@ -34,7 +34,7 @@ export default function LiveTransactions() { render: (txHash: string) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '20%' + width: '135px' }, { title: 'FROM', @@ -45,7 +45,7 @@ export default function LiveTransactions() { }, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '25%' + width: '175px' }, { title: 'TO', @@ -54,7 +54,7 @@ export default function LiveTransactions() { const reci = recipients.split(',') return ( @@ -65,15 +65,15 @@ export default function LiveTransactions() { )}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '25%' + width: '175px' }, { title: 'AGE', dataIndex: 'ts', - render: (ts: number) => {fromNow(ts * 1000)}, + render: (ts: number) => {fromNow(ts * 1000)}, cellAlignment: 'center', headerAlignment: 'center', - width: '15%' + width: '75px' }, ]; @@ -94,19 +94,19 @@ export default function LiveTransactions() { gap="spacing-sm" > Live Transactions -
- - +
+ + View All Transactions - - - + + + ) } diff --git a/components/Home/OverView.tsx b/components/Home/OverView.tsx index 4a7d289..e1284ec 100644 --- a/components/Home/OverView.tsx +++ b/components/Home/OverView.tsx @@ -10,7 +10,7 @@ const OverView: FC = () => { = () => { = () => { Transactions {data?.totalTransactions} + + + Transactions + {data?.totalTransactions} + + Total Blocks + {data?.totalBlocks} + + Total Blocks {data?.totalBlocks} @@ -54,17 +81,31 @@ const OverView: FC = () => { Daily Transactions {data?.dailyTransactions} + + + Total Transactions + {data?.dailyTransactions} + ) diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index 119df04..eec51a4 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -91,7 +91,6 @@ export default function Navbar() { diff --git a/components/Reusables/BlockHashLink.tsx b/components/Reusables/BlockHashLink.tsx index 5798b0a..bdea74c 100644 --- a/components/Reusables/BlockHashLink.tsx +++ b/components/Reusables/BlockHashLink.tsx @@ -1,16 +1,26 @@ import React, { useState } from 'react'; -import { Box, Text } from '../../blocks'; +import { Box, Text, Tooltip, Copy } from '../../blocks'; import { rightMaskString } from '../../utils/helpers'; import Link from 'next/link'; const BlockHashLink = ({ blockHash, masking = false }) => { const [isHovered, setIsHovered] = useState(false); + const [tooltipText, setToolTipText] = useState('Copy'); const handleMouseEnter = () => setIsHovered(true); const handleMouseLeave = () => setIsHovered(false); const maskedBlockHash = masking ? rightMaskString(blockHash) : blockHash; + const copyData = () => { + navigator.clipboard.writeText(blockHash); + setToolTipText('Copied'); + + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; + return ( { {maskedBlockHash} )} + + + + + + ); }; diff --git a/components/Transactions/ConsensusInfo.tsx b/components/Transactions/ConsensusInfo.tsx index be3b432..cbe5c56 100644 --- a/components/Transactions/ConsensusInfo.tsx +++ b/components/Transactions/ConsensusInfo.tsx @@ -127,16 +127,18 @@ const ConsensusInfo = (props: IProps) => { )} - - - - - + + + + + + + @@ -233,16 +235,18 @@ const ConsensusInfo = (props: IProps) => { )} - - - - - + + + + + + + diff --git a/components/Transactions/ListView.tsx b/components/Transactions/ListView.tsx index 889394d..0f423d6 100644 --- a/components/Transactions/ListView.tsx +++ b/components/Transactions/ListView.tsx @@ -1,10 +1,8 @@ import React from 'react'; -import { Box, Text, Tag, Table, Ethereum, Polygon, BNB } from '../../blocks'; -import { Tick, EtheriumMonotone, BnbMonotone, PolygonMonotone, PushMonotone } from '../../blocks/icons' - -import { fromNow, convertCaipToObject, capitalizeStr, centerMaskString, rightMaskString} from '../../utils/helpers' +import { Box, Text, Tag, Table } from '../../blocks'; +import { Tick } from '../../blocks/icons' +import { fromNow, capitalizeStr} from '../../utils/helpers' import { useRouter } from 'next/router' -import moment from 'moment'; import { TagVariant } from '../../blocks/tag'; import { Transaction } from '../../types/transaction'; import { useTheme } from 'styled-components'; @@ -19,6 +17,7 @@ interface dataProps { } interface IProps { data?: dataProps + isLoading?: boolean } const ListView = (props: IProps) => { @@ -36,7 +35,7 @@ const ListView = (props: IProps) => { render: (status: string) => } label={capitalizeStr(status)} variant={status.toLowerCase() as TagVariant}>, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '10%' + width: '110px' }, { title: 'TX HASH', @@ -44,7 +43,7 @@ const ListView = (props: IProps) => { render: (txHash: string) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '15%' + width: '165px' }, { title: 'BLOCK HASH', @@ -52,7 +51,7 @@ const ListView = (props: IProps) => { render: (blockHash: string) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '15%' + width: '165px' }, { title: 'FROM', @@ -63,7 +62,7 @@ const ListView = (props: IProps) => { }, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '20%' + width: '220px' }, { title: 'TO', @@ -81,7 +80,7 @@ const ListView = (props: IProps) => { )}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '20%' + width: '240px' }, { title: 'CATEGORY', @@ -89,15 +88,15 @@ const ListView = (props: IProps) => { render: (category: string) => {category}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '13%' + width: '125px' }, { title: 'AGE', dataIndex: 'ts', - render: (ts: number) => {fromNow(ts * 1000)}, + render: (ts: number) => {fromNow(ts * 1000)}, cellAlignment: 'center', headerAlignment: 'center', - width: '6%' + width: '75px' }, ]; @@ -114,7 +113,9 @@ const ListView = (props: IProps) => { return ( -
+ +
+ ); }; diff --git a/components/Transactions/TxDetails.tsx b/components/Transactions/TxDetails.tsx index e26f5ac..464eabd 100644 --- a/components/Transactions/TxDetails.tsx +++ b/components/Transactions/TxDetails.tsx @@ -1,5 +1,5 @@ -import React from 'react'; -import { Box, Text, Tag } from '../../blocks'; +import React, { useState } from 'react'; +import { Box, Text, Tag, Tooltip, Copy } from '../../blocks'; import { Transaction } from '../../types/transaction'; import moment from 'moment'; import { TagVariant } from '../../blocks/tag'; @@ -14,6 +14,7 @@ interface IProps { const TXDetails = (props: IProps) => { let status: TagVariant = "default" + const [tooltipText, setToolTipText] = useState('Copy'); if (props.data?.status) { status = props.data.status.toLowerCase() as TagVariant @@ -27,6 +28,15 @@ const TXDetails = (props: IProps) => { dateTime = `${formattedTime}, ${detailedTime}` } + const copyData = (value) => { + navigator.clipboard.writeText(value); + setToolTipText('Copied'); + + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; + return ( <> { flexDirection="column" gap="spacing-sm" > - {props.data?.txnHash} + + {props.data?.txnHash} + + + + copyData(props.data?.txnHash)} + autoSize + size={24} + color="icon-tertiary" + /> + + + + + } label={capitalizeStr(status)} variant={status}> {props.data?.category} @@ -81,7 +106,17 @@ const TXDetails = (props: IProps) => { gap="spacing-xxxs" > Transaction Hash - {props.data?.txnHash} + + {props.data?.txnHash} + + copyData(props.data?.txnHash)} + autoSize + size={24} + color="icon-tertiary" + /> + + { const [showAll, setShowAll] = useState(false); + const [tooltipText, setToolTipText] = useState('Copy'); const toggleShowAll = () => { setShowAll(!showAll); @@ -21,6 +22,15 @@ const TxTravels = (props: IProps) => { const displayedRecipients = showAll ? recipients : recipients.slice(0, MAX_DISPLAY); const showMoreButton = recipients.length > MAX_DISPLAY; + const copyData = (value) => { + navigator.clipboard.writeText(value); + setToolTipText('Copied'); + + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; + return ( <> { display="flex" flexDirection="column" gap="spacing-sm" + justifyContent="flex-start" > -
+ + +
+ + + + copyData(props.data?.from)} + autoSize + size={24} + color="icon-tertiary" + /> + + + + + {displayedRecipients.map((recipient, index) => ( -
+ +
+ + + + copyData(recipient.address)} + autoSize + size={24} + color="icon-tertiary" + /> + + + + ))} {showMoreButton && ( @@ -91,9 +133,25 @@ const TxTravels = (props: IProps) => { display="flex" flexDirection="column" gap="spacing-xxxs" + justifyContent="flex-start" > From -
+ +
+ + + + copyData(props.data?.from)} + autoSize + size={24} + color="icon-tertiary" + /> + + + + + { display="flex" flexDirection="column" gap="spacing-xs" + justifyContent="flex-start" > {displayedRecipients.map((recipient, index) => ( -
+ +
+ + + + copyData(recipient.address)} + autoSize + size={24} + color="icon-tertiary" + /> + + + + + + ))} {showMoreButton && ( diff --git a/sections/Home/index.tsx b/sections/Home/index.tsx index 236b464..0543900 100644 --- a/sections/Home/index.tsx +++ b/sections/Home/index.tsx @@ -35,7 +35,7 @@ const Home = () => { diff --git a/sections/Transactions/index.tsx b/sections/Transactions/index.tsx index d12f070..10c213a 100644 --- a/sections/Transactions/index.tsx +++ b/sections/Transactions/index.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { Box, Text, Spinner, Pagination } from '../../blocks'; import ListView from '../../components/Transactions/ListView'; import { useLiveTransactions } from '../../hooks/useLiveTransactions'; @@ -6,15 +6,19 @@ import { PerPageItems } from '../../utils/constants' const Transactions = () => { const [page, setPage] = useState(1); + const [cachedTotalPages, setCachedTotalPages] = useState(0); // State for caching totalPages + const { data, isLoading } = useLiveTransactions({ page }); - - if (isLoading) { - return ( - - - - ) - } + + // Cache totalPages when new data is fetched + useEffect(() => { + if (data?.totalPages) { + setCachedTotalPages(data.totalPages); + } + }, [data?.totalPages]); + + // Use the cached totalPages when data is loading + const totalPages = data?.totalPages ?? cachedTotalPages; return ( { gap="spacing-md" > Transactions - + - setPage(page)} - /> + { + totalPages > 1 && setPage(page)} + /> + } ); diff --git a/utils/helpers.ts b/utils/helpers.ts index 8f856bf..3baaa1e 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -73,8 +73,9 @@ export function isErrorWithMessage(error: unknown): error is { message: string } } export function getValidatorNode(signers: Signer[] | undefined) { - const signer = signers?.find(signer => signer.role === 1); - return signer?.node + // const signer = signers?.find(signer => signer.role === 1); + // return signer?.node + return generateRandomHash() } export function centerMaskString(str, len = 15) { @@ -201,3 +202,9 @@ export const fromNow = (timestamp: number): string => { const diffInYears = Math.floor(diffInMonths / 12); return `${diffInYears}y ago`; } + +function generateRandomHash() { + const randomPart = Math.random().toString(16).substr(2, 8); // 8 random hex characters + const timePart = Date.now().toString(16); // Convert current time to hex + return randomPart + timePart; +} \ No newline at end of file diff --git a/utils/json-rpc.ts b/utils/json-rpc.ts index a332817..bcf3940 100644 --- a/utils/json-rpc.ts +++ b/utils/json-rpc.ts @@ -1,6 +1,6 @@ import axios from 'axios'; -const API_BASE = 'http://localhost:3000/rpc'; +const API_BASE = 'https://anode1.push.org/rpc'; const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); @@ -13,7 +13,7 @@ export const makeJsonRpcRequest = async (id, method, params = {}) => { }; try { - // await delay(500000); + await delay(5000); const response = await axios.post(API_BASE, data); if (response.data.error) { throw new Error('JSON-RPC Error: ' + response.data.error.message); From 44466183d7e8326ecaa76988e97b54ba9eeb5762 Mon Sep 17 00:00:00 2001 From: rozaso Date: Wed, 18 Sep 2024 20:39:28 -0700 Subject: [PATCH 19/42] Fix build failures. --- .env | 1 - components/Transactions/ConsensusInfo.tsx | 2 ++ components/Transactions/TxTravels.tsx | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index 6677a09..0000000 --- a/.env +++ /dev/null @@ -1 +0,0 @@ -APP_ENV = 'local' \ No newline at end of file diff --git a/components/Transactions/ConsensusInfo.tsx b/components/Transactions/ConsensusInfo.tsx index cbe5c56..1de672c 100644 --- a/components/Transactions/ConsensusInfo.tsx +++ b/components/Transactions/ConsensusInfo.tsx @@ -73,6 +73,7 @@ const ConsensusInfo = (props: IProps) => { > {displayedNodes.map((node, index) => ( { > {displayedNodes.map((node, index) => ( { justifyContent="flex-start" > {displayedRecipients.map((recipient, index) => ( - +
@@ -167,7 +167,7 @@ const TxTravels = (props: IProps) => { justifyContent="flex-start" > {displayedRecipients.map((recipient, index) => ( - +
From 126ae9181d042aa1dee2e38eca951cd6e7b025a3 Mon Sep 17 00:00:00 2001 From: rozaso Date: Wed, 18 Sep 2024 22:10:03 -0700 Subject: [PATCH 20/42] setup deployment. --- next.config.js | 5 ++ package.json | 17 +++-- yarn.lock | 197 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 209 insertions(+), 10 deletions(-) diff --git a/next.config.js b/next.config.js index a4a5d6a..9e0b197 100644 --- a/next.config.js +++ b/next.config.js @@ -5,6 +5,11 @@ const nextConfig = { devIndicators: { buildActivity: false, }, + images: { + unoptimized: true, // Disable Next.js image optimization for GitHub Pages + }, + basePath: '/push-analytics-dashboard', // Set this to the repo name if deploying to a subdirectory + assetPrefix: '/push-analytics-dashboard', // Ensures assets are served from the correct path }; module.exports = nextConfig; diff --git a/package.json b/package.json index f5b7055..9296764 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "dev": "next dev -p 4000", "build": "next build", "start": "next start -p 4000", - "lint": "next lint -p 4000" + "lint": "next lint", + "export": "next export", + "deploy": "npm run build && npm run export && gh-pages -d out" }, "dependencies": { "@emotion/react": "^11.10.5", @@ -19,8 +21,11 @@ "@radix-ui/react-tooltip": "^1.1.1", "@reach/combobox": "^0.18.0", "@reach/tabs": "^0.18.0", + "@table-library/react-table-library": "^4.1.7", "apexcharts": "^3.36.3", "axios": "^1.1.3", + "blockies": "0.0.2", + "blockies-react-svg": "^0.0.13", "date-fns": "^2.29.3", "echarts": "^5.4.2", "echarts-for-react": "^3.0.2", @@ -29,6 +34,7 @@ "moment": "^2.29.4", "next": "13.0.0", "numeral": "^2.0.6", + "rc-pagination": "^4.2.0", "react": "18.2.0", "react-apexcharts": "^1.4.0", "react-dom": "18.2.0", @@ -36,16 +42,12 @@ "react-loading-skeleton": "^3.3.1", "react-query": "^3.39.3", "react-router-dom": "^6.9.0", + "react-slider": "^2.0.6", "react-toastify": "^9.0.8", "react-toggle-dark-mode": "^1.1.0", "react-use": "^17.4.0", - "styled-components": "^5.3.6", "sonner": "^1.5.0", - "@table-library/react-table-library": "^4.1.7", - "rc-pagination": "^4.2.0", - "react-slider": "^2.0.6", - "blockies": "0.0.2", - "blockies-react-svg": "^0.0.13" + "styled-components": "^5.3.6" }, "devDependencies": { "@types/lodash": "^4.14.188", @@ -56,6 +58,7 @@ "babel-plugin-styled-components": "^2.0.7", "eslint": "8.26.0", "eslint-config-next": "13.0.0", + "gh-pages": "^6.1.1", "typescript": "4.8.4" } } diff --git a/yarn.lock b/yarn.lock index a9be4aa..03c58b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1267,11 +1267,23 @@ array-includes@^3.1.4, array-includes@^3.1.5: get-intrinsic "^1.1.1" is-string "^1.0.7" +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== + dependencies: + array-uniq "^1.0.1" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== + array.prototype.flat@^1.2.5: version "1.3.0" resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz" @@ -1297,6 +1309,11 @@ ast-types-flow@^0.0.7: resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz" integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== +async@^3.2.4: + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" @@ -1486,6 +1503,16 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +commander@^11.0.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906" + integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" @@ -1666,6 +1693,11 @@ echarts@^5.4.2: tslib "2.3.0" zrender "5.4.3" +email-addresses@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/email-addresses/-/email-addresses-5.0.0.tgz#7ae9e7f58eef7d5e3e2c2c2d3ea49b78dc854fa6" + integrity sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw== + emoji-regex@^9.2.2: version "9.2.2" resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" @@ -1731,7 +1763,7 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== @@ -2016,6 +2048,20 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ== + +filenamify@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-4.3.0.tgz#62391cb58f02b09971c9d4f9d63b3cf9aba03106" + integrity sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg== + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.1" + trim-repeated "^1.0.0" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" @@ -2023,11 +2069,28 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + find-root@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz" integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + find-up@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" @@ -2063,6 +2126,15 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" +fs-extra@^11.1.1: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" @@ -2110,6 +2182,19 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" +gh-pages@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-6.1.1.tgz#e80af927a081cb480657fde5a0b87ea2e77d6c74" + integrity sha512-upnohfjBwN5hBP9w2dPE7HO5JJTHzSGMV1JrLrHvNuqmjoYHg6TBrCcnEoorjG/e0ejbuvnwyKMdTyM40PEByw== + dependencies: + async "^3.2.4" + commander "^11.0.0" + email-addresses "^5.0.0" + filenamify "^4.3.0" + find-cache-dir "^3.3.1" + fs-extra "^11.1.1" + globby "^6.1.0" + glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" @@ -2136,7 +2221,7 @@ glob@7.1.7, glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.2.0: +glob@^7.0.3, glob@^7.2.0: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -2172,6 +2257,22 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw== + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + grapheme-splitter@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" @@ -2453,6 +2554,15 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.2: version "3.3.3" resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz" @@ -2486,6 +2596,13 @@ lines-and-columns@^1.1.6: resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + locate-path@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" @@ -2517,6 +2634,13 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + match-sorter@^6.0.2: version "6.3.4" resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.4.tgz#afa779d8e922c81971fbcb4781c7003ace781be7" @@ -2654,7 +2778,7 @@ numeral@^2.0.6: resolved "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz" integrity sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA== -object-assign@^4.1.1: +object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -2738,6 +2862,13 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + p-limit@^3.0.2: version "3.1.0" resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" @@ -2745,6 +2876,13 @@ p-limit@^3.0.2: dependencies: yocto-queue "^0.1.0" +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + p-locate@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" @@ -2752,6 +2890,11 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" @@ -2804,6 +2947,30 @@ picomatch@^2.3.0, picomatch@^2.3.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + postcss-value-parser@^4.0.2: version "4.2.0" resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" @@ -3147,6 +3314,11 @@ screenfull@^5.1.0: resolved "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz" integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA== +semver@^6.0.0: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + semver@^6.3.0: version "6.3.0" resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" @@ -3308,6 +3480,13 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-outer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== + dependencies: + escape-string-regexp "^1.0.2" + styled-components@^5.3.5, styled-components@^5.3.6: version "5.3.6" resolved "https://registry.npmjs.org/styled-components/-/styled-components-5.3.6.tgz" @@ -3447,6 +3626,13 @@ toggle-selection@^1.0.6: resolved "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz" integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== +trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg== + dependencies: + escape-string-regexp "^1.0.2" + ts-easing@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz" @@ -3511,6 +3697,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + unload@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7" From 21e5321982734a182ec8dbd59e2be054207b88c9 Mon Sep 17 00:00:00 2001 From: rozaso Date: Thu, 19 Sep 2024 08:18:20 -0700 Subject: [PATCH 21/42] Revert back the next.config.js --- next.config.js | 7 +------ package.json | 4 +--- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/next.config.js b/next.config.js index 9e0b197..ebbb189 100644 --- a/next.config.js +++ b/next.config.js @@ -4,12 +4,7 @@ const nextConfig = { swcMinify: true, devIndicators: { buildActivity: false, - }, - images: { - unoptimized: true, // Disable Next.js image optimization for GitHub Pages - }, - basePath: '/push-analytics-dashboard', // Set this to the repo name if deploying to a subdirectory - assetPrefix: '/push-analytics-dashboard', // Ensures assets are served from the correct path + } }; module.exports = nextConfig; diff --git a/package.json b/package.json index 9296764..c8d8be4 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,7 @@ "dev": "next dev -p 4000", "build": "next build", "start": "next start -p 4000", - "lint": "next lint", - "export": "next export", - "deploy": "npm run build && npm run export && gh-pages -d out" + "lint": "next lint -p 4000" }, "dependencies": { "@emotion/react": "^11.10.5", From dab03328a6dcb7e2a341c557cb51d0151309fc7b Mon Sep 17 00:00:00 2001 From: rozaso Date: Thu, 19 Sep 2024 09:55:55 -0700 Subject: [PATCH 22/42] Remove LINK component and react-router-dom --- blocks/index.ts | 2 - blocks/link/Link.tsx | 40 ------------------ blocks/link/index.ts | 1 - blocks/menu/Menu.constants.ts | 10 ----- blocks/menu/Menu.tsx | 36 ---------------- blocks/menu/Menu.types.ts | 43 ------------------- blocks/menu/MenuItem.tsx | 77 ----------------------------------- blocks/menu/index.ts | 4 -- package.json | 1 - utils/json-rpc.ts | 1 - yarn.lock | 20 --------- 11 files changed, 235 deletions(-) delete mode 100644 blocks/link/Link.tsx delete mode 100644 blocks/link/index.ts delete mode 100644 blocks/menu/Menu.constants.ts delete mode 100644 blocks/menu/Menu.tsx delete mode 100644 blocks/menu/Menu.types.ts delete mode 100644 blocks/menu/MenuItem.tsx delete mode 100644 blocks/menu/index.ts diff --git a/blocks/index.ts b/blocks/index.ts index e6cf785..7db2c45 100644 --- a/blocks/index.ts +++ b/blocks/index.ts @@ -3,9 +3,7 @@ export { Box, type BoxProps } from './box'; export { Button, type ButtonProps } from './button'; export { Dropdown, type DropdownProps } from './dropdown'; export { HoverableSVG, type HoverableSVGProps } from './hoverableSVG'; -export { Link, type LinkProps } from './link'; export { Lozenge, type LozengeProps } from './lozenge'; -export { Menu, type MenuProps, MenuItem, type MenuItemComponentProps } from './menu'; export { Modal, type ModalProps, modal } from './modal'; export { notification } from './notification'; export { Pagination, type PaginationProps } from './pagination'; diff --git a/blocks/link/Link.tsx b/blocks/link/Link.tsx deleted file mode 100644 index fe99a8a..0000000 --- a/blocks/link/Link.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { FC } from 'react'; -import { Link as RouterLink, LinkProps as RouterLinkProps } from 'react-router-dom'; -import styled, { FlattenSimpleInterpolation } from 'styled-components'; - -import { TransformedHTMLAttributes } from '../Blocks.types'; -import { Text, TextProps } from '../text'; - -export type LinkProps = RouterLinkProps & { - css?: FlattenSimpleInterpolation; - textProps?: TextProps; - isText?: boolean; -} & TransformedHTMLAttributes; - -const StyledLink = styled(RouterLink)` - /* Link CSS */ - - text-decoration: none; - - &:hover > * { - color: ${({ isText }) => (isText ? 'var(--text-brand-medium)' : '')}; - } - - /* Extra CSS props */ - ${(props) => props.css || ''} -`; - -const Link: FC = ({ textProps, isText = true, ...props }) => { - return ( - - {isText ? {props?.children} : props.children} - - ); -}; - -Link.displayName = 'Link'; - -export { Link }; diff --git a/blocks/link/index.ts b/blocks/link/index.ts deleted file mode 100644 index 3db78f5..0000000 --- a/blocks/link/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Link'; diff --git a/blocks/menu/Menu.constants.ts b/blocks/menu/Menu.constants.ts deleted file mode 100644 index cc560bc..0000000 --- a/blocks/menu/Menu.constants.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { MenuProps } from './Menu.types'; - -export const menuCSSPropsKeys: (keyof MenuProps)[] = [ - 'height', - 'maxHeight', - 'minHeight', - 'maxWidth', - 'minWidth', - 'width', -]; diff --git a/blocks/menu/Menu.tsx b/blocks/menu/Menu.tsx deleted file mode 100644 index e338340..0000000 --- a/blocks/menu/Menu.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { FC } from 'react'; -import styled from 'styled-components'; - -import type { MenuProps } from './Menu.types'; -import { menuCSSPropsKeys } from './Menu.constants'; - -const StyledMenu = styled.div.withConfig({ - shouldForwardProp: (prop, defaultValidatorFn) => - !menuCSSPropsKeys.includes(prop as keyof MenuProps) && defaultValidatorFn(prop), -})` - display: flex; - flex-direction: column; - background-color: var(--surface-primary); - border: var(--border-sm) solid var(--stroke-secondary); - border-radius: var(--radius-xs); - padding: var(--spacing-xxs); - margin: var(--spacing-none); - gap: var(--spacing-xs); - - /* Menu non-responsive styles */ - width: ${(props) => props.width}; - min-width: ${(props) => props.minWidth || '145px'}; - max-width: ${(props) => props.maxWidth}; - height: ${(props) => props.height}; - min-height: ${(props) => props.minHeight}; - max-height: ${(props) => props.maxHeight}; - - /* Extra CSS props */ - ${(props) => props.css || ''} -`; - -const Menu: FC = ({ children, ...props }) => {children}; - -Menu.displayName = 'Menu'; - -export { Menu }; diff --git a/blocks/menu/Menu.types.ts b/blocks/menu/Menu.types.ts deleted file mode 100644 index 2654e26..0000000 --- a/blocks/menu/Menu.types.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { ReactNode } from 'react'; -import { FlattenSimpleInterpolation } from 'styled-components'; - -export type MenuNonResponsiveProps = { - /* Sets height css property */ - height?: string; - /* Sets max-height css property */ - maxHeight?: string; - /* Sets min-height css property */ - minHeight?: string; - /* Sets max-width css property */ - maxWidth?: string; - /* Sets min-width css property */ - minWidth?: string; - /* Sets width css property */ - width?: string; -}; - -export type MenuComponentProps = { - /* Additional prop from styled components to apply custom css to Menu */ - css?: FlattenSimpleInterpolation; - /* Child react nodes rendered by Menu */ - children: ReactNode; -}; - -export type MenuItemComponentProps = { - /* icon element */ - icon?: ReactNode; - /* function attached to the menu item */ - onClick?: () => void; - /* menu item text */ - label?: string; - /* link option incase you need to redirect or open a link */ - destination?: string; - // add the option to open in a new tab - newTab?: boolean; - /* disabled option on the item*/ - disabled?: boolean; - /* Additional prop from styled components to apply custom css to Menu */ - css?: FlattenSimpleInterpolation; -}; - -export type MenuProps = MenuNonResponsiveProps & MenuComponentProps; diff --git a/blocks/menu/MenuItem.tsx b/blocks/menu/MenuItem.tsx deleted file mode 100644 index 4d2d329..0000000 --- a/blocks/menu/MenuItem.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { FC } from 'react'; -import styled from 'styled-components'; - -import { MenuItemComponentProps } from './Menu.types'; -import * as RadixDropdown from '@radix-ui/react-dropdown-menu'; -import { Link } from '../link'; -import { textVariants } from '../text'; - -const StyledMenuItem = styled(RadixDropdown.Item)` - // Menu default styles - padding: var(--spacing-none) var(--spacing-xxxs); - display: flex; - flex-direction: row; - flex: 1; - align-items: center; - gap: var(--spacing-xxxs); - border-radius: var(--radius-xxs); - - [role='img'] { - width: 24px; - height: 24px; - } - - &:hover { - background-color: var(--surface-secondary); - outline: none !important; - } - - cursor: pointer; - min-height: 32px; - - /* Extra CSS props */ - ${(props) => props.css || ''}; -`; - -const StyledLabel = styled.span` - color: var(--components-dropdown-text-default); - text-align: center; - - font-family: var(--font-family); - font-size: ${textVariants['bs-regular'].fontSize}; - font-style: ${textVariants['bs-regular'].fontStyle}; - font-weight: ${textVariants['bs-regular'].fontWeight}; - line-height: ${textVariants['bs-regular'].lineHeight}; -`; - -const MenuItem: FC = ({ icon, label, onClick, destination, newTab, disabled, ...props }) => { - const menuContent = ( - - {icon} - {label} - - ); - - return ( -
- {destination ? ( - - {menuContent} - - ) : ( - menuContent - )} -
- ); -}; - -MenuItem.displayName = 'MenuItem'; - -export { MenuItem }; diff --git a/blocks/menu/index.ts b/blocks/menu/index.ts deleted file mode 100644 index 6cb2776..0000000 --- a/blocks/menu/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './Menu'; -export * from './MenuItem'; -export * from './Menu.types'; -export * from './Menu.constants'; diff --git a/package.json b/package.json index c8d8be4..87a7f92 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,6 @@ "react-loader-spinner": "^5.3.4", "react-loading-skeleton": "^3.3.1", "react-query": "^3.39.3", - "react-router-dom": "^6.9.0", "react-slider": "^2.0.6", "react-toastify": "^9.0.8", "react-toggle-dark-mode": "^1.1.0", diff --git a/utils/json-rpc.ts b/utils/json-rpc.ts index bcf3940..59a0a47 100644 --- a/utils/json-rpc.ts +++ b/utils/json-rpc.ts @@ -13,7 +13,6 @@ export const makeJsonRpcRequest = async (id, method, params = {}) => { }; try { - await delay(5000); const response = await axios.post(API_BASE, data); if (response.data.error) { throw new Error('JSON-RPC Error: ' + response.data.error.message); diff --git a/yarn.lock b/yarn.lock index 03c58b9..5bf52ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1018,11 +1018,6 @@ "@react-spring/shared" "~9.5.5" "@react-spring/types" "~9.5.5" -"@remix-run/router@1.19.0": - version "1.19.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.19.0.tgz#745dbffbce67f05386d57ca22c51dfd85c979593" - integrity sha512-zDICCLKEwbVYTS6TjYaWtHXxkdoUvD/QXvyVZjGCsWz5vyH7aFeONlPffPdW+Y/t6KT0MgXb2Mfjun9YpWN1dA== - "@rushstack/eslint-patch@^1.1.3": version "1.2.0" resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz" @@ -3098,21 +3093,6 @@ react-remove-scroll@2.5.7: use-callback-ref "^1.3.0" use-sidecar "^1.1.2" -react-router-dom@^6.9.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.26.0.tgz#8debe13295c58605c04f93018d659a763245e58c" - integrity sha512-RRGUIiDtLrkX3uYcFiCIxKFWMcWQGMojpYZfcstc63A1+sSnVgILGIm9gNUA6na3Fm1QuPGSBQH2EMbAZOnMsQ== - dependencies: - "@remix-run/router" "1.19.0" - react-router "6.26.0" - -react-router@6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.26.0.tgz#d5af4c46835b202348ef2b7ddacd32a2db539fde" - integrity sha512-wVQq0/iFYd3iZ9H2l3N3k4PL8EEHcb0XlU2Na8nEwmiXgIUElEH6gaJDtUQxJ+JFzmIXaQjfdpcGWaM6IoQGxg== - dependencies: - "@remix-run/router" "1.19.0" - react-slider@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/react-slider/-/react-slider-2.0.6.tgz#8c7ff0301211f7c3ff32aa0163b33bdab6258559" From fe764d1a1847afe5b5b10e7fa9bc688eda53a1f8 Mon Sep 17 00:00:00 2001 From: rozaso Date: Thu, 19 Sep 2024 20:22:59 -0700 Subject: [PATCH 23/42] Styling fixes and validator random generator. --- components/Blocks/ConsensusInfo.tsx | 4 +- components/Blocks/Details.tsx | 30 +++++++++++++-- components/Reusables/BlockHashLink.tsx | 38 +++++++++++-------- components/Reusables/TxHashLink.tsx | 46 ++++++++++++++++++----- components/Transactions/ConsensusInfo.tsx | 4 +- components/Transactions/TxTravels.tsx | 2 +- utils/json-rpc.ts | 2 +- 7 files changed, 92 insertions(+), 34 deletions(-) diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index 42724dd..d4509ab 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Box, Text, Button, Add, Ethereum, Tooltip, Copy } from '../../blocks'; +import { Box, Text, Tooltip, Copy } from '../../blocks'; import { BlockDetails } from '../../types/block' interface IProps { @@ -23,7 +23,7 @@ const ConsensusInfo = (props: IProps) => { setShowAllPayload(!showAllPayload); }; - const nodes = props.data?.signers.map((signer) => signer.node) || [] + const nodes = props.data?.signers.map((signer) => signer.node) || ['0x2a466dd9e7dc394fc8a2f54c456a7dd00dec3d70', '0x377e68b95912de5fdc1729b4bc2ae397e95752d6'] const displayedNodes = showAll ? nodes : nodes.slice(0, MAX_DISPLAY_NODES); const showMoreButton = nodes.length > MAX_DISPLAY_NODES; diff --git a/components/Blocks/Details.tsx b/components/Blocks/Details.tsx index 4c8c9e3..b63d10e 100644 --- a/components/Blocks/Details.tsx +++ b/components/Blocks/Details.tsx @@ -1,5 +1,5 @@ -import React from 'react'; -import { Box, Text } from '../../blocks'; +import React, { useState } from 'react'; +import { Box, Text, Tooltip, Copy } from '../../blocks'; import moment from 'moment'; import { BlockDetails } from '../../types/block' import { getValidatorNode } from '../../utils/helpers' @@ -10,6 +10,7 @@ interface IProps { } const Details = (props: IProps) => { + const [tooltipText, setToolTipText] = useState('Copy'); let dateTime = '' if (props.data?.ts) { @@ -19,6 +20,14 @@ const Details = (props: IProps) => { dateTime = `${formattedTime}, ${detailedTime}` } + const copyData = (value) => { + navigator.clipboard.writeText(value); + setToolTipText('Copied'); + + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; return ( <> @@ -48,7 +57,22 @@ const Details = (props: IProps) => { flexDirection="column" gap="spacing-sm" > - { props.data?.blockHash } + + { props.data?.blockHash } + + + + copyData(props.data?.blockHash)} + autoSize + size={24} + color="icon-tertiary" + /> + + + + + { getValidatorNode(props.data?.signers) } { dateTime }
diff --git a/components/Reusables/BlockHashLink.tsx b/components/Reusables/BlockHashLink.tsx index bdea74c..27351d7 100644 --- a/components/Reusables/BlockHashLink.tsx +++ b/components/Reusables/BlockHashLink.tsx @@ -31,27 +31,35 @@ const BlockHashLink = ({ blockHash, masking = false }) => { onMouseLeave={handleMouseLeave} > {isHovered ? ( - - - {maskedBlockHash} - - + + + + {maskedBlockHash} + + + + + + + + ) : ( {maskedBlockHash} )} - - - - - + ); }; diff --git a/components/Reusables/TxHashLink.tsx b/components/Reusables/TxHashLink.tsx index 9c95386..7308f0c 100644 --- a/components/Reusables/TxHashLink.tsx +++ b/components/Reusables/TxHashLink.tsx @@ -1,14 +1,24 @@ import React, { useState } from 'react'; -import { Box, Text } from '../../blocks'; +import { Box, Text, Tooltip, Copy } from '../../blocks'; import { rightMaskString } from '../../utils/helpers' import Link from 'next/link' const TxHashLink = ({ txHash }) => { const [isHovered, setIsHovered] = useState(false); + const [tooltipText, setToolTipText] = useState('Copy'); const handleMouseEnter = () => setIsHovered(true); const handleMouseLeave = () => setIsHovered(false); + const copyData = () => { + navigator.clipboard.writeText(txHash); + setToolTipText('Copied'); + + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; + return ( { onMouseLeave={handleMouseLeave} > {isHovered ? ( - - - {rightMaskString(txHash)} - - - + + + + {rightMaskString(txHash)} + + + + + + + + ) : ( { setShowAllPayload(!showAllPayload); }; - const nodes = props.blockDetails?.signers.map((signer) => signer.node) || [] + const nodes = props.blockDetails?.signers.map((signer) => signer.node) || ['0x2a466dd9e7dc394fc8a2f54c456a7dd00dec3d70', '0x377e68b95912de5fdc1729b4bc2ae397e95752d6'] const displayedNodes = showAll ? nodes : nodes.slice(0, MAX_DISPLAY_NODES); const showMoreButton = nodes.length > MAX_DISPLAY_NODES; diff --git a/components/Transactions/TxTravels.tsx b/components/Transactions/TxTravels.tsx index 2aa380d..c25551a 100644 --- a/components/Transactions/TxTravels.tsx +++ b/components/Transactions/TxTravels.tsx @@ -133,7 +133,7 @@ const TxTravels = (props: IProps) => { display="flex" flexDirection="column" gap="spacing-xxxs" - justifyContent="flex-start" + justifyContent="flex-start" > From diff --git a/utils/json-rpc.ts b/utils/json-rpc.ts index 59a0a47..d4ac30d 100644 --- a/utils/json-rpc.ts +++ b/utils/json-rpc.ts @@ -1,6 +1,6 @@ import axios from 'axios'; -const API_BASE = 'https://anode1.push.org/rpc'; +const API_BASE = 'http://localhost:3000/rpc'; const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); From 38d88bb3ea04dc15122a14a0a24c2484677dccdc Mon Sep 17 00:00:00 2001 From: rozaso Date: Thu, 19 Sep 2024 20:29:25 -0700 Subject: [PATCH 24/42] Udpate API URL. --- utils/json-rpc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/json-rpc.ts b/utils/json-rpc.ts index d4ac30d..59a0a47 100644 --- a/utils/json-rpc.ts +++ b/utils/json-rpc.ts @@ -1,6 +1,6 @@ import axios from 'axios'; -const API_BASE = 'http://localhost:3000/rpc'; +const API_BASE = 'https://anode1.push.org/rpc'; const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); From 9bafb368c85a8140bdc464d428bb3b570ecf41df Mon Sep 17 00:00:00 2001 From: rozaso Date: Fri, 27 Sep 2024 00:17:05 -0700 Subject: [PATCH 25/42] Fixes for latest backend deployment. --- components/Blocks/Details.tsx | 2 +- components/Blocks/ListView.tsx | 2 +- components/Home/LiveBlocks.tsx | 2 +- components/Home/LiveTransactions.tsx | 2 +- components/Home/SearchBar.tsx | 11 +++++++---- components/Reusables/AddressComponent.tsx | 2 +- components/Transactions/ListView.tsx | 2 +- components/Transactions/TxDetails.tsx | 2 +- hooks/useBlocks.ts | 2 +- hooks/useGetTransactionsByUser.ts | 2 +- hooks/useLiveTransactions.ts | 2 +- hooks/useSearchByAddress.ts | 2 +- sections/User/index.tsx | 4 +--- utils/api.ts | 2 +- utils/helpers.ts | 4 ++-- utils/json-rpc.ts | 2 +- 16 files changed, 23 insertions(+), 22 deletions(-) diff --git a/components/Blocks/Details.tsx b/components/Blocks/Details.tsx index b63d10e..7eeaf3c 100644 --- a/components/Blocks/Details.tsx +++ b/components/Blocks/Details.tsx @@ -14,7 +14,7 @@ const Details = (props: IProps) => { let dateTime = '' if (props.data?.ts) { - const timestamp = props.data?.ts + const timestamp = (props.data?.ts / 1000) const formattedTime = moment.unix(timestamp).utc().fromNow(); // "40 minutes ago" const detailedTime = moment.unix(timestamp).utc().format('ddd, MMM DD YYYY HH:mm:ss [GMT]'); // "Sun, Jul 21 2024 18:33:47 GMT" dateTime = `${formattedTime}, ${detailedTime}` diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx index a70be4a..dbea54f 100644 --- a/components/Blocks/ListView.tsx +++ b/components/Blocks/ListView.tsx @@ -53,7 +53,7 @@ const Blocks = () => { { title: 'AGE', dataIndex: 'ts', - render: (text) => {fromNow(text * 1000)}, + render: (text) => {fromNow(text)}, cellAlignment: 'center', headerAlignment: 'center', width: '80px' diff --git a/components/Home/LiveBlocks.tsx b/components/Home/LiveBlocks.tsx index 19f9d59..403c9da 100644 --- a/components/Home/LiveBlocks.tsx +++ b/components/Home/LiveBlocks.tsx @@ -43,7 +43,7 @@ export default function LiveBlocks() { { title: 'AGE', dataIndex: 'ts', - render: (text) => {fromNow(text * 1000)}, + render: (text) => {fromNow(text)}, cellAlignment: 'center', headerAlignment: 'center', width: '65px' diff --git a/components/Home/LiveTransactions.tsx b/components/Home/LiveTransactions.tsx index e99c3f7..1a6ae4d 100644 --- a/components/Home/LiveTransactions.tsx +++ b/components/Home/LiveTransactions.tsx @@ -70,7 +70,7 @@ export default function LiveTransactions() { { title: 'AGE', dataIndex: 'ts', - render: (ts: number) => {fromNow(ts * 1000)}, + render: (ts: number) => {fromNow(ts)}, cellAlignment: 'center', headerAlignment: 'center', width: '75px' diff --git a/components/Home/SearchBar.tsx b/components/Home/SearchBar.tsx index 45030ab..01fce87 100644 --- a/components/Home/SearchBar.tsx +++ b/components/Home/SearchBar.tsx @@ -32,11 +32,10 @@ export default function SearchBar() { useEffect(() => { if (debouncedQuery) { if (!isLoading && data) { + const blocks = data?.blocks; + const transactions = blocks.flatMap((block) => block.transactions); // Use flatMap to flatten the transactions + const isSearchedTransaction = transactions.find((tx) => tx.txnHash === debouncedQuery); - const blocks = data?.blocks - const transactions = blocks.map((block) => block.transactions) - - const isSearchedTransaction = transactions.find((tx) => tx.txnHash === debouncedQuery) if (isSearchedTransaction) { router.push(`/transactions/${debouncedQuery}`) return @@ -48,6 +47,10 @@ export default function SearchBar() { return } + if (blocks.length >= 1) { + router.push(`/users/${debouncedQuery}`) + return + } } } }, [debouncedQuery, data, isLoading]); diff --git a/components/Reusables/AddressComponent.tsx b/components/Reusables/AddressComponent.tsx index 4fe3fdd..1346096 100644 --- a/components/Reusables/AddressComponent.tsx +++ b/components/Reusables/AddressComponent.tsx @@ -45,7 +45,7 @@ const Address = ({ address, wrap = false, masking = true }) => { onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} > - { getChainIcon(result.chainId) } + { getChainIcon("") } {isHovered ? ( { { title: 'AGE', dataIndex: 'ts', - render: (ts: number) => {fromNow(ts * 1000)}, + render: (ts: number) => {fromNow(ts)}, cellAlignment: 'center', headerAlignment: 'center', width: '75px' diff --git a/components/Transactions/TxDetails.tsx b/components/Transactions/TxDetails.tsx index 464eabd..e97bcb9 100644 --- a/components/Transactions/TxDetails.tsx +++ b/components/Transactions/TxDetails.tsx @@ -22,7 +22,7 @@ const TXDetails = (props: IProps) => { let dateTime = '' if (props.data?.ts) { - const timestamp = props.data?.ts + const timestamp = (props.data?.ts / 1000) const formattedTime = moment.unix(timestamp).utc().fromNow(); // "40 minutes ago" const detailedTime = moment.unix(timestamp).utc().format('ddd, MMM DD YYYY HH:mm:ss [GMT]'); // "Sun, Jul 21 2024 18:33:47 GMT" dateTime = `${formattedTime}, ${detailedTime}` diff --git a/hooks/useBlocks.ts b/hooks/useBlocks.ts index 9aa5ef1..f793ab6 100644 --- a/hooks/useBlocks.ts +++ b/hooks/useBlocks.ts @@ -14,7 +14,7 @@ export const useLiveBlocks = (props: inputProps) => { console.log("props : ", props) const getBlocks = () => makeJsonRpcRequest(RPC_ID, 'getBlocks', { - "startTime": Math.floor(Date.now() / 1000), + "startTime": Math.floor(Date.now()), "direction": "DESC", "showDetails": false, "pageSize": props.perPageItems || PerPageItems, diff --git a/hooks/useGetTransactionsByUser.ts b/hooks/useGetTransactionsByUser.ts index 4577bc3..381fe78 100644 --- a/hooks/useGetTransactionsByUser.ts +++ b/hooks/useGetTransactionsByUser.ts @@ -12,7 +12,7 @@ export interface searchProps { export const useGetTransactionsByUser = (params: searchProps) => { const getTransactionsByUser = () => makeJsonRpcRequest(RPC_ID, 'getTransactionsByUser', { "searchTerm": params.address, - "startTime": Math.floor(Date.now() / 1000), + "startTime": Math.floor(Date.now()), "direction": "DESC", "pageSize": PerPageItems, "page": params.page, diff --git a/hooks/useLiveTransactions.ts b/hooks/useLiveTransactions.ts index 62cc74a..633fec8 100644 --- a/hooks/useLiveTransactions.ts +++ b/hooks/useLiveTransactions.ts @@ -57,7 +57,7 @@ type inputProps = { export const useLiveTransactions = (props: inputProps) => { const getTransactions = () => makeJsonRpcRequest(RPC_ID, 'getTxs', { - "startTime": Math.floor(Date.now() / 1000), + "startTime": Math.floor(Date.now()), "direction": "DESC", "pageSize": props.perPageItems || PerPageItems, "page": props.page diff --git a/hooks/useSearchByAddress.ts b/hooks/useSearchByAddress.ts index a7659f1..873183e 100644 --- a/hooks/useSearchByAddress.ts +++ b/hooks/useSearchByAddress.ts @@ -14,7 +14,7 @@ export interface searchProps { export const useSearchByAddress = (params: searchProps) => { const searchByAddress = () => makeJsonRpcRequest(RPC_ID, 'searchByAddress', { "searchTerm": params.address, - "startTime": Math.floor(Date.now() / 1000), + "startTime": Math.floor(Date.now()), "direction": "DESC", "pageSize": PerPageItems, "page": params.page, diff --git a/sections/User/index.tsx b/sections/User/index.tsx index 4858677..7dd36c7 100644 --- a/sections/User/index.tsx +++ b/sections/User/index.tsx @@ -39,9 +39,7 @@ const Search = () => { ) } - console.log("::::: Address: ", address) - - address = address && convertCaipToObject(address).result.address + // address = address && convertCaipToObject(address).result.address if (!address) { return null diff --git a/utils/api.ts b/utils/api.ts index 273f9f2..6efa613 100644 --- a/utils/api.ts +++ b/utils/api.ts @@ -5,7 +5,7 @@ import axios from 'axios'; import { CREDENTIALKEYS } from './constants'; const API_BASE = 'https://backend.epns.io/apis/v1'; -const API_ANODE_BASE = 'https://anode1.push.org/' +const API_ANODE_BASE = 'https://anode2.push.org/' export const login = async ({ user, pass }) => { try { diff --git a/utils/helpers.ts b/utils/helpers.ts index 3baaa1e..b1e2cdf 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -145,7 +145,7 @@ export const convertCaipToObject = (addressinCAIP: string): { const addressComponent = addressinCAIP.split(':'); - if (addressComponent.length === 3 && isValidAddress(addressComponent[2])) { + if (addressComponent.length === 3) { return { result: { chain: addressComponent[0], @@ -153,7 +153,7 @@ export const convertCaipToObject = (addressinCAIP: string): { address: addressComponent[2], }, }; - } else if (addressComponent.length === 2 && isValidAddress(addressComponent[1])) { + } else if (addressComponent.length === 2) { return { result: { chain: addressComponent[0], diff --git a/utils/json-rpc.ts b/utils/json-rpc.ts index 59a0a47..930de4b 100644 --- a/utils/json-rpc.ts +++ b/utils/json-rpc.ts @@ -1,6 +1,6 @@ import axios from 'axios'; -const API_BASE = 'https://anode1.push.org/rpc'; +const API_BASE = 'https://anode2.push.org/rpc'; const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); From c2116ebcc2bf575f4d15cf1a706a839df5e469fe Mon Sep 17 00:00:00 2001 From: rozaso Date: Fri, 27 Sep 2024 11:30:35 -0700 Subject: [PATCH 26/42] Fix backend deployment API changes issues. --- components/Reusables/AddressComponent.tsx | 6 +- components/Transactions/ConsensusInfo.tsx | 23 ++-- hooks/useLiveTxByHash.ts | 1 + package.json | 1 + types/block.ts | 6 ++ utils/helpers.ts | 123 +++++++++++++++++----- yarn.lock | 5 + 7 files changed, 126 insertions(+), 39 deletions(-) diff --git a/components/Reusables/AddressComponent.tsx b/components/Reusables/AddressComponent.tsx index 1346096..7be8391 100644 --- a/components/Reusables/AddressComponent.tsx +++ b/components/Reusables/AddressComponent.tsx @@ -25,7 +25,7 @@ const Address = ({ address, wrap = false, masking = true }) => { case 56: return default: - return + return } } catch (err) { return @@ -33,7 +33,7 @@ const Address = ({ address, wrap = false, masking = true }) => { } const { result } = convertCaipToObject(address) - + const maskedAddress = masking ? centerMaskString(result.address) : result.address; return ( @@ -45,7 +45,7 @@ const Address = ({ address, wrap = false, masking = true }) => { onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} > - { getChainIcon("") } + { result.chainId && getChainIcon(result.chainId) } {isHovered ? ( { setShowAllPayload(!showAllPayload); }; - const nodes = props.blockDetails?.signers.map((signer) => signer.node) || ['0x2a466dd9e7dc394fc8a2f54c456a7dd00dec3d70', '0x377e68b95912de5fdc1729b4bc2ae397e95752d6'] + const nodes = buildNodeVotes(props.blockDetails?.blockDataAsJson) + + const displayedNodes = showAll ? nodes : nodes.slice(0, MAX_DISPLAY_NODES); const showMoreButton = nodes.length > MAX_DISPLAY_NODES; - const payload = props.transaction?.txnData || ""; const displayedPayload = showAllPayload ? payload : payload.substring(0, MAX_DISPLAY_CHARS); const showMorePayloadButton = payload.length > MAX_DISPLAY_CHARS; @@ -73,14 +76,16 @@ const ConsensusInfo = (props: IProps) => { > {displayedNodes.map((node, index) => ( - {node} - }label={'Accepted'} variant='success'> + + {node.node} + }label={`${node.vote}`} variant={node.vote === 'Accepted' ? 'success' : 'danger'}> ))} @@ -169,7 +174,7 @@ const ConsensusInfo = (props: IProps) => { > {displayedNodes.map((node, index) => ( { width="60vw" > - {node} + {node.node} @@ -187,7 +192,7 @@ const ConsensusInfo = (props: IProps) => { borderRadius="radius-xs" padding="spacing-xxs spacing-sm" > - Accepted + }label={`${node.vote}`} variant={node.vote === 'Accepted' ? 'success' : 'danger'}> diff --git a/hooks/useLiveTxByHash.ts b/hooks/useLiveTxByHash.ts index b810957..0651531 100644 --- a/hooks/useLiveTxByHash.ts +++ b/hooks/useLiveTxByHash.ts @@ -27,6 +27,7 @@ export const useLiveTxByHash = (params: TxDetailsProps) => { const blockDetails: BlockDetails = { blockData: blocks[0].blockData, + blockDataAsJson: blocks[0].blockDataAsJson, blockHash: blocks[0].blockHash, blockSize: blocks[0].blockSize, totalNumberOfTxns: blocks[0].totalNumberOfTxns, diff --git a/package.json b/package.json index 87a7f92..c5e1ac0 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "echarts": "^5.4.2", "echarts-for-react": "^3.0.2", "ethers": "^6.13.2", + "jwt-decode": "^4.0.0", "lodash": "^4.17.21", "moment": "^2.29.4", "next": "13.0.0", diff --git a/types/block.ts b/types/block.ts index 7e10936..6c2b5ea 100644 --- a/types/block.ts +++ b/types/block.ts @@ -23,6 +23,12 @@ export interface Block { export interface BlockDetails { blockData: string, + blockDataAsJson: { + ts: number; + txobjList: any[]; + attesttoken: string; + signersList: Signer[]; + } blockHash: string, blockSize: number, totalNumberOfTxns: number, diff --git a/utils/helpers.ts b/utils/helpers.ts index b1e2cdf..6a24b53 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -137,35 +137,54 @@ export const caip10ToWallet = (wallet: string) => { } export const convertCaipToObject = (addressinCAIP: string): { - result: { chainId: string | null; chain: string; address: string } + result: { chainId: string | null; chain: string | null; address: string | null } } => { - if (!addressinCAIP) { - throw new Error('CAIP address cannot be null or empty'); - } - - const addressComponent = addressinCAIP.split(':'); - - if (addressComponent.length === 3) { - return { - result: { - chain: addressComponent[0], - chainId: addressComponent[1], - address: addressComponent[2], - }, - }; - } else if (addressComponent.length === 2) { - return { - result: { - chain: addressComponent[0], - chainId: null, - address: addressComponent[1], - }, - }; - } else { - throw new Error('Invalid CAIP Format'); - } + // Check if the input is a valid non-empty string + if (!addressinCAIP || typeof addressinCAIP !== 'string') { + return { + result: { + chain: null, + chainId: null, + address: null, + }, + }; + } + + const addressComponent = addressinCAIP.split(':'); + + // Handle cases where there are exactly three components (chain, chainId, address) + if (addressComponent.length === 3) { + return { + result: { + chain: addressComponent[0], + chainId: addressComponent[1], + address: addressComponent[2], + }, + }; + } + // Handle cases where there are exactly two components (chain, address) + else if (addressComponent.length === 2) { + return { + result: { + chain: addressComponent[0], + chainId: null, + address: addressComponent[1], + }, + }; + } + // If the input doesn't match the expected format, return the address only + else { + return { + result: { + chain: null, + chainId: null, + address: addressinCAIP, + }, + }; + } }; + export const fromNow = (timestamp: number): string => { const now = Date.now(); const diffInSeconds = Math.floor((now - timestamp) / 1000); @@ -207,4 +226,54 @@ function generateRandomHash() { const randomPart = Math.random().toString(16).substr(2, 8); // 8 random hex characters const timePart = Date.now().toString(16); // Convert current time to hex return randomPart + timePart; -} \ No newline at end of file +} + +// Define the type for a vote +interface Vote { + node: string; + vote: string; +} + +// Function to decode a base64 string +const decodeBase64 = (data: string) => atob(data) + +// Function to calculate votes and build the result array +export const buildNodeVotes = (blockDataAsJson: any): Vote[] => { + try { + // Step 1: Base64 decode the attesttoken and then JWT decode it + const decodedBase64 = decodeBase64(decodeBase64(blockDataAsJson.attesttoken)); + + // Retrieve the nodes array from the decoded JWT + const nodes = JSON.parse(decodedBase64).nodes; + + + // Step 2: Initialize the votes array with the correct type + const votes: Vote[] = []; + + // First node's vote comes from validatordata.vote + const validatorVote = blockDataAsJson.txobjList[0].validatordata.vote; + const firstVote = validatorVote === 1 ? 'Accepted' : 'Rejected'; + + votes.push({ + node: nodes[0].nodeId, + vote: firstVote, + }); + + // Step 3: Remaining nodes' votes come from attestordataList + const attestordataList = blockDataAsJson.txobjList[0].attestordataList; + + attestordataList.forEach((attestor, index) => { + const vote = attestor.vote === 1 ? 'Accepted' : 'Rejected'; + + // Mapping the remaining node IDs + votes.push({ + node: nodes[index + 1].nodeId, // Index + 1 to skip the first node + vote: vote, + }); + }); + + return votes; + } catch (e) { + return []; + } +}; diff --git a/yarn.lock b/yarn.lock index 5bf52ba..207f5e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2566,6 +2566,11 @@ jsonfile@^6.0.1: array-includes "^3.1.5" object.assign "^4.1.3" +jwt-decode@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b" + integrity sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA== + language-subtag-registry@~0.3.2: version "0.3.22" resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz" From b8e3e85bb779a8789f5f0595350bd9003c51e4b1 Mon Sep 17 00:00:00 2001 From: rozaso Date: Fri, 27 Sep 2024 11:45:36 -0700 Subject: [PATCH 27/42] More fixes --- components/Blocks/ConsensusInfo.tsx | 19 ++++++++++++++++--- components/Blocks/Details.tsx | 2 +- components/Blocks/ListView.tsx | 2 +- components/Home/LiveBlocks.tsx | 2 +- hooks/useLiveBlockByHash.ts | 1 + utils/helpers.ts | 7 +++---- 6 files changed, 23 insertions(+), 10 deletions(-) diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index d4509ab..96d35b3 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -1,6 +1,8 @@ import React, { useState } from 'react'; import { Box, Text, Tooltip, Copy } from '../../blocks'; import { BlockDetails } from '../../types/block' +import { buildNodeVotes } from '../../utils/helpers' +import { PushMonotone } from '../../blocks/icons' interface IProps { data: BlockDetails | null | undefined, @@ -23,7 +25,9 @@ const ConsensusInfo = (props: IProps) => { setShowAllPayload(!showAllPayload); }; - const nodes = props.data?.signers.map((signer) => signer.node) || ['0x2a466dd9e7dc394fc8a2f54c456a7dd00dec3d70', '0x377e68b95912de5fdc1729b4bc2ae397e95752d6'] + + const nodes = buildNodeVotes(props.data?.blockDataAsJson) + const displayedNodes = showAll ? nodes : nodes.slice(0, MAX_DISPLAY_NODES); const showMoreButton = nodes.length > MAX_DISPLAY_NODES; @@ -68,7 +72,16 @@ const ConsensusInfo = (props: IProps) => { gap="spacing-xs" > {displayedNodes.map((node, index) => ( - {node} + + + {node.node} + ))} {showMoreButton && ( @@ -157,7 +170,7 @@ const ConsensusInfo = (props: IProps) => { gap="spacing-xs" > {displayedNodes.map((node, index) => ( - {node} + {node.node} ))} {showMoreButton && ( diff --git a/components/Blocks/Details.tsx b/components/Blocks/Details.tsx index 7eeaf3c..bfa08e3 100644 --- a/components/Blocks/Details.tsx +++ b/components/Blocks/Details.tsx @@ -73,7 +73,7 @@ const Details = (props: IProps) => { - { getValidatorNode(props.data?.signers) } + { getValidatorNode(props.data?.blockDataAsJson) } { dateTime } diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx index dbea54f..ba3f5d8 100644 --- a/components/Blocks/ListView.tsx +++ b/components/Blocks/ListView.tsx @@ -63,7 +63,7 @@ const Blocks = () => { const dataSource = data?.blocks?.map(block => ({ id: block.blockHash, blockHash: block.blockHash, - validator: getValidatorNode(block.blockDataAsJson?.signersList), // Define this function or update data mapping accordingly + validator: getValidatorNode(block.blockDataAsJson), // Define this function or update data mapping accordingly totalNumberOfTxns: block.totalNumberOfTxns, blockSize: block.blockSize, ts: block.ts diff --git a/components/Home/LiveBlocks.tsx b/components/Home/LiveBlocks.tsx index 403c9da..fbb1dfd 100644 --- a/components/Home/LiveBlocks.tsx +++ b/components/Home/LiveBlocks.tsx @@ -53,7 +53,7 @@ export default function LiveBlocks() { const dataSource = data?.blocks?.map(block => ({ id: block.blockHash, blockHash: block.blockHash, - validator: getValidatorNode(block.blockDataAsJson?.signersList), // Define this function or update data mapping accordingly + validator: getValidatorNode(block.blockDataAsJson), // Define this function or update data mapping accordingly totalNumberOfTxns: block.totalNumberOfTxns, ts: block.ts })) || []; diff --git a/hooks/useLiveBlockByHash.ts b/hooks/useLiveBlockByHash.ts index 04c5a8c..aacdf33 100644 --- a/hooks/useLiveBlockByHash.ts +++ b/hooks/useLiveBlockByHash.ts @@ -24,6 +24,7 @@ export const useLiveBlockByHash = (params: BlockDetailsProps) => { // Creating a summary of the block details const blockDetails: BlockDetails = { blockData: blocks[0].blockData, + blockDataAsJson: blocks[0].blockDataAsJson, blockHash: blocks[0].blockHash, blockSize: blocks[0].blockSize, totalNumberOfTxns: blocks[0].totalNumberOfTxns, diff --git a/utils/helpers.ts b/utils/helpers.ts index 6a24b53..a9cc7a5 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -72,10 +72,9 @@ export function isErrorWithMessage(error: unknown): error is { message: string } return typeof error === 'object' && error !== null && 'message' in error; } -export function getValidatorNode(signers: Signer[] | undefined) { - // const signer = signers?.find(signer => signer.role === 1); - // return signer?.node - return generateRandomHash() +export function getValidatorNode(blockDataAsJson) { + const nodes = buildNodeVotes(blockDataAsJson) + return nodes[0]?.node ?? "" } export function centerMaskString(str, len = 15) { From 72110c8c9ee419af6c20524145c2d6d785bcf9e4 Mon Sep 17 00:00:00 2001 From: rozaso Date: Fri, 27 Sep 2024 11:48:59 -0700 Subject: [PATCH 28/42] Fix search --- components/Home/SearchBar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/Home/SearchBar.tsx b/components/Home/SearchBar.tsx index 01fce87..30ababf 100644 --- a/components/Home/SearchBar.tsx +++ b/components/Home/SearchBar.tsx @@ -34,14 +34,14 @@ export default function SearchBar() { if (!isLoading && data) { const blocks = data?.blocks; const transactions = blocks.flatMap((block) => block.transactions); // Use flatMap to flatten the transactions + const isSearchedTransaction = transactions.find((tx) => tx.txnHash === debouncedQuery); - if (isSearchedTransaction) { router.push(`/transactions/${debouncedQuery}`) return } - const isSearchedBlock = blocks && blocks.length > 0 && blocks.map((block) => block.blockHash === debouncedQuery) + const isSearchedBlock = blocks.some(block => block.blockHash === debouncedQuery); if (isSearchedBlock) { router.push(`/blocks/${debouncedQuery}`) return From 701ab916ba513c4a5c256781afcfc8da63fd6ba6 Mon Sep 17 00:00:00 2001 From: rozaso Date: Fri, 27 Sep 2024 11:58:19 -0700 Subject: [PATCH 29/42] UI fixes and removing Notificaions By Channel from dashboard. --- components/Blocks/BlockTxDetails.tsx | 4 ++-- components/Blocks/ConsensusInfo.tsx | 4 ++-- components/Blocks/Details.tsx | 4 ++-- components/Dashboard/LineChartSet/index.tsx | 4 ++-- components/Navbar/index.tsx | 4 ++-- components/Transactions/ConsensusInfo.tsx | 4 ++-- components/Transactions/TxDetails.tsx | 4 ++-- components/Transactions/TxTravels.tsx | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/components/Blocks/BlockTxDetails.tsx b/components/Blocks/BlockTxDetails.tsx index fa33072..0f7ca62 100644 --- a/components/Blocks/BlockTxDetails.tsx +++ b/components/Blocks/BlockTxDetails.tsx @@ -11,7 +11,7 @@ const BlockTXDetails = (props: IProps) => { return ( <> { { return ( <> { { return ( <> { - + /> */} {/* @@ -99,7 +99,7 @@ export default function Navbar() { { return ( <> { { return ( <> { { return ( <> { Date: Tue, 8 Oct 2024 08:45:18 -0700 Subject: [PATCH 30/42] Fix UI issues. --- components/Blocks/ConsensusInfo.tsx | 77 +++++++++----- components/Reusables/AddressComponent.tsx | 119 ++++++++++++---------- components/Reusables/BlockHashLink.tsx | 106 ++++++++++--------- components/Reusables/TxHashLink.tsx | 114 +++++++++++---------- components/Transactions/ConsensusInfo.tsx | 106 +++++++++++-------- 5 files changed, 306 insertions(+), 216 deletions(-) diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index 4a76072..e5382e9 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -101,20 +101,30 @@ const ConsensusInfo = (props: IProps) => { - - Payload Data - + + + + Payload Data + + - {displayedPayload} + padding="spacing-xs" + width="100%" + maxWidth="750px" /* Adjust as per your layout */ + > + + {displayedPayload} + + {showMorePayloadButton && ( { cursor="pointer" onClick={toggleShowAllPayload} > - - {showAllPayload ? 'Show Less' : 'Show More'} + + {showAllPayload ? "Show Less" : "Show More"} )} - - - + + + - + @@ -170,7 +180,16 @@ const ConsensusInfo = (props: IProps) => { gap="spacing-xs" > {displayedNodes.map((node, index) => ( - {node.node} + + + {node.node} + ))} {showMoreButton && ( @@ -201,9 +220,17 @@ const ConsensusInfo = (props: IProps) => { border="border-sm solid stroke-tertiary" borderRadius="radius-xs" padding="spacing-sm" - width="88vw" + width="100%" + maxWidth="750px" /* Adjust as per your layout */ > - {displayedPayload} + + {displayedPayload} + + {showMorePayloadButton && ( { - const [isHovered, setIsHovered] = useState(false); + function getChainIcon(chainId) { + try { + if (!chainId) { + return + } - const handleMouseEnter = () => setIsHovered(true); - const handleMouseLeave = () => setIsHovered(false); + switch(Number(chainId)) { + case 1: + case 11155111: + return + case 137: + case 80002: + case 1101: + case 2442: + return + case 56: + case 97: + return + case 42161: + case 421614: + return + case 10: + case 11155420: + return + default: + return + } + } catch (err) { + return + } + } + const { result } = convertCaipToObject(address) - function getChainIcon(chainId) { - try { - if (!chainId) { - return - } + const maskedAddress = masking ? centerMaskString(result.address) : result.address; - switch(Number(chainId)) { - case 1: - return - case 137: - return - case 56: - return - default: - return - } - } catch (err) { - return - } - } + return ( + + {result.chainId && getChainIcon(result.chainId)} + + + {maskedAddress} + + + + ); +}; - const { result } = convertCaipToObject(address) +const AddressLink = styled(Link)` + pointer-events: none; + text-decoration: none; +`; - const maskedAddress = masking ? centerMaskString(result.address) : result.address; +const AddressText = styled(Text)` + color: var(--text-primary); +`; - return ( - - { result.chainId && getChainIcon(result.chainId) } - {isHovered ? ( - - - {maskedAddress} - - - ) : ( - - {maskedAddress} - - )} - - ); -}; +const AddressContainer = styled(Box)` + display: flex; + flex-direction: row; + gap: 8px; + align-items: center; + + &:hover ${/* sc-selector */ AddressLink} { + pointer-events: auto; + } + + &:hover ${/* sc-selector */ AddressText} { + color: var(--text-brand-medium); + } +`; export default Address; diff --git a/components/Reusables/BlockHashLink.tsx b/components/Reusables/BlockHashLink.tsx index 27351d7..a78ef57 100644 --- a/components/Reusables/BlockHashLink.tsx +++ b/components/Reusables/BlockHashLink.tsx @@ -2,14 +2,11 @@ import React, { useState } from 'react'; import { Box, Text, Tooltip, Copy } from '../../blocks'; import { rightMaskString } from '../../utils/helpers'; import Link from 'next/link'; +import styled from 'styled-components'; -const BlockHashLink = ({ blockHash, masking = false }) => { - const [isHovered, setIsHovered] = useState(false); +const BlockHashLinkComponent = ({ blockHash, masking = false }) => { const [tooltipText, setToolTipText] = useState('Copy'); - const handleMouseEnter = () => setIsHovered(true); - const handleMouseLeave = () => setIsHovered(false); - const maskedBlockHash = masking ? rightMaskString(blockHash) : blockHash; const copyData = () => { @@ -17,51 +14,68 @@ const BlockHashLink = ({ blockHash, masking = false }) => { setToolTipText('Copied'); setTimeout(() => { - setToolTipText('Copy'); + setToolTipText('Copy'); }, 1000); }; return ( - - {isHovered ? ( - - - - {maskedBlockHash} - - - - - - - - - ) : ( - - {maskedBlockHash} - - )} - - - + + + + {maskedBlockHash} + + + + + + + + ); }; -export default BlockHashLink; + +const CopyIconButton = styled.button` + opacity: 0; + pointer-events: none; + transition: opacity 0.2s ease-in-out; + display: flex; + align-items: center; + background: none; + border: none; + cursor: pointer; + padding: 0; +`; + +const BlockHashLink = styled(Link)` + text-decoration: none; +`; + +const BlockHashText = styled(Text)` + color: var(--text-primary); + transition: color 0.2s ease-in-out; +`; + +const BlockHashContainer = styled(Box)` + display: flex; + flex-direction: row; + gap: spacing-xxs; + align-items: center; + + &:hover ${CopyIconButton}, + &:focus-within ${CopyIconButton} { + opacity: 1; + pointer-events: auto; + } + + &:hover ${BlockHashText}, + &:focus-within ${BlockHashText} { + color: var(--text-brand-medium); + } +`; + +export default BlockHashLinkComponent; diff --git a/components/Reusables/TxHashLink.tsx b/components/Reusables/TxHashLink.tsx index 7308f0c..385d149 100644 --- a/components/Reusables/TxHashLink.tsx +++ b/components/Reusables/TxHashLink.tsx @@ -2,68 +2,80 @@ import React, { useState } from 'react'; import { Box, Text, Tooltip, Copy } from '../../blocks'; import { rightMaskString } from '../../utils/helpers' import Link from 'next/link' +import styled from 'styled-components'; -const TxHashLink = ({ txHash }) => { - const [isHovered, setIsHovered] = useState(false); +const TxHashLinkComponent = ({ txHash }) => { const [tooltipText, setToolTipText] = useState('Copy'); - const handleMouseEnter = () => setIsHovered(true); - const handleMouseLeave = () => setIsHovered(false); - const copyData = () => { navigator.clipboard.writeText(txHash); setToolTipText('Copied'); - + setTimeout(() => { - setToolTipText('Copy'); + setToolTipText('Copy'); }, 1000); }; return ( - - {isHovered ? ( - - - - {rightMaskString(txHash)} - - - - - - - - - ) : ( - - {rightMaskString(txHash)} - - )} - + + + + {rightMaskString(txHash)} + + + + + + + + ); }; -export default TxHashLink; + +const CopyIconButton = styled.button` + opacity: 0; + pointer-events: none; + transition: opacity 0.2s ease-in-out; + display: flex; + justify-content: flex-end; + align-items: center; + background: none; + border: none; + cursor: pointer; + padding: 0; +`; + +const TxHashText = styled(Text)` + color: var(--text-primary); + transition: color 0.2s ease-in-out; +`; + +const TxHashLinkStyled = styled(Link)` + text-decoration: none; +`; + +const TxHashContainer = styled(Box)` + display: flex; + flex-direction: row; + gap: spacing-xxs; + align-items: center; + + &:hover ${CopyIconButton}, + &:focus-within ${CopyIconButton} { + opacity: 1; + pointer-events: auto; + } + + &:hover ${TxHashText}, + &:focus-within ${TxHashText} { + color: var(--text-brand-medium); + } +`; + + +export default TxHashLinkComponent; diff --git a/components/Transactions/ConsensusInfo.tsx b/components/Transactions/ConsensusInfo.tsx index 1b6eddf..253c66c 100644 --- a/components/Transactions/ConsensusInfo.tsx +++ b/components/Transactions/ConsensusInfo.tsx @@ -106,19 +106,30 @@ const ConsensusInfo = (props: IProps) => { - - Payload Data + + + + Payload Data + + - {displayedPayload} + padding="spacing-xs" + width="100%" + maxWidth="750px" /* Adjust as per your layout */ + > + + {displayedPayload} + + {showMorePayloadButton && ( { cursor="pointer" onClick={toggleShowAllPayload} > - - {showAllPayload ? 'Show Less' : 'Show More'} + + {showAllPayload ? "Show Less" : "Show More"} )} - - - + + + @@ -215,19 +226,30 @@ const ConsensusInfo = (props: IProps) => { - - Payload Data + { displayedPayload && + + + Payload Data + + - {displayedPayload} + + {displayedPayload} + + {showMorePayloadButton && ( { cursor="pointer" onClick={toggleShowAllPayload} > - - {showAllPayload ? 'Show Less' : 'Show More'} + + {showAllPayload ? "Show Less" : "Show More"} )} - + { displayedPayload && - - - + + + - + } - + } ); From 343bddedc24389d1befd9714ae44bd591a5ab791 Mon Sep 17 00:00:00 2001 From: rozaso Date: Fri, 11 Oct 2024 07:46:06 -0700 Subject: [PATCH 31/42] Fix mobile styling issues with the layout. --- blocks/theme/variables/variables.spacing.ts | 2 +- components/Blocks/ConsensusInfo.tsx | 6 +++++- components/Blocks/Details.tsx | 7 +++++-- components/Reusables/BlockHashLink.tsx | 2 +- components/Transactions/ConsensusInfo.tsx | 17 +++++++++-------- components/Transactions/TxDetails.tsx | 9 ++++++--- components/Transactions/TxTravels.tsx | 6 ++++-- 7 files changed, 31 insertions(+), 18 deletions(-) diff --git a/blocks/theme/variables/variables.spacing.ts b/blocks/theme/variables/variables.spacing.ts index aefd530..13fd802 100644 --- a/blocks/theme/variables/variables.spacing.ts +++ b/blocks/theme/variables/variables.spacing.ts @@ -10,5 +10,5 @@ export const spacingVariables = { 'spacing-xxl': '48px', 'spacing-xxxl': '64px', 'spacing-xxxxl': '128px', - 'spacing-xxxxxl': '168px', + 'spacing-xxxxxl': '148px', }; diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index e5382e9..539e64e 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -188,7 +188,11 @@ const ConsensusInfo = (props: IProps) => { gap="spacing-xs" > - {node.node} + + {node.node} + ))} diff --git a/components/Blocks/Details.tsx b/components/Blocks/Details.tsx index 1a17aad..0986410 100644 --- a/components/Blocks/Details.tsx +++ b/components/Blocks/Details.tsx @@ -94,7 +94,10 @@ const Details = (props: IProps) => { gap="spacing-xxxs" > Block Hash - { props.data?.blockHash } + + + { props.data?.blockHash } + @@ -104,7 +107,7 @@ const Details = (props: IProps) => { gap="spacing-xxxs" > Validator - { getValidatorNode(props.data?.signers) } + { getValidatorNode(props.data?.signers) } { - + { displayedPayload && Payload Data @@ -157,8 +157,8 @@ const ConsensusInfo = (props: IProps) => { - - + } + { key={node.node} display="flex" flexDirection="row" - gap="spacing-lg" + justifyContent="space-between" + alignItems="center" + gap="spacing-xs" > - + + + {node.node} diff --git a/components/Transactions/TxDetails.tsx b/components/Transactions/TxDetails.tsx index fdf8e68..956f6cb 100644 --- a/components/Transactions/TxDetails.tsx +++ b/components/Transactions/TxDetails.tsx @@ -37,6 +37,7 @@ const TXDetails = (props: IProps) => { }, 1000); }; + return ( <> { gap="spacing-xxxs" > Transaction Hash - - {props.data?.txnHash} + + + {props.data?.txnHash} + copyData(props.data?.txnHash)} @@ -135,7 +138,7 @@ const TXDetails = (props: IProps) => { gap="spacing-xxxs" > Block Hash - + { > From -
+
@@ -168,7 +168,9 @@ const TxTravels = (props: IProps) => { > {displayedRecipients.map((recipient, index) => ( -
+ +
+ From c84fb9a81a30183e3d2a655cc33bead786a848b5 Mon Sep 17 00:00:00 2001 From: rozaso Date: Fri, 11 Oct 2024 07:52:43 -0700 Subject: [PATCH 32/42] fix: revert back the spacing. --- blocks/theme/variables/variables.spacing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blocks/theme/variables/variables.spacing.ts b/blocks/theme/variables/variables.spacing.ts index 13fd802..aefd530 100644 --- a/blocks/theme/variables/variables.spacing.ts +++ b/blocks/theme/variables/variables.spacing.ts @@ -10,5 +10,5 @@ export const spacingVariables = { 'spacing-xxl': '48px', 'spacing-xxxl': '64px', 'spacing-xxxxl': '128px', - 'spacing-xxxxxl': '148px', + 'spacing-xxxxxl': '168px', }; From 123b7d513819e651e0a4989fb893563b0c5c943b Mon Sep 17 00:00:00 2001 From: rozaso Date: Fri, 11 Oct 2024 07:56:55 -0700 Subject: [PATCH 33/42] Fix: Header responsiveness. --- blocks/theme/variables/variables.spacing.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blocks/theme/variables/variables.spacing.ts b/blocks/theme/variables/variables.spacing.ts index aefd530..13fd802 100644 --- a/blocks/theme/variables/variables.spacing.ts +++ b/blocks/theme/variables/variables.spacing.ts @@ -10,5 +10,5 @@ export const spacingVariables = { 'spacing-xxl': '48px', 'spacing-xxxl': '64px', 'spacing-xxxxl': '128px', - 'spacing-xxxxxl': '168px', + 'spacing-xxxxxl': '148px', }; From c8950c108e883952570dc14bb30d391400b59c3c Mon Sep 17 00:00:00 2001 From: abhishek-01k Date: Mon, 21 Oct 2024 19:00:16 +0530 Subject: [PATCH 34/42] Fixed UI Fixes for push scan --- .yarn/install-state.gz | Bin 0 -> 495266 bytes blocks/icons/components/Discord.tsx | 37 + blocks/icons/components/Github.tsx | 37 + blocks/icons/components/Telegram.tsx | 37 + blocks/icons/components/Twitter.tsx | 30 + blocks/icons/index.ts | 7 + blocks/tooltip/Tooltip.tsx | 10 +- common/Common.constants.ts | 29 + common/index.ts | 3 +- components/Blocks/Details.tsx | 256 +- components/Footer/index.tsx | 107 +- components/Home/LiveBlocks.tsx | 13 +- components/Home/LiveTransactions.tsx | 3 +- components/Home/OverView.tsx | 3 +- components/Home/SearchBar.tsx | 10 +- components/Navbar/index.tsx | 119 +- components/Reusables/AddressComponent.tsx | 156 +- components/Reusables/BlockHashLink.tsx | 6 +- components/Reusables/TxHashLink.tsx | 110 +- components/Transactions/ListView.tsx | 8 +- components/Transactions/TxDetails.tsx | 353 +- layout/index.tsx | 5 +- sections/Home/index.tsx | 3 + sections/Transactions/txHash.tsx | 4 +- yarn.lock | 9321 ++++++++++++--------- 25 files changed, 6372 insertions(+), 4295 deletions(-) create mode 100644 .yarn/install-state.gz create mode 100644 blocks/icons/components/Discord.tsx create mode 100644 blocks/icons/components/Github.tsx create mode 100644 blocks/icons/components/Telegram.tsx create mode 100644 blocks/icons/components/Twitter.tsx create mode 100644 common/Common.constants.ts diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz new file mode 100644 index 0000000000000000000000000000000000000000..1b38ade22c6a83a259b0dcfebe7d890c1340bb25 GIT binary patch literal 495266 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 G-WUJ^y)R?{ literal 0 HcmV?d00001 diff --git a/blocks/icons/components/Discord.tsx b/blocks/icons/components/Discord.tsx new file mode 100644 index 0000000..f9b4ce8 --- /dev/null +++ b/blocks/icons/components/Discord.tsx @@ -0,0 +1,37 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Discord: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Discord; diff --git a/blocks/icons/components/Github.tsx b/blocks/icons/components/Github.tsx new file mode 100644 index 0000000..2668ffe --- /dev/null +++ b/blocks/icons/components/Github.tsx @@ -0,0 +1,37 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Github: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Github; diff --git a/blocks/icons/components/Telegram.tsx b/blocks/icons/components/Telegram.tsx new file mode 100644 index 0000000..1f0eef2 --- /dev/null +++ b/blocks/icons/components/Telegram.tsx @@ -0,0 +1,37 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Telegram: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default Telegram; diff --git a/blocks/icons/components/Twitter.tsx b/blocks/icons/components/Twitter.tsx new file mode 100644 index 0000000..6ce05b8 --- /dev/null +++ b/blocks/icons/components/Twitter.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const Twitter: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + } + {...restProps} + /> + ); +}; + +export default Twitter; diff --git a/blocks/icons/index.ts b/blocks/icons/index.ts index ecb14ee..be0c06e 100644 --- a/blocks/icons/index.ts +++ b/blocks/icons/index.ts @@ -56,6 +56,8 @@ export { default as Dash } from './components/Dash'; export { default as Dashboard } from './components/Dashboard'; +export { default as Discord } from './components/Discord'; + export { default as EditProfile } from './components/EditProfile'; export { default as EtheriumMonotone } from './components/EtheriumMonotone'; @@ -80,6 +82,8 @@ export { default as GovernanceFilled } from './components/GovernanceFilled'; export { default as Group } from './components/Group'; export { default as GroupFilled } from './components/GroupFilled'; +export { default as Github } from './components/Github'; + export { default as InboxBell } from './components/InboxBell'; export { default as EmptyInbox } from './components/EmptyInbox'; export { default as InboxBellFilled } from './components/InboxBellFilled'; @@ -160,6 +164,9 @@ export { default as Tick } from './components/Tick'; export { default as TickCircleFilled } from './components/TickCircleFilled'; export { default as TickDecoratedCircleFilled } from './components/TickDecoratedCircleFilled'; +export { default as Twitter } from './components/Twitter'; +export { default as Telegram } from './components/Telegram'; + export { default as UserFilled } from './components/UserFilled'; export { default as UserSwitch } from './components/UserSwitch'; diff --git a/blocks/tooltip/Tooltip.tsx b/blocks/tooltip/Tooltip.tsx index 70c510b..dc495a2 100644 --- a/blocks/tooltip/Tooltip.tsx +++ b/blocks/tooltip/Tooltip.tsx @@ -1,11 +1,11 @@ -import React, { type FC, useRef, useState } from 'react'; +import React,{ type FC, useRef, useState } from 'react'; import styled from 'styled-components'; import * as RadixTooltip from '@radix-ui/react-tooltip'; import type { TooltipProps } from './Tooltip.types'; import { getTooltipPositionalCSS } from './Tooltip.utils'; import { tooltipCSSPropsKeys } from './Tooltip.constants'; -import { useIsVisible } from '../../common'; import { textVariants } from '../text'; +import { useIsVisible } from '../../common'; const RadixTooltipContent = styled(RadixTooltip.Content).withConfig({ shouldForwardProp: (prop) => !tooltipCSSPropsKeys.includes(prop as keyof TooltipProps), @@ -13,9 +13,9 @@ const RadixTooltipContent = styled(RadixTooltip.Content).withConfig({ /* Tooltip default styles */ display: flex; flex-direction: column; - gap: var(--s1); - padding: var(--s2); - border-radius: var(--r3); + gap: var(--spacing-xxxs); + padding: var(--spacing-xxs); + border-radius: var(--radius-xs); font-family: var(--font-family); word-wrap: break-word; color: var(--text-primary-inverse); diff --git a/common/Common.constants.ts b/common/Common.constants.ts new file mode 100644 index 0000000..333b40a --- /dev/null +++ b/common/Common.constants.ts @@ -0,0 +1,29 @@ +import { FC } from 'react'; +import { + ArbitrumMonotone, + BnbMonotone, + EtheriumMonotone, + IconProps, + OptimismMonotone, + PolygonMonotone, + PushMonotone, +} from '../blocks/icons'; + +export const CHAIN_LOGO: { + [x: number | string]: FC; +} = { + 1: EtheriumMonotone, + 11155111: EtheriumMonotone, + 137: PolygonMonotone, + 80002: PolygonMonotone, + 97: BnbMonotone, + 56: BnbMonotone, + 42161: ArbitrumMonotone, + 421614: ArbitrumMonotone, + 11155420: OptimismMonotone, + 10: OptimismMonotone, + 2442: PolygonMonotone, + 1101: PolygonMonotone, + '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': OptimismMonotone, + devnet: PushMonotone, +}; diff --git a/common/index.ts b/common/index.ts index dba93b5..2c2603c 100644 --- a/common/index.ts +++ b/common/index.ts @@ -1,2 +1,3 @@ export * from './hooks'; -export * from './components'; \ No newline at end of file +export * from './components'; +export * from './Common.constants'; diff --git a/components/Blocks/Details.tsx b/components/Blocks/Details.tsx index 0986410..591e501 100644 --- a/components/Blocks/Details.tsx +++ b/components/Blocks/Details.tsx @@ -1,127 +1,167 @@ +// React, NextJS imports import React, { useState } from 'react'; -import { Box, Text, Tooltip, Copy } from '../../blocks'; + +// External Components imports +import { css } from 'styled-components'; import moment from 'moment'; -import { BlockDetails } from '../../types/block' -import { getValidatorNode } from '../../utils/helpers' + +// Internal Components imports +import { Box, Text, Tooltip, Copy } from '../../blocks'; +import { BlockDetails } from '../../types/block'; +import { getValidatorNode } from '../../utils/helpers'; interface IProps { - data: BlockDetails | null | undefined, - isLoading: boolean + data: BlockDetails | null | undefined; + isLoading: boolean; } const Details = (props: IProps) => { - const [tooltipText, setToolTipText] = useState('Copy'); + const [tooltipText, setToolTipText] = useState('Copy'); - let dateTime = '' - if (props.data?.ts) { - const timestamp = (props.data?.ts / 1000) - const formattedTime = moment.unix(timestamp).utc().fromNow(); // "40 minutes ago" - const detailedTime = moment.unix(timestamp).utc().format('ddd, MMM DD YYYY HH:mm:ss [GMT]'); // "Sun, Jul 21 2024 18:33:47 GMT" - dateTime = `${formattedTime}, ${detailedTime}` - } + let dateTime = ''; + if (props.data?.ts) { + const timestamp = props.data?.ts / 1000; + const formattedTime = moment.unix(timestamp).utc().fromNow(); // "40 minutes ago" + const detailedTime = moment + .unix(timestamp) + .utc() + .format('ddd, MMM DD YYYY HH:mm:ss [GMT]'); // "Sun, Jul 21 2024 18:33:47 GMT" + dateTime = `${formattedTime}, ${detailedTime}`; + } - const copyData = (value) => { - navigator.clipboard.writeText(value); - setToolTipText('Copied'); - - setTimeout(() => { - setToolTipText('Copy'); - }, 1000); - }; + const copyData = (value) => { + navigator.clipboard.writeText(value); + setToolTipText('Copied'); - return ( - <> - - - Block Hash - Validator - Timestamp - + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; - - - { props.data?.blockHash } - - - - copyData(props.data?.blockHash)} - autoSize - size={24} - color="icon-tertiary" - /> - - - - - - { getValidatorNode(props.data?.blockDataAsJson) } - { dateTime } + return ( + <> + + + <> + + {props.data?.blockHash} + + + + + copyData(props.data?.blockHash)} + autoSize + size={24} + color="icon-tertiary" + /> + + + + + + {getValidatorNode(props.data?.blockDataAsJson)} + + + + + {dateTime} + + + - - - Block Hash - - - { props.data?.blockHash } - - - + {/* Mobile View */} + + + + Block Hash + - - Validator - { getValidatorNode(props.data?.signers) } - + + + {props.data?.blockHash} + + + - - Timestamp - { dateTime } + + + Validator + + + + {getValidatorNode(props.data?.signers)} + + + - - - - ); + + + Timestamp + + + {dateTime} + + + + + ); }; -export default Details; \ No newline at end of file +export default Details; + +const DetailRow = ({ label, children }) => ( + + + + {label} + + + + {children} + + +); diff --git a/components/Footer/index.tsx b/components/Footer/index.tsx index c3a3c85..e2fd363 100644 --- a/components/Footer/index.tsx +++ b/components/Footer/index.tsx @@ -1,22 +1,22 @@ // React, NextJS imports import React, { useEffect, useState } from 'react'; -import Image from 'next/image'; +import Link from 'next/link'; // External Library imports -import { useTheme as Theme } from '../../contexts/ThemeContext'; -import TwitterIconDark from "../../public/static/X-dark.svg"; -import TwitterIconLight from "../../public/static/X.svg"; -import GithubIconDark from "../../public/static/github-dark.svg"; -import GithubIconLight from "../../public/static/github.svg"; -import TelegramIconDark from "../../public/static/telegram-dark.svg"; -import TelegramIconLight from "../../public/static/telegram.svg"; -import DiscordIconDark from "../../public/static/discord-dark.svg"; -import DiscordIconLight from "../../public/static/discord.svg"; +import { css } from 'styled-components'; import { getHeathCheck } from '../../utils/api'; -import { Box, Text, TickCircleFilled, CrossFilled, Link } from '../../blocks'; +import { + Box, + Text, + TickCircleFilled, + CrossFilled, + Twitter, + Github, + Telegram, + Discord, +} from '../../blocks'; export default function Footer() { - const { isDarkMode } = Theme(); const [data, setData] = useState(true); const [isLoading, setIsLoading] = React.useState(false); @@ -25,7 +25,7 @@ export default function Footer() { setIsLoading(true); try { const res = await getHeathCheck(); - setData(res.status === "OK"); + setData(res.status === 'OK'); } catch (e) { console.log('Error occured', e); } @@ -33,80 +33,59 @@ export default function Footer() { })(); }, []); - return ( - - + - - - + + - - - + + - - - - + + + - - + + - - { data ? : } - { data ? 'All systems operational' : 'Not all system are operational' } + + {data ? ( + + ) : ( + + )} + + {data ? 'All systems operational' : 'Not all system are operational'} + ); diff --git a/components/Home/LiveBlocks.tsx b/components/Home/LiveBlocks.tsx index fbb1dfd..10b13b2 100644 --- a/components/Home/LiveBlocks.tsx +++ b/components/Home/LiveBlocks.tsx @@ -1,11 +1,16 @@ +// React, NextJS imports import React from 'react'; -import { Box, Text, Front, Table } from '../../blocks'; -import { useRouter } from 'next/router' import Link from 'next/link' +import { useRouter } from 'next/router' + +// External Components imports +import { css, useTheme } from 'styled-components'; + +// Internal Components imports +import { Box, Text, Front, Table } from '../../blocks'; import { useLiveBlocks } from '../../hooks/useBlocks'; import { getValidatorNode } from '../../utils/helpers' import { centerMaskString, fromNow } from '../../utils/helpers' -import { useTheme } from 'styled-components'; import BlockHashLink from '../Reusables/BlockHashLink' export default function LiveBlocks() { @@ -60,7 +65,7 @@ export default function LiveBlocks() { return ( { const from = JSON.parse(params); - return
+ return
}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', @@ -54,7 +54,6 @@ export default function LiveTransactions() { const reci = recipients.split(',') return ( diff --git a/components/Home/OverView.tsx b/components/Home/OverView.tsx index e1284ec..8cb8088 100644 --- a/components/Home/OverView.tsx +++ b/components/Home/OverView.tsx @@ -1,4 +1,5 @@ import React, { FC } from 'react'; +import { css } from 'styled-components'; import { Box, Text, Separator, Skeleton } from '../../blocks'; import { useCounts } from '../../hooks/useCounts'; @@ -87,7 +88,7 @@ const OverView: FC = () => { align-items="flex-start" gap="spacing-xxxs" padding="spacing-none spacing-lg spacing-none spacing-lg" - css={`border-left: var(--border-sm) solid var(--stroke-tertiary);`} + css={css`border-left: var(--border-sm) solid var(--stroke-tertiary);`} > Daily Transactions {data?.dailyTransactions} diff --git a/components/Home/SearchBar.tsx b/components/Home/SearchBar.tsx index 30ababf..394464c 100644 --- a/components/Home/SearchBar.tsx +++ b/components/Home/SearchBar.tsx @@ -1,9 +1,13 @@ +// React, NextJS imports import React, { useCallback, useState, useEffect } from 'react'; -import { TextInput, Search } from '../../blocks'; -import { ethers } from 'ethers'; +import { useRouter } from 'next/router' import { useDebounce } from 'react-use'; + +import { ethers } from 'ethers'; + +// Internal Components imports +import { TextInput, Search } from '../../blocks'; import { useSearchByAddress } from '../../hooks/useSearchByAddress'; -import { useRouter } from 'next/router' export default function SearchBar() { const router = useRouter() diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index 064f6a8..def99b7 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -1,22 +1,20 @@ // React, NextJS imports import React from 'react'; import { useRouter } from 'next/router'; -import Image from 'next/image'; +import Link from 'next/link'; // External Library imports import { DarkModeSwitch } from 'react-toggle-dark-mode'; -import { Button, useMediaQuery } from '@mui/material'; -import { useTheme } from 'styled-components'; +import { useMediaQuery } from '@mui/material'; +import { css, useTheme } from 'styled-components'; // Internal Components imports import { useTheme as Theme } from '../../contexts/ThemeContext'; import { useData } from '../../contexts/DataContext'; import { ROUTES, CREDENTIALKEYS } from '../../utils/constants'; import { ThemeType } from '../../types/theme'; -import { Box, Text, Lozenge, MoonFilled, PushLogo } from '../../blocks'; -import SearchBar from '../Home/SearchBar' -import ChainsDropDown from '../Reusables/ChainsDropDown' -import Link from 'next/link' +import { Box, Text, Lozenge,PushLogo } from '../../blocks'; +import SearchBar from '../Home/SearchBar'; export default function Navbar() { const { isDarkMode, darkModeToggle } = Theme(); @@ -38,74 +36,77 @@ export default function Navbar() { return ( router.push('/home')} > - router.push('/home')} - > - - PushScan - - ALPHA - - + + + PushScan + - - { asPath !== '/dashboard' && ( - - Analytics - - )} - - - - { asPath !== '/home' && ( - - - - )} + + ALPHA + - { asPath === '/home' && Push Blockchain Explorer } - + {asPath !== '/dashboard' && ( + + + Analytics + + + )} + + + + {asPath !== '/home' && ( + + + + )} ); diff --git a/components/Reusables/AddressComponent.tsx b/components/Reusables/AddressComponent.tsx index ecce9ad..087f535 100644 --- a/components/Reusables/AddressComponent.tsx +++ b/components/Reusables/AddressComponent.tsx @@ -1,81 +1,117 @@ import React, { useState } from 'react'; -import { Box, Text } from '../../blocks'; -import { EtheriumMonotone, BnbMonotone, PolygonMonotone, PushMonotone, ArbitrumMonotone, OptimismMonotone } from '../../blocks/icons' -import { convertCaipToObject, centerMaskString } from '../../utils/helpers' -import Link from 'next/link' +import { Box, Text, Tooltip } from '../../blocks'; +import { + PushMonotone, + TickCircleFilled, + Copy, +} from '../../blocks/icons'; +import { convertCaipToObject, centerMaskString } from '../../utils/helpers'; +import Link from 'next/link'; import styled from 'styled-components'; +import { CHAIN_LOGO } from '../../common'; -const Address = ({ address, wrap = false, masking = true }) => { - function getChainIcon(chainId) { - try { - if (!chainId) { - return - } - - switch(Number(chainId)) { - case 1: - case 11155111: - return - case 137: - case 80002: - case 1101: - case 2442: - return - case 56: - case 97: - return - case 42161: - case 421614: - return - case 10: - case 11155420: - return - default: - return - } - } catch (err) { - return - } +const Address = ({ address, wrap = false, masking = true, allowCopy=false }) => { + function getChainIcon(chainId) { + try { + if (!chainId) { + return ; + } + + const IconComponent = CHAIN_LOGO[chainId]; + return ; + } catch (err) { + return ; } + } + + const { result } = convertCaipToObject(address); + + const maskedAddress = masking + ? centerMaskString(result.address) + : result.address; - const { result } = convertCaipToObject(address) + const [tooltipText, setToolTipText] = useState('Copy'); - const maskedAddress = masking ? centerMaskString(result.address) : result.address; + const copyData = () => { + navigator.clipboard.writeText(address); + setToolTipText('Copied'); + + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; - return ( - - {result.chainId && getChainIcon(result.chainId)} - - - {maskedAddress} - - - - ); + return ( + + {result.chainId && getChainIcon(result.chainId)} + + + {maskedAddress} + + + {allowCopy && ( + + + {tooltipText === 'Copied' ? ( + + ) : ( + + )} + + + )} + + ); }; const AddressLink = styled(Link)` - pointer-events: none; - text-decoration: none; + pointer-events: none; + text-decoration: none; `; const AddressText = styled(Text)` - color: var(--text-primary); + color: var(--text-primary); +`; + +const CopyIconButton = styled.button` + opacity: 0; + pointer-events: none; + transition: opacity 0.2s ease-in-out; + display: flex; + justify-content: flex-end; + align-items: center; + background: none; + border: none; + cursor: pointer; + padding: 0; `; const AddressContainer = styled(Box)` - display: flex; - flex-direction: row; - gap: 8px; - align-items: center; + display: flex; + flex-direction: row; + gap: var(--spacing-xxs, 8px); + align-items: center; - &:hover ${/* sc-selector */ AddressLink} { - pointer-events: auto; - } + &:hover ${AddressLink} { + pointer-events: auto; + } - &:hover ${/* sc-selector */ AddressText} { - color: var(--text-brand-medium); - } + &:hover ${AddressText} { + color: var(--text-brand-medium); + } + + &:hover ${CopyIconButton} { + opacity: 1; + pointer-events: auto; + } + + `; + + export default Address; diff --git a/components/Reusables/BlockHashLink.tsx b/components/Reusables/BlockHashLink.tsx index 5dfac51..1edb1cd 100644 --- a/components/Reusables/BlockHashLink.tsx +++ b/components/Reusables/BlockHashLink.tsx @@ -4,7 +4,7 @@ import { rightMaskString } from '../../utils/helpers'; import Link from 'next/link'; import styled from 'styled-components'; -const BlockHashLinkComponent = ({ blockHash, masking = false }) => { +const BlockHashLinkComponent = ({ blockHash, masking = false, allowCopy = false }) => { const [tooltipText, setToolTipText] = useState('Copy'); const maskedBlockHash = masking ? rightMaskString(blockHash) : blockHash; @@ -25,7 +25,7 @@ const BlockHashLinkComponent = ({ blockHash, masking = false }) => { {maskedBlockHash} - + {allowCopy && { color="icon-tertiary" /> - + } ); }; diff --git a/components/Reusables/TxHashLink.tsx b/components/Reusables/TxHashLink.tsx index 385d149..bfb8852 100644 --- a/components/Reusables/TxHashLink.tsx +++ b/components/Reusables/TxHashLink.tsx @@ -1,81 +1,81 @@ import React, { useState } from 'react'; -import { Box, Text, Tooltip, Copy } from '../../blocks'; -import { rightMaskString } from '../../utils/helpers' -import Link from 'next/link' +import { Box, Text, Tooltip, Copy, TickCircleFilled } from '../../blocks'; +import { rightMaskString } from '../../utils/helpers'; +import Link from 'next/link'; import styled from 'styled-components'; -const TxHashLinkComponent = ({ txHash }) => { - const [tooltipText, setToolTipText] = useState('Copy'); +const TxHashLinkComponent = ({ txHash, allowCopy = false }) => { + const [tooltipText, setToolTipText] = useState('Copy'); - const copyData = () => { - navigator.clipboard.writeText(txHash); - setToolTipText('Copied'); + const copyData = () => { + navigator.clipboard.writeText(txHash); + setToolTipText('Copied'); - setTimeout(() => { - setToolTipText('Copy'); - }, 1000); - }; + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; - return ( - - - - {rightMaskString(txHash)} - - + return ( + + + {rightMaskString(txHash)} + + {allowCopy && ( - - + {tooltipText === 'Copied' ? ( + - + size={16} + color="icon-state-success-bold" + /> + ) : ( + + )} + - - ); + )} + + ); }; - const CopyIconButton = styled.button` - opacity: 0; - pointer-events: none; - transition: opacity 0.2s ease-in-out; - display: flex; - justify-content: flex-end; - align-items: center; - background: none; - border: none; - cursor: pointer; - padding: 0; + opacity: 0; + pointer-events: none; + transition: opacity 0.2s ease-in-out; + display: flex; + justify-content: flex-end; + align-items: center; + background: none; + border: none; + cursor: pointer; + padding: 0; `; const TxHashText = styled(Text)` - color: var(--text-primary); - transition: color 0.2s ease-in-out; + color: var(--text-primary); + transition: color 0.2s ease-in-out; `; const TxHashLinkStyled = styled(Link)` - text-decoration: none; + text-decoration: none; `; const TxHashContainer = styled(Box)` - display: flex; - flex-direction: row; - gap: spacing-xxs; - align-items: center; + display: flex; + flex-direction: row; + gap: spacing-xxs; + align-items: center; - &:hover ${CopyIconButton}, - &:focus-within ${CopyIconButton} { - opacity: 1; - pointer-events: auto; - } + &:hover ${CopyIconButton} { + opacity: 1; + pointer-events: auto; + } - &:hover ${TxHashText}, - &:focus-within ${TxHashText} { - color: var(--text-brand-medium); - } + &:hover ${TxHashText} { + color: var(--text-brand-medium); + } `; - export default TxHashLinkComponent; diff --git a/components/Transactions/ListView.tsx b/components/Transactions/ListView.tsx index e36c323..647ff5c 100644 --- a/components/Transactions/ListView.tsx +++ b/components/Transactions/ListView.tsx @@ -40,7 +40,7 @@ const ListView = (props: IProps) => { { title: 'TX HASH', dataIndex: 'txHash', - render: (txHash: string) => , + render: (txHash: string) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '165px' @@ -48,7 +48,7 @@ const ListView = (props: IProps) => { { title: 'BLOCK HASH', dataIndex: 'blockHash', - render: (blockHash: string) => , + render: (blockHash: string) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '165px' @@ -58,7 +58,7 @@ const ListView = (props: IProps) => { dataIndex: 'from', render: (params) => { const from = JSON.parse(params); - return
+ return
}, cellAlignment: 'flex-start', headerAlignment: 'flex-start', @@ -74,7 +74,7 @@ const ListView = (props: IProps) => { display="flex" flexDirection="column" > -
+
{ reci.length > 1 && {`+ ${reci.length - 1} more`}} )}, diff --git a/components/Transactions/TxDetails.tsx b/components/Transactions/TxDetails.tsx index 956f6cb..bc1ebce 100644 --- a/components/Transactions/TxDetails.tsx +++ b/components/Transactions/TxDetails.tsx @@ -1,166 +1,227 @@ +// React, NextJS imports import React, { useState } from 'react'; -import { Box, Text, Tag, Tooltip, Copy } from '../../blocks'; -import { Transaction } from '../../types/transaction'; + +// External Components imports +import { css } from 'styled-components'; import moment from 'moment'; + +// Internal Components imports +import { Box, Text, Tag, Tooltip, Copy } from '../../blocks'; +import { Tick } from '../../blocks/icons'; import { TagVariant } from '../../blocks/tag'; -import { Tick } from '../../blocks/icons' -import BlockHashLink from '../Reusables/BlockHashLink' -import { capitalizeStr } from '../../utils/helpers' +import { Transaction } from '../../types/transaction'; +import BlockHashLink from '../Reusables/BlockHashLink'; +import { capitalizeStr } from '../../utils/helpers'; interface IProps { - data: Transaction | null | undefined, - isLoading: boolean + data: Transaction | null | undefined; + isLoading: boolean; } const TXDetails = (props: IProps) => { - let status: TagVariant = "default" - const [tooltipText, setToolTipText] = useState('Copy'); - - if (props.data?.status) { - status = props.data.status.toLowerCase() as TagVariant - } - - let dateTime = '' - if (props.data?.ts) { - const timestamp = (props.data?.ts / 1000) - const formattedTime = moment.unix(timestamp).utc().fromNow(); // "40 minutes ago" - const detailedTime = moment.unix(timestamp).utc().format('ddd, MMM DD YYYY HH:mm:ss [GMT]'); // "Sun, Jul 21 2024 18:33:47 GMT" - dateTime = `${formattedTime}, ${detailedTime}` - } - - const copyData = (value) => { - navigator.clipboard.writeText(value); - setToolTipText('Copied'); - - setTimeout(() => { - setToolTipText('Copy'); - }, 1000); - }; - - - return ( - <> - - - Transaction Hash - Status - Block Hash - Category - Timestamp - + let status: TagVariant = 'default'; + const [tooltipText, setToolTipText] = useState('Copy'); + + if (props.data?.status) { + status = props.data.status.toLowerCase() as TagVariant; + } + + let dateTime = ''; + if (props.data?.ts) { + const timestamp = props.data?.ts / 1000; + const formattedTime = moment.unix(timestamp).utc().fromNow(); // "40 minutes ago" + const detailedTime = moment + .unix(timestamp) + .utc() + .format('ddd, MMM DD YYYY HH:mm:ss [GMT]'); // "Sun, Jul 21 2024 18:33:47 GMT" + dateTime = `${formattedTime}, ${detailedTime}`; + } + + const copyData = (value) => { + navigator.clipboard.writeText(value); + setToolTipText('Copied'); + + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; - - - {props.data?.txnHash} - - - - copyData(props.data?.txnHash)} - autoSize - size={24} - color="icon-tertiary" - /> - - - - - - } label={capitalizeStr(status)} variant={status}> - - {props.data?.category} - {dateTime} + return ( + <> + + + + + {props.data?.txnHash} + + + + + copyData(props.data?.txnHash)} + autoSize + size={24} + color="icon-tertiary" + /> + + + + + } + label={capitalizeStr(status)} + variant={status} + > + + + + + + + + {props.data?.category} + + + + + + {dateTime} + + + + + {/* Mobile View */} + + + + Transaction Hash + + - - Transaction Hash - - - {props.data?.txnHash} - - - copyData(props.data?.txnHash)} - autoSize - size={24} - color="icon-tertiary" - /> - - - - - - Status - } label={capitalizeStr(status)} variant={status}> + + {props.data?.txnHash} + + + + copyData(props.data?.txnHash)} + autoSize + size={24} + color="icon-tertiary" + /> + + + - + + + Status + + } + label={capitalizeStr(status)} + variant={status} + > + - - Block Hash - - + + + Block Hash + + + + + - - Category - {props.data?.category} - + + + Category{' '} + + + {props.data?.category} + + - - Timestamp - { dateTime } - - - - ); + + + Timestamp + + + {dateTime} + + + + + ); }; -export default TXDetails; \ No newline at end of file +export default TXDetails; + +const DetailRow = ({ label, children }) => ( + + + + {label} + + + + {children} + + +); diff --git a/layout/index.tsx b/layout/index.tsx index e6d9df6..3d633bc 100644 --- a/layout/index.tsx +++ b/layout/index.tsx @@ -1,8 +1,11 @@ +// React, NextJS imports import React from 'react'; + +// Internal Components imports import { Box } from '../blocks'; +import { ContentLayout } from '../common' import FooterSection from '../sections/Footer'; import HeaderSection from '../sections/Header'; -import { ContentLayout } from '../common' export default function Layout({ children }) { return ( diff --git a/sections/Home/index.tsx b/sections/Home/index.tsx index 0543900..021d4ab 100644 --- a/sections/Home/index.tsx +++ b/sections/Home/index.tsx @@ -1,4 +1,7 @@ +// React, NextJS imports import React from 'react'; + +// Internal Components imports import { Box, Text } from '../../blocks'; import SearchBar from '../../components/Home/SearchBar' import OverView from '../../components/Home/OverView' diff --git a/sections/Transactions/txHash.tsx b/sections/Transactions/txHash.tsx index 1768144..c2cbdf1 100644 --- a/sections/Transactions/txHash.tsx +++ b/sections/Transactions/txHash.tsx @@ -1,11 +1,13 @@ import React, { useState } from 'react'; + +import { useRouter } from 'next/router'; + import { Box, Text, Spinner } from '../../blocks'; import Advanced from '../../components/Reusables/Advanced'; import ConsensusInfo from '../../components/Transactions/ConsensusInfo'; import TXDetails from '../../components/Transactions/TxDetails' import TxTravels from '../../components/Transactions/TxTravels' import { useLiveTxByHash } from '../../hooks/useLiveTxByHash'; -import { useRouter } from 'next/router'; const Details = () => { const router = useRouter(); diff --git a/yarn.lock b/yarn.lock index 207f5e1..f80982b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,3778 +1,5543 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@adraffy/ens-normalize@1.10.1": - version "1.10.1" - resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" - integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/generator@^7.20.0": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.20.0.tgz" - integrity sha512-GUPcXxWibClgmYJuIwC2Bc2Lg+8b9VjaJ+HlNdACEVt+Wlr1eoU1OPZjZRm7Hzl0gaTsUZNQfeihvZJhG7oc3w== - dependencies: - "@babel/types" "^7.20.0" - "@jridgewell/gen-mapping" "^0.3.2" - jsesc "^2.5.1" - -"@babel/helper-annotate-as-pure@^7.16.0": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz" - integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== - -"@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== - dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" - -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.16.0", "@babel/helper-module-imports@^7.16.7": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-plugin-utils@^7.18.6": - version "7.19.0" - resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz" - integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== - -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== - -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.18.10", "@babel/parser@^7.20.0": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.20.0.tgz" - integrity sha512-G9VgAhEaICnz8iiJeGJQyVl6J2nTjbW0xeisva0PK6XcKsga7BIaqm4ZF8Rg1Wbaqmy6znspNqhPaPkyukujzg== - -"@babel/plugin-syntax-jsx@^7.17.12": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz" - integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/runtime-corejs3@^7.10.2": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.20.0.tgz" - integrity sha512-v1JH7PeAAGBEyTQM9TqojVl+b20zXtesFKCJHu50xMxZKD1fX0TKaKHPsZfFkXfs7D1M9M6Eeqg1FkJ3a0x2dA== - dependencies: - core-js-pure "^3.25.1" - regenerator-runtime "^0.13.10" - -"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.4.tgz#6ef37d678428306e7d75f054d5b1bdb8cf8aa8ee" - integrity sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.19.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.0.tgz" - integrity sha512-NDYdls71fTXoU8TZHfbBWg7DiZfNzClcKui/+kyi6ppD2L1qnWW3VV6CjtaBXSUGGhiTWJ6ereOIkUvenif66Q== - dependencies: - regenerator-runtime "^0.13.10" - -"@babel/runtime@^7.23.8", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb" - integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/template@^7.18.10": - version "7.18.10" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz" - integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.10" - "@babel/types" "^7.18.10" - -"@babel/traverse@^7.4.5": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.0.tgz" - integrity sha512-5+cAXQNARgjRUK0JWu2UBwja4JLSO/rBMPJzpsKb+oBF5xlUuCfljQepS4XypBQoiigL0VQjTZy6WiONtUdScQ== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.0" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.20.0" - "@babel/types" "^7.20.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.0": - version "7.20.0" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.20.0.tgz" - integrity sha512-Jlgt3H0TajCW164wkTOTzHkZb075tMQMULzrLUoUeKmO7eFL96GgDxf7/Axhc5CAuKE3KFyVW1p6ysKsi2oXAg== - dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" - to-fast-properties "^2.0.0" - -"@emotion/babel-plugin@^11.10.5": - version "11.10.5" - resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.5.tgz" - integrity sha512-xE7/hyLHJac7D2Ve9dKroBBZqBT7WuPQmWcq7HSGb84sUuP4mlOWoB8dvVfD9yk5DHkU1m6RW7xSoDtnQHNQeA== - dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/plugin-syntax-jsx" "^7.17.12" - "@babel/runtime" "^7.18.3" - "@emotion/hash" "^0.9.0" - "@emotion/memoize" "^0.8.0" - "@emotion/serialize" "^1.1.1" - babel-plugin-macros "^3.1.0" - convert-source-map "^1.5.0" - escape-string-regexp "^4.0.0" - find-root "^1.1.0" - source-map "^0.5.7" - stylis "4.1.3" - -"@emotion/cache@^11.10.3", "@emotion/cache@^11.10.5": - version "11.10.5" - resolved "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.5.tgz" - integrity sha512-dGYHWyzTdmK+f2+EnIGBpkz1lKc4Zbj2KHd4cX3Wi8/OWr5pKslNjc3yABKH4adRGCvSX4VDC0i04mrrq0aiRA== - dependencies: - "@emotion/memoize" "^0.8.0" - "@emotion/sheet" "^1.2.1" - "@emotion/utils" "^1.2.0" - "@emotion/weak-memoize" "^0.3.0" - stylis "4.1.3" - -"@emotion/hash@^0.9.0": - version "0.9.0" - resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz" - integrity sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ== - -"@emotion/is-prop-valid@^1.1.0", "@emotion/is-prop-valid@^1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz" - integrity sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg== - dependencies: - "@emotion/memoize" "^0.8.0" - -"@emotion/memoize@^0.8.0": - version "0.8.0" - resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz" - integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== - -"@emotion/react@^11.10.5": - version "11.10.5" - resolved "https://registry.npmjs.org/@emotion/react/-/react-11.10.5.tgz" - integrity sha512-TZs6235tCJ/7iF6/rvTaOH4oxQg2gMAcdHemjwLKIjKz4rRuYe1HJ2TQJKnAcRAfOUDdU8XoDadCe1rl72iv8A== - dependencies: - "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.10.5" - "@emotion/cache" "^11.10.5" - "@emotion/serialize" "^1.1.1" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" - "@emotion/utils" "^1.2.0" - "@emotion/weak-memoize" "^0.3.0" - hoist-non-react-statics "^3.3.1" - -"@emotion/serialize@^1.1.1": - version "1.1.1" - resolved "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz" - integrity sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA== - dependencies: - "@emotion/hash" "^0.9.0" - "@emotion/memoize" "^0.8.0" - "@emotion/unitless" "^0.8.0" - "@emotion/utils" "^1.2.0" - csstype "^3.0.2" - -"@emotion/sheet@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz" - integrity sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA== - -"@emotion/styled@^11.10.5": - version "11.10.5" - resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.5.tgz" - integrity sha512-8EP6dD7dMkdku2foLoruPCNkRevzdcBaY6q0l0OsbyJK+x8D9HWjX27ARiSIKNF634hY9Zdoedh8bJCiva8yZw== - dependencies: - "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.10.5" - "@emotion/is-prop-valid" "^1.2.0" - "@emotion/serialize" "^1.1.1" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" - "@emotion/utils" "^1.2.0" - -"@emotion/stylis@^0.8.4": - version "0.8.5" - resolved "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz" - integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== - -"@emotion/unitless@^0.7.4": - version "0.7.5" - resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz" - integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== - -"@emotion/unitless@^0.8.0": - version "0.8.0" - resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz" - integrity sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw== - -"@emotion/use-insertion-effect-with-fallbacks@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz" - integrity sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A== - -"@emotion/utils@^1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz" - integrity sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw== - -"@emotion/weak-memoize@^0.3.0": - version "0.3.0" - resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz" - integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== - -"@eslint/eslintrc@^1.3.3": - version "1.3.3" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz" - integrity sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.4.0" - globals "^13.15.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@floating-ui/core@^1.6.0": - version "1.6.5" - resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz" - integrity sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA== - dependencies: - "@floating-ui/utils" "^0.2.5" - -"@floating-ui/dom@^1.0.0": - version "1.6.8" - resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz" - integrity sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q== - dependencies: - "@floating-ui/core" "^1.6.0" - "@floating-ui/utils" "^0.2.5" - -"@floating-ui/react-dom@^2.0.0": - version "2.1.1" - resolved "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz" - integrity sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg== - dependencies: - "@floating-ui/dom" "^1.0.0" - -"@floating-ui/utils@^0.2.5": - version "0.2.5" - resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz" - integrity sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ== - -"@humanwhocodes/config-array@^0.11.6": - version "0.11.6" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.6.tgz" - integrity sha512-jJr+hPTJYKyDILJfhNSHsjiwXYf26Flsz8DvNndOsHs5pwSnpGUEy8yzF0JYhCEvTDdV2vuOK5tt8BVhwO5/hg== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.4" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" - -"@mui/base@5.0.0-alpha.104": - version "5.0.0-alpha.104" - resolved "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.104.tgz" - integrity sha512-tQPxZTzfYMwxYfKhEwufbTfdLpNjFdW7bXq6dK0j8651AAyZL4M8wynWUQ98hH1362R26mZFhVxHB2UD9t7VuA== - dependencies: - "@babel/runtime" "^7.19.0" - "@emotion/is-prop-valid" "^1.2.0" - "@mui/types" "^7.2.0" - "@mui/utils" "^5.10.9" - "@popperjs/core" "^2.11.6" - clsx "^1.2.1" - prop-types "^15.8.1" - react-is "^18.2.0" - -"@mui/core-downloads-tracker@^5.10.12": - version "5.10.12" - resolved "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.12.tgz" - integrity sha512-cR8lOS606G++iVHR8I6ySgMAEiPoA3DxO/nLeqiv7w7d1707kvKoV4/7SWjh4ui+kHb052xlf/G196q2EKx31w== - -"@mui/icons-material@^5.10.9": - version "5.10.9" - resolved "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.10.9.tgz" - integrity sha512-sqClXdEM39WKQJOQ0ZCPTptaZgqwibhj2EFV9N0v7BU1PO8y4OcX/a2wIQHn4fNuDjIZktJIBrmU23h7aqlGgg== - dependencies: - "@babel/runtime" "^7.19.0" - -"@mui/material@^5.10.12": - version "5.10.12" - resolved "https://registry.npmjs.org/@mui/material/-/material-5.10.12.tgz" - integrity sha512-rG9ZTkG9qUwujyAY1I+uQAa9pkGdsWY3KN+wvS/6H6ZbYIA06QRwmig6ySC6LbeB3WL/I/1ngwJqWX7nfINSbA== - dependencies: - "@babel/runtime" "^7.19.0" - "@mui/base" "5.0.0-alpha.104" - "@mui/core-downloads-tracker" "^5.10.12" - "@mui/system" "^5.10.12" - "@mui/types" "^7.2.0" - "@mui/utils" "^5.10.9" - "@types/react-transition-group" "^4.4.5" - clsx "^1.2.1" - csstype "^3.1.1" - prop-types "^15.8.1" - react-is "^18.2.0" - react-transition-group "^4.4.5" - -"@mui/private-theming@^5.10.9": - version "5.10.9" - resolved "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.10.9.tgz" - integrity sha512-BN7/CnsVPVyBaQpDTij4uV2xGYHHHhOgpdxeYLlIu+TqnsVM7wUeF+37kXvHovxM6xmL5qoaVUD98gDC0IZnHg== - dependencies: - "@babel/runtime" "^7.19.0" - "@mui/utils" "^5.10.9" - prop-types "^15.8.1" - -"@mui/styled-engine@^5.10.8": - version "5.10.8" - resolved "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.10.8.tgz" - integrity sha512-w+y8WI18EJV6zM/q41ug19cE70JTeO6sWFsQ7tgePQFpy6ToCVPh0YLrtqxUZXSoMStW5FMw0t9fHTFAqPbngw== - dependencies: - "@babel/runtime" "^7.19.0" - "@emotion/cache" "^11.10.3" - csstype "^3.1.1" - prop-types "^15.8.1" - -"@mui/system@^5.10.12": - version "5.10.12" - resolved "https://registry.npmjs.org/@mui/system/-/system-5.10.12.tgz" - integrity sha512-9DcN3hF2KTTTpZ0K5Tn20B+Tz7tIqDmJLk1M6P0CYoAGUN/xrcF/6dn1zZ829rxE5tmauoDUekTfomrvPsvlSQ== - dependencies: - "@babel/runtime" "^7.19.0" - "@mui/private-theming" "^5.10.9" - "@mui/styled-engine" "^5.10.8" - "@mui/types" "^7.2.0" - "@mui/utils" "^5.10.9" - clsx "^1.2.1" - csstype "^3.1.1" - prop-types "^15.8.1" - -"@mui/types@^7.2.0": - version "7.2.0" - resolved "https://registry.npmjs.org/@mui/types/-/types-7.2.0.tgz" - integrity sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA== - -"@mui/utils@^5.10.9": - version "5.10.9" - resolved "https://registry.npmjs.org/@mui/utils/-/utils-5.10.9.tgz" - integrity sha512-2tdHWrq3+WCy+G6TIIaFx3cg7PorXZ71P375ExuX61od1NOAJP1mK90VxQ8N4aqnj2vmO3AQDkV4oV2Ktvt4bA== - dependencies: - "@babel/runtime" "^7.19.0" - "@types/prop-types" "^15.7.5" - "@types/react-is" "^16.7.1 || ^17.0.0" - prop-types "^15.8.1" - react-is "^18.2.0" - -"@next/env@13.0.0": - version "13.0.0" - resolved "https://registry.npmjs.org/@next/env/-/env-13.0.0.tgz" - integrity sha512-65v9BVuah2Mplohm4+efsKEnoEuhmlGm8B2w6vD1geeEP2wXtlSJCvR/cCRJ3fD8wzCQBV41VcMBQeYET6MRkg== - -"@next/eslint-plugin-next@13.0.0": - version "13.0.0" - resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.0.0.tgz" - integrity sha512-z+gnX4Zizatqatc6f4CQrcC9oN8Us3Vrq/OLyc98h7K/eWctrnV91zFZodmJHUjx0cITY8uYM7LXD7IdYkg3kg== - dependencies: - glob "7.1.7" - -"@next/swc-android-arm-eabi@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.0.0.tgz#15cd89d19d3c00d123fdfe367bab38c362f6c515" - integrity sha512-+DUQkYF93gxFjWY+CYWE1QDX6gTgnUiWf+W4UqZjM1Jcef8U97fS6xYh+i+8rH4MM0AXHm7OSakvfOMzmjU6VA== - -"@next/swc-android-arm64@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-13.0.0.tgz#9410365bb07097268d4773a46b02cfe6b3fe3ab7" - integrity sha512-RW9Uy3bMSc0zVGCa11klFuwfP/jdcdkhdruqnrJ7v+7XHm6OFKkSRzX6ee7yGR1rdDZvTnP4GZSRSpzjLv/N0g== - -"@next/swc-darwin-arm64@13.0.0": - version "13.0.0" - resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.0.0.tgz" - integrity sha512-APA26nps1j4qyhOIzkclW/OmgotVHj1jBxebSpMCPw2rXfiNvKNY9FA0TcuwPmUCNqaTnm703h6oW4dvp73A4Q== - -"@next/swc-darwin-x64@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.0.0.tgz#6b214753410e1d8512a1491045acea1e188df7d6" - integrity sha512-qsUhUdoFuRJiaJ7LnvTQ6GZv1QnMDcRXCIjxaN0FNVXwrjkq++U7KjBUaxXkRzLV4C7u0NHLNOp0iZwNNE7ypw== - -"@next/swc-freebsd-x64@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.0.0.tgz#eeb176bdb585f48882bdac1d04271b918ca87590" - integrity sha512-sCdyCbboS7CwdnevKH9J6hkJI76LUw1jVWt4eV7kISuLiPba3JmehZSWm80oa4ADChRVAwzhLAo2zJaYRrInbg== - -"@next/swc-linux-arm-gnueabihf@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.0.0.tgz#2c2a9622c93f87a8baca94e068f674da4cae6018" - integrity sha512-/X/VxfFA41C9jrEv+sUsPLQ5vbDPVIgG0CJrzKvrcc+b+4zIgPgtfsaWq9ockjHFQi3ycvlZK4TALOXO8ovQ6Q== - -"@next/swc-linux-arm64-gnu@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.0.0.tgz#69505827e2928fb18034150fd4d754d54c4a1c4b" - integrity sha512-x6Oxr1GIi0ZtNiT6jbw+JVcbEi3UQgF7mMmkrgfL4mfchOwXtWSHKTSSPnwoJWJfXYa0Vy1n8NElWNTGAqoWFw== - -"@next/swc-linux-arm64-musl@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.0.0.tgz#487a88f2583a046e882328fe0665b37eca4fd0f6" - integrity sha512-SnMH9ngI+ipGh3kqQ8+mDtWunirwmhQnQeZkEq9e/9Xsgjf04OetqrqRHKM1HmJtG2qMUJbyXFJ0F81TPuT+3g== - -"@next/swc-linux-x64-gnu@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.0.0.tgz#29e89c7e4fd2e2b16ad059076f6261998aee53df" - integrity sha512-VSQwTX9EmdbotArtA1J67X8964oQfe0xHb32x4tu+JqTR+wOHyG6wGzPMdXH2oKAp6rdd7BzqxUXXf0J+ypHlw== - -"@next/swc-linux-x64-musl@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.0.0.tgz#2f63aae922d2b2829aec21bf8f9adda8b6c16365" - integrity sha512-xBCP0nnpO0q4tsytXkvIwWFINtbFRyVY5gxa1zB0vlFtqYR9lNhrOwH3CBrks3kkeaePOXd611+8sjdUtrLnXA== - -"@next/swc-win32-arm64-msvc@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.0.0.tgz#4117bad96c2a6775f70294fba45c63951a8a21ac" - integrity sha512-NutwDafqhGxqPj/eiUixJq9ImS/0sgx6gqlD7jRndCvQ2Q8AvDdu1+xKcGWGNnhcDsNM/n1avf1e62OG1GaqJg== - -"@next/swc-win32-ia32-msvc@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.0.0.tgz#5914eb86f9ea92a00d76cb094dd9734b3bf2012c" - integrity sha512-zNaxaO+Kl/xNz02E9QlcVz0pT4MjkXGDLb25qxtAzyJL15aU0+VjjbIZAYWctG59dvggNIUNDWgoBeVTKB9xLg== - -"@next/swc-win32-x64-msvc@13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.0.0.tgz#c54a5a739dee04b20338d305226a2acdf701f67f" - integrity sha512-FFOGGWwTCRMu9W7MF496Urefxtuo2lttxF1vwS+1rIRsKvuLrWhVaVTj3T8sf2EBL6gtJbmh4TYlizS+obnGKA== - -"@noble/curves@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" - integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== - dependencies: - "@noble/hashes" "1.3.2" - -"@noble/hashes@1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" - integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@popperjs/core@^2.11.6": - version "2.11.6" - resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.6.tgz" - integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw== - -"@radix-ui/primitive@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz" - integrity sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA== - -"@radix-ui/react-arrow@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz" - integrity sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw== - dependencies: - "@radix-ui/react-primitive" "2.0.0" - -"@radix-ui/react-collection@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz" - integrity sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw== - dependencies: - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-context" "1.1.0" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-slot" "1.1.0" - -"@radix-ui/react-compose-refs@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz" - integrity sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw== - -"@radix-ui/react-context@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz" - integrity sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A== - -"@radix-ui/react-dialog@^1.1.1": - version "1.1.1" - resolved "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz" - integrity sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg== - dependencies: - "@radix-ui/primitive" "1.1.0" - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-context" "1.1.0" - "@radix-ui/react-dismissable-layer" "1.1.0" - "@radix-ui/react-focus-guards" "1.1.0" - "@radix-ui/react-focus-scope" "1.1.0" - "@radix-ui/react-id" "1.1.0" - "@radix-ui/react-portal" "1.1.1" - "@radix-ui/react-presence" "1.1.0" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-slot" "1.1.0" - "@radix-ui/react-use-controllable-state" "1.1.0" - aria-hidden "^1.1.1" - react-remove-scroll "2.5.7" - -"@radix-ui/react-direction@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz" - integrity sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg== - -"@radix-ui/react-dismissable-layer@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz" - integrity sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig== - dependencies: - "@radix-ui/primitive" "1.1.0" - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-use-callback-ref" "1.1.0" - "@radix-ui/react-use-escape-keydown" "1.1.0" - -"@radix-ui/react-dropdown-menu@^2.1.1": - version "2.1.1" - resolved "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz" - integrity sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ== - dependencies: - "@radix-ui/primitive" "1.1.0" - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-context" "1.1.0" - "@radix-ui/react-id" "1.1.0" - "@radix-ui/react-menu" "2.1.1" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-use-controllable-state" "1.1.0" - -"@radix-ui/react-focus-guards@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz" - integrity sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw== - -"@radix-ui/react-focus-scope@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz" - integrity sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA== - dependencies: - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-use-callback-ref" "1.1.0" - -"@radix-ui/react-id@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz" - integrity sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA== - dependencies: - "@radix-ui/react-use-layout-effect" "1.1.0" - -"@radix-ui/react-menu@2.1.1": - version "2.1.1" - resolved "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz" - integrity sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ== - dependencies: - "@radix-ui/primitive" "1.1.0" - "@radix-ui/react-collection" "1.1.0" - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-context" "1.1.0" - "@radix-ui/react-direction" "1.1.0" - "@radix-ui/react-dismissable-layer" "1.1.0" - "@radix-ui/react-focus-guards" "1.1.0" - "@radix-ui/react-focus-scope" "1.1.0" - "@radix-ui/react-id" "1.1.0" - "@radix-ui/react-popper" "1.2.0" - "@radix-ui/react-portal" "1.1.1" - "@radix-ui/react-presence" "1.1.0" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-roving-focus" "1.1.0" - "@radix-ui/react-slot" "1.1.0" - "@radix-ui/react-use-callback-ref" "1.1.0" - aria-hidden "^1.1.1" - react-remove-scroll "2.5.7" - -"@radix-ui/react-popper@1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz" - integrity sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg== - dependencies: - "@floating-ui/react-dom" "^2.0.0" - "@radix-ui/react-arrow" "1.1.0" - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-context" "1.1.0" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-use-callback-ref" "1.1.0" - "@radix-ui/react-use-layout-effect" "1.1.0" - "@radix-ui/react-use-rect" "1.1.0" - "@radix-ui/react-use-size" "1.1.0" - "@radix-ui/rect" "1.1.0" - -"@radix-ui/react-portal@1.1.1": - version "1.1.1" - resolved "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz" - integrity sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g== - dependencies: - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-use-layout-effect" "1.1.0" - -"@radix-ui/react-presence@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz" - integrity sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ== - dependencies: - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-use-layout-effect" "1.1.0" - -"@radix-ui/react-primitive@2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz" - integrity sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw== - dependencies: - "@radix-ui/react-slot" "1.1.0" - -"@radix-ui/react-roving-focus@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz" - integrity sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA== - dependencies: - "@radix-ui/primitive" "1.1.0" - "@radix-ui/react-collection" "1.1.0" - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-context" "1.1.0" - "@radix-ui/react-direction" "1.1.0" - "@radix-ui/react-id" "1.1.0" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-use-callback-ref" "1.1.0" - "@radix-ui/react-use-controllable-state" "1.1.0" - -"@radix-ui/react-slot@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz" - integrity sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw== - dependencies: - "@radix-ui/react-compose-refs" "1.1.0" - -"@radix-ui/react-switch@^1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.0.tgz" - integrity sha512-OBzy5WAj641k0AOSpKQtreDMe+isX0MQJ1IVyF03ucdF3DunOnROVrjWs8zsXUxC3zfZ6JL9HFVCUlMghz9dJw== - dependencies: - "@radix-ui/primitive" "1.1.0" - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-context" "1.1.0" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-use-controllable-state" "1.1.0" - "@radix-ui/react-use-previous" "1.1.0" - "@radix-ui/react-use-size" "1.1.0" - -"@radix-ui/react-tooltip@^1.1.1": - version "1.1.2" - resolved "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz" - integrity sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w== - dependencies: - "@radix-ui/primitive" "1.1.0" - "@radix-ui/react-compose-refs" "1.1.0" - "@radix-ui/react-context" "1.1.0" - "@radix-ui/react-dismissable-layer" "1.1.0" - "@radix-ui/react-id" "1.1.0" - "@radix-ui/react-popper" "1.2.0" - "@radix-ui/react-portal" "1.1.1" - "@radix-ui/react-presence" "1.1.0" - "@radix-ui/react-primitive" "2.0.0" - "@radix-ui/react-slot" "1.1.0" - "@radix-ui/react-use-controllable-state" "1.1.0" - "@radix-ui/react-visually-hidden" "1.1.0" - -"@radix-ui/react-use-callback-ref@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz" - integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw== - -"@radix-ui/react-use-controllable-state@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz" - integrity sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw== - dependencies: - "@radix-ui/react-use-callback-ref" "1.1.0" - -"@radix-ui/react-use-escape-keydown@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz" - integrity sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw== - dependencies: - "@radix-ui/react-use-callback-ref" "1.1.0" - -"@radix-ui/react-use-layout-effect@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz" - integrity sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w== - -"@radix-ui/react-use-previous@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz" - integrity sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og== - -"@radix-ui/react-use-rect@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz" - integrity sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ== - dependencies: - "@radix-ui/rect" "1.1.0" - -"@radix-ui/react-use-size@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz" - integrity sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw== - dependencies: - "@radix-ui/react-use-layout-effect" "1.1.0" - -"@radix-ui/react-visually-hidden@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz" - integrity sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ== - dependencies: - "@radix-ui/react-primitive" "2.0.0" - -"@radix-ui/rect@1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz" - integrity sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg== - -"@reach/auto-id@0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@reach/auto-id/-/auto-id-0.18.0.tgz#4b97085cd1cf1360a9bedc6e9c78e97824014f0d" - integrity sha512-XwY1IwhM7mkHZFghhjiqjQ6dstbOdpbFLdggeke75u8/8icT8uEHLbovFUgzKjy9qPvYwZIB87rLiR8WdtOXCg== - dependencies: - "@reach/utils" "0.18.0" - -"@reach/combobox@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@reach/combobox/-/combobox-0.18.0.tgz#8b3879b7c2dc426cddf0941b041d1ddc6d9adee6" - integrity sha512-x60PiPOIB4azeyh+FZ/svh0kXZRCneGCXVLL6htWs1VmaKq+TWR/48V03yQX5cSKjvRM8UFDVn47mpcg5ZSFtg== - dependencies: - "@reach/auto-id" "0.18.0" - "@reach/descendants" "0.18.0" - "@reach/polymorphic" "0.18.0" - "@reach/popover" "0.18.0" - "@reach/portal" "0.18.0" - "@reach/utils" "0.18.0" - -"@reach/descendants@0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@reach/descendants/-/descendants-0.18.0.tgz#16fe52a5154da262994b0b8768baff4f670922d1" - integrity sha512-GXUxnM6CfrX5URdnipPIl3Tlc6geuz4xb4n61y4tVWXQX1278Ra9Jz9DMRN8x4wheHAysvrYwnR/SzAlxQzwtA== - dependencies: - "@reach/utils" "0.18.0" - -"@reach/observe-rect@1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@reach/observe-rect/-/observe-rect-1.2.0.tgz#d7a6013b8aafcc64c778a0ccb83355a11204d3b2" - integrity sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ== - -"@reach/polymorphic@0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@reach/polymorphic/-/polymorphic-0.18.0.tgz#2fe42007a774e06cdbc8e13e0d46f2dc30f2f1ed" - integrity sha512-N9iAjdMbE//6rryZZxAPLRorzDcGBnluf7YQij6XDLiMtfCj1noa7KyLpEc/5XCIB/EwhX3zCluFAwloBKdblA== - -"@reach/popover@0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@reach/popover/-/popover-0.18.0.tgz#1eba3e9ed826ac69dfdf3b01a1dab15ca889b5fc" - integrity sha512-mpnWWn4w74L2U7fcneVdA6Fz3yKWNdZIRMoK8s6H7F8U2dLM/qN7AjzjEBqi6LXKb3Uf1ge4KHSbMixW0BygJQ== - dependencies: - "@reach/polymorphic" "0.18.0" - "@reach/portal" "0.18.0" - "@reach/rect" "0.18.0" - "@reach/utils" "0.18.0" - tabbable "^5.3.3" - -"@reach/portal@0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@reach/portal/-/portal-0.18.0.tgz#dd466f5110689d14a0e7491b3aa8a449e8cefb40" - integrity sha512-TImozRapd576ofRk30Le2L3lRTFXF1p47B182wnp5eMTdZa74JX138BtNGEPJFOyrMaVmguVF8SSwZ6a0fon1Q== - dependencies: - "@reach/utils" "0.18.0" - -"@reach/rect@0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@reach/rect/-/rect-0.18.0.tgz#d1dc45adc92f80cc54b64498e19de909ced40722" - integrity sha512-Xk8urN4NLn3F70da/DtByMow83qO6DF6vOxpLjuDBqud+kjKgxAU9vZMBSZJyH37+F8mZinRnHyXtlLn5njQOg== - dependencies: - "@reach/observe-rect" "1.2.0" - "@reach/utils" "0.18.0" - -"@reach/tabs@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@reach/tabs/-/tabs-0.18.0.tgz#f2e789d445d61a371eace9415841502729d099c9" - integrity sha512-gTRJzStWJJtgMhn9FDEmKogAJMcqNaGZx0i1SGoTdVM+D29DBhVeRdO8qEg+I2l2k32DkmuZxG/Mrh+GZTjczQ== - dependencies: - "@reach/auto-id" "0.18.0" - "@reach/descendants" "0.18.0" - "@reach/polymorphic" "0.18.0" - "@reach/utils" "0.18.0" - -"@reach/utils@0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.18.0.tgz#4f3cebe093dd436eeaff633809bf0f68f4f9d2ee" - integrity sha512-KdVMdpTgDyK8FzdKO9SCpiibuy/kbv3pwgfXshTI6tEcQT1OOwj7BAksnzGC0rPz0UholwC+AgkqEl3EJX3M1A== - -"@react-spring/animated@~9.5.5": - version "9.5.5" - resolved "https://registry.npmjs.org/@react-spring/animated/-/animated-9.5.5.tgz" - integrity sha512-glzViz7syQ3CE6BQOwAyr75cgh0qsihm5lkaf24I0DfU63cMm/3+br299UEYkuaHNmfDfM414uktiPlZCNJbQA== - dependencies: - "@react-spring/shared" "~9.5.5" - "@react-spring/types" "~9.5.5" - -"@react-spring/core@~9.5.5": - version "9.5.5" - resolved "https://registry.npmjs.org/@react-spring/core/-/core-9.5.5.tgz" - integrity sha512-shaJYb3iX18Au6gkk8ahaF0qx0LpS0Yd+ajb4asBaAQf6WPGuEdJsbsNSgei1/O13JyEATsJl20lkjeslJPMYA== - dependencies: - "@react-spring/animated" "~9.5.5" - "@react-spring/rafz" "~9.5.5" - "@react-spring/shared" "~9.5.5" - "@react-spring/types" "~9.5.5" - -"@react-spring/konva@~9.5.5": - version "9.5.5" - resolved "https://registry.npmjs.org/@react-spring/konva/-/konva-9.5.5.tgz" - integrity sha512-0CNh+1vCIjNUklTFwMvxg+H83Jo2OWykBrdEA28ccmnpZgkQ8Kq5xyvaPFLzcDKV67OXHnaWiCYKpRbhLy2wng== - dependencies: - "@react-spring/animated" "~9.5.5" - "@react-spring/core" "~9.5.5" - "@react-spring/shared" "~9.5.5" - "@react-spring/types" "~9.5.5" - -"@react-spring/native@~9.5.5": - version "9.5.5" - resolved "https://registry.npmjs.org/@react-spring/native/-/native-9.5.5.tgz" - integrity sha512-kauqmyJ8u7aVy2bBs22vl1SdB2i5uYIL4rP53k1KDWrFSqJh4j3efWkbTt9uzR5cMXuNVbkNo9OYVFUcQBz50A== - dependencies: - "@react-spring/animated" "~9.5.5" - "@react-spring/core" "~9.5.5" - "@react-spring/shared" "~9.5.5" - "@react-spring/types" "~9.5.5" - -"@react-spring/rafz@~9.5.5": - version "9.5.5" - resolved "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.5.5.tgz" - integrity sha512-F/CLwB0d10jL6My5vgzRQxCNY2RNyDJZedRBK7FsngdCmzoq3V4OqqNc/9voJb9qRC2wd55oGXUeXv2eIaFmsw== - -"@react-spring/shared@~9.5.5": - version "9.5.5" - resolved "https://registry.npmjs.org/@react-spring/shared/-/shared-9.5.5.tgz" - integrity sha512-YwW70Pa/YXPOwTutExHZmMQSHcNC90kJOnNR4G4mCDNV99hE98jWkIPDOsgqbYx3amIglcFPiYKMaQuGdr8dyQ== - dependencies: - "@react-spring/rafz" "~9.5.5" - "@react-spring/types" "~9.5.5" - -"@react-spring/three@~9.5.5": - version "9.5.5" - resolved "https://registry.npmjs.org/@react-spring/three/-/three-9.5.5.tgz" - integrity sha512-9kTIaSceqFIl5EIrdwM7Z53o5I+9BGNVzbp4oZZYMao+GMAWOosnlQdDG5GeqNsIqfW9fZCEquGqagfKAxftcA== - dependencies: - "@react-spring/animated" "~9.5.5" - "@react-spring/core" "~9.5.5" - "@react-spring/shared" "~9.5.5" - "@react-spring/types" "~9.5.5" - -"@react-spring/types@~9.5.5": - version "9.5.5" - resolved "https://registry.npmjs.org/@react-spring/types/-/types-9.5.5.tgz" - integrity sha512-7I/qY8H7Enwasxr4jU6WmtNK+RZ4Z/XvSlDvjXFVe7ii1x0MoSlkw6pD7xuac8qrHQRm9BTcbZNyeeKApYsvCg== - -"@react-spring/web@~9.5.5": - version "9.5.5" - resolved "https://registry.npmjs.org/@react-spring/web/-/web-9.5.5.tgz" - integrity sha512-+moT8aDX/ho/XAhU+HRY9m0LVV9y9CK6NjSRaI+30Re150pB3iEip6QfnF4qnhSCQ5drpMF0XRXHgOTY/xbtFw== - dependencies: - "@react-spring/animated" "~9.5.5" - "@react-spring/core" "~9.5.5" - "@react-spring/shared" "~9.5.5" - "@react-spring/types" "~9.5.5" - -"@react-spring/zdog@~9.5.5": - version "9.5.5" - resolved "https://registry.npmjs.org/@react-spring/zdog/-/zdog-9.5.5.tgz" - integrity sha512-LZgjo2kLlGmUqfE2fdVnvLXz+4eYyQARRvB9KQ4PTEynaETTG89Xgn9YxLrh1p57DzH7gEmTGDZ5hEw3pWqu8g== - dependencies: - "@react-spring/animated" "~9.5.5" - "@react-spring/core" "~9.5.5" - "@react-spring/shared" "~9.5.5" - "@react-spring/types" "~9.5.5" - -"@rushstack/eslint-patch@^1.1.3": - version "1.2.0" - resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz" - integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== - -"@swc/helpers@0.4.11": - version "0.4.11" - resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.4.11.tgz" - integrity sha512-rEUrBSGIoSFuYxwBYtlUFMlE2CwGhmW+w9355/5oduSw8e5h2+Tj4UrAGNNgP9915++wj5vkQo0UuOBqOAq4nw== - dependencies: - tslib "^2.4.0" - -"@table-library/react-table-library@^4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@table-library/react-table-library/-/react-table-library-4.1.7.tgz#90b71f959228f420d2deffeecc9eace879cb4c2e" - integrity sha512-KKFjdACvEUeD9yhgXBjZUJSdE9pxUbJdou4Pp71FW8dxQWc7LcMcSxpveSfGXw8KlcWY0hThJOwyjQb+UKOmnw== - dependencies: - clsx "1.1.1" - react-virtualized-auto-sizer "1.0.7" - react-window "1.8.7" - -"@types/hoist-non-react-statics@*": - version "3.3.1" - resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz" - integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== - dependencies: - "@types/react" "*" - hoist-non-react-statics "^3.3.0" - -"@types/js-cookie@^2.2.6": - version "2.2.7" - resolved "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz" - integrity sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/lodash@^4.14.188": - version "4.14.188" - resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.188.tgz" - integrity sha512-zmEmF5OIM3rb7SbLCFYoQhO4dGt2FRM9AMkxvA3LaADOF1n8in/zGJlWji9fmafLoNyz+FoL6FE0SLtGIArD7w== - -"@types/node@18.11.7": - version "18.11.7" - resolved "https://registry.npmjs.org/@types/node/-/node-18.11.7.tgz" - integrity sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ== - -"@types/node@18.15.13": - version "18.15.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" - integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== - -"@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - -"@types/prop-types@*", "@types/prop-types@^15.7.5": - version "15.7.5" - resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" - integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== - -"@types/react-dom@18.0.8": - version "18.0.8" - resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.8.tgz" - integrity sha512-C3GYO0HLaOkk9dDAz3Dl4sbe4AKUGTCfFIZsz3n/82dPNN8Du533HzKatDxeUYWu24wJgMP1xICqkWk1YOLOIw== - dependencies: - "@types/react" "*" - -"@types/react-is@^16.7.1 || ^17.0.0": - version "17.0.3" - resolved "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz" - integrity sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw== - dependencies: - "@types/react" "*" - -"@types/react-transition-group@^4.4.5": - version "4.4.5" - resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz" - integrity sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA== - dependencies: - "@types/react" "*" - -"@types/react@*", "@types/react@18.0.24": - version "18.0.24" - resolved "https://registry.npmjs.org/@types/react/-/react-18.0.24.tgz" - integrity sha512-wRJWT6ouziGUy+9uX0aW4YOJxAY0bG6/AOk5AW5QSvZqI7dk6VBIbXvcVgIw/W5Jrl24f77df98GEKTJGOLx7Q== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/scheduler@*": - version "0.16.2" - resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz" - integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== - -"@types/styled-components@^5.1.26": - version "5.1.26" - resolved "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.26.tgz" - integrity sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw== - dependencies: - "@types/hoist-non-react-statics" "*" - "@types/react" "*" - csstype "^3.0.2" - -"@typescript-eslint/parser@^5.21.0": - version "5.41.0" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.41.0.tgz" - integrity sha512-HQVfix4+RL5YRWZboMD1pUfFN8MpRH4laziWkkAzyO1fvNOY/uinZcvo3QiFJVS/siNHupV8E5+xSwQZrl6PZA== - dependencies: - "@typescript-eslint/scope-manager" "5.41.0" - "@typescript-eslint/types" "5.41.0" - "@typescript-eslint/typescript-estree" "5.41.0" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@5.41.0": - version "5.41.0" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.41.0.tgz" - integrity sha512-xOxPJCnuktUkY2xoEZBKXO5DBCugFzjrVndKdUnyQr3+9aDWZReKq9MhaoVnbL+maVwWJu/N0SEtrtEUNb62QQ== - dependencies: - "@typescript-eslint/types" "5.41.0" - "@typescript-eslint/visitor-keys" "5.41.0" - -"@typescript-eslint/types@5.41.0": - version "5.41.0" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.41.0.tgz" - integrity sha512-5BejraMXMC+2UjefDvrH0Fo/eLwZRV6859SXRg+FgbhA0R0l6lDqDGAQYhKbXhPN2ofk2kY5sgGyLNL907UXpA== - -"@typescript-eslint/typescript-estree@5.41.0": - version "5.41.0" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.41.0.tgz" - integrity sha512-SlzFYRwFSvswzDSQ/zPkIWcHv8O5y42YUskko9c4ki+fV6HATsTODUPbRbcGDFYP86gaJL5xohUEytvyNNcXWg== - dependencies: - "@typescript-eslint/types" "5.41.0" - "@typescript-eslint/visitor-keys" "5.41.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/visitor-keys@5.41.0": - version "5.41.0" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.41.0.tgz" - integrity sha512-vilqeHj267v8uzzakbm13HkPMl7cbYpKVjgFWZPIOHIJHZtinvypUhJ5xBXfWYg4eFKqztbMMpOgFpT9Gfx4fw== - dependencies: - "@typescript-eslint/types" "5.41.0" - eslint-visitor-keys "^3.3.0" - -"@xobotyi/scrollbar-width@^1.9.5": - version "1.9.5" - resolved "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz" - integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ== - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn@^8.8.0: - version "8.8.1" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz" - integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== - -aes-js@4.0.0-beta.5: - version "4.0.0-beta.5" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" - integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -apexcharts@^3.36.3: - version "3.36.3" - resolved "https://registry.npmjs.org/apexcharts/-/apexcharts-3.36.3.tgz" - integrity sha512-8/FXEs0ohXMff07Gv28XjhPwEJphIUdq2/wii/pcvi54Tw6z1mjrV8ydN8rlWi/ve8BAPBefJkLmRWv7UOBsLw== - dependencies: - svg.draggable.js "^2.2.2" - svg.easing.js "^2.0.0" - svg.filter.js "^2.0.2" - svg.pathmorphing.js "^0.1.3" - svg.resize.js "^1.4.3" - svg.select.js "^3.0.1" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -aria-hidden@^1.1.1: - version "1.2.4" - resolved "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz" - integrity sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A== - dependencies: - tslib "^2.0.0" - -aria-query@^4.2.2: - version "4.2.2" - resolved "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz" - integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== - dependencies: - "@babel/runtime" "^7.10.2" - "@babel/runtime-corejs3" "^7.10.2" - -array-includes@^3.1.4, array-includes@^3.1.5: - version "3.1.5" - resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz" - integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - get-intrinsic "^1.1.1" - is-string "^1.0.7" - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== - dependencies: - array-uniq "^1.0.1" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== - -array.prototype.flat@^1.2.5: - version "1.3.0" - resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz" - integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.2" - es-shim-unscopables "^1.0.0" - -array.prototype.flatmap@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz" - integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.2" - es-shim-unscopables "^1.0.0" - -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz" - integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== - -async@^3.2.4: - version "3.2.6" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" - integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -axe-core@^4.4.3: - version "4.5.0" - resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.5.0.tgz" - integrity sha512-4+rr8eQ7+XXS5nZrKcMO/AikHL0hVqy+lHWAnE3xdHl+aguag8SOQ6eEqLexwLNWgXIMfunGuD3ON1/6Kyet0A== - -axios@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz" - integrity sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA== - dependencies: - follow-redirects "^1.15.0" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - -axobject-query@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz" - integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== - -babel-plugin-macros@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz" - integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== - dependencies: - "@babel/runtime" "^7.12.5" - cosmiconfig "^7.0.0" - resolve "^1.19.0" - -"babel-plugin-styled-components@>= 1.12.0", babel-plugin-styled-components@^2.0.7: - version "2.0.7" - resolved "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz" - integrity sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.16.0" - "@babel/helper-module-imports" "^7.16.0" - babel-plugin-syntax-jsx "^6.18.0" - lodash "^4.17.11" - picomatch "^2.3.0" - -babel-plugin-syntax-jsx@^6.18.0: - version "6.18.0" - resolved "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz" - integrity sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -big-integer@^1.6.16: - version "1.6.52" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" - integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== - -blockies-react-svg@^0.0.13: - version "0.0.13" - resolved "https://registry.yarnpkg.com/blockies-react-svg/-/blockies-react-svg-0.0.13.tgz#785500bebdbe5e4aea8e094b3241f73669470b00" - integrity sha512-w3Upvq5xnO2m0KEf4QhExLDpPMlJZes0Oi5e1EaILTpU+TtDGipoqxJuGGMhFHl2Qg7cuw4P1pAgEMy+Y3nZrg== - -blockies@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/blockies/-/blockies-0.0.2.tgz#22ad58da4f6b382bc79bf4386c5820c70047e4ed" - integrity sha512-D9kUW071jJxjp+8w99Bcf7TxJAnhoNfglLHAVHn2dmacbZcULCq4Zi2w8/NZpPQ8lsiX1E+LiEhZITJhxNmo6g== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -broadcast-channel@^3.4.1: - version "3.7.0" - resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.7.0.tgz#2dfa5c7b4289547ac3f6705f9c00af8723889937" - integrity sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg== - dependencies: - "@babel/runtime" "^7.7.2" - detect-node "^2.1.0" - js-sha3 "0.8.0" - microseconds "0.2.0" - nano-time "1.0.0" - oblivious-set "1.0.0" - rimraf "3.0.2" - unload "2.2.0" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelize@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz" - integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== - -caniuse-lite@^1.0.30001406: - version "1.0.30001426" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001426.tgz" - integrity sha512-n7cosrHLl8AWt0wwZw/PJZgUg3lV0gk9LMI7ikGJwhyhgsd2Nb65vKvmSexCqq/J7rbH3mFG6yZZiPR5dLPW5A== - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -classnames@^2.3.2: - version "2.5.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" - integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== - -client-only@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" - integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== - -clsx@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" - integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== - -clsx@^1.1.1, clsx@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" - integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -commander@^11.0.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906" - integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -convert-source-map@^1.5.0: - version "1.9.0" - resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - -copy-to-clipboard@^3.3.1: - version "3.3.3" - resolved "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz" - integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== - dependencies: - toggle-selection "^1.0.6" - -core-js-pure@^3.25.1: - version "3.26.0" - resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.26.0.tgz" - integrity sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA== - -cosmiconfig@^7.0.0: - version "7.0.1" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz" - integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -cross-spawn@^7.0.2: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -css-color-keywords@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz" - integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg== - -css-in-js-utils@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-3.1.0.tgz" - integrity sha512-fJAcud6B3rRu+KHYk+Bwf+WFL2MDCJJ1XG9x137tJQ0xYxor7XziQtuGFbWNdqrvF4Tk26O3H73nfVqXt/fW1A== - dependencies: - hyphenate-style-name "^1.0.3" - -css-to-react-native@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz" - integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ== - dependencies: - camelize "^1.0.0" - css-color-keywords "^1.0.0" - postcss-value-parser "^4.0.2" - -css-tree@^1.1.2: - version "1.1.3" - resolved "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz" - integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== - dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" - -csstype@^3.0.2, csstype@^3.0.6, csstype@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz" - integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== - -damerau-levenshtein@^1.0.8: - version "1.0.8" - resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" - integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== - -date-fns@^2.29.3: - version "2.29.3" - resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz" - integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA== - -debug@^2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -define-properties@^1.1.3, define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -detect-node-es@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz" - integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== - -detect-node@^2.0.4, detect-node@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dom-helpers@^5.0.1: - version "5.2.1" - resolved "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz" - integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== - dependencies: - "@babel/runtime" "^7.8.7" - csstype "^3.0.2" - -echarts-for-react@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.2.tgz" - integrity sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA== - dependencies: - fast-deep-equal "^3.1.3" - size-sensor "^1.0.1" - -echarts@^5.4.2: - version "5.4.2" - resolved "https://registry.npmjs.org/echarts/-/echarts-5.4.2.tgz" - integrity sha512-2W3vw3oI2tWJdyAz+b8DuWS0nfXtSDqlDmqgin/lfzbkB01cuMEN66KWBlmur3YMp5nEDEEt5s23pllnAzB4EA== - dependencies: - tslib "2.3.0" - zrender "5.4.3" - -email-addresses@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/email-addresses/-/email-addresses-5.0.0.tgz#7ae9e7f58eef7d5e3e2c2c2d3ea49b78dc854fa6" - integrity sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -error-stack-parser@^2.0.6: - version "2.1.4" - resolved "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz" - integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== - dependencies: - stackframe "^1.3.4" - -es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5: - version "1.20.4" - resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz" - integrity sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-weakref "^1.0.2" - object-inspect "^1.12.2" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trimend "^1.0.5" - string.prototype.trimstart "^1.0.5" - unbox-primitive "^1.0.2" - -es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== - dependencies: - has "^1.0.3" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-config-next@13.0.0: - version "13.0.0" - resolved "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.0.0.tgz" - integrity sha512-y2nqWS2tycWySdVhb+rhp6CuDmDazGySqkzzQZf3UTyfHyC7og1m5m/AtMFwCo5mtvDqvw1BENin52kV9733lg== - dependencies: - "@next/eslint-plugin-next" "13.0.0" - "@rushstack/eslint-patch" "^1.1.3" - "@typescript-eslint/parser" "^5.21.0" - eslint-import-resolver-node "^0.3.6" - eslint-import-resolver-typescript "^2.7.1" - eslint-plugin-import "^2.26.0" - eslint-plugin-jsx-a11y "^6.5.1" - eslint-plugin-react "^7.31.7" - eslint-plugin-react-hooks "^4.5.0" - -eslint-import-resolver-node@^0.3.6: - version "0.3.6" - resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz" - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== - dependencies: - debug "^3.2.7" - resolve "^1.20.0" - -eslint-import-resolver-typescript@^2.7.1: - version "2.7.1" - resolved "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz" - integrity sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ== - dependencies: - debug "^4.3.4" - glob "^7.2.0" - is-glob "^4.0.3" - resolve "^1.22.0" - tsconfig-paths "^3.14.1" - -eslint-module-utils@^2.7.3: - version "2.7.4" - resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== - dependencies: - debug "^3.2.7" - -eslint-plugin-import@^2.26.0: - version "2.26.0" - resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz" - integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== - dependencies: - array-includes "^3.1.4" - array.prototype.flat "^1.2.5" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.3" - has "^1.0.3" - is-core-module "^2.8.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.values "^1.1.5" - resolve "^1.22.0" - tsconfig-paths "^3.14.1" - -eslint-plugin-jsx-a11y@^6.5.1: - version "6.6.1" - resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz" - integrity sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q== - dependencies: - "@babel/runtime" "^7.18.9" - aria-query "^4.2.2" - array-includes "^3.1.5" - ast-types-flow "^0.0.7" - axe-core "^4.4.3" - axobject-query "^2.2.0" - damerau-levenshtein "^1.0.8" - emoji-regex "^9.2.2" - has "^1.0.3" - jsx-ast-utils "^3.3.2" - language-tags "^1.0.5" - minimatch "^3.1.2" - semver "^6.3.0" - -eslint-plugin-react-hooks@^4.5.0: - version "4.6.0" - resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz" - integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== - -eslint-plugin-react@^7.31.7: - version "7.31.10" - resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.10.tgz" - integrity sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA== - dependencies: - array-includes "^3.1.5" - array.prototype.flatmap "^1.3.0" - doctrine "^2.1.0" - estraverse "^5.3.0" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.1.2" - object.entries "^1.1.5" - object.fromentries "^2.0.5" - object.hasown "^1.1.1" - object.values "^1.1.5" - prop-types "^15.8.1" - resolve "^2.0.0-next.3" - semver "^6.3.0" - string.prototype.matchall "^4.0.7" - -eslint-scope@^7.1.1: - version "7.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== - -eslint@8.26.0: - version "8.26.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz" - integrity sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg== - dependencies: - "@eslint/eslintrc" "^1.3.3" - "@humanwhocodes/config-array" "^0.11.6" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.3.0" - espree "^9.4.0" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.15.0" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-sdsl "^4.1.4" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.1" - regexpp "^3.2.0" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - -espree@^9.4.0: - version "9.4.0" - resolved "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz" - integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== - dependencies: - acorn "^8.8.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.3.0" - -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -ethers@^6.13.2: - version "6.13.2" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.2.tgz#4b67d4b49e69b59893931a032560999e5e4419fe" - integrity sha512-9VkriTTed+/27BGuY1s0hf441kqwHJ1wtN2edksEtiRvXx+soxRX3iSXTfFqq2+YwrOqbDoTHjIhQnjJRlzKmg== - dependencies: - "@adraffy/ens-normalize" "1.10.1" - "@noble/curves" "1.2.0" - "@noble/hashes" "1.3.2" - "@types/node" "18.15.13" - aes-js "4.0.0-beta.5" - tslib "2.4.0" - ws "8.17.1" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fast-loops@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/fast-loops/-/fast-loops-1.1.3.tgz" - integrity sha512-8EZzEP0eKkEEVX+drtd9mtuQ+/QrlfW/5MlwcwK5Nds6EkZ/tRzEexkzUY2mIssnAyVLT+TKHuRXmFNNXYUd6g== - -fast-shallow-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz" - integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw== - -fastest-stable-stringify@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz" - integrity sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q== - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -filename-reserved-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" - integrity sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ== - -filenamify@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-4.3.0.tgz#62391cb58f02b09971c9d4f9d63b3cf9aba03106" - integrity sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg== - dependencies: - filename-reserved-regex "^2.0.0" - strip-outer "^1.0.1" - trim-repeated "^1.0.0" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-cache-dir@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-root@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz" - integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== - -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -follow-redirects@^1.15.0: - version "1.15.2" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - -form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - -fs-extra@^11.1.1: - version "11.2.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" - integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - -functions-have-names@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-nonce@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz" - integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -gh-pages@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-6.1.1.tgz#e80af927a081cb480657fde5a0b87ea2e77d6c74" - integrity sha512-upnohfjBwN5hBP9w2dPE7HO5JJTHzSGMV1JrLrHvNuqmjoYHg6TBrCcnEoorjG/e0ejbuvnwyKMdTyM40PEByw== - dependencies: - async "^3.2.4" - commander "^11.0.0" - email-addresses "^5.0.0" - filenamify "^4.3.0" - find-cache-dir "^3.3.1" - fs-extra "^11.1.1" - globby "^6.1.0" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@7.1.7, glob@^7.1.3: - version "7.1.7" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.3, glob@^7.2.0: - version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.15.0: - version "13.17.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz" - integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== - dependencies: - type-fest "^0.20.2" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw== - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -graceful-fs@^4.1.6, graceful-fs@^4.2.0: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1: - version "3.3.2" - resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - -hyphenate-style-name@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz" - integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== - -ignore@^5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" - integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inline-style-prefixer@^6.0.0: - version "6.0.4" - resolved "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-6.0.4.tgz" - integrity sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg== - dependencies: - css-in-js-utils "^3.1.0" - fast-loops "^1.1.3" - -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -js-cookie@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz" - integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== - -js-sdsl@^4.1.4: - version "4.1.5" - resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz" - integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q== - -js-sha3@0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json5@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz" - integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== - dependencies: - minimist "^1.2.0" - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.2: - version "3.3.3" - resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz" - integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== - dependencies: - array-includes "^3.1.5" - object.assign "^4.1.3" - -jwt-decode@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-4.0.0.tgz#2270352425fd413785b2faf11f6e755c5151bd4b" - integrity sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA== - -language-subtag-registry@~0.3.2: - version "0.3.22" - resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz" - integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== - -language-tags@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz" - integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== - dependencies: - language-subtag-registry "~0.3.2" - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash@^4.17.11, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -make-dir@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -match-sorter@^6.0.2: - version "6.3.4" - resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.4.tgz#afa779d8e922c81971fbcb4781c7003ace781be7" - integrity sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg== - dependencies: - "@babel/runtime" "^7.23.8" - remove-accents "0.5.0" - -mdn-data@2.0.14: - version "2.0.14" - resolved "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz" - integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== - -"memoize-one@>=3.1.1 <6": - version "5.2.1" - resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" - integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -microseconds@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39" - integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12: - version "2.1.35" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimist@^1.2.0, minimist@^1.2.6: - version "1.2.7" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz" - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== - -moment@^2.29.4: - version "2.29.4" - resolved "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz" - integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.2, ms@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -nano-css@^5.3.1: - version "5.3.5" - resolved "https://registry.npmjs.org/nano-css/-/nano-css-5.3.5.tgz" - integrity sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg== - dependencies: - css-tree "^1.1.2" - csstype "^3.0.6" - fastest-stable-stringify "^2.0.2" - inline-style-prefixer "^6.0.0" - rtl-css-js "^1.14.0" - sourcemap-codec "^1.4.8" - stacktrace-js "^2.0.2" - stylis "^4.0.6" - -nano-time@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef" - integrity sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA== - dependencies: - big-integer "^1.6.16" - -nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -next@13.0.0: - version "13.0.0" - resolved "https://registry.npmjs.org/next/-/next-13.0.0.tgz" - integrity sha512-puH1WGM6rGeFOoFdXXYfUxN9Sgi4LMytCV5HkQJvVUOhHfC1DoVqOfvzaEteyp6P04IW+gbtK2Q9pInVSrltPA== - dependencies: - "@next/env" "13.0.0" - "@swc/helpers" "0.4.11" - caniuse-lite "^1.0.30001406" - postcss "8.4.14" - styled-jsx "5.1.0" - use-sync-external-store "1.2.0" - optionalDependencies: - "@next/swc-android-arm-eabi" "13.0.0" - "@next/swc-android-arm64" "13.0.0" - "@next/swc-darwin-arm64" "13.0.0" - "@next/swc-darwin-x64" "13.0.0" - "@next/swc-freebsd-x64" "13.0.0" - "@next/swc-linux-arm-gnueabihf" "13.0.0" - "@next/swc-linux-arm64-gnu" "13.0.0" - "@next/swc-linux-arm64-musl" "13.0.0" - "@next/swc-linux-x64-gnu" "13.0.0" - "@next/swc-linux-x64-musl" "13.0.0" - "@next/swc-win32-arm64-msvc" "13.0.0" - "@next/swc-win32-ia32-msvc" "13.0.0" - "@next/swc-win32-x64-msvc" "13.0.0" - -numeral@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/numeral/-/numeral-2.0.6.tgz" - integrity sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA== - -object-assign@^4.0.1, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.12.2, object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.3, object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.entries@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz" - integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.fromentries@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz" - integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.hasown@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz" - integrity sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A== - dependencies: - define-properties "^1.1.4" - es-abstract "^1.19.5" - -object.values@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -oblivious-set@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/oblivious-set/-/oblivious-set-1.0.0.tgz#c8316f2c2fb6ff7b11b6158db3234c49f733c566" - integrity sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw== - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.3.0, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== - -pkg-dir@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -postcss-value-parser@^4.0.2: - version "4.2.0" - resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -postcss@8.4.14: - version "8.4.14" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz" - integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== - dependencies: - nanoid "^3.3.4" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prop-types@^15.5.7, prop-types@^15.6.2, prop-types@^15.8.1: - version "15.8.1" - resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - -punycode@^2.1.0: - version "2.1.1" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -rc-pagination@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-4.2.0.tgz#b7222b429dec38f6c74e139a30ae7765e9a0b8a6" - integrity sha512-V6qeANJsT6tmOcZ4XiUmj8JXjRLbkusuufpuoBw2GiAn94fIixYjFLmbruD1Sbhn8fPLDnWawPp4CN37zQorvw== - dependencies: - "@babel/runtime" "^7.10.1" - classnames "^2.3.2" - rc-util "^5.38.0" - -rc-util@^5.38.0: - version "5.43.0" - resolved "https://registry.yarnpkg.com/rc-util/-/rc-util-5.43.0.tgz#bba91fbef2c3e30ea2c236893746f3e9b05ecc4c" - integrity sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw== - dependencies: - "@babel/runtime" "^7.18.3" - react-is "^18.2.0" - -react-apexcharts@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.4.0.tgz" - integrity sha512-DrcMV4aAMrUG+n6412yzyATWEyCDWlpPBBhVbpzBC4PDeuYU6iF84SmExbck+jx5MUm4U5PM3/T307Mc3kzc9Q== - dependencies: - prop-types "^15.5.7" - -react-dom@18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.0" - -react-is@^16.13.1, react-is@^16.7.0: - version "16.13.1" - resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-is@^18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - -react-loader-spinner@^5.3.4: - version "5.3.4" - resolved "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-5.3.4.tgz" - integrity sha512-G2vw4ssX+RDZ/vfaeva06yfNqyFViv/u+tVZ3kFLy5TKNlNx2DbuwreBSpRtPespQA+VxinxUJsigwLwG9erOg== - dependencies: - react-is "^18.2.0" - styled-components "^5.3.5" - styled-tools "^1.7.2" - -react-loading-skeleton@^3.3.1: - version "3.3.1" - resolved "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.3.1.tgz" - integrity sha512-NilqqwMh2v9omN7LteiDloEVpFyMIa0VGqF+ukqp0ncVlYu1sKYbYGX9JEl+GtOT9TKsh04zCHAbavnQ2USldA== - -react-query@^3.39.3: - version "3.39.3" - resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.39.3.tgz#4cea7127c6c26bdea2de5fb63e51044330b03f35" - integrity sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g== - dependencies: - "@babel/runtime" "^7.5.5" - broadcast-channel "^3.4.1" - match-sorter "^6.0.2" - -react-remove-scroll-bar@^2.3.4: - version "2.3.6" - resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz" - integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g== - dependencies: - react-style-singleton "^2.2.1" - tslib "^2.0.0" - -react-remove-scroll@2.5.7: - version "2.5.7" - resolved "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz" - integrity sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA== - dependencies: - react-remove-scroll-bar "^2.3.4" - react-style-singleton "^2.2.1" - tslib "^2.1.0" - use-callback-ref "^1.3.0" - use-sidecar "^1.1.2" - -react-slider@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/react-slider/-/react-slider-2.0.6.tgz#8c7ff0301211f7c3ff32aa0163b33bdab6258559" - integrity sha512-gJxG1HwmuMTJ+oWIRCmVWvgwotNCbByTwRkFZC6U4MBsHqJBmxwbYRJUmxy4Tke1ef8r9jfXjgkmY/uHOCEvbA== - dependencies: - prop-types "^15.8.1" - -react-spring@^9.0.0-rc.3: - version "9.5.5" - resolved "https://registry.npmjs.org/react-spring/-/react-spring-9.5.5.tgz" - integrity sha512-vMGVd2yjgxWcRCzoLn9AD1d24+WpunHBRg5DoehcRdiBocaOH6qgle0xN9C5LPplXfv4yIpS5QWGN5MKrWxSZg== - dependencies: - "@react-spring/core" "~9.5.5" - "@react-spring/konva" "~9.5.5" - "@react-spring/native" "~9.5.5" - "@react-spring/three" "~9.5.5" - "@react-spring/web" "~9.5.5" - "@react-spring/zdog" "~9.5.5" - -react-style-singleton@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz" - integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== - dependencies: - get-nonce "^1.0.0" - invariant "^2.2.4" - tslib "^2.0.0" - -react-toastify@^9.0.8: - version "9.0.8" - resolved "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.8.tgz" - integrity sha512-EwM+teWt49HSHx+67qI08yLAW1zAsBxCXLCsUfxHYv1W7/R3ZLhrqKalh7j+kjgPna1h5LQMSMwns4tB4ww2yQ== - dependencies: - clsx "^1.1.1" - -react-toggle-dark-mode@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/react-toggle-dark-mode/-/react-toggle-dark-mode-1.1.0.tgz" - integrity sha512-C3qv5JxDrzAWptapUjkHGoUINz4zuKZ/ZN42lBnM8So7kEKLJu2ynDwGMSfE0C8t7K7EYEGAK+fu2MtoqVYuWw== - dependencies: - react-spring "^9.0.0-rc.3" - -react-transition-group@^4.4.5: - version "4.4.5" - resolved "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz" - integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== - dependencies: - "@babel/runtime" "^7.5.5" - dom-helpers "^5.0.1" - loose-envify "^1.4.0" - prop-types "^15.6.2" - -react-universal-interface@^0.6.2: - version "0.6.2" - resolved "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz" - integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw== - -react-use@^17.4.0: - version "17.4.0" - resolved "https://registry.npmjs.org/react-use/-/react-use-17.4.0.tgz" - integrity sha512-TgbNTCA33Wl7xzIJegn1HndB4qTS9u03QUwyNycUnXaweZkE4Kq2SB+Yoxx8qbshkZGYBDvUXbXWRUmQDcZZ/Q== - dependencies: - "@types/js-cookie" "^2.2.6" - "@xobotyi/scrollbar-width" "^1.9.5" - copy-to-clipboard "^3.3.1" - fast-deep-equal "^3.1.3" - fast-shallow-equal "^1.0.0" - js-cookie "^2.2.1" - nano-css "^5.3.1" - react-universal-interface "^0.6.2" - resize-observer-polyfill "^1.5.1" - screenfull "^5.1.0" - set-harmonic-interval "^1.0.1" - throttle-debounce "^3.0.1" - ts-easing "^0.2.0" - tslib "^2.1.0" - -react-virtualized-auto-sizer@1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.7.tgz#bfb8414698ad1597912473de3e2e5f82180c1195" - integrity sha512-Mxi6lwOmjwIjC1X4gABXMJcKHsOo0xWl3E3ugOgufB8GJU+MqrtY35aBuvCYv/razQ1Vbp7h1gWJjGjoNN5pmA== - -react-window@1.8.7: - version "1.8.7" - resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.7.tgz#5e9fd0d23f48f432d7022cdb327219353a15f0d4" - integrity sha512-JHEZbPXBpKMmoNO1bNhoXOOLg/ujhL/BU4IqVU9r8eQPcy5KQnGHIHDRkJ0ns9IM5+Aq5LNwt3j8t3tIrePQzA== - dependencies: - "@babel/runtime" "^7.0.0" - memoize-one ">=3.1.1 <6" - -react@18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== - dependencies: - loose-envify "^1.1.0" - -regenerator-runtime@^0.13.10: - version "0.13.10" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.10.tgz" - integrity sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw== - -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - -regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - -regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -remove-accents@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.5.0.tgz#77991f37ba212afba162e375b627631315bed687" - integrity sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A== - -resize-observer-polyfill@^1.5.1: - version "1.5.1" - resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz" - integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0: - version "1.22.1" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^2.0.0-next.3: - version "2.0.0-next.4" - resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz" - integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@3.0.2, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rtl-css-js@^1.14.0: - version "1.16.1" - resolved "https://registry.npmjs.org/rtl-css-js/-/rtl-css-js-1.16.1.tgz" - integrity sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg== - dependencies: - "@babel/runtime" "^7.1.2" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - -scheduler@^0.23.0: - version "0.23.0" - resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz" - integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== - dependencies: - loose-envify "^1.1.0" - -screenfull@^5.1.0: - version "5.2.0" - resolved "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz" - integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA== - -semver@^6.0.0: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^6.3.0: - version "6.3.0" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.3.7: - version "7.3.8" - resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== - dependencies: - lru-cache "^6.0.0" - -set-harmonic-interval@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz" - integrity sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g== - -shallowequal@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz" - integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -size-sensor@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.1.tgz" - integrity sha512-QTy7MnuugCFXIedXRpUSk9gUnyNiaxIdxGfUjr8xxXOqIB3QvBUYP9+b51oCg2C4dnhaeNk/h57TxjbvoJrJUA== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -sonner@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/sonner/-/sonner-1.5.0.tgz#af359f817063318415326b33aab54c5d17c747b7" - integrity sha512-FBjhG/gnnbN6FY0jaNnqZOMmB73R+5IiyYAw8yBj7L54ER7HB3fOSE5OFiQiE2iXWxeXKvg6fIP4LtVppHEdJA== - -source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== - -source-map@0.5.6: - version "0.5.6" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz" - integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA== - -source-map@^0.5.7: - version "0.5.7" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" - integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== - -source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -sourcemap-codec@^1.4.8: - version "1.4.8" - resolved "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== - -stack-generator@^2.0.5: - version "2.0.10" - resolved "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz" - integrity sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ== - dependencies: - stackframe "^1.3.4" - -stackframe@^1.3.4: - version "1.3.4" - resolved "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz" - integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== - -stacktrace-gps@^3.0.4: - version "3.1.2" - resolved "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz" - integrity sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ== - dependencies: - source-map "0.5.6" - stackframe "^1.3.4" - -stacktrace-js@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz" - integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg== - dependencies: - error-stack-parser "^2.0.6" - stack-generator "^2.0.5" - stacktrace-gps "^3.0.4" - -string.prototype.matchall@^4.0.7: - version "4.0.7" - resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz" - integrity sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - has-symbols "^1.0.3" - internal-slot "^1.0.3" - regexp.prototype.flags "^1.4.1" - side-channel "^1.0.4" - -string.prototype.trimend@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz" - integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - -string.prototype.trimstart@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz" - integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.19.5" - -strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -strip-outer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" - integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== - dependencies: - escape-string-regexp "^1.0.2" - -styled-components@^5.3.5, styled-components@^5.3.6: - version "5.3.6" - resolved "https://registry.npmjs.org/styled-components/-/styled-components-5.3.6.tgz" - integrity sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/traverse" "^7.4.5" - "@emotion/is-prop-valid" "^1.1.0" - "@emotion/stylis" "^0.8.4" - "@emotion/unitless" "^0.7.4" - babel-plugin-styled-components ">= 1.12.0" - css-to-react-native "^3.0.0" - hoist-non-react-statics "^3.0.0" - shallowequal "^1.1.0" - supports-color "^5.5.0" - -styled-jsx@5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.0.tgz" - integrity sha512-/iHaRJt9U7T+5tp6TRelLnqBqiaIT0HsO0+vgyj8hK2KUk7aejFqRrumqPUlAqDwAj8IbS/1hk3IhBAAK/FCUQ== - dependencies: - client-only "0.0.1" - -styled-tools@^1.7.2: - version "1.7.2" - resolved "https://registry.npmjs.org/styled-tools/-/styled-tools-1.7.2.tgz" - integrity sha512-IjLxzM20RMwAsx8M1QoRlCG/Kmq8lKzCGyospjtSXt/BTIIcvgTonaxQAsKnBrsZNwhpHzO9ADx5te0h76ILVg== - -stylis@4.1.3, stylis@^4.0.6: - version "4.1.3" - resolved "https://registry.npmjs.org/stylis/-/stylis-4.1.3.tgz" - integrity sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA== - -supports-color@^5.3.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -svg.draggable.js@^2.2.2: - version "2.2.2" - resolved "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz" - integrity sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw== - dependencies: - svg.js "^2.0.1" - -svg.easing.js@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz" - integrity sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA== - dependencies: - svg.js ">=2.3.x" - -svg.filter.js@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz" - integrity sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw== - dependencies: - svg.js "^2.2.5" - -svg.js@>=2.3.x, svg.js@^2.0.1, svg.js@^2.2.5, svg.js@^2.4.0, svg.js@^2.6.5: - version "2.7.1" - resolved "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz" - integrity sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA== - -svg.pathmorphing.js@^0.1.3: - version "0.1.3" - resolved "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz" - integrity sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww== - dependencies: - svg.js "^2.4.0" - -svg.resize.js@^1.4.3: - version "1.4.3" - resolved "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz" - integrity sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw== - dependencies: - svg.js "^2.6.5" - svg.select.js "^2.1.2" - -svg.select.js@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz" - integrity sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ== - dependencies: - svg.js "^2.2.5" - -svg.select.js@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz" - integrity sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw== - dependencies: - svg.js "^2.6.5" - -tabbable@^5.3.3: - version "5.3.3" - resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.3.3.tgz#aac0ff88c73b22d6c3c5a50b1586310006b47fbf" - integrity sha512-QD9qKY3StfbZqWOPLp0++pOrAVb/HbUi5xCc8cUo4XjP19808oaMiDzn0leBY5mCespIBM0CIZePzZjgzR83kA== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -throttle-debounce@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-3.0.1.tgz" - integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toggle-selection@^1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz" - integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== - -trim-repeated@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" - integrity sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg== - dependencies: - escape-string-regexp "^1.0.2" - -ts-easing@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/ts-easing/-/ts-easing-0.2.0.tgz" - integrity sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ== - -tsconfig-paths@^3.14.1: - version "3.14.1" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" - integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== - -tslib@2.4.0, tslib@^2.0.0, tslib@^2.1.0, tslib@^2.4.0: - version "2.4.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" - integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== - -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -typescript@4.8.4: - version "4.8.4" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz" - integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -universalify@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" - integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== - -unload@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7" - integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA== - dependencies: - "@babel/runtime" "^7.6.2" - detect-node "^2.0.4" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -use-callback-ref@^1.3.0: - version "1.3.2" - resolved "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.2.tgz" - integrity sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA== - dependencies: - tslib "^2.0.0" - -use-sidecar@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz" - integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== - dependencies: - detect-node-es "^1.1.0" - tslib "^2.0.0" - -use-sync-external-store@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" - integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -word-wrap@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@8.17.1: - version "8.17.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" - integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^1.10.0: - version "1.10.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zrender@5.4.3: - version "5.4.3" - resolved "https://registry.npmjs.org/zrender/-/zrender-5.4.3.tgz" - integrity sha512-DRUM4ZLnoaT0PBVvGBDO9oWIDBKFdAVieNWxWwK0niYzJCMwGchRk21/hsE+RKkIveH3XHCyvXcJDkgLVvfizQ== - dependencies: - tslib "2.3.0" +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@adraffy/ens-normalize@npm:1.10.1": + version: 1.10.1 + resolution: "@adraffy/ens-normalize@npm:1.10.1" + checksum: 10c0/fdd647604e8fac6204921888aaf5a6bc65eabf0d2921bc5f93b64d01f4bc33ead167c1445f7de05468d05cd92ac31b74c68d2be840c62b79d73693308f885c06 + languageName: node + linkType: hard + +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/code-frame@npm:7.18.6" + dependencies: + "@babel/highlight": "npm:^7.18.6" + checksum: 10c0/e3966f2717b7ebd9610524730e10b75ee74154f62617e5e115c97dbbbabc5351845c9aa850788012cb4d9aee85c3dc59fe6bef36690f244e8dcfca34bd35e9c9 + languageName: node + linkType: hard + +"@babel/generator@npm:^7.20.0": + version: 7.20.0 + resolution: "@babel/generator@npm:7.20.0" + dependencies: + "@babel/types": "npm:^7.20.0" + "@jridgewell/gen-mapping": "npm:^0.3.2" + jsesc: "npm:^2.5.1" + checksum: 10c0/12d981f2b391a7ffaacbc4b91bbed47721c8063bb66fccfdee0dc929629de674bb6a0b37000980cb24e2c6a6a04fd3e5a5df0eb4a9074315009c59de19f55a70 + languageName: node + linkType: hard + +"@babel/helper-annotate-as-pure@npm:^7.16.0": + version: 7.18.6 + resolution: "@babel/helper-annotate-as-pure@npm:7.18.6" + dependencies: + "@babel/types": "npm:^7.18.6" + checksum: 10c0/e413cd022e1e21232c1ce98f3e1198ec5f4774c7eceb81155a45f9cb6d8481f3983c52f83252309856668e728c751f0340d29854b604530a694899208df6bcc3 + languageName: node + linkType: hard + +"@babel/helper-environment-visitor@npm:^7.18.9": + version: 7.18.9 + resolution: "@babel/helper-environment-visitor@npm:7.18.9" + checksum: 10c0/a69dd50ea91d8143b899a40ca7a387fa84dbaa02e606d8692188c7c59bd4007bcd632c189f7b7dab72cb7a016e159557a6fccf7093ab9b584d87cf2ea8cf36b7 + languageName: node + linkType: hard + +"@babel/helper-function-name@npm:^7.19.0": + version: 7.19.0 + resolution: "@babel/helper-function-name@npm:7.19.0" + dependencies: + "@babel/template": "npm:^7.18.10" + "@babel/types": "npm:^7.19.0" + checksum: 10c0/a4181d23274d926df3a8032fb2ff210b8a27c83fedd9e7bd148a6877cb4070be4caf69ddae1bf29447e1e84da807ff769a31ca661ef55ecd4d4d672073a68c48 + languageName: node + linkType: hard + +"@babel/helper-hoist-variables@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-hoist-variables@npm:7.18.6" + dependencies: + "@babel/types": "npm:^7.18.6" + checksum: 10c0/830aa7ca663b0d2a025513ab50a9a10adb2a37d8cf3ba40bb74b8ac14d45fbc3d08c37b1889b10d36558edfbd34ff914909118ae156c2f0915f2057901b90eff + languageName: node + linkType: hard + +"@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.16.0, @babel/helper-module-imports@npm:^7.16.7": + version: 7.18.6 + resolution: "@babel/helper-module-imports@npm:7.18.6" + dependencies: + "@babel/types": "npm:^7.18.6" + checksum: 10c0/a92e28fc4b5dbb0d0afd4a313efc0cf5b26ce1adc0c01fc22724c997789ac7d7f4f30bc9143d94a6ba8b0a035933cf63a727a365ce1c57dbca0935f48de96244 + languageName: node + linkType: hard + +"@babel/helper-plugin-utils@npm:^7.18.6": + version: 7.19.0 + resolution: "@babel/helper-plugin-utils@npm:7.19.0" + checksum: 10c0/9ae9c09cf7e3b6023be2bb66f3ca3b5fa8c2b21b58bd09819d494fcd7ab2a1844056c8dfd609ffb474e3c857a1bc979fa7a60931b0c71d69a3e939ba724498ac + languageName: node + linkType: hard + +"@babel/helper-split-export-declaration@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/helper-split-export-declaration@npm:7.18.6" + dependencies: + "@babel/types": "npm:^7.18.6" + checksum: 10c0/1335b510a9aefcbf60d89648e622715774e56040d72302dc5e176c8d837c9ab81414ccfa9ed771a9f98da7192579bb12ab7a95948bfdc69b03b4a882b3983e48 + languageName: node + linkType: hard + +"@babel/helper-string-parser@npm:^7.19.4": + version: 7.19.4 + resolution: "@babel/helper-string-parser@npm:7.19.4" + checksum: 10c0/e20c81582e75df2a020a1c547376668a6e1e1c2ca535a6b7abb25b83d5536c99c0d113184bbe87c1a26e923a9bb0c6e5279fca8db6bd609cd3499fafafc01598 + languageName: node + linkType: hard + +"@babel/helper-string-parser@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-string-parser@npm:7.25.7" + checksum: 10c0/73ef2ceb81f8294678a0afe8ab0103729c0370cac2e830e0d5128b03be5f6a2635838af31d391d763e3c5a4460ed96f42fd7c9b552130670d525be665913bc4c + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.18.6, @babel/helper-validator-identifier@npm:^7.19.1": + version: 7.19.1 + resolution: "@babel/helper-validator-identifier@npm:7.19.1" + checksum: 10c0/f978ecfea840f65b64ab9e17fac380625a45f4fe1361eeb29867fcfd1c9eaa72abd7023f2f40ac3168587d7e5153660d16cfccb352a557be2efd347a051b4b20 + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.25.7": + version: 7.25.7 + resolution: "@babel/helper-validator-identifier@npm:7.25.7" + checksum: 10c0/07438e5bf01ab2882a15027fdf39ac3b0ba1b251774a5130917907014684e2f70fef8fd620137ca062c4c4eedc388508d2ea7a3a7d9936a32785f4fe116c68c0 + languageName: node + linkType: hard + +"@babel/highlight@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/highlight@npm:7.18.6" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.18.6" + chalk: "npm:^2.0.0" + js-tokens: "npm:^4.0.0" + checksum: 10c0/a6a6928d25099ef04c337fcbb829fab8059bb67d31ac37212efd611bdbe247d0e71a5096c4524272cb56399f40251fac57c025e42d3bc924db0183a6435a60ac + languageName: node + linkType: hard + +"@babel/parser@npm:^7.18.10, @babel/parser@npm:^7.20.0": + version: 7.20.0 + resolution: "@babel/parser@npm:7.20.0" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/644e0da72116cfbb7a084523f3cfc26685fb65202e9bcd4da45c0efa8e258ed66a653525000401f6f2d010f7fa8291892b6b81193aa01e359e6b58b20f69e609 + languageName: node + linkType: hard + +"@babel/plugin-syntax-jsx@npm:^7.17.12": + version: 7.18.6 + resolution: "@babel/plugin-syntax-jsx@npm:7.18.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.18.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/d6d88b16e727bfe75c6ad6674bf7171bd5b2007ebab3f785eff96a98889cc2dd9d9b05a9ad8a265e04e67eddee81d63fcade27db033bb5aa5cc73f45cc450d6d + languageName: node + linkType: hard + +"@babel/runtime-corejs3@npm:^7.10.2": + version: 7.20.0 + resolution: "@babel/runtime-corejs3@npm:7.20.0" + dependencies: + core-js-pure: "npm:^3.25.1" + regenerator-runtime: "npm:^0.13.10" + checksum: 10c0/b4d45dc966263c05fa6b68201a6ed388abbd7c47fab43a200c54f9857e2d17dd84cb5f3b07cc15616b60b65c201684318ee74edb1fe9afe2c1b5fa38ad043c8d + languageName: node + linkType: hard + +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.10.1": + version: 7.25.4 + resolution: "@babel/runtime@npm:7.25.4" + dependencies: + regenerator-runtime: "npm:^0.14.0" + checksum: 10c0/33e937e685f0bfc2d40c219261e2e50d0df7381a6e7cbf56b770e0c5d77cb0c21bf4d97da566cf0164317ed7508e992082c7b6cce7aaa3b17da5794f93fbfb46 + languageName: node + linkType: hard + +"@babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.19.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7": + version: 7.20.0 + resolution: "@babel/runtime@npm:7.20.0" + dependencies: + regenerator-runtime: "npm:^0.13.10" + checksum: 10c0/945bc7d406c5b39be3e72c9c8cc2ba4aa71e0ec0df8493b39c5af295e7ce728aa917783f80244a4e9f9c0f827988d88722b1c9e45845a3dd753e1025f72d787e + languageName: node + linkType: hard + +"@babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.6.2, @babel/runtime@npm:^7.7.2": + version: 7.25.0 + resolution: "@babel/runtime@npm:7.25.0" + dependencies: + regenerator-runtime: "npm:^0.14.0" + checksum: 10c0/bd3faf246170826cef2071a94d7b47b49d532351360ecd17722d03f6713fd93a3eb3dbd9518faa778d5e8ccad7392a7a604e56bd37aaad3f3aa68d619ccd983d + languageName: node + linkType: hard + +"@babel/template@npm:^7.18.10": + version: 7.18.10 + resolution: "@babel/template@npm:7.18.10" + dependencies: + "@babel/code-frame": "npm:^7.18.6" + "@babel/parser": "npm:^7.18.10" + "@babel/types": "npm:^7.18.10" + checksum: 10c0/d807944427b8899125e71687d2f631731e44a64a155d39e479ff9d1eaf5341de78c5c19cf64d3341bd676e16f779f13b588aac0ec75bf65f822d8936ee227490 + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.4.5": + version: 7.20.0 + resolution: "@babel/traverse@npm:7.20.0" + dependencies: + "@babel/code-frame": "npm:^7.18.6" + "@babel/generator": "npm:^7.20.0" + "@babel/helper-environment-visitor": "npm:^7.18.9" + "@babel/helper-function-name": "npm:^7.19.0" + "@babel/helper-hoist-variables": "npm:^7.18.6" + "@babel/helper-split-export-declaration": "npm:^7.18.6" + "@babel/parser": "npm:^7.20.0" + "@babel/types": "npm:^7.20.0" + debug: "npm:^4.1.0" + globals: "npm:^11.1.0" + checksum: 10c0/6f34c946b85a29b2973b8bc37c7a7acaeee0ad050e5f0955dabe5009f514ad9e717c8978649ac237d536284ad9f3bb4d2b749c9cd78ed9fa07f635dcedb8afaa + languageName: node + linkType: hard + +"@babel/types@npm:^7.18.10, @babel/types@npm:^7.18.6, @babel/types@npm:^7.19.0, @babel/types@npm:^7.20.0": + version: 7.20.0 + resolution: "@babel/types@npm:7.20.0" + dependencies: + "@babel/helper-string-parser": "npm:^7.19.4" + "@babel/helper-validator-identifier": "npm:^7.19.1" + to-fast-properties: "npm:^2.0.0" + checksum: 10c0/8b9c960eb013142eaf6294d77b75e469b7e97461bd7ad939e625ed74865fbf5a1c20b7989ec3357d0f4ffd93dd79d6daead08c0c06647815d8bbe94dae445f5c + languageName: node + linkType: hard + +"@babel/types@npm:^7.8.3": + version: 7.25.8 + resolution: "@babel/types@npm:7.25.8" + dependencies: + "@babel/helper-string-parser": "npm:^7.25.7" + "@babel/helper-validator-identifier": "npm:^7.25.7" + to-fast-properties: "npm:^2.0.0" + checksum: 10c0/55ca2d6df6426c98db2769ce884ce5e9de83a512ea2dd7bcf56c811984dc14351cacf42932a723630c5afcff2455809323decd645820762182f10b7b5252b59f + languageName: node + linkType: hard + +"@emotion/babel-plugin@npm:^11.10.5": + version: 11.10.5 + resolution: "@emotion/babel-plugin@npm:11.10.5" + dependencies: + "@babel/helper-module-imports": "npm:^7.16.7" + "@babel/plugin-syntax-jsx": "npm:^7.17.12" + "@babel/runtime": "npm:^7.18.3" + "@emotion/hash": "npm:^0.9.0" + "@emotion/memoize": "npm:^0.8.0" + "@emotion/serialize": "npm:^1.1.1" + babel-plugin-macros: "npm:^3.1.0" + convert-source-map: "npm:^1.5.0" + escape-string-regexp: "npm:^4.0.0" + find-root: "npm:^1.1.0" + source-map: "npm:^0.5.7" + stylis: "npm:4.1.3" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/b877d089c07ad7e571f7d1b8393c21b8ab54dc24b4b7533827c00549a4fe5345af55869f57c139f7dec09615b93ca66195aa31023bbc5af89cf3ec85e80a2281 + languageName: node + linkType: hard + +"@emotion/cache@npm:^11.10.3, @emotion/cache@npm:^11.10.5": + version: 11.10.5 + resolution: "@emotion/cache@npm:11.10.5" + dependencies: + "@emotion/memoize": "npm:^0.8.0" + "@emotion/sheet": "npm:^1.2.1" + "@emotion/utils": "npm:^1.2.0" + "@emotion/weak-memoize": "npm:^0.3.0" + stylis: "npm:4.1.3" + checksum: 10c0/eeb6891ab04cf17ace0e175742550b97c30df777d6c5b145e91c4c9fbd783c29b4dabe12a8c786b78f37176313a8295c9b90c69d875e6caab5f7e4677a18be91 + languageName: node + linkType: hard + +"@emotion/hash@npm:^0.9.0": + version: 0.9.0 + resolution: "@emotion/hash@npm:0.9.0" + checksum: 10c0/0910d3e9ec46cc780f691c96fb6f6f67b4f080b50ecf4f441bc4b33b5906e28099f530a368fe0b31c6bad38a857ac44df3c36f8978be603789d71330ac01af12 + languageName: node + linkType: hard + +"@emotion/is-prop-valid@npm:^1.1.0, @emotion/is-prop-valid@npm:^1.2.0": + version: 1.2.0 + resolution: "@emotion/is-prop-valid@npm:1.2.0" + dependencies: + "@emotion/memoize": "npm:^0.8.0" + checksum: 10c0/098bfde166ddbc3ad635157dff8dd8b90ceb5ee2804b3dbc9ffbffcac33955390d6c6e94dc36b1fde8c90f49dc1e1359dfdcd967906b006a3966382dbe8cc90b + languageName: node + linkType: hard + +"@emotion/memoize@npm:^0.8.0": + version: 0.8.0 + resolution: "@emotion/memoize@npm:0.8.0" + checksum: 10c0/246087ec09b32b295af67a094253831f398aabd953d03d14f186acb8607ed2a755e944f5e20b5ccebb461f15c2e5ccbf8fe977bcf3be951cf10961c504e1e65b + languageName: node + linkType: hard + +"@emotion/react@npm:^11.10.5": + version: 11.10.5 + resolution: "@emotion/react@npm:11.10.5" + dependencies: + "@babel/runtime": "npm:^7.18.3" + "@emotion/babel-plugin": "npm:^11.10.5" + "@emotion/cache": "npm:^11.10.5" + "@emotion/serialize": "npm:^1.1.1" + "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.0" + "@emotion/utils": "npm:^1.2.0" + "@emotion/weak-memoize": "npm:^0.3.0" + hoist-non-react-statics: "npm:^3.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + react: ">=16.8.0" + peerDependenciesMeta: + "@babel/core": + optional: true + "@types/react": + optional: true + checksum: 10c0/911fdc54a44304e70e8f2721ba2c323695171856d5337c761ff5f952f2e651d54b1b5b68319573a0d9a5a847d13f622c2d951317176ea701607d349f8a9cd0f5 + languageName: node + linkType: hard + +"@emotion/serialize@npm:^1.1.1": + version: 1.1.1 + resolution: "@emotion/serialize@npm:1.1.1" + dependencies: + "@emotion/hash": "npm:^0.9.0" + "@emotion/memoize": "npm:^0.8.0" + "@emotion/unitless": "npm:^0.8.0" + "@emotion/utils": "npm:^1.2.0" + csstype: "npm:^3.0.2" + checksum: 10c0/ea353abbf530ede8b74fe4df30eb626f245f710ce0bfcb9d34e72630a1dede688fddf02b1143f33a1a4ef5b66b70715a3c1cd6a12ec43f5b585ed60d4f3e8712 + languageName: node + linkType: hard + +"@emotion/sheet@npm:^1.2.1": + version: 1.2.1 + resolution: "@emotion/sheet@npm:1.2.1" + checksum: 10c0/88268c00005d310df3ebb249b839ad0b234943da5a0cc614b232b9bd4ae600292dca9b0f61c45cde3a592c77459e880d77a2aa73af20ec3c0d579afccc3f71af + languageName: node + linkType: hard + +"@emotion/styled@npm:^11.10.5": + version: 11.10.5 + resolution: "@emotion/styled@npm:11.10.5" + dependencies: + "@babel/runtime": "npm:^7.18.3" + "@emotion/babel-plugin": "npm:^11.10.5" + "@emotion/is-prop-valid": "npm:^1.2.0" + "@emotion/serialize": "npm:^1.1.1" + "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.0" + "@emotion/utils": "npm:^1.2.0" + peerDependencies: + "@babel/core": ^7.0.0 + "@emotion/react": ^11.0.0-rc.0 + react: ">=16.8.0" + peerDependenciesMeta: + "@babel/core": + optional: true + "@types/react": + optional: true + checksum: 10c0/63f974c508df651115ff28b2230feddfc27e0cfcb1a4b0dbdf03c57dfdb06edfc6858b298c0c475326d5a3b25982271625d75d107b4c85c2c0166c12fc0091b8 + languageName: node + linkType: hard + +"@emotion/stylis@npm:^0.8.4": + version: 0.8.5 + resolution: "@emotion/stylis@npm:0.8.5" + checksum: 10c0/f109e3f11cb0d48e8658aaa23578c5bcfe35e297819cfb089a3de6ba8dc0f89b0960474922690c6028df5d2e1895b4967f2fb280642c030054c312f1e137ce26 + languageName: node + linkType: hard + +"@emotion/unitless@npm:^0.7.4": + version: 0.7.5 + resolution: "@emotion/unitless@npm:0.7.5" + checksum: 10c0/4d0d94f53cb97b4481bbfa394953e1899a0b877644642ba9dd7247c27eb8c48e14e22aeb11411d7d9874685ad85dd5fb5b50eb78c6d8840eb56a84b92dcef2f4 + languageName: node + linkType: hard + +"@emotion/unitless@npm:^0.8.0": + version: 0.8.0 + resolution: "@emotion/unitless@npm:0.8.0" + checksum: 10c0/1f2cfb7c0ccb83c20b1c6d8d92a74a93da4b2a440f9a0d49ded08647faf299065a2ffde17e1335920fa10397b85f8635bbfe14f3cd29222a59ea81d978478072 + languageName: node + linkType: hard + +"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.0": + version: 1.0.0 + resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.0" + peerDependencies: + react: ">=16.8.0" + checksum: 10c0/0c5fbd36a4f416a5abaf428ba3dca6e79018c4c74016ecb4e3991a11cf8b5dbd306d7770fee09692971335e33f97e3b555deda595e5ae7831841505078bd07d7 + languageName: node + linkType: hard + +"@emotion/utils@npm:^1.2.0": + version: 1.2.0 + resolution: "@emotion/utils@npm:1.2.0" + checksum: 10c0/7051cec83bb49688549667484058d3a19a30001fa3692c23f7a2e727c05121f952854e1196feb9ece4fa36914705ebf474edba833a2178bdc133c654b5e3ca7d + languageName: node + linkType: hard + +"@emotion/weak-memoize@npm:^0.3.0": + version: 0.3.0 + resolution: "@emotion/weak-memoize@npm:0.3.0" + checksum: 10c0/1771687cc3b3280371de12698f1b78756c64654fc7d15ce76e1fb5d4adf9fd49d4411e41276bbfd5b521ef9cef647196aa9dca26f936c466fb80bf48491fa844 + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^1.3.3": + version: 1.3.3 + resolution: "@eslint/eslintrc@npm:1.3.3" + dependencies: + ajv: "npm:^6.12.4" + debug: "npm:^4.3.2" + espree: "npm:^9.4.0" + globals: "npm:^13.15.0" + ignore: "npm:^5.2.0" + import-fresh: "npm:^3.2.1" + js-yaml: "npm:^4.1.0" + minimatch: "npm:^3.1.2" + strip-json-comments: "npm:^3.1.1" + checksum: 10c0/78fe61ae304362df50ae20f00cd41744f20b8ee58d59dddbd6db58a6241238217b7ee9591c315ac9f7737075c0277e551f586d44927eb2e84e643c477db8386f + languageName: node + linkType: hard + +"@floating-ui/core@npm:^1.6.0": + version: 1.6.5 + resolution: "@floating-ui/core@npm:1.6.5" + dependencies: + "@floating-ui/utils": "npm:^0.2.5" + checksum: 10c0/41651f6ebed3123809a3992966d9d6b740048fe255e4754df61043ce28b40ba7202cf7ac163873b7f4c5f9969930e9d7cd3691e178739304eed1adc42bb6c628 + languageName: node + linkType: hard + +"@floating-ui/dom@npm:^1.0.0": + version: 1.6.8 + resolution: "@floating-ui/dom@npm:1.6.8" + dependencies: + "@floating-ui/core": "npm:^1.6.0" + "@floating-ui/utils": "npm:^0.2.5" + checksum: 10c0/d52e257bbf1f04da7882d847dfe128783966a19e6d6a9e6d09d57d32bdc7255efce7ae15c3be781e349ae3b18c4575e910afde3e73ae57c31763e8a799f19f45 + languageName: node + linkType: hard + +"@floating-ui/react-dom@npm:^2.0.0": + version: 2.1.1 + resolution: "@floating-ui/react-dom@npm:2.1.1" + dependencies: + "@floating-ui/dom": "npm:^1.0.0" + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 10c0/732ab64600c511ceb0563b87bc557aa61789fec4f416a3f092bab89e508fa1d3ee5ade0f42051cc56eb5e4db867b87ab7fd48ce82db9fd4c01d94ffa08f60115 + languageName: node + linkType: hard + +"@floating-ui/utils@npm:^0.2.5": + version: 0.2.5 + resolution: "@floating-ui/utils@npm:0.2.5" + checksum: 10c0/9e1c7330433c3a8f226c5a44ed1dcdda13b313c4126ce3281f970d1e471b1c9fd9e1559cc76a0592af25d55a3f81afe1a5778aa7b80e51c9fa01930cd1d5557e + languageName: node + linkType: hard + +"@humanwhocodes/config-array@npm:^0.11.6": + version: 0.11.6 + resolution: "@humanwhocodes/config-array@npm:0.11.6" + dependencies: + "@humanwhocodes/object-schema": "npm:^1.2.1" + debug: "npm:^4.1.1" + minimatch: "npm:^3.0.4" + checksum: 10c0/28bc0630d11c77c45aeff7cbab79159c9cce88ff1f3bc0e4cb9ff4fb271b6d3bfebcbc1ec56ae7f2b28cb31f0903ba98960b6730e66b232cc5d8f374b7d3239d + languageName: node + linkType: hard + +"@humanwhocodes/module-importer@npm:^1.0.1": + version: 1.0.1 + resolution: "@humanwhocodes/module-importer@npm:1.0.1" + checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 + languageName: node + linkType: hard + +"@humanwhocodes/object-schema@npm:^1.2.1": + version: 1.2.1 + resolution: "@humanwhocodes/object-schema@npm:1.2.1" + checksum: 10c0/c3c35fdb70c04a569278351c75553e293ae339684ed75895edc79facc7276e351115786946658d78133130c0cca80e57e2203bc07f8fa7fe7980300e8deef7db + languageName: node + linkType: hard + +"@jridgewell/gen-mapping@npm:^0.3.2": + version: 0.3.2 + resolution: "@jridgewell/gen-mapping@npm:0.3.2" + dependencies: + "@jridgewell/set-array": "npm:^1.0.1" + "@jridgewell/sourcemap-codec": "npm:^1.4.10" + "@jridgewell/trace-mapping": "npm:^0.3.9" + checksum: 10c0/82685c8735c63fe388badee45e2970a6bc83eed1c84d46d8652863bafeca22a6c6cc15812f5999a4535366f4668ccc9ba6d5c67dfb72e846fa8a063806f10afd + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:3.1.0": + version: 3.1.0 + resolution: "@jridgewell/resolve-uri@npm:3.1.0" + checksum: 10c0/78055e2526108331126366572045355051a930f017d1904a4f753d3f4acee8d92a14854948095626f6163cffc24ea4e3efa30637417bb866b84743dec7ef6fd9 + languageName: node + linkType: hard + +"@jridgewell/set-array@npm:^1.0.1": + version: 1.1.2 + resolution: "@jridgewell/set-array@npm:1.1.2" + checksum: 10c0/bc7ab4c4c00470de4e7562ecac3c0c84f53e7ee8a711e546d67c47da7febe7c45cd67d4d84ee3c9b2c05ae8e872656cdded8a707a283d30bd54fbc65aef821ab + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.10": + version: 1.4.14 + resolution: "@jridgewell/sourcemap-codec@npm:1.4.14" + checksum: 10c0/3fbaff1387c1338b097eeb6ff92890d7838f7de0dde259e4983763b44540bfd5ca6a1f7644dc8ad003a57f7e80670d5b96a8402f1386ba9aee074743ae9bad51 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.9": + version: 0.3.17 + resolution: "@jridgewell/trace-mapping@npm:0.3.17" + dependencies: + "@jridgewell/resolve-uri": "npm:3.1.0" + "@jridgewell/sourcemap-codec": "npm:1.4.14" + checksum: 10c0/40b65fcbdd7cc5a60dbe0a2780b6670ebbc1a31c96e43833e0bf2fee0773b1ba5137ab7d137b28fc3f215567bd5f9d06b7b30634ba15636c13bd8a863c20ae9a + languageName: node + linkType: hard + +"@mui/base@npm:5.0.0-alpha.104": + version: 5.0.0-alpha.104 + resolution: "@mui/base@npm:5.0.0-alpha.104" + dependencies: + "@babel/runtime": "npm:^7.19.0" + "@emotion/is-prop-valid": "npm:^1.2.0" + "@mui/types": "npm:^7.2.0" + "@mui/utils": "npm:^5.10.9" + "@popperjs/core": "npm:^2.11.6" + clsx: "npm:^1.2.1" + prop-types: "npm:^15.8.1" + react-is: "npm:^18.2.0" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/be9a4b5bec06151af8a8f2a5f7c49af28a6f6d68138eb4dd8131109cb194e61091a514d620eae18247248cb3aeb3e90449ae19bbc87180417967c17e4895e12d + languageName: node + linkType: hard + +"@mui/core-downloads-tracker@npm:^5.10.12": + version: 5.10.12 + resolution: "@mui/core-downloads-tracker@npm:5.10.12" + checksum: 10c0/a1bc50df61f0dd81f13e9bc79620a6ef27d8f910e50206badcd042755e237def4b71655976f2f4e2b4901d0ac302ce73884d838619e5500c2a3794132e91812e + languageName: node + linkType: hard + +"@mui/icons-material@npm:^5.10.9": + version: 5.10.9 + resolution: "@mui/icons-material@npm:5.10.9" + dependencies: + "@babel/runtime": "npm:^7.19.0" + peerDependencies: + "@mui/material": ^5.0.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/fab8113997efca311bb3ee288a916d84310df97e3e1bc91e25a256518b486a18ba1a9b6f0007936a22ba08c64824184419117e018fc6bde8172413c9c491ef8d + languageName: node + linkType: hard + +"@mui/material@npm:^5.10.12": + version: 5.10.12 + resolution: "@mui/material@npm:5.10.12" + dependencies: + "@babel/runtime": "npm:^7.19.0" + "@mui/base": "npm:5.0.0-alpha.104" + "@mui/core-downloads-tracker": "npm:^5.10.12" + "@mui/system": "npm:^5.10.12" + "@mui/types": "npm:^7.2.0" + "@mui/utils": "npm:^5.10.9" + "@types/react-transition-group": "npm:^4.4.5" + clsx: "npm:^1.2.1" + csstype: "npm:^3.1.1" + prop-types: "npm:^15.8.1" + react-is: "npm:^18.2.0" + react-transition-group: "npm:^4.4.5" + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@types/react": + optional: true + checksum: 10c0/303594a70ee132002a55358b1859d1c95adecb9f15a9d50faef75631341254d3bf365e653b9e9fa86ce1e6ca3b9f10c3f29920acfbebc342c9492736209bf6e2 + languageName: node + linkType: hard + +"@mui/private-theming@npm:^5.10.9": + version: 5.10.9 + resolution: "@mui/private-theming@npm:5.10.9" + dependencies: + "@babel/runtime": "npm:^7.19.0" + "@mui/utils": "npm:^5.10.9" + prop-types: "npm:^15.8.1" + peerDependencies: + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/4438636e74c9f815d95f50c8b2a4a64e7ef85df4775dd66c89acb485880ac74cae719650693adb9c70a22eed81cbb3b659293ecb0cfc5934630adfdb63f5407a + languageName: node + linkType: hard + +"@mui/styled-engine@npm:^5.10.8": + version: 5.10.8 + resolution: "@mui/styled-engine@npm:5.10.8" + dependencies: + "@babel/runtime": "npm:^7.19.0" + "@emotion/cache": "npm:^11.10.3" + csstype: "npm:^3.1.1" + prop-types: "npm:^15.8.1" + peerDependencies: + "@emotion/react": ^11.4.1 + "@emotion/styled": ^11.3.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + checksum: 10c0/fb36680c683336cc6466d980ee639360f18756a0878a6817445e44eb2266dda03ee9e1b2e58d0933dedc021bcdd873cebdc8b8156614ffb8cd32c96d30c521c9 + languageName: node + linkType: hard + +"@mui/system@npm:^5.10.12": + version: 5.10.12 + resolution: "@mui/system@npm:5.10.12" + dependencies: + "@babel/runtime": "npm:^7.19.0" + "@mui/private-theming": "npm:^5.10.9" + "@mui/styled-engine": "npm:^5.10.8" + "@mui/types": "npm:^7.2.0" + "@mui/utils": "npm:^5.10.9" + clsx: "npm:^1.2.1" + csstype: "npm:^3.1.1" + prop-types: "npm:^15.8.1" + peerDependencies: + "@emotion/react": ^11.5.0 + "@emotion/styled": ^11.3.0 + "@types/react": ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@emotion/react": + optional: true + "@emotion/styled": + optional: true + "@types/react": + optional: true + checksum: 10c0/204d2ce89e7f8c985237e3047215a878684940843d7abb0ac39098021ca41d57abc4e076dc6be4566235077a61b706e69ea12fe33bfa7e23c25f47fc851ecc54 + languageName: node + linkType: hard + +"@mui/types@npm:^7.2.0": + version: 7.2.0 + resolution: "@mui/types@npm:7.2.0" + peerDependencies: + "@types/react": "*" + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/ccb444a6e3548da30565acbc484bb761adb01b2905d4ab8650233eb6247812fa058c3433f439cfb0f03a7e22a7aa6a13e22b8e30767cb8fb19b529457b07e366 + languageName: node + linkType: hard + +"@mui/utils@npm:^5.10.9": + version: 5.10.9 + resolution: "@mui/utils@npm:5.10.9" + dependencies: + "@babel/runtime": "npm:^7.19.0" + "@types/prop-types": "npm:^15.7.5" + "@types/react-is": "npm:^16.7.1 || ^17.0.0" + prop-types: "npm:^15.8.1" + react-is: "npm:^18.2.0" + peerDependencies: + react: ^17.0.0 || ^18.0.0 + checksum: 10c0/8e26770973bbeec625d95f0a5fc804da786723a574040b3bfc6564eb575bcd6a5dc571635bfe8eec1a14a36839eb49be898cb2ce45ee28aa47277ebde21fadee + languageName: node + linkType: hard + +"@next/env@npm:13.0.0": + version: 13.0.0 + resolution: "@next/env@npm:13.0.0" + checksum: 10c0/8aa0a4b4429b56640e357f4779b29d0c6c90fd758e60f85e5dde622db739968944850381006567729e19e9f7302e5354b266af13b559a40c278ddd47f7213768 + languageName: node + linkType: hard + +"@next/eslint-plugin-next@npm:13.0.0": + version: 13.0.0 + resolution: "@next/eslint-plugin-next@npm:13.0.0" + dependencies: + glob: "npm:7.1.7" + checksum: 10c0/bfa4ca73bf3d801ff951be8de7598c6f92c3d2fc0177fe5b5a4647785f9eaf535dca186446bc088e31ddfe03a28816870b4ccce1d9a0a26c01fdef619e3ae486 + languageName: node + linkType: hard + +"@next/swc-android-arm-eabi@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-android-arm-eabi@npm:13.0.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@next/swc-android-arm64@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-android-arm64@npm:13.0.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@next/swc-darwin-arm64@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-darwin-arm64@npm:13.0.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@next/swc-darwin-x64@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-darwin-x64@npm:13.0.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@next/swc-freebsd-x64@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-freebsd-x64@npm:13.0.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@next/swc-linux-arm-gnueabihf@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-linux-arm-gnueabihf@npm:13.0.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@next/swc-linux-arm64-gnu@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-linux-arm64-gnu@npm:13.0.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@next/swc-linux-arm64-musl@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-linux-arm64-musl@npm:13.0.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@next/swc-linux-x64-gnu@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-linux-x64-gnu@npm:13.0.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@next/swc-linux-x64-musl@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-linux-x64-musl@npm:13.0.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@next/swc-win32-arm64-msvc@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-win32-arm64-msvc@npm:13.0.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@next/swc-win32-ia32-msvc@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-win32-ia32-msvc@npm:13.0.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@next/swc-win32-x64-msvc@npm:13.0.0": + version: 13.0.0 + resolution: "@next/swc-win32-x64-msvc@npm:13.0.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@noble/curves@npm:1.2.0": + version: 1.2.0 + resolution: "@noble/curves@npm:1.2.0" + dependencies: + "@noble/hashes": "npm:1.3.2" + checksum: 10c0/0bac7d1bbfb3c2286910b02598addd33243cb97c3f36f987ecc927a4be8d7d88e0fcb12b0f0ef8a044e7307d1844dd5c49bb724bfa0a79c8ec50ba60768c97f6 + languageName: node + linkType: hard + +"@noble/hashes@npm:1.3.2": + version: 1.3.2 + resolution: "@noble/hashes@npm:1.3.2" + checksum: 10c0/2482cce3bce6a596626f94ca296e21378e7a5d4c09597cbc46e65ffacc3d64c8df73111f2265444e36a3168208628258bbbaccba2ef24f65f58b2417638a20e7 + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1 + languageName: node + linkType: hard + +"@popperjs/core@npm:^2.11.6": + version: 2.11.6 + resolution: "@popperjs/core@npm:2.11.6" + checksum: 10c0/90b1361ab1a19cd351e482a88cb6cf13cf25973e20797bf9b97223e64b87bde8d9668ab2f33be24475e2a092d362ac256c361b16ea4e4ab5b21f2aeaef5f9bb7 + languageName: node + linkType: hard + +"@radix-ui/primitive@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/primitive@npm:1.1.0" + checksum: 10c0/1dcc8b5401799416ff8bdb15c7189b4536c193220ad8fd348a48b88f804ee38cec7bd03e2b9641f7da24610e2f61f23a306911ce883af92c4e8c1abac634cb61 + languageName: node + linkType: hard + +"@radix-ui/react-arrow@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-arrow@npm:1.1.0" + dependencies: + "@radix-ui/react-primitive": "npm:2.0.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/cbe059dfa5a9c1677478d363bb5fd75b0c7a08221d0ac7f8e7b9aec9dbae9754f6a3518218cf63e4ed53df6c36d193c8d2618d03433a37aa0cb7ee77a60a591f + languageName: node + linkType: hard + +"@radix-ui/react-collection@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-collection@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-slot": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/fecb9f0871c827070a8794b39c7379fdc7d0855c4b05804f0b395eef39c37b2c2b6779865d6cb35d3bc74b6b380107bd8b3754d1730a34ea88913e6cd0eb84d4 + languageName: node + linkType: hard + +"@radix-ui/react-compose-refs@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-compose-refs@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/7e18706084397d9458ca3473d8565b10691da06f6499a78edbcc4bd72cde08f62e91120658d17d58c19fc39d6b1dffe0133cc4535c8f5fce470abd478f6107e5 + languageName: node + linkType: hard + +"@radix-ui/react-context@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-context@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/c843980f568cc61b512708863ec84c42a02e0f88359b22ad1c0e290cea3e6d7618eccbd2cd37bd974fadaa7636cbed5bda27553722e61197eb53852eaa34f1bb + languageName: node + linkType: hard + +"@radix-ui/react-dialog@npm:^1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-dialog@npm:1.1.1" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-dismissable-layer": "npm:1.1.0" + "@radix-ui/react-focus-guards": "npm:1.1.0" + "@radix-ui/react-focus-scope": "npm:1.1.0" + "@radix-ui/react-id": "npm:1.1.0" + "@radix-ui/react-portal": "npm:1.1.1" + "@radix-ui/react-presence": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-slot": "npm:1.1.0" + "@radix-ui/react-use-controllable-state": "npm:1.1.0" + aria-hidden: "npm:^1.1.1" + react-remove-scroll: "npm:2.5.7" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/a21e318e8d45bed22067880f66beb4ea91118a6c0d43aa20de495c0373b53c12dfe28f58196d5b33300573a5e24e064ec53648a576f02366fb5a297d887b0860 + languageName: node + linkType: hard + +"@radix-ui/react-direction@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-direction@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/eb07d8cc3ae2388b824e0a11ae0e3b71fb0c49972b506e249cec9f27a5b7ef4305ee668c98b674833c92e842163549a83beb0a197dec1ec65774bdeeb61f932c + languageName: node + linkType: hard + +"@radix-ui/react-dismissable-layer@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-dismissable-layer@npm:1.1.0" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + "@radix-ui/react-use-escape-keydown": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/72967068ab02127b668ecfd0a1863149e2a42d9fd12d3247f51422a41f3d5faa82a147a5b0a8a6ec609eff8fe6baede6fb7d6111f76896656d13567e3ec29ba8 + languageName: node + linkType: hard + +"@radix-ui/react-dropdown-menu@npm:^2.1.1": + version: 2.1.1 + resolution: "@radix-ui/react-dropdown-menu@npm:2.1.1" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-id": "npm:1.1.0" + "@radix-ui/react-menu": "npm:2.1.1" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-controllable-state": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/b54f1e41ddc8c3709ba2f8a59621138268d0380aca8399450a234997cc2214e4a6acf1a64ab387558ba39c0bd5839995a668bd71781762daac7618a2d71b4082 + languageName: node + linkType: hard + +"@radix-ui/react-focus-guards@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-focus-guards@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/23af9ff17244568db9b2e99ae6e5718747a4b656bf12b1b15b0d3adca407988641a930612eca35a61b7e15d1ce312b3db13ea95999fa31ae641aaaac1e325df8 + languageName: node + linkType: hard + +"@radix-ui/react-focus-scope@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-focus-scope@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/2593d4bbd4a3525624675ec1d5a591a44f015f43f449b99a5a33228159b83f445e8f1c6bc6f9f2011387abaeadd3df406623c08d4e795b7ae509795652a1d069 + languageName: node + linkType: hard + +"@radix-ui/react-id@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-id@npm:1.1.0" + dependencies: + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/acf13e29e51ee96336837fc0cfecc306328b20b0e0070f6f0f7aa7a621ded4a1ee5537cfad58456f64bae76caa7f8769231e88dc7dc106197347ee433c275a79 + languageName: node + linkType: hard + +"@radix-ui/react-menu@npm:2.1.1": + version: 2.1.1 + resolution: "@radix-ui/react-menu@npm:2.1.1" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-collection": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-direction": "npm:1.1.0" + "@radix-ui/react-dismissable-layer": "npm:1.1.0" + "@radix-ui/react-focus-guards": "npm:1.1.0" + "@radix-ui/react-focus-scope": "npm:1.1.0" + "@radix-ui/react-id": "npm:1.1.0" + "@radix-ui/react-popper": "npm:1.2.0" + "@radix-ui/react-portal": "npm:1.1.1" + "@radix-ui/react-presence": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-roving-focus": "npm:1.1.0" + "@radix-ui/react-slot": "npm:1.1.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + aria-hidden: "npm:^1.1.1" + react-remove-scroll: "npm:2.5.7" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/2cb11867430276d8db595886ae0e01e67a555676d37e108d5a6c386df23329482115a041b6a4057fad6b855aa423681805c20d1f290fd1502e521e8e55aafb54 + languageName: node + linkType: hard + +"@radix-ui/react-popper@npm:1.2.0": + version: 1.2.0 + resolution: "@radix-ui/react-popper@npm:1.2.0" + dependencies: + "@floating-ui/react-dom": "npm:^2.0.0" + "@radix-ui/react-arrow": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + "@radix-ui/react-use-rect": "npm:1.1.0" + "@radix-ui/react-use-size": "npm:1.1.0" + "@radix-ui/rect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/a78ea534b9822d07153fff0895b6cdf742e7213782b140b3ab94a76df0ca70e6001925aea946e99ca680fc63a7fcca49c1d62e8dc5a2f651692fba3541e180c0 + languageName: node + linkType: hard + +"@radix-ui/react-portal@npm:1.1.1": + version: 1.1.1 + resolution: "@radix-ui/react-portal@npm:1.1.1" + dependencies: + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/7e7130fcb0d99197322cd97987e1d7279b6c264fb6be3d883cbfcd49267740d83ca17b431e0d98848afd6067a13ee823ca396a8b63ae68f18a728cf70398c830 + languageName: node + linkType: hard + +"@radix-ui/react-presence@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-presence@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/58acb658b15b72991ad7a234ea90995902c470b3a182aa90ad03145cbbeaa40f211700c444bfa14cf47537cbb6b732e1359bc5396182de839bd680843c11bf31 + languageName: node + linkType: hard + +"@radix-ui/react-primitive@npm:2.0.0": + version: 2.0.0 + resolution: "@radix-ui/react-primitive@npm:2.0.0" + dependencies: + "@radix-ui/react-slot": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/00cb6ca499252ca848c299212ba6976171cea7608b10b3f9a9639d6732dea2df1197ba0d97c001a4fdb29313c3e7fc2a490f6245dd3579617a0ffd85ae964fdd + languageName: node + linkType: hard + +"@radix-ui/react-roving-focus@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-roving-focus@npm:1.1.0" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-collection": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-direction": "npm:1.1.0" + "@radix-ui/react-id": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + "@radix-ui/react-use-controllable-state": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/ce367d3033a12d639a8d445d2efa090aa4bc5a78125be568f8c8e4e59f30afd51b585a90031ec18cdba19afbaf1974633dbc0c2c3d2a14d9eb1bfea2ddbe5369 + languageName: node + linkType: hard + +"@radix-ui/react-slot@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-slot@npm:1.1.0" + dependencies: + "@radix-ui/react-compose-refs": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/a2e8bfb70c440506dd84a1a274f9a8bc433cca37ceae275e53552c9122612e3837744d7fc6f113d6ef1a11491aa914f4add71d76de41cb6d4db72547a8e261ae + languageName: node + linkType: hard + +"@radix-ui/react-switch@npm:^1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-switch@npm:1.1.0" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-use-controllable-state": "npm:1.1.0" + "@radix-ui/react-use-previous": "npm:1.1.0" + "@radix-ui/react-use-size": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/49a250371dccce2a06564ce5812ffbd13b7b69fffe8473529a8a344d8caf95d4068f7d47bd257228e35802f008ba66af410b4d8456bc4257da237fa657c74d50 + languageName: node + linkType: hard + +"@radix-ui/react-tooltip@npm:^1.1.1": + version: 1.1.2 + resolution: "@radix-ui/react-tooltip@npm:1.1.2" + dependencies: + "@radix-ui/primitive": "npm:1.1.0" + "@radix-ui/react-compose-refs": "npm:1.1.0" + "@radix-ui/react-context": "npm:1.1.0" + "@radix-ui/react-dismissable-layer": "npm:1.1.0" + "@radix-ui/react-id": "npm:1.1.0" + "@radix-ui/react-popper": "npm:1.2.0" + "@radix-ui/react-portal": "npm:1.1.1" + "@radix-ui/react-presence": "npm:1.1.0" + "@radix-ui/react-primitive": "npm:2.0.0" + "@radix-ui/react-slot": "npm:1.1.0" + "@radix-ui/react-use-controllable-state": "npm:1.1.0" + "@radix-ui/react-visually-hidden": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/76f3abcd27f7f673612631abc340a17e6ab0e5d20b901fe4828400de05d4d8a8711392417b028be86a3053a0881b80d0ed41c4e027eb64c1af9fe74db70d3786 + languageName: node + linkType: hard + +"@radix-ui/react-use-callback-ref@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-callback-ref@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/e954863f3baa151faf89ac052a5468b42650efca924417470efd1bd254b411a94c69c30de2fdbb90187b38cb984795978e12e30423dc41e4309d93d53b66d819 + languageName: node + linkType: hard + +"@radix-ui/react-use-controllable-state@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-controllable-state@npm:1.1.0" + dependencies: + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/2af883b5b25822ac226e60a6bfde647c0123a76345052a90219026059b3f7225844b2c13a9a16fba859c1cda5fb3d057f2a04503f71780e607516492db4eb3a1 + languageName: node + linkType: hard + +"@radix-ui/react-use-escape-keydown@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-escape-keydown@npm:1.1.0" + dependencies: + "@radix-ui/react-use-callback-ref": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/910fd696e5a0994b0e06b9cb68def8a865f47951a013ec240c77db2a9e1e726105602700ef5e5f01af49f2f18fe0e73164f9a9651021f28538ef8a30d91f3fbb + languageName: node + linkType: hard + +"@radix-ui/react-use-layout-effect@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-layout-effect@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/9bf87ece1845c038ed95863cfccf9d75f557c2400d606343bab0ab3192b9806b9840e6aa0a0333fdf3e83cf9982632852192f3e68d7d8367bc8c788dfdf8e62b + languageName: node + linkType: hard + +"@radix-ui/react-use-previous@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-previous@npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/9787d24790d4e330715127f2f4db56c4cbed9b0a47f97e11a68582c08a356a53c1ec41c7537382f6fb8d0db25de152770f17430e8eaf0fa59705be97760acbad + languageName: node + linkType: hard + +"@radix-ui/react-use-rect@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-rect@npm:1.1.0" + dependencies: + "@radix-ui/rect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/c2e30150ab49e2cec238cda306fd748c3d47fb96dcff69a3b08e1d19108d80bac239d48f1747a25dadca614e3e967267d43b91e60ea59db2befbc7bea913ff84 + languageName: node + linkType: hard + +"@radix-ui/react-use-size@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-use-size@npm:1.1.0" + dependencies: + "@radix-ui/react-use-layout-effect": "npm:1.1.0" + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/4c8b89037597fdc1824d009e0c941b510c7c6c30f83024cc02c934edd748886786e7d9f36f57323b02ad29833e7fa7e8974d81969b4ab33d8f41661afa4f30a6 + languageName: node + linkType: hard + +"@radix-ui/react-visually-hidden@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/react-visually-hidden@npm:1.1.0" + dependencies: + "@radix-ui/react-primitive": "npm:2.0.0" + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + checksum: 10c0/db138dd5f3c94958a9f836740d4408c89c4a73e770eaba5ead921e69b3c0d196c5cd58323d82829a9bc05a74873c299195dfd8366b9808e53a9a3dbca5a1e5fe + languageName: node + linkType: hard + +"@radix-ui/rect@npm:1.1.0": + version: 1.1.0 + resolution: "@radix-ui/rect@npm:1.1.0" + checksum: 10c0/a26ff7f8708fb5f2f7949baad70a6b2a597d761ee4dd4aadaf1c1a33ea82ea23dfef6ce6366a08310c5d008cdd60b2e626e4ee03fa342bd5f246ddd9d427f6be + languageName: node + linkType: hard + +"@reach/auto-id@npm:0.18.0": + version: 0.18.0 + resolution: "@reach/auto-id@npm:0.18.0" + dependencies: + "@reach/utils": "npm:0.18.0" + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + checksum: 10c0/631e693633dae0aa7981af0b71efe1790939ed96ffb6eb98a8b7f29f051fdb966a0ea517f25dde4b2e40d75f07e55f833ab56fff06152f96182728d80a7890e0 + languageName: node + linkType: hard + +"@reach/combobox@npm:^0.18.0": + version: 0.18.0 + resolution: "@reach/combobox@npm:0.18.0" + dependencies: + "@reach/auto-id": "npm:0.18.0" + "@reach/descendants": "npm:0.18.0" + "@reach/polymorphic": "npm:0.18.0" + "@reach/popover": "npm:0.18.0" + "@reach/portal": "npm:0.18.0" + "@reach/utils": "npm:0.18.0" + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + checksum: 10c0/c18c316bd902567fadb7b920059d2dd0697dbc313923bc7631eb8f5629251647654e6058ceaf2e7fa3b1522b29b4cc47f51fe600f4b1f010e1998cd60f021ed7 + languageName: node + linkType: hard + +"@reach/descendants@npm:0.18.0": + version: 0.18.0 + resolution: "@reach/descendants@npm:0.18.0" + dependencies: + "@reach/utils": "npm:0.18.0" + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + checksum: 10c0/6f7fdb3aaef2ab7c92a82716c536ce0b4e715c019fd7ba89190fead4ca4f4d0b16de37edbe052c3ad35eaa505f4d14ea5975a9ee866916799813174b63d989e1 + languageName: node + linkType: hard + +"@reach/observe-rect@npm:1.2.0": + version: 1.2.0 + resolution: "@reach/observe-rect@npm:1.2.0" + checksum: 10c0/e2d2b399381e466705bcf7535ba1ed29866792d7aff386a2a41ca1f5ae9d8920f21c769d67b82b38045cd14e1c2aa29dbf6f37a77f323d16d01378eb02ad2925 + languageName: node + linkType: hard + +"@reach/polymorphic@npm:0.18.0": + version: 0.18.0 + resolution: "@reach/polymorphic@npm:0.18.0" + peerDependencies: + react: ^16.8.0 || 17.x + checksum: 10c0/dfde6dc901005f92e16f0e3601f0c659b70ee14d91e612cd68c9a918744fd94de30e8065d73663b72964225d3476f377c650daf2ac1e256de61df9ee386aabdc + languageName: node + linkType: hard + +"@reach/popover@npm:0.18.0": + version: 0.18.0 + resolution: "@reach/popover@npm:0.18.0" + dependencies: + "@reach/polymorphic": "npm:0.18.0" + "@reach/portal": "npm:0.18.0" + "@reach/rect": "npm:0.18.0" + "@reach/utils": "npm:0.18.0" + tabbable: "npm:^5.3.3" + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + checksum: 10c0/26e3a0334d1e8a81171953773730c90f905b3200d868ae5394835aa37f7074499c430239ffc853cfbe6fe6e87f980961cb286c1f645af036a7a20c8150107855 + languageName: node + linkType: hard + +"@reach/portal@npm:0.18.0": + version: 0.18.0 + resolution: "@reach/portal@npm:0.18.0" + dependencies: + "@reach/utils": "npm:0.18.0" + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + checksum: 10c0/164091ab17db643fe3b27f7a9d6da78bec347ed8a04b320ffca90a3beff6c8da2c642d370dd3d82b5e6fbf10f9511cb09be18c587b2598e9841380fa1574807d + languageName: node + linkType: hard + +"@reach/rect@npm:0.18.0": + version: 0.18.0 + resolution: "@reach/rect@npm:0.18.0" + dependencies: + "@reach/observe-rect": "npm:1.2.0" + "@reach/utils": "npm:0.18.0" + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + checksum: 10c0/9da897b3708f7b6214ef18590cd7bfbf9ccf3e8801c0458be26886acbe8e547a313e6434d6c30950998900880d529f182bce8e9704e15996edb1f5c6a388f39f + languageName: node + linkType: hard + +"@reach/tabs@npm:^0.18.0": + version: 0.18.0 + resolution: "@reach/tabs@npm:0.18.0" + dependencies: + "@reach/auto-id": "npm:0.18.0" + "@reach/descendants": "npm:0.18.0" + "@reach/polymorphic": "npm:0.18.0" + "@reach/utils": "npm:0.18.0" + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + checksum: 10c0/d2168cc5c04026eab70baff166e90c2c0d07f6efcfdfbb95790d655e25078edaea6980643673528563f60764ec7fab7baddb44190c8ccba01fa0389679743a46 + languageName: node + linkType: hard + +"@reach/utils@npm:0.18.0": + version: 0.18.0 + resolution: "@reach/utils@npm:0.18.0" + peerDependencies: + react: ^16.8.0 || 17.x + react-dom: ^16.8.0 || 17.x + checksum: 10c0/33890a9ed77af843ad63671ffafedf06d88cc7611ff6b454ebadb1bfdd1ef2fbcbb91dc38096d7004de3e9373e2506b835080ae4cd273918d5f80a26bc9d5e1b + languageName: node + linkType: hard + +"@react-spring/animated@npm:~9.5.5": + version: 9.5.5 + resolution: "@react-spring/animated@npm:9.5.5" + dependencies: + "@react-spring/shared": "npm:~9.5.5" + "@react-spring/types": "npm:~9.5.5" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/f7c68d5685365e4ddb6112c3e8e31f6104825f487fdebd5ff8c16e047e5ff2b8570b1cf1585a68b1bd679324dfb56ae5421da17341a04b3c79951d3f35f26cbd + languageName: node + linkType: hard + +"@react-spring/core@npm:~9.5.5": + version: 9.5.5 + resolution: "@react-spring/core@npm:9.5.5" + dependencies: + "@react-spring/animated": "npm:~9.5.5" + "@react-spring/rafz": "npm:~9.5.5" + "@react-spring/shared": "npm:~9.5.5" + "@react-spring/types": "npm:~9.5.5" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/fe40f99e6de261391c2bf0ca56eeac071c0e1b6cf5a145b2acaefc12d076bcadae973bbfa4adf2171240268884befd2d7f4cb3cd5be4dd8106a3dd6179e059b4 + languageName: node + linkType: hard + +"@react-spring/konva@npm:~9.5.5": + version: 9.5.5 + resolution: "@react-spring/konva@npm:9.5.5" + dependencies: + "@react-spring/animated": "npm:~9.5.5" + "@react-spring/core": "npm:~9.5.5" + "@react-spring/shared": "npm:~9.5.5" + "@react-spring/types": "npm:~9.5.5" + peerDependencies: + konva: ">=2.6" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-konva: ^16.8.0 || ^17.0.0 + checksum: 10c0/056420cd7fb3de08c2131753421052783365eee9b191c2a1b5748246e6f2375833147899fbb06348cb8e839f168b34a29e91ccf0b509f6650baa8799f1d9e234 + languageName: node + linkType: hard + +"@react-spring/native@npm:~9.5.5": + version: 9.5.5 + resolution: "@react-spring/native@npm:9.5.5" + dependencies: + "@react-spring/animated": "npm:~9.5.5" + "@react-spring/core": "npm:~9.5.5" + "@react-spring/shared": "npm:~9.5.5" + "@react-spring/types": "npm:~9.5.5" + peerDependencies: + react: ^16.8.0 || >=17.0.0 || >=18.0.0 + react-native: ">=0.58" + checksum: 10c0/85112cdd1769fbc57b8510c5d37d1302689abdfec979799025c874cb9bb82ce288dc0d7881a314988717976b08953d16c0b815dbf4c3913774e83d93c1e19208 + languageName: node + linkType: hard + +"@react-spring/rafz@npm:~9.5.5": + version: 9.5.5 + resolution: "@react-spring/rafz@npm:9.5.5" + checksum: 10c0/a0e05c8bd2bee5996c12985dd502e05378ae46044fd09279f726bd10cd0d5037017f15040c4c171fb04a6cd31c90c4f61605629e5b09566765b0edafce091b7c + languageName: node + linkType: hard + +"@react-spring/shared@npm:~9.5.5": + version: 9.5.5 + resolution: "@react-spring/shared@npm:9.5.5" + dependencies: + "@react-spring/rafz": "npm:~9.5.5" + "@react-spring/types": "npm:~9.5.5" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/5df013703b90eead6740f25b28599356b57a4f2a0002ff1ca7beaed581076c88d926f84c52de800052ee2ecfef870f51fced8fc0035b57312c6e0a28418b029e + languageName: node + linkType: hard + +"@react-spring/three@npm:~9.5.5": + version: 9.5.5 + resolution: "@react-spring/three@npm:9.5.5" + dependencies: + "@react-spring/animated": "npm:~9.5.5" + "@react-spring/core": "npm:~9.5.5" + "@react-spring/shared": "npm:~9.5.5" + "@react-spring/types": "npm:~9.5.5" + peerDependencies: + "@react-three/fiber": ">=6.0" + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + three: ">=0.126" + checksum: 10c0/3d36e9406d3f38af9a2c99a0ccdeaeefe8b99da4f7247d272b8622c6a0d72489f74a941b183556cf908646f34e355aa4513924c403611a2d153104c422e2a1bb + languageName: node + linkType: hard + +"@react-spring/types@npm:~9.5.5": + version: 9.5.5 + resolution: "@react-spring/types@npm:9.5.5" + checksum: 10c0/2bd314101f6d79f23816e87992ef442acc1dd86323a10ba5e613741090e6e096ee854e25a442c750dc7ea9b3954d1e945263c550d3bb4ac23588c9ec1d23c5da + languageName: node + linkType: hard + +"@react-spring/web@npm:~9.5.5": + version: 9.5.5 + resolution: "@react-spring/web@npm:9.5.5" + dependencies: + "@react-spring/animated": "npm:~9.5.5" + "@react-spring/core": "npm:~9.5.5" + "@react-spring/shared": "npm:~9.5.5" + "@react-spring/types": "npm:~9.5.5" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/01db4ad68305fbada3735c44a7972a3a8dcff630758bfbe75e48dffc27cf77c303f598f2be176b66d6bf4e61f66a38e64e007859e5fd369e662f829d26839499 + languageName: node + linkType: hard + +"@react-spring/zdog@npm:~9.5.5": + version: 9.5.5 + resolution: "@react-spring/zdog@npm:9.5.5" + dependencies: + "@react-spring/animated": "npm:~9.5.5" + "@react-spring/core": "npm:~9.5.5" + "@react-spring/shared": "npm:~9.5.5" + "@react-spring/types": "npm:~9.5.5" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-zdog: ">=1.0" + zdog: ">=1.0" + checksum: 10c0/a7a8a7bd407eaddd34fc9323485db9d5df7234e92dee520a709c78ab0cb765b116b6571d28c054e208ac62df76d9dc5f4b6d9c82264d9fa2145cb808b86b0a8f + languageName: node + linkType: hard + +"@rushstack/eslint-patch@npm:^1.1.3": + version: 1.2.0 + resolution: "@rushstack/eslint-patch@npm:1.2.0" + checksum: 10c0/96c7622ab54b759f9aca2b03ba98acdfae39adb8c7a97b429a8f5c90adb49cc2c38db894c9a02f4ad8088f132575146c091c15b1f10ed34026ffd2491930c3a4 + languageName: node + linkType: hard + +"@swc/helpers@npm:0.4.11": + version: 0.4.11 + resolution: "@swc/helpers@npm:0.4.11" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/8806dda1f3cc243d80b1270405142563ed425350f9f4c7cfdd84967ead094878a3135b7ca1185052af0faef99982e57bb22e7f5fa80f1e9a3dab20e9e1051dfc + languageName: node + linkType: hard + +"@table-library/react-table-library@npm:^4.1.7": + version: 4.1.7 + resolution: "@table-library/react-table-library@npm:4.1.7" + dependencies: + clsx: "npm:1.1.1" + react-virtualized-auto-sizer: "npm:1.0.7" + react-window: "npm:1.8.7" + peerDependencies: + "@emotion/react": ">= 11" + react: ">=16.8.0" + react-dom: ">=16.8.0" + checksum: 10c0/a084cea10d0d66dce02585268211a9a21872b8be077fbfc38abf09b5df8e1a248639c607831bb992ff64e565cf7497bcb44fa79fbaf9c51a53ee3ed308b4123e + languageName: node + linkType: hard + +"@types/hoist-non-react-statics@npm:*": + version: 3.3.1 + resolution: "@types/hoist-non-react-statics@npm:3.3.1" + dependencies: + "@types/react": "npm:*" + hoist-non-react-statics: "npm:^3.3.0" + checksum: 10c0/5ed808e5fbf0979fe07acd631147420c30319383f4388a57e0fb811c6ff30abef286e937a84c7b00f4647ca7f1ab390cc42af0bfc7547a87d2e59e0e7072d92b + languageName: node + linkType: hard + +"@types/js-cookie@npm:^2.2.6": + version: 2.2.7 + resolution: "@types/js-cookie@npm:2.2.7" + checksum: 10c0/29196c6829982b5efa79117122a7d62cf4bc2f6397ce8eac1539319ff5dce3b44b2d86f2ac064f2ed3488fb24439358f24af6914fde5c5c4bab9a85728a13a6f + languageName: node + linkType: hard + +"@types/json5@npm:^0.0.29": + version: 0.0.29 + resolution: "@types/json5@npm:0.0.29" + checksum: 10c0/6bf5337bc447b706bb5b4431d37686aa2ea6d07cfd6f79cc31de80170d6ff9b1c7384a9c0ccbc45b3f512bae9e9f75c2e12109806a15331dc94e8a8db6dbb4ac + languageName: node + linkType: hard + +"@types/lodash@npm:^4.14.188": + version: 4.14.188 + resolution: "@types/lodash@npm:4.14.188" + checksum: 10c0/4debfc61d27544ac71296d5b1128bb86ae78fd38d2f9378ab5e8de6a99eb4403f8d0efc0ac4c055930c4f6014433bc2ce39a2e9245d036aa75e596ff786b16ff + languageName: node + linkType: hard + +"@types/node@npm:18.11.7": + version: 18.11.7 + resolution: "@types/node@npm:18.11.7" + checksum: 10c0/65e95517d3a601ab1d2b473a2e7989da8c87681cbc201ea9a8bf1f2b50227bc8755e07a4b00258376c6a4df614c270ff059f08135397261c9dd6f12601ec8fd6 + languageName: node + linkType: hard + +"@types/node@npm:18.15.13": + version: 18.15.13 + resolution: "@types/node@npm:18.15.13" + checksum: 10c0/6e5f61c559e60670a7a8fb88e31226ecc18a21be103297ca4cf9848f0a99049dae77f04b7ae677205f2af494f3701b113ba8734f4b636b355477a6534dbb8ada + languageName: node + linkType: hard + +"@types/parse-json@npm:^4.0.0": + version: 4.0.0 + resolution: "@types/parse-json@npm:4.0.0" + checksum: 10c0/1d3012ab2fcdad1ba313e1d065b737578f6506c8958e2a7a5bdbdef517c7e930796cb1599ee067d5dee942fb3a764df64b5eef7e9ae98548d776e86dcffba985 + languageName: node + linkType: hard + +"@types/prop-types@npm:*, @types/prop-types@npm:^15.7.5": + version: 15.7.5 + resolution: "@types/prop-types@npm:15.7.5" + checksum: 10c0/648aae41423821c61c83823ae36116c8d0f68258f8b609bdbc257752dcd616438d6343d554262aa9a7edaee5a19aca2e028a74fa2d0f40fffaf2816bc7056857 + languageName: node + linkType: hard + +"@types/react-dom@npm:18.0.8": + version: 18.0.8 + resolution: "@types/react-dom@npm:18.0.8" + dependencies: + "@types/react": "npm:*" + checksum: 10c0/e5e18d30a272b799e7579929b27f8cd078c5ee92cc11a4be80b63d9f4330d22c97cc2aeb89945fc8e88d59a92438fa89f37ac92021665021988ed56cb864b424 + languageName: node + linkType: hard + +"@types/react-is@npm:^16.7.1 || ^17.0.0": + version: 17.0.3 + resolution: "@types/react-is@npm:17.0.3" + dependencies: + "@types/react": "npm:*" + checksum: 10c0/839382b66b2b2e3023647f5ba0c382ddc6aa01c1bc9f64608f82bbc871a905ba9b988838619914d8348c2a511717c6bd3701cb866bb9e4abfabdbe544efb695b + languageName: node + linkType: hard + +"@types/react-transition-group@npm:^4.4.5": + version: 4.4.5 + resolution: "@types/react-transition-group@npm:4.4.5" + dependencies: + "@types/react": "npm:*" + checksum: 10c0/c0d81634ca5e1efac3ca6f6f006245976d584833ab9e933edf08b66551c1c7b9f0bc7878897f57ba44b137d3754583d623c932fe4b7721840ae5218ec2414942 + languageName: node + linkType: hard + +"@types/react@npm:*, @types/react@npm:18.0.24": + version: 18.0.24 + resolution: "@types/react@npm:18.0.24" + dependencies: + "@types/prop-types": "npm:*" + "@types/scheduler": "npm:*" + csstype: "npm:^3.0.2" + checksum: 10c0/8ea907a8f944421a120f4db9fe52fe3752837e11031ff16b866e835adebb09b2b2ca3ac5f8aa622683778f6d40f791a369c9008c45537c1a7eb64347648fae3c + languageName: node + linkType: hard + +"@types/scheduler@npm:*": + version: 0.16.2 + resolution: "@types/scheduler@npm:0.16.2" + checksum: 10c0/89a3a922f03609b61c270d534226791edeedcb1b06f0225d5543ac17830254624ef9d8a97ad05418e4ce549dd545bddf1ff28cb90658ff10721ad14556ca68a5 + languageName: node + linkType: hard + +"@types/styled-components@npm:^5.1.26": + version: 5.1.26 + resolution: "@types/styled-components@npm:5.1.26" + dependencies: + "@types/hoist-non-react-statics": "npm:*" + "@types/react": "npm:*" + csstype: "npm:^3.0.2" + checksum: 10c0/61c53b035d82bbf6071d3f15348f2e9a43af8c28c630ab472d153277082a578aa60116ddc67bcfea1340d93577d5758c359f0a4d4d1291a419cebb3f8677b63e + languageName: node + linkType: hard + +"@typescript-eslint/parser@npm:^5.21.0": + version: 5.41.0 + resolution: "@typescript-eslint/parser@npm:5.41.0" + dependencies: + "@typescript-eslint/scope-manager": "npm:5.41.0" + "@typescript-eslint/types": "npm:5.41.0" + "@typescript-eslint/typescript-estree": "npm:5.41.0" + debug: "npm:^4.3.4" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/d07df9fe001cc79df1e57460312dcbede03f4d524b99350fb9ef5af896b132bb747d96865a28dbae3566393c212e779315e67aa582072a59bb23d3675ab9ad2b + languageName: node + linkType: hard + +"@typescript-eslint/scope-manager@npm:5.41.0": + version: 5.41.0 + resolution: "@typescript-eslint/scope-manager@npm:5.41.0" + dependencies: + "@typescript-eslint/types": "npm:5.41.0" + "@typescript-eslint/visitor-keys": "npm:5.41.0" + checksum: 10c0/76c1fb1d0838d333d0dd2caa52e18b471ff7b711899cd541fa0a011289fc79115e8617da4279273103a4e1b4d2cc7f8d0ddb1c396642a41acdd5b7fa6379aa55 + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:5.41.0": + version: 5.41.0 + resolution: "@typescript-eslint/types@npm:5.41.0" + checksum: 10c0/015a7a550f451ad9a78937254429f55bc2e0d1c2e7de263180fdbf55735a20dd39b4beac42a24e8568a5aaf3b5db4704f69518f15a1b7e973135f0939c272019 + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:5.41.0": + version: 5.41.0 + resolution: "@typescript-eslint/typescript-estree@npm:5.41.0" + dependencies: + "@typescript-eslint/types": "npm:5.41.0" + "@typescript-eslint/visitor-keys": "npm:5.41.0" + debug: "npm:^4.3.4" + globby: "npm:^11.1.0" + is-glob: "npm:^4.0.3" + semver: "npm:^7.3.7" + tsutils: "npm:^3.21.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/3a1c1f3b7026dcdaac920adeb3565fb2102aa8c69cb653a51e24cdd7ca0c2cdfcd2cc1f1c461ac9f88533f570fdf9094df5d0eaf4093245b4572568feabf1192 + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:5.41.0": + version: 5.41.0 + resolution: "@typescript-eslint/visitor-keys@npm:5.41.0" + dependencies: + "@typescript-eslint/types": "npm:5.41.0" + eslint-visitor-keys: "npm:^3.3.0" + checksum: 10c0/5dfce8e4980dabbbaf3b85eb68913251c153c2602d7e32ea52ccd3c8d702b1c298f0b8339d1b61016f01d539556eb4bc386e33c339f64da19bb1ee42ce11fe65 + languageName: node + linkType: hard + +"@xobotyi/scrollbar-width@npm:^1.9.5": + version: 1.9.5 + resolution: "@xobotyi/scrollbar-width@npm:1.9.5" + checksum: 10c0/4ebc79e4f798e2a5e89a5122f8fc4a086f08a92a44ac020599c4fe20d105b7d76ba06c094260b5f386a75e7ce6f6c518d9fc295228b651296b99c4477f986ac4 + languageName: node + linkType: hard + +"acorn-jsx@npm:^5.3.2": + version: 5.3.2 + resolution: "acorn-jsx@npm:5.3.2" + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: 10c0/4c54868fbef3b8d58927d5e33f0a4de35f59012fe7b12cf9dfbb345fb8f46607709e1c4431be869a23fb63c151033d84c4198fa9f79385cec34fcb1dd53974c1 + languageName: node + linkType: hard + +"acorn@npm:^8.8.0": + version: 8.8.1 + resolution: "acorn@npm:8.8.1" + bin: + acorn: bin/acorn + checksum: 10c0/9fd00e3373ecd6c7e8f6adfb3216f5bc9ac050e6fc4ef932f03dbd1d45ccc08289ae16fc9eec10c5de8f1ca65b5f70c02635e1e9015d109dae96fdede340abf5 + languageName: node + linkType: hard + +"aes-js@npm:4.0.0-beta.5": + version: 4.0.0-beta.5 + resolution: "aes-js@npm:4.0.0-beta.5" + checksum: 10c0/444f4eefa1e602cbc4f2a3c644bc990f93fd982b148425fee17634da510586fc09da940dcf8ace1b2d001453c07ff042e55f7a0482b3cc9372bf1ef75479090c + languageName: node + linkType: hard + +"ajv@npm:^6.10.0, ajv@npm:^6.12.4": + version: 6.12.6 + resolution: "ajv@npm:6.12.6" + dependencies: + fast-deep-equal: "npm:^3.1.1" + fast-json-stable-stringify: "npm:^2.0.0" + json-schema-traverse: "npm:^0.4.1" + uri-js: "npm:^4.2.2" + checksum: 10c0/41e23642cbe545889245b9d2a45854ebba51cda6c778ebced9649420d9205f2efb39cb43dbc41e358409223b1ea43303ae4839db682c848b891e4811da1a5a71 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 + languageName: node + linkType: hard + +"ansi-styles@npm:^3.2.1": + version: 3.2.1 + resolution: "ansi-styles@npm:3.2.1" + dependencies: + color-convert: "npm:^1.9.0" + checksum: 10c0/ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b + languageName: node + linkType: hard + +"ansi-styles@npm:^4.1.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 + languageName: node + linkType: hard + +"apexcharts@npm:^3.36.3": + version: 3.36.3 + resolution: "apexcharts@npm:3.36.3" + dependencies: + svg.draggable.js: "npm:^2.2.2" + svg.easing.js: "npm:^2.0.0" + svg.filter.js: "npm:^2.0.2" + svg.pathmorphing.js: "npm:^0.1.3" + svg.resize.js: "npm:^1.4.3" + svg.select.js: "npm:^3.0.1" + checksum: 10c0/51b6fb75356117725009418e5483c2168b7cf1574daef40c5000cf4b27d8a5288ae03aaa830410ca2de034e29aa690ff98d219987af249925518d02ddeb50ca0 + languageName: node + linkType: hard + +"argparse@npm:^2.0.1": + version: 2.0.1 + resolution: "argparse@npm:2.0.1" + checksum: 10c0/c5640c2d89045371c7cedd6a70212a04e360fd34d6edeae32f6952c63949e3525ea77dbec0289d8213a99bbaeab5abfa860b5c12cf88a2e6cf8106e90dd27a7e + languageName: node + linkType: hard + +"aria-hidden@npm:^1.1.1": + version: 1.2.4 + resolution: "aria-hidden@npm:1.2.4" + dependencies: + tslib: "npm:^2.0.0" + checksum: 10c0/8abcab2e1432efc4db415e97cb3959649ddf52c8fc815d7384f43f3d3abf56f1c12852575d00df9a8927f421d7e0712652dd5f8db244ea57634344e29ecfc74a + languageName: node + linkType: hard + +"aria-query@npm:^4.2.2": + version: 4.2.2 + resolution: "aria-query@npm:4.2.2" + dependencies: + "@babel/runtime": "npm:^7.10.2" + "@babel/runtime-corejs3": "npm:^7.10.2" + checksum: 10c0/7e224fbbb4de8210c5d8cbaf0e1a22caa78f2068bf231f4c75302bd77eeba1c3e3b97912080535140be60174720d2ac817e5d6fec18592951b4b6488d4da7cdc + languageName: node + linkType: hard + +"array-includes@npm:^3.1.4, array-includes@npm:^3.1.5": + version: 3.1.5 + resolution: "array-includes@npm:3.1.5" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.4" + es-abstract: "npm:^1.19.5" + get-intrinsic: "npm:^1.1.1" + is-string: "npm:^1.0.7" + checksum: 10c0/a328af3cc590e077863d6a9fa673eda0ddac8e64d05da6696a18ab376f8bc633fc29c98b858a860ab93e4a98be8aef5e62ac00142275acd4090e7b077d2e1909 + languageName: node + linkType: hard + +"array-union@npm:^1.0.1": + version: 1.0.2 + resolution: "array-union@npm:1.0.2" + dependencies: + array-uniq: "npm:^1.0.1" + checksum: 10c0/18686767c0cfdae8dc4acf5ac119b0f0eacad82b7fcc0aa62cc41f93c5ad406d494b6a6e53d85e52e8f0349b67a4fec815feeb537e95c02510d747bc9a4157c7 + languageName: node + linkType: hard + +"array-union@npm:^2.1.0": + version: 2.1.0 + resolution: "array-union@npm:2.1.0" + checksum: 10c0/429897e68110374f39b771ec47a7161fc6a8fc33e196857c0a396dc75df0b5f65e4d046674db764330b6bb66b39ef48dd7c53b6a2ee75cfb0681e0c1a7033962 + languageName: node + linkType: hard + +"array-uniq@npm:^1.0.1": + version: 1.0.3 + resolution: "array-uniq@npm:1.0.3" + checksum: 10c0/3acbaf9e6d5faeb1010e2db04ab171b8d265889e46c61762e502979bdc5e55656013726e9a61507de3c82d329a0dc1e8072630a3454b4f2b881cb19ba7fd8aa6 + languageName: node + linkType: hard + +"array.prototype.flat@npm:^1.2.5": + version: 1.3.0 + resolution: "array.prototype.flat@npm:1.3.0" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.3" + es-abstract: "npm:^1.19.2" + es-shim-unscopables: "npm:^1.0.0" + checksum: 10c0/59010c65c428c68eafa5ffe3d7fc304c7e3a4ebcbb229e87ee2f51507f6eb439371e80297e25e7f59f84741db4712fe006c4c570f7a54a3018b9b563afd72601 + languageName: node + linkType: hard + +"array.prototype.flatmap@npm:^1.3.0": + version: 1.3.0 + resolution: "array.prototype.flatmap@npm:1.3.0" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.3" + es-abstract: "npm:^1.19.2" + es-shim-unscopables: "npm:^1.0.0" + checksum: 10c0/f837de45bd1f22eb0aaf5fd79324e18a1461d6cf93edc4d48ef4695587cb5bf051c1e3de87477fbd7bb70fe6c71c8d11f10ea3c8c797553709ad1d11e649d120 + languageName: node + linkType: hard + +"ast-types-flow@npm:^0.0.7": + version: 0.0.7 + resolution: "ast-types-flow@npm:0.0.7" + checksum: 10c0/f381529f2da535949ba6cceddbdfaa33b4d5105842e147ec63582f560ea9ecc1a08f66457664f3109841d3053641fa8b9fa94ba607f1ea9f6c804fe5dee44a1d + languageName: node + linkType: hard + +"async@npm:^3.2.4": + version: 3.2.6 + resolution: "async@npm:3.2.6" + checksum: 10c0/36484bb15ceddf07078688d95e27076379cc2f87b10c03b6dd8a83e89475a3c8df5848859dd06a4c95af1e4c16fc973de0171a77f18ea00be899aca2a4f85e70 + languageName: node + linkType: hard + +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: 10c0/d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d + languageName: node + linkType: hard + +"axe-core@npm:^4.4.3": + version: 4.5.0 + resolution: "axe-core@npm:4.5.0" + checksum: 10c0/7ca80c6815174eaf4355d88f0622e2f2d2982312a2cf152ec0775aef5c6059da042e50e11a018ee7faa5b06bdcae9e75a3a55164ca6f4249122841a3255f3b4e + languageName: node + linkType: hard + +"axios@npm:^1.1.3": + version: 1.1.3 + resolution: "axios@npm:1.1.3" + dependencies: + follow-redirects: "npm:^1.15.0" + form-data: "npm:^4.0.0" + proxy-from-env: "npm:^1.1.0" + checksum: 10c0/78aea19cc15019fb0fb86ec737a9dccb88a8f8e8f00b0e6c5024a76d8df523daf88a7abf8c6593b0cdd9a346806be9f41285d793d8b6653c99877de11245bfa4 + languageName: node + linkType: hard + +"axobject-query@npm:^2.2.0": + version: 2.2.0 + resolution: "axobject-query@npm:2.2.0" + checksum: 10c0/75e173c4f8477814a03c46b5864810c0d62d15515e3e1067093d934b77d2dd68704a4e5141e190e305fee9630405c1ea013642f50ed476b27d8d79033c489ce9 + languageName: node + linkType: hard + +"babel-plugin-macros@npm:^3.1.0": + version: 3.1.0 + resolution: "babel-plugin-macros@npm:3.1.0" + dependencies: + "@babel/runtime": "npm:^7.12.5" + cosmiconfig: "npm:^7.0.0" + resolve: "npm:^1.19.0" + checksum: 10c0/c6dfb15de96f67871d95bd2e8c58b0c81edc08b9b087dc16755e7157f357dc1090a8dc60ebab955e92587a9101f02eba07e730adc253a1e4cf593ca3ebd3839c + languageName: node + linkType: hard + +"babel-plugin-styled-components@npm:>= 1.12.0, babel-plugin-styled-components@npm:^2.0.7": + version: 2.0.7 + resolution: "babel-plugin-styled-components@npm:2.0.7" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.16.0" + "@babel/helper-module-imports": "npm:^7.16.0" + babel-plugin-syntax-jsx: "npm:^6.18.0" + lodash: "npm:^4.17.11" + picomatch: "npm:^2.3.0" + peerDependencies: + styled-components: ">= 2" + checksum: 10c0/1c639742fb177f36648077a44fd473fe050aa5c664a16ecaa8e366426c44520c2a0011682b90f5b62f3c4317c22938410a6044b7cd99eaba831c00d41a2395c1 + languageName: node + linkType: hard + +"babel-plugin-syntax-jsx@npm:^6.18.0": + version: 6.18.0 + resolution: "babel-plugin-syntax-jsx@npm:6.18.0" + checksum: 10c0/d5954e9c2a3dd519f23e78674ecfba61394a8fae63499afdeca4214fad68997556ebd15ce012bbc4d527ae0e3cecc98d3e8f78004a68707122642d0df4ab7213 + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee + languageName: node + linkType: hard + +"big-integer@npm:^1.6.16": + version: 1.6.52 + resolution: "big-integer@npm:1.6.52" + checksum: 10c0/9604224b4c2ab3c43c075d92da15863077a9f59e5d4205f4e7e76acd0cd47e8d469ec5e5dba8d9b32aa233951893b29329ca56ac80c20ce094b4a647a66abae0 + languageName: node + linkType: hard + +"blockies-react-svg@npm:^0.0.13": + version: 0.0.13 + resolution: "blockies-react-svg@npm:0.0.13" + peerDependencies: + react: ">=16.8.0" + checksum: 10c0/242484a8e0a909cbad96a087562517a5f56050138b246d4bd2d1dab3e804ae3491265a736d2124855bacfa2e5b60ca206f1aa460019c0386cdc1cb3790e8a235 + languageName: node + linkType: hard + +"blockies@npm:0.0.2": + version: 0.0.2 + resolution: "blockies@npm:0.0.2" + checksum: 10c0/f38e5be511d15a3cc2fd6958a89105dea5d16431f0afca22a6bc89ea47320754241167c5c48854c38423b40babe069c913f9b8897edbbff42ba85f96a812d113 + languageName: node + linkType: hard + +"brace-expansion@npm:^1.1.7": + version: 1.1.11 + resolution: "brace-expansion@npm:1.1.11" + dependencies: + balanced-match: "npm:^1.0.0" + concat-map: "npm:0.0.1" + checksum: 10c0/695a56cd058096a7cb71fb09d9d6a7070113c7be516699ed361317aca2ec169f618e28b8af352e02ab4233fb54eb0168460a40dc320bab0034b36ab59aaad668 + languageName: node + linkType: hard + +"braces@npm:^3.0.2": + version: 3.0.2 + resolution: "braces@npm:3.0.2" + dependencies: + fill-range: "npm:^7.0.1" + checksum: 10c0/321b4d675791479293264019156ca322163f02dc06e3c4cab33bb15cd43d80b51efef69b0930cfde3acd63d126ebca24cd0544fa6f261e093a0fb41ab9dda381 + languageName: node + linkType: hard + +"broadcast-channel@npm:^3.4.1": + version: 3.7.0 + resolution: "broadcast-channel@npm:3.7.0" + dependencies: + "@babel/runtime": "npm:^7.7.2" + detect-node: "npm:^2.1.0" + js-sha3: "npm:0.8.0" + microseconds: "npm:0.2.0" + nano-time: "npm:1.0.0" + oblivious-set: "npm:1.0.0" + rimraf: "npm:3.0.2" + unload: "npm:2.2.0" + checksum: 10c0/95978446f24c685be666f5508a91350bcd4075c08feda929d26c0c678fb24bd421901f19fa8d36cb6f5ed480a334072f3bdce48fa177a8cb29793d88693911cc + languageName: node + linkType: hard + +"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2": + version: 1.0.2 + resolution: "call-bind@npm:1.0.2" + dependencies: + function-bind: "npm:^1.1.1" + get-intrinsic: "npm:^1.0.2" + checksum: 10c0/74ba3f31e715456e22e451d8d098779b861eba3c7cac0d9b510049aced70d75c231ba05071f97e1812c98e34e2bee734c0c6126653e0088c2d9819ca047f4073 + languageName: node + linkType: hard + +"callsites@npm:^3.0.0": + version: 3.1.0 + resolution: "callsites@npm:3.1.0" + checksum: 10c0/fff92277400eb06c3079f9e74f3af120db9f8ea03bad0e84d9aede54bbe2d44a56cccb5f6cf12211f93f52306df87077ecec5b712794c5a9b5dac6d615a3f301 + languageName: node + linkType: hard + +"camelize@npm:^1.0.0": + version: 1.0.1 + resolution: "camelize@npm:1.0.1" + checksum: 10c0/4c9ac55efd356d37ac483bad3093758236ab686192751d1c9daa43188cc5a07b09bd431eb7458a4efd9ca22424bba23253e7b353feb35d7c749ba040de2385fb + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001406": + version: 1.0.30001426 + resolution: "caniuse-lite@npm:1.0.30001426" + checksum: 10c0/5b955cc191c1d7f3fb92ccde08d3d2003f3071fe96ce416d6c17c8aa725aa50e2d1546b3a47334a435b2992e125b3d81b47641d98f6c447a5ac71aff3b858f9a + languageName: node + linkType: hard + +"chalk@npm:^2.0.0": + version: 2.4.2 + resolution: "chalk@npm:2.4.2" + dependencies: + ansi-styles: "npm:^3.2.1" + escape-string-regexp: "npm:^1.0.5" + supports-color: "npm:^5.3.0" + checksum: 10c0/e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073 + languageName: node + linkType: hard + +"chalk@npm:^4.0.0": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: "npm:^4.1.0" + supports-color: "npm:^7.1.0" + checksum: 10c0/4a3fef5cc34975c898ffe77141450f679721df9dde00f6c304353fa9c8b571929123b26a0e4617bde5018977eb655b31970c297b91b63ee83bb82aeb04666880 + languageName: node + linkType: hard + +"classnames@npm:^2.3.2": + version: 2.5.1 + resolution: "classnames@npm:2.5.1" + checksum: 10c0/afff4f77e62cea2d79c39962980bf316bacb0d7c49e13a21adaadb9221e1c6b9d3cdb829d8bb1b23c406f4e740507f37e1dcf506f7e3b7113d17c5bab787aa69 + languageName: node + linkType: hard + +"client-only@npm:0.0.1": + version: 0.0.1 + resolution: "client-only@npm:0.0.1" + checksum: 10c0/9d6cfd0c19e1c96a434605added99dff48482152af791ec4172fb912a71cff9027ff174efd8cdb2160cc7f377543e0537ffc462d4f279bc4701de3f2a3c4b358 + languageName: node + linkType: hard + +"clsx@npm:1.1.1": + version: 1.1.1 + resolution: "clsx@npm:1.1.1" + checksum: 10c0/5c34e1d5623e3dce0dbf22eedd4f3cc7cd0dee6b1b1ef3ad49d042c9d86372a1dc7788c2ca3213ec08e65ad0e91572ae7cb77183a478c9977bd5327e8f43ffe5 + languageName: node + linkType: hard + +"clsx@npm:^1.1.1, clsx@npm:^1.2.1": + version: 1.2.1 + resolution: "clsx@npm:1.2.1" + checksum: 10c0/34dead8bee24f5e96f6e7937d711978380647e936a22e76380290e35486afd8634966ce300fc4b74a32f3762c7d4c0303f442c3e259f4ce02374eb0c82834f27 + languageName: node + linkType: hard + +"color-convert@npm:^1.9.0": + version: 1.9.3 + resolution: "color-convert@npm:1.9.3" + dependencies: + color-name: "npm:1.1.3" + checksum: 10c0/5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 + languageName: node + linkType: hard + +"color-name@npm:1.1.3": + version: 1.1.3 + resolution: "color-name@npm:1.1.3" + checksum: 10c0/566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 + languageName: node + linkType: hard + +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: "npm:~1.0.0" + checksum: 10c0/0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5 + languageName: node + linkType: hard + +"commander@npm:^11.0.0": + version: 11.1.0 + resolution: "commander@npm:11.1.0" + checksum: 10c0/13cc6ac875e48780250f723fb81c1c1178d35c5decb1abb1b628b3177af08a8554e76b2c0f29de72d69eef7c864d12613272a71fabef8047922bc622ab75a179 + languageName: node + linkType: hard + +"commondir@npm:^1.0.1": + version: 1.0.1 + resolution: "commondir@npm:1.0.1" + checksum: 10c0/33a124960e471c25ee19280c9ce31ccc19574b566dc514fe4f4ca4c34fa8b0b57cf437671f5de380e11353ea9426213fca17687dd2ef03134fea2dbc53809fd6 + languageName: node + linkType: hard + +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: 10c0/c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f + languageName: node + linkType: hard + +"convert-source-map@npm:^1.5.0": + version: 1.9.0 + resolution: "convert-source-map@npm:1.9.0" + checksum: 10c0/281da55454bf8126cbc6625385928c43479f2060984180c42f3a86c8b8c12720a24eac260624a7d1e090004028d2dee78602330578ceec1a08e27cb8bb0a8a5b + languageName: node + linkType: hard + +"copy-to-clipboard@npm:^3.3.1": + version: 3.3.3 + resolution: "copy-to-clipboard@npm:3.3.3" + dependencies: + toggle-selection: "npm:^1.0.6" + checksum: 10c0/3ebf5e8ee00601f8c440b83ec08d838e8eabb068c1fae94a9cda6b42f288f7e1b552f3463635f419af44bf7675afc8d0390d30876cf5c2d5d35f86d9c56a3e5f + languageName: node + linkType: hard + +"core-js-pure@npm:^3.25.1": + version: 3.26.0 + resolution: "core-js-pure@npm:3.26.0" + checksum: 10c0/d2fd6f787903c77d9ea4f3c961bd79e4632e12ae2ddf55ecba0bbb186d31e46b0649e98f9d9a8def2a5127ad2272f31650f54e84f80b833dd822291730c6dd77 + languageName: node + linkType: hard + +"cosmiconfig@npm:^7.0.0": + version: 7.0.1 + resolution: "cosmiconfig@npm:7.0.1" + dependencies: + "@types/parse-json": "npm:^4.0.0" + import-fresh: "npm:^3.2.1" + parse-json: "npm:^5.0.0" + path-type: "npm:^4.0.0" + yaml: "npm:^1.10.0" + checksum: 10c0/3cd38525ba22e13da0ef9f4be131df226c94f5b96fb50f6297eb17baeedefe15cf5819f8c73cde69f71cc5034e712c86bd20c7756883dd8094087680ecc25932 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.2": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 10c0/5738c312387081c98d69c98e105b6327b069197f864a60593245d64c8089c8a0a744e16349281210d56835bb9274130d825a78b2ad6853ca13cfbeffc0c31750 + languageName: node + linkType: hard + +"css-color-keywords@npm:^1.0.0": + version: 1.0.0 + resolution: "css-color-keywords@npm:1.0.0" + checksum: 10c0/af205a86c68e0051846ed91eb3e30b4517e1904aac040013ff1d742019b3f9369ba5658ba40901dbbc121186fc4bf0e75a814321cc3e3182fbb2feb81c6d9cb7 + languageName: node + linkType: hard + +"css-in-js-utils@npm:^3.1.0": + version: 3.1.0 + resolution: "css-in-js-utils@npm:3.1.0" + dependencies: + hyphenate-style-name: "npm:^1.0.3" + checksum: 10c0/8bb042e8f7701a7edadc3cce5ce2d5cf41189631d7e2aed194d5a7059b25776dded2a0466cb9da1d1f3fc6c99dcecb51e45671148d073b8a2a71e34755152e52 + languageName: node + linkType: hard + +"css-to-react-native@npm:^3.0.0": + version: 3.0.0 + resolution: "css-to-react-native@npm:3.0.0" + dependencies: + camelize: "npm:^1.0.0" + css-color-keywords: "npm:^1.0.0" + postcss-value-parser: "npm:^4.0.2" + checksum: 10c0/03dcf5381ff6a888e3621aaffd812fd52df803d01c264b99142a9f73942007c2e953bd27339d6e2da2504a940a2b0d3cc702d3a737165703a0d8ae9c5626c1c1 + languageName: node + linkType: hard + +"css-tree@npm:^1.1.2": + version: 1.1.3 + resolution: "css-tree@npm:1.1.3" + dependencies: + mdn-data: "npm:2.0.14" + source-map: "npm:^0.6.1" + checksum: 10c0/499a507bfa39b8b2128f49736882c0dd636b0cd3370f2c69f4558ec86d269113286b7df469afc955de6a68b0dba00bc533e40022a73698081d600072d5d83c1c + languageName: node + linkType: hard + +"csstype@npm:^3.0.2, csstype@npm:^3.0.6, csstype@npm:^3.1.1": + version: 3.1.1 + resolution: "csstype@npm:3.1.1" + checksum: 10c0/7c8b8c5923049d84132581c13bae6e1faf999746fe3998ba5f3819a8e1cdc7512ace87b7d0a4a69f0f4b8ba11daf835d4f1390af23e09fc4f0baad52c084753a + languageName: node + linkType: hard + +"damerau-levenshtein@npm:^1.0.8": + version: 1.0.8 + resolution: "damerau-levenshtein@npm:1.0.8" + checksum: 10c0/4c2647e0f42acaee7d068756c1d396e296c3556f9c8314bac1ac63ffb236217ef0e7e58602b18bb2173deec7ec8e0cac8e27cccf8f5526666b4ff11a13ad54a3 + languageName: node + linkType: hard + +"date-fns@npm:^2.29.3": + version: 2.29.3 + resolution: "date-fns@npm:2.29.3" + checksum: 10c0/aa9128c876ef69a05988029d6aa3d7e5c47a1e978f18b77b48126683d1a2e6605a16c3f5293ca9f4ca790d0755b5061fcea5b469f097871cd53f6590a5c1adc4 + languageName: node + linkType: hard + +"debug@npm:^2.6.9": + version: 2.6.9 + resolution: "debug@npm:2.6.9" + dependencies: + ms: "npm:2.0.0" + checksum: 10c0/121908fb839f7801180b69a7e218a40b5a0b718813b886b7d6bdb82001b931c938e2941d1e4450f33a1b1df1da653f5f7a0440c197f29fbf8a6e9d45ff6ef589 + languageName: node + linkType: hard + +"debug@npm:^3.2.7": + version: 3.2.7 + resolution: "debug@npm:3.2.7" + dependencies: + ms: "npm:^2.1.1" + checksum: 10c0/37d96ae42cbc71c14844d2ae3ba55adf462ec89fd3a999459dec3833944cd999af6007ff29c780f1c61153bcaaf2c842d1e4ce1ec621e4fc4923244942e4a02a + languageName: node + linkType: hard + +"debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.2, debug@npm:^4.3.4": + version: 4.3.4 + resolution: "debug@npm:4.3.4" + dependencies: + ms: "npm:2.1.2" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10c0/cedbec45298dd5c501d01b92b119cd3faebe5438c3917ff11ae1bff86a6c722930ac9c8659792824013168ba6db7c4668225d845c633fbdafbbf902a6389f736 + languageName: node + linkType: hard + +"deep-is@npm:^0.1.3": + version: 0.1.4 + resolution: "deep-is@npm:0.1.4" + checksum: 10c0/7f0ee496e0dff14a573dc6127f14c95061b448b87b995fc96c017ce0a1e66af1675e73f1d6064407975bc4ea6ab679497a29fff7b5b9c4e99cb10797c1ad0b4c + languageName: node + linkType: hard + +"define-properties@npm:^1.1.3, define-properties@npm:^1.1.4": + version: 1.1.4 + resolution: "define-properties@npm:1.1.4" + dependencies: + has-property-descriptors: "npm:^1.0.0" + object-keys: "npm:^1.1.1" + checksum: 10c0/1e09acd814c3761f2355d9c8a18fbc2b5d2e1073e1302245c134e96aacbff51b152e2a6f5f5db23af3c43e26f4e3a0d42f569aa4135f49046246c934bfb8e1dc + languageName: node + linkType: hard + +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: 10c0/d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19 + languageName: node + linkType: hard + +"detect-node-es@npm:^1.1.0": + version: 1.1.0 + resolution: "detect-node-es@npm:1.1.0" + checksum: 10c0/e562f00de23f10c27d7119e1af0e7388407eb4b06596a25f6d79a360094a109ff285de317f02b090faae093d314cf6e73ac3214f8a5bb3a0def5bece94557fbe + languageName: node + linkType: hard + +"detect-node@npm:^2.0.4, detect-node@npm:^2.1.0": + version: 2.1.0 + resolution: "detect-node@npm:2.1.0" + checksum: 10c0/f039f601790f2e9d4654e499913259a798b1f5246ae24f86ab5e8bd4aaf3bce50484234c494f11fb00aecb0c6e2733aa7b1cf3f530865640b65fbbd65b2c4e09 + languageName: node + linkType: hard + +"dir-glob@npm:^3.0.1": + version: 3.0.1 + resolution: "dir-glob@npm:3.0.1" + dependencies: + path-type: "npm:^4.0.0" + checksum: 10c0/dcac00920a4d503e38bb64001acb19df4efc14536ada475725e12f52c16777afdee4db827f55f13a908ee7efc0cb282e2e3dbaeeb98c0993dd93d1802d3bf00c + languageName: node + linkType: hard + +"doctrine@npm:^2.1.0": + version: 2.1.0 + resolution: "doctrine@npm:2.1.0" + dependencies: + esutils: "npm:^2.0.2" + checksum: 10c0/b6416aaff1f380bf56c3b552f31fdf7a69b45689368deca72d28636f41c16bb28ec3ebc40ace97db4c1afc0ceeb8120e8492fe0046841c94c2933b2e30a7d5ac + languageName: node + linkType: hard + +"doctrine@npm:^3.0.0": + version: 3.0.0 + resolution: "doctrine@npm:3.0.0" + dependencies: + esutils: "npm:^2.0.2" + checksum: 10c0/c96bdccabe9d62ab6fea9399fdff04a66e6563c1d6fb3a3a063e8d53c3bb136ba63e84250bbf63d00086a769ad53aef92d2bd483f03f837fc97b71cbee6b2520 + languageName: node + linkType: hard + +"dom-helpers@npm:^5.0.1": + version: 5.2.1 + resolution: "dom-helpers@npm:5.2.1" + dependencies: + "@babel/runtime": "npm:^7.8.7" + csstype: "npm:^3.0.2" + checksum: 10c0/f735074d66dd759b36b158fa26e9d00c9388ee0e8c9b16af941c38f014a37fc80782de83afefd621681b19ac0501034b4f1c4a3bff5caa1b8667f0212b5e124c + languageName: node + linkType: hard + +"echarts-for-react@npm:^3.0.2": + version: 3.0.2 + resolution: "echarts-for-react@npm:3.0.2" + dependencies: + fast-deep-equal: "npm:^3.1.3" + size-sensor: "npm:^1.0.1" + peerDependencies: + echarts: ^3.0.0 || ^4.0.0 || ^5.0.0 + react: ^15.0.0 || >=16.0.0 + checksum: 10c0/a67d76d2cea6fdb8efa9e305fa998f4933053a647df13ea58b4ea0c7892a72e9afb7523a7382d98b541983e5e073adafc2c4103d7dcb88d86757c4582d45e400 + languageName: node + linkType: hard + +"echarts@npm:^5.4.2": + version: 5.4.2 + resolution: "echarts@npm:5.4.2" + dependencies: + tslib: "npm:2.3.0" + zrender: "npm:5.4.3" + checksum: 10c0/6a5aeca309fb68c5f5cd0be831973b161f7ed8a5eccc3c855d7ffe15d531b650a262b13bfda461be8c979e2c3039c3b4ddc0368638281b2dfd833f3324673464 + languageName: node + linkType: hard + +"email-addresses@npm:^5.0.0": + version: 5.0.0 + resolution: "email-addresses@npm:5.0.0" + checksum: 10c0/fc8a6f84e378bbe601ce39a3d8d86bc7e4584030ae9eb1938e12943f7fb5207e5fd7ae449cced3bea70968a519ade560d55ca170208c3f1413d7d25d8613a577 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 + languageName: node + linkType: hard + +"error-ex@npm:^1.3.1": + version: 1.3.2 + resolution: "error-ex@npm:1.3.2" + dependencies: + is-arrayish: "npm:^0.2.1" + checksum: 10c0/ba827f89369b4c93382cfca5a264d059dfefdaa56ecc5e338ffa58a6471f5ed93b71a20add1d52290a4873d92381174382658c885ac1a2305f7baca363ce9cce + languageName: node + linkType: hard + +"error-stack-parser@npm:^2.0.6": + version: 2.1.4 + resolution: "error-stack-parser@npm:2.1.4" + dependencies: + stackframe: "npm:^1.3.4" + checksum: 10c0/7679b780043c98b01fc546725484e0cfd3071bf5c906bbe358722972f04abf4fc3f0a77988017665bab367f6ef3fc2d0185f7528f45966b83e7c99c02d5509b9 + languageName: node + linkType: hard + +"es-abstract@npm:^1.19.0, es-abstract@npm:^1.19.1, es-abstract@npm:^1.19.2, es-abstract@npm:^1.19.5": + version: 1.20.4 + resolution: "es-abstract@npm:1.20.4" + dependencies: + call-bind: "npm:^1.0.2" + es-to-primitive: "npm:^1.2.1" + function-bind: "npm:^1.1.1" + function.prototype.name: "npm:^1.1.5" + get-intrinsic: "npm:^1.1.3" + get-symbol-description: "npm:^1.0.0" + has: "npm:^1.0.3" + has-property-descriptors: "npm:^1.0.0" + has-symbols: "npm:^1.0.3" + internal-slot: "npm:^1.0.3" + is-callable: "npm:^1.2.7" + is-negative-zero: "npm:^2.0.2" + is-regex: "npm:^1.1.4" + is-shared-array-buffer: "npm:^1.0.2" + is-string: "npm:^1.0.7" + is-weakref: "npm:^1.0.2" + object-inspect: "npm:^1.12.2" + object-keys: "npm:^1.1.1" + object.assign: "npm:^4.1.4" + regexp.prototype.flags: "npm:^1.4.3" + safe-regex-test: "npm:^1.0.0" + string.prototype.trimend: "npm:^1.0.5" + string.prototype.trimstart: "npm:^1.0.5" + unbox-primitive: "npm:^1.0.2" + checksum: 10c0/724a6db288e5c2596a169939eb7750d1542c1516fc5a7100b9785fcd955bac9f7f8a35010e20ab4b5c6b2bc228573b82033f4d61ad926f1081d7953f61398c2e + languageName: node + linkType: hard + +"es-shim-unscopables@npm:^1.0.0": + version: 1.0.0 + resolution: "es-shim-unscopables@npm:1.0.0" + dependencies: + has: "npm:^1.0.3" + checksum: 10c0/d54a66239fbd19535b3e50333913260394f14d2d7adb136a95396a13ca584bab400cf9cb2ffd9232f3fe2f0362540bd3a708240c493e46e13fe0b90cfcfedc3d + languageName: node + linkType: hard + +"es-to-primitive@npm:^1.2.1": + version: 1.2.1 + resolution: "es-to-primitive@npm:1.2.1" + dependencies: + is-callable: "npm:^1.1.4" + is-date-object: "npm:^1.0.1" + is-symbol: "npm:^1.0.2" + checksum: 10c0/0886572b8dc075cb10e50c0af62a03d03a68e1e69c388bd4f10c0649ee41b1fbb24840a1b7e590b393011b5cdbe0144b776da316762653685432df37d6de60f1 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": + version: 1.0.5 + resolution: "escape-string-regexp@npm:1.0.5" + checksum: 10c0/a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9 + languageName: node + linkType: hard + +"eslint-config-next@npm:13.0.0": + version: 13.0.0 + resolution: "eslint-config-next@npm:13.0.0" + dependencies: + "@next/eslint-plugin-next": "npm:13.0.0" + "@rushstack/eslint-patch": "npm:^1.1.3" + "@typescript-eslint/parser": "npm:^5.21.0" + eslint-import-resolver-node: "npm:^0.3.6" + eslint-import-resolver-typescript: "npm:^2.7.1" + eslint-plugin-import: "npm:^2.26.0" + eslint-plugin-jsx-a11y: "npm:^6.5.1" + eslint-plugin-react: "npm:^7.31.7" + eslint-plugin-react-hooks: "npm:^4.5.0" + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 + typescript: ">=3.3.1" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10c0/6b4c7895b5119410ff7beb05ee05e2a823acf60a9997ce04bf8ef29333615b72818f29fc04b21751ba2855be42c20378efda3eb8d2bfa9152727a11929d8b01a + languageName: node + linkType: hard + +"eslint-import-resolver-node@npm:^0.3.6": + version: 0.3.6 + resolution: "eslint-import-resolver-node@npm:0.3.6" + dependencies: + debug: "npm:^3.2.7" + resolve: "npm:^1.20.0" + checksum: 10c0/20e06f3fa27b49de7159c8db54b4d7f82c156498e0050c491fcf7395922f927765b8296bf857c3b487da361bd65c1dcc68203832ef8e9179b461aa4192406535 + languageName: node + linkType: hard + +"eslint-import-resolver-typescript@npm:^2.7.1": + version: 2.7.1 + resolution: "eslint-import-resolver-typescript@npm:2.7.1" + dependencies: + debug: "npm:^4.3.4" + glob: "npm:^7.2.0" + is-glob: "npm:^4.0.3" + resolve: "npm:^1.22.0" + tsconfig-paths: "npm:^3.14.1" + peerDependencies: + eslint: "*" + eslint-plugin-import: "*" + checksum: 10c0/42e2af8f86bc39413a1dbd597f9e3c645568e2ba02a960dea2e77e6970f57b3a90193ac7c950e28286404956a9b7d1a69fd5072795afe1b98a76d401a612128e + languageName: node + linkType: hard + +"eslint-module-utils@npm:^2.7.3": + version: 2.7.4 + resolution: "eslint-module-utils@npm:2.7.4" + dependencies: + debug: "npm:^3.2.7" + peerDependenciesMeta: + eslint: + optional: true + checksum: 10c0/a14368a03d01824e4780e76df08460bbd5dcbf9d58944faf8660079559d169ab2b163b9b1b21fa2955c31c76f4ad348fdcde1bf0ef50cda7e14b89f6257b0eda + languageName: node + linkType: hard + +"eslint-plugin-import@npm:^2.26.0": + version: 2.26.0 + resolution: "eslint-plugin-import@npm:2.26.0" + dependencies: + array-includes: "npm:^3.1.4" + array.prototype.flat: "npm:^1.2.5" + debug: "npm:^2.6.9" + doctrine: "npm:^2.1.0" + eslint-import-resolver-node: "npm:^0.3.6" + eslint-module-utils: "npm:^2.7.3" + has: "npm:^1.0.3" + is-core-module: "npm:^2.8.1" + is-glob: "npm:^4.0.3" + minimatch: "npm:^3.1.2" + object.values: "npm:^1.1.5" + resolve: "npm:^1.22.0" + tsconfig-paths: "npm:^3.14.1" + peerDependencies: + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + checksum: 10c0/d4b6f22dbbc72997b37ccb6f5948e7ae02f1f93bb2a1da7dea830ecd4d7f0ba60c69418cb298d54ffa0aa854f96b2ad9df3d21ca2bff6617e625cd26266eb74f + languageName: node + linkType: hard + +"eslint-plugin-jsx-a11y@npm:^6.5.1": + version: 6.6.1 + resolution: "eslint-plugin-jsx-a11y@npm:6.6.1" + dependencies: + "@babel/runtime": "npm:^7.18.9" + aria-query: "npm:^4.2.2" + array-includes: "npm:^3.1.5" + ast-types-flow: "npm:^0.0.7" + axe-core: "npm:^4.4.3" + axobject-query: "npm:^2.2.0" + damerau-levenshtein: "npm:^1.0.8" + emoji-regex: "npm:^9.2.2" + has: "npm:^1.0.3" + jsx-ast-utils: "npm:^3.3.2" + language-tags: "npm:^1.0.5" + minimatch: "npm:^3.1.2" + semver: "npm:^6.3.0" + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + checksum: 10c0/7095a78f538e92d046ff67ba27a6b8ba75e7baba273cda348ed2893018b4cce0628fe85e5bf529251f394cd61b21d7a172c697b296e3917cc170f80f6419e9b3 + languageName: node + linkType: hard + +"eslint-plugin-react-hooks@npm:^4.5.0": + version: 4.6.0 + resolution: "eslint-plugin-react-hooks@npm:4.6.0" + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + checksum: 10c0/58c7e10ea5792c33346fcf5cb4024e14837035ce412ff99c2dcb7c4f903dc9b17939078f80bfef826301ce326582c396c00e8e0ac9d10ac2cde2b42d33763c65 + languageName: node + linkType: hard + +"eslint-plugin-react@npm:^7.31.7": + version: 7.31.10 + resolution: "eslint-plugin-react@npm:7.31.10" + dependencies: + array-includes: "npm:^3.1.5" + array.prototype.flatmap: "npm:^1.3.0" + doctrine: "npm:^2.1.0" + estraverse: "npm:^5.3.0" + jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" + minimatch: "npm:^3.1.2" + object.entries: "npm:^1.1.5" + object.fromentries: "npm:^2.0.5" + object.hasown: "npm:^1.1.1" + object.values: "npm:^1.1.5" + prop-types: "npm:^15.8.1" + resolve: "npm:^2.0.0-next.3" + semver: "npm:^6.3.0" + string.prototype.matchall: "npm:^4.0.7" + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + checksum: 10c0/0a3ed9547e337f7eac4364f45229a8094ea4ac5073f1c4b8662f84c75284703bfebdf5dfe2cb55bcaeedec43f0445ed76ca650388f642d5ad1c9fe530bf3f159 + languageName: node + linkType: hard + +"eslint-scope@npm:^7.1.1": + version: 7.1.1 + resolution: "eslint-scope@npm:7.1.1" + dependencies: + esrecurse: "npm:^4.3.0" + estraverse: "npm:^5.2.0" + checksum: 10c0/3ae3280cbea34af3b816e941b83888aca063aaa0169966ff7e4c1bfb0715dbbeac3811596e56315e8ceea84007a7403754459ae4f1d19f25487eb02acd951aa7 + languageName: node + linkType: hard + +"eslint-utils@npm:^3.0.0": + version: 3.0.0 + resolution: "eslint-utils@npm:3.0.0" + dependencies: + eslint-visitor-keys: "npm:^2.0.0" + peerDependencies: + eslint: ">=5" + checksum: 10c0/45aa2b63667a8d9b474c98c28af908d0a592bed1a4568f3145cd49fb5d9510f545327ec95561625290313fe126e6d7bdfe3fdbdb6f432689fab6b9497d3bfb52 + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^2.0.0": + version: 2.1.0 + resolution: "eslint-visitor-keys@npm:2.1.0" + checksum: 10c0/9f0e3a2db751d84067d15977ac4b4472efd6b303e369e6ff241a99feac04da758f46d5add022c33d06b53596038dbae4b4aceb27c7e68b8dfc1055b35e495787 + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^3.3.0": + version: 3.3.0 + resolution: "eslint-visitor-keys@npm:3.3.0" + checksum: 10c0/fc6a9b5bdee8d90e35e7564fd9db10fdf507a2c089a4f0d4d3dd091f7f4ac6790547c8b1b7a760642ef819f875ef86dd5bcb8cdf01b0775f57a699f4e6a20a18 + languageName: node + linkType: hard + +"eslint@npm:8.26.0": + version: 8.26.0 + resolution: "eslint@npm:8.26.0" + dependencies: + "@eslint/eslintrc": "npm:^1.3.3" + "@humanwhocodes/config-array": "npm:^0.11.6" + "@humanwhocodes/module-importer": "npm:^1.0.1" + "@nodelib/fs.walk": "npm:^1.2.8" + ajv: "npm:^6.10.0" + chalk: "npm:^4.0.0" + cross-spawn: "npm:^7.0.2" + debug: "npm:^4.3.2" + doctrine: "npm:^3.0.0" + escape-string-regexp: "npm:^4.0.0" + eslint-scope: "npm:^7.1.1" + eslint-utils: "npm:^3.0.0" + eslint-visitor-keys: "npm:^3.3.0" + espree: "npm:^9.4.0" + esquery: "npm:^1.4.0" + esutils: "npm:^2.0.2" + fast-deep-equal: "npm:^3.1.3" + file-entry-cache: "npm:^6.0.1" + find-up: "npm:^5.0.0" + glob-parent: "npm:^6.0.2" + globals: "npm:^13.15.0" + grapheme-splitter: "npm:^1.0.4" + ignore: "npm:^5.2.0" + import-fresh: "npm:^3.0.0" + imurmurhash: "npm:^0.1.4" + is-glob: "npm:^4.0.0" + is-path-inside: "npm:^3.0.3" + js-sdsl: "npm:^4.1.4" + js-yaml: "npm:^4.1.0" + json-stable-stringify-without-jsonify: "npm:^1.0.1" + levn: "npm:^0.4.1" + lodash.merge: "npm:^4.6.2" + minimatch: "npm:^3.1.2" + natural-compare: "npm:^1.4.0" + optionator: "npm:^0.9.1" + regexpp: "npm:^3.2.0" + strip-ansi: "npm:^6.0.1" + strip-json-comments: "npm:^3.1.0" + text-table: "npm:^0.2.0" + bin: + eslint: bin/eslint.js + checksum: 10c0/da97a44bac58770d44dc6a2daa57cbb67ac888c060dde5a87c7785ea34a2cea61568d5238d375a14bfd548ffff7cd61691ab5a81c4625c7c97412b2d45b63843 + languageName: node + linkType: hard + +"espree@npm:^9.4.0": + version: 9.4.0 + resolution: "espree@npm:9.4.0" + dependencies: + acorn: "npm:^8.8.0" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^3.3.0" + checksum: 10c0/95f1f9ac49fa112bfc2d2e82fd9e85192367090a9ee03b1e43594e85e29a3458b603b4cf7cd5ccfb156da2b94d07e7f5428474c830faa6f19db47a0b86dd3656 + languageName: node + linkType: hard + +"esquery@npm:^1.4.0": + version: 1.4.0 + resolution: "esquery@npm:1.4.0" + dependencies: + estraverse: "npm:^5.1.0" + checksum: 10c0/b9b18178d33c4335210c76e062de979dc38ee6b49deea12bff1b2315e6cfcca1fd7f8bc49f899720ad8ff25967ac95b5b182e81a8b7b59ff09dbd0d978c32f64 + languageName: node + linkType: hard + +"esrecurse@npm:^4.3.0": + version: 4.3.0 + resolution: "esrecurse@npm:4.3.0" + dependencies: + estraverse: "npm:^5.2.0" + checksum: 10c0/81a37116d1408ded88ada45b9fb16dbd26fba3aadc369ce50fcaf82a0bac12772ebd7b24cd7b91fc66786bf2c1ac7b5f196bc990a473efff972f5cb338877cf5 + languageName: node + linkType: hard + +"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0": + version: 5.3.0 + resolution: "estraverse@npm:5.3.0" + checksum: 10c0/1ff9447b96263dec95d6d67431c5e0771eb9776427421260a3e2f0fdd5d6bd4f8e37a7338f5ad2880c9f143450c9b1e4fc2069060724570a49cf9cf0312bd107 + languageName: node + linkType: hard + +"esutils@npm:^2.0.2": + version: 2.0.3 + resolution: "esutils@npm:2.0.3" + checksum: 10c0/9a2fe69a41bfdade834ba7c42de4723c97ec776e40656919c62cbd13607c45e127a003f05f724a1ea55e5029a4cf2de444b13009f2af71271e42d93a637137c7 + languageName: node + linkType: hard + +"ethers@npm:^6.13.2": + version: 6.13.2 + resolution: "ethers@npm:6.13.2" + dependencies: + "@adraffy/ens-normalize": "npm:1.10.1" + "@noble/curves": "npm:1.2.0" + "@noble/hashes": "npm:1.3.2" + "@types/node": "npm:18.15.13" + aes-js: "npm:4.0.0-beta.5" + tslib: "npm:2.4.0" + ws: "npm:8.17.1" + checksum: 10c0/5956389a180992f8b6d90bc21b2e0f28619a098513d3aeb7a350a0b7c5852d635a9d7fd4ced1af50c985dd88398716f66dfd4a2de96c5c3a67150b93543d92af + languageName: node + linkType: hard + +"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": + version: 3.1.3 + resolution: "fast-deep-equal@npm:3.1.3" + checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0 + languageName: node + linkType: hard + +"fast-glob@npm:^3.2.9": + version: 3.2.12 + resolution: "fast-glob@npm:3.2.12" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 10c0/08604fb8ef6442ce74068bef3c3104382bb1f5ab28cf75e4ee904662778b60ad620e1405e692b7edea598ef445f5d387827a965ba034e1892bf54b1dfde97f26 + languageName: node + linkType: hard + +"fast-json-stable-stringify@npm:^2.0.0": + version: 2.1.0 + resolution: "fast-json-stable-stringify@npm:2.1.0" + checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b + languageName: node + linkType: hard + +"fast-levenshtein@npm:^2.0.6": + version: 2.0.6 + resolution: "fast-levenshtein@npm:2.0.6" + checksum: 10c0/111972b37338bcb88f7d9e2c5907862c280ebf4234433b95bc611e518d192ccb2d38119c4ac86e26b668d75f7f3894f4ff5c4982899afced7ca78633b08287c4 + languageName: node + linkType: hard + +"fast-loops@npm:^1.1.3": + version: 1.1.3 + resolution: "fast-loops@npm:1.1.3" + checksum: 10c0/ba71c001704c44a617053ed34b1a8c0d2ed9723022eb7b93c98299d9862f93213609b32c9daec7d606625ab318769d11da8bb06e9ddd9c28e3bda1249fb6e36d + languageName: node + linkType: hard + +"fast-shallow-equal@npm:^1.0.0": + version: 1.0.0 + resolution: "fast-shallow-equal@npm:1.0.0" + checksum: 10c0/526c393c011ab5a0ca5a36c5ea25c9730acd027503ccbec6c7825397ab9375f51f67f14c8829b4c4b1ccccede695391dd14863a15e40a37fc4af08c1440a1b66 + languageName: node + linkType: hard + +"fastest-stable-stringify@npm:^2.0.2": + version: 2.0.2 + resolution: "fastest-stable-stringify@npm:2.0.2" + checksum: 10c0/abbe5ff48f13f5819e7312dbb38bae5d9960694cffd315b464df9adcd02a8fa7e9eec32c314655674c7134905c544b7a0c14b05bfbe30b3f678609bebc9fecb9 + languageName: node + linkType: hard + +"fastq@npm:^1.6.0": + version: 1.13.0 + resolution: "fastq@npm:1.13.0" + dependencies: + reusify: "npm:^1.0.4" + checksum: 10c0/76c7b5dafb93c7e74359a3e6de834ce7a7c2e3a3184050ed4cb652661de55cf8d4895178d8d3ccd23069395056c7bb15450660d38fb382ca88c142b22694d7c9 + languageName: node + linkType: hard + +"file-entry-cache@npm:^6.0.1": + version: 6.0.1 + resolution: "file-entry-cache@npm:6.0.1" + dependencies: + flat-cache: "npm:^3.0.4" + checksum: 10c0/58473e8a82794d01b38e5e435f6feaf648e3f36fdb3a56e98f417f4efae71ad1c0d4ebd8a9a7c50c3ad085820a93fc7494ad721e0e4ebc1da3573f4e1c3c7cdd + languageName: node + linkType: hard + +"filename-reserved-regex@npm:^2.0.0": + version: 2.0.0 + resolution: "filename-reserved-regex@npm:2.0.0" + checksum: 10c0/453740b7f9fd126e508da555b37e38c1f7ff19f5e9f3d297b2de1beb09854957baddd74c83235e87b16e9ce27a2368798896669edad5a81b5b7bd8cb57c942fc + languageName: node + linkType: hard + +"filenamify@npm:^4.3.0": + version: 4.3.0 + resolution: "filenamify@npm:4.3.0" + dependencies: + filename-reserved-regex: "npm:^2.0.0" + strip-outer: "npm:^1.0.1" + trim-repeated: "npm:^1.0.0" + checksum: 10c0/dcfd2f116d66f78c9dd58bb0f0d9b6529d89c801a9f37a4f86e7adc0acecb6881c7fb7c3231dc9e6754b767edcfdca89cba3a492a58afd2b48479b30d14ccf8f + languageName: node + linkType: hard + +"fill-range@npm:^7.0.1": + version: 7.0.1 + resolution: "fill-range@npm:7.0.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: 10c0/7cdad7d426ffbaadf45aeb5d15ec675bbd77f7597ad5399e3d2766987ed20bda24d5fac64b3ee79d93276f5865608bb22344a26b9b1ae6c4d00bd94bf611623f + languageName: node + linkType: hard + +"find-cache-dir@npm:^3.3.1": + version: 3.3.2 + resolution: "find-cache-dir@npm:3.3.2" + dependencies: + commondir: "npm:^1.0.1" + make-dir: "npm:^3.0.2" + pkg-dir: "npm:^4.1.0" + checksum: 10c0/92747cda42bff47a0266b06014610981cfbb71f55d60f2c8216bc3108c83d9745507fb0b14ecf6ab71112bed29cd6fb1a137ee7436179ea36e11287e3159e587 + languageName: node + linkType: hard + +"find-root@npm:^1.1.0": + version: 1.1.0 + resolution: "find-root@npm:1.1.0" + checksum: 10c0/1abc7f3bf2f8d78ff26d9e00ce9d0f7b32e5ff6d1da2857bcdf4746134c422282b091c672cde0572cac3840713487e0a7a636af9aa1b74cb11894b447a521efa + languageName: node + linkType: hard + +"find-up@npm:^4.0.0": + version: 4.1.0 + resolution: "find-up@npm:4.1.0" + dependencies: + locate-path: "npm:^5.0.0" + path-exists: "npm:^4.0.0" + checksum: 10c0/0406ee89ebeefa2d507feb07ec366bebd8a6167ae74aa4e34fb4c4abd06cf782a3ce26ae4194d70706f72182841733f00551c209fe575cb00bd92104056e78c1 + languageName: node + linkType: hard + +"find-up@npm:^5.0.0": + version: 5.0.0 + resolution: "find-up@npm:5.0.0" + dependencies: + locate-path: "npm:^6.0.0" + path-exists: "npm:^4.0.0" + checksum: 10c0/062c5a83a9c02f53cdd6d175a37ecf8f87ea5bbff1fdfb828f04bfa021441bc7583e8ebc0872a4c1baab96221fb8a8a275a19809fb93fbc40bd69ec35634069a + languageName: node + linkType: hard + +"flat-cache@npm:^3.0.4": + version: 3.0.4 + resolution: "flat-cache@npm:3.0.4" + dependencies: + flatted: "npm:^3.1.0" + rimraf: "npm:^3.0.2" + checksum: 10c0/f274dcbadb09ad8d7b6edf2ee9b034bc40bf0c12638f6c4084e9f1d39208cb104a5ebbb24b398880ef048200eaa116852f73d2d8b72e8c9627aba8c3e27ca057 + languageName: node + linkType: hard + +"flatted@npm:^3.1.0": + version: 3.2.7 + resolution: "flatted@npm:3.2.7" + checksum: 10c0/207a87c7abfc1ea6928ea16bac84f9eaa6d44d365620ece419e5c41cf44a5e9902b4c1f59c9605771b10e4565a0cb46e99d78e0464e8aabb42c97de880642257 + languageName: node + linkType: hard + +"follow-redirects@npm:^1.15.0": + version: 1.15.2 + resolution: "follow-redirects@npm:1.15.2" + peerDependenciesMeta: + debug: + optional: true + checksum: 10c0/da5932b70e63944d38eecaa16954bac4347036f08303c913d166eda74809d8797d38386e3a0eb1d2fe37d2aaff2764cce8e9dbd99459d860cf2cdfa237923b5f + languageName: node + linkType: hard + +"form-data@npm:^4.0.0": + version: 4.0.0 + resolution: "form-data@npm:4.0.0" + dependencies: + asynckit: "npm:^0.4.0" + combined-stream: "npm:^1.0.8" + mime-types: "npm:^2.1.12" + checksum: 10c0/cb6f3ac49180be03ff07ba3ff125f9eba2ff0b277fb33c7fc47569fc5e616882c5b1c69b9904c4c4187e97dd0419dd03b134174756f296dec62041e6527e2c6e + languageName: node + linkType: hard + +"fs-extra@npm:^11.1.1": + version: 11.2.0 + resolution: "fs-extra@npm:11.2.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^6.0.1" + universalify: "npm:^2.0.0" + checksum: 10c0/d77a9a9efe60532d2e790e938c81a02c1b24904ef7a3efb3990b835514465ba720e99a6ea56fd5e2db53b4695319b644d76d5a0e9988a2beef80aa7b1da63398 + languageName: node + linkType: hard + +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948 + languageName: node + linkType: hard + +"function-bind@npm:^1.1.1": + version: 1.1.1 + resolution: "function-bind@npm:1.1.1" + checksum: 10c0/60b74b2407e1942e1ed7f8c284f8ef714d0689dcfce5319985a5b7da3fc727f40b4a59ec72dc55aa83365ad7b8fa4fac3a30d93c850a2b452f29ae03dbc10a1e + languageName: node + linkType: hard + +"function.prototype.name@npm:^1.1.5": + version: 1.1.5 + resolution: "function.prototype.name@npm:1.1.5" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.3" + es-abstract: "npm:^1.19.0" + functions-have-names: "npm:^1.2.2" + checksum: 10c0/b75fb8c5261f03a54f7cb53a8c99e0c40297efc3cf750c51d3a2e56f6741701c14eda51986d30c24063136a4c32d1643df9d1dd2f2a14b64fa011edd3e7117ae + languageName: node + linkType: hard + +"functions-have-names@npm:^1.2.2": + version: 1.2.3 + resolution: "functions-have-names@npm:1.2.3" + checksum: 10c0/33e77fd29bddc2d9bb78ab3eb854c165909201f88c75faa8272e35899e2d35a8a642a15e7420ef945e1f64a9670d6aa3ec744106b2aa42be68ca5114025954ca + languageName: node + linkType: hard + +"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.0, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3": + version: 1.1.3 + resolution: "get-intrinsic@npm:1.1.3" + dependencies: + function-bind: "npm:^1.1.1" + has: "npm:^1.0.3" + has-symbols: "npm:^1.0.3" + checksum: 10c0/6f201d5f95ea0dd6c8d0dc2c265603aff0b9e15614cb70f8f4674bb3d2b2369d521efaa84d0b70451d2c00762ebd28402758bf46279c6f2a00d242ebac0d8442 + languageName: node + linkType: hard + +"get-nonce@npm:^1.0.0": + version: 1.0.1 + resolution: "get-nonce@npm:1.0.1" + checksum: 10c0/2d7df55279060bf0568549e1ffc9b84bc32a32b7541675ca092dce56317cdd1a59a98dcc4072c9f6a980779440139a3221d7486f52c488e69dc0fd27b1efb162 + languageName: node + linkType: hard + +"get-symbol-description@npm:^1.0.0": + version: 1.0.0 + resolution: "get-symbol-description@npm:1.0.0" + dependencies: + call-bind: "npm:^1.0.2" + get-intrinsic: "npm:^1.1.1" + checksum: 10c0/23bc3b44c221cdf7669a88230c62f4b9e30393b61eb21ba4400cb3e346801bd8f95fe4330ee78dbae37aecd874646d53e3e76a17a654d0c84c77f6690526d6bb + languageName: node + linkType: hard + +"gh-pages@npm:^6.1.1": + version: 6.1.1 + resolution: "gh-pages@npm:6.1.1" + dependencies: + async: "npm:^3.2.4" + commander: "npm:^11.0.0" + email-addresses: "npm:^5.0.0" + filenamify: "npm:^4.3.0" + find-cache-dir: "npm:^3.3.1" + fs-extra: "npm:^11.1.1" + globby: "npm:^6.1.0" + bin: + gh-pages: bin/gh-pages.js + gh-pages-clean: bin/gh-pages-clean.js + checksum: 10c0/1a0c1843862e3d85cdf7a165e92ab504e14b20d1c59398355cb73602041d8a3d509f9c5d80788628048610b751cb32731ed38079691c2b5f9d720664be3f1fa6 + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee + languageName: node + linkType: hard + +"glob-parent@npm:^6.0.2": + version: 6.0.2 + resolution: "glob-parent@npm:6.0.2" + dependencies: + is-glob: "npm:^4.0.3" + checksum: 10c0/317034d88654730230b3f43bb7ad4f7c90257a426e872ea0bf157473ac61c99bf5d205fad8f0185f989be8d2fa6d3c7dce1645d99d545b6ea9089c39f838e7f8 + languageName: node + linkType: hard + +"glob@npm:7.1.7, glob@npm:^7.1.3": + version: 7.1.7 + resolution: "glob@npm:7.1.7" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.0.4" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 10c0/173245e6f9ccf904309eb7ef4a44a11f3bf68e9e341dff5a28b5db0dd7123b7506daf41497f3437a0710f57198187b758c2351eeaabce4d16935e956920da6a4 + languageName: node + linkType: hard + +"glob@npm:^7.0.3, glob@npm:^7.2.0": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.1.1" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe + languageName: node + linkType: hard + +"globals@npm:^11.1.0": + version: 11.12.0 + resolution: "globals@npm:11.12.0" + checksum: 10c0/758f9f258e7b19226bd8d4af5d3b0dcf7038780fb23d82e6f98932c44e239f884847f1766e8fa9cc5635ccb3204f7fa7314d4408dd4002a5e8ea827b4018f0a1 + languageName: node + linkType: hard + +"globals@npm:^13.15.0": + version: 13.17.0 + resolution: "globals@npm:13.17.0" + dependencies: + type-fest: "npm:^0.20.2" + checksum: 10c0/f2aa3b9f21608bed3570f281e95a8050d9700580edd4b59ed5464c83e0b7a346f74abc13f850c7f07a972cd198ee1f2b0de6a5977baf547e50b1002428f0dd09 + languageName: node + linkType: hard + +"globby@npm:^11.1.0": + version: 11.1.0 + resolution: "globby@npm:11.1.0" + dependencies: + array-union: "npm:^2.1.0" + dir-glob: "npm:^3.0.1" + fast-glob: "npm:^3.2.9" + ignore: "npm:^5.2.0" + merge2: "npm:^1.4.1" + slash: "npm:^3.0.0" + checksum: 10c0/b39511b4afe4bd8a7aead3a27c4ade2b9968649abab0a6c28b1a90141b96ca68ca5db1302f7c7bd29eab66bf51e13916b8e0a3d0ac08f75e1e84a39b35691189 + languageName: node + linkType: hard + +"globby@npm:^6.1.0": + version: 6.1.0 + resolution: "globby@npm:6.1.0" + dependencies: + array-union: "npm:^1.0.1" + glob: "npm:^7.0.3" + object-assign: "npm:^4.0.1" + pify: "npm:^2.0.0" + pinkie-promise: "npm:^2.0.0" + checksum: 10c0/656ad1f0d02c6ef378c07589519ed3ec27fe988ea177195c05b8aff280320f3d67b91fa0baa6f7e49288f9bf1f92fc84f783a79ac3ed66278f3fa082e627ed84 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 + languageName: node + linkType: hard + +"grapheme-splitter@npm:^1.0.4": + version: 1.0.4 + resolution: "grapheme-splitter@npm:1.0.4" + checksum: 10c0/108415fb07ac913f17040dc336607772fcea68c7f495ef91887edddb0b0f5ff7bc1d1ab181b125ecb2f0505669ef12c9a178a3bbd2dd8e042d8c5f1d7c90331a + languageName: node + linkType: hard + +"has-bigints@npm:^1.0.1, has-bigints@npm:^1.0.2": + version: 1.0.2 + resolution: "has-bigints@npm:1.0.2" + checksum: 10c0/724eb1485bfa3cdff6f18d95130aa190561f00b3fcf9f19dc640baf8176b5917c143b81ec2123f8cddb6c05164a198c94b13e1377c497705ccc8e1a80306e83b + languageName: node + linkType: hard + +"has-flag@npm:^3.0.0": + version: 3.0.0 + resolution: "has-flag@npm:3.0.0" + checksum: 10c0/1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 + languageName: node + linkType: hard + +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 10c0/2e789c61b7888d66993e14e8331449e525ef42aac53c627cc53d1c3334e768bcb6abdc4f5f0de1478a25beec6f0bd62c7549058b7ac53e924040d4f301f02fd1 + languageName: node + linkType: hard + +"has-property-descriptors@npm:^1.0.0": + version: 1.0.0 + resolution: "has-property-descriptors@npm:1.0.0" + dependencies: + get-intrinsic: "npm:^1.1.1" + checksum: 10c0/d4ca882b6960d6257bd28baa3ddfa21f068d260411004a093b30ca357c740e11e985771c85216a6d1eef4161e862657f48c4758ec8ab515223b3895200ad164b + languageName: node + linkType: hard + +"has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": + version: 1.0.3 + resolution: "has-symbols@npm:1.0.3" + checksum: 10c0/e6922b4345a3f37069cdfe8600febbca791c94988c01af3394d86ca3360b4b93928bbf395859158f88099cb10b19d98e3bbab7c9ff2c1bd09cf665ee90afa2c3 + languageName: node + linkType: hard + +"has-tostringtag@npm:^1.0.0": + version: 1.0.0 + resolution: "has-tostringtag@npm:1.0.0" + dependencies: + has-symbols: "npm:^1.0.2" + checksum: 10c0/1cdba76b7d13f65198a92b8ca1560ba40edfa09e85d182bf436d928f3588a9ebd260451d569f0ed1b849c4bf54f49c862aa0d0a77f9552b1855bb6deb526c011 + languageName: node + linkType: hard + +"has@npm:^1.0.3": + version: 1.0.3 + resolution: "has@npm:1.0.3" + dependencies: + function-bind: "npm:^1.1.1" + checksum: 10c0/e1da0d2bd109f116b632f27782cf23182b42f14972ca9540e4c5aa7e52647407a0a4a76937334fddcb56befe94a3494825ec22b19b51f5e5507c3153fd1a5e1b + languageName: node + linkType: hard + +"hoist-non-react-statics@npm:^3.0.0, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1": + version: 3.3.2 + resolution: "hoist-non-react-statics@npm:3.3.2" + dependencies: + react-is: "npm:^16.7.0" + checksum: 10c0/fe0889169e845d738b59b64badf5e55fa3cf20454f9203d1eb088df322d49d4318df774828e789898dcb280e8a5521bb59b3203385662ca5e9218a6ca5820e74 + languageName: node + linkType: hard + +"hyphenate-style-name@npm:^1.0.3": + version: 1.0.4 + resolution: "hyphenate-style-name@npm:1.0.4" + checksum: 10c0/b19c3e2cd1dc426f6f893752fec08140abf79058a1b6238422e45373ed81389f02e1a2ba2ef4e9b2430d4e900a0f5ba12307de82320604e81ac1b722abd2ee62 + languageName: node + linkType: hard + +"ignore@npm:^5.2.0": + version: 5.2.0 + resolution: "ignore@npm:5.2.0" + checksum: 10c0/7fb7b4c4c52c2555113ff968f8a83b8ac21b076282bfcb3f468c3fb429be69bd56222306c31de95dd452c647fc6ae24339b8047ebe3ef34c02591abfec58da01 + languageName: node + linkType: hard + +"import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1": + version: 3.3.0 + resolution: "import-fresh@npm:3.3.0" + dependencies: + parent-module: "npm:^1.0.0" + resolve-from: "npm:^4.0.0" + checksum: 10c0/7f882953aa6b740d1f0e384d0547158bc86efbf2eea0f1483b8900a6f65c5a5123c2cf09b0d542cc419d0b98a759ecaeb394237e97ea427f2da221dc3cd80cc3 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2 + languageName: node + linkType: hard + +"inherits@npm:2": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 + languageName: node + linkType: hard + +"inline-style-prefixer@npm:^6.0.0": + version: 6.0.4 + resolution: "inline-style-prefixer@npm:6.0.4" + dependencies: + css-in-js-utils: "npm:^3.1.0" + fast-loops: "npm:^1.1.3" + checksum: 10c0/d3d42bf0c48d621ea4bcfb077b5d370b106995422300a3a472674f96c9b489d96b4aac6f29dea3bb26ff2dfd7293e4752098bc2b53407769eafdb66c6c4c1764 + languageName: node + linkType: hard + +"internal-slot@npm:^1.0.3": + version: 1.0.3 + resolution: "internal-slot@npm:1.0.3" + dependencies: + get-intrinsic: "npm:^1.1.0" + has: "npm:^1.0.3" + side-channel: "npm:^1.0.4" + checksum: 10c0/bb41342a474c1b607458b0c716c742d779a6ed9dfaf7986e5d20d1e7f55b7f3676e4d9f416bc253af4fd78d367e1f83e586f74840302bcf2e60c424f9284dde5 + languageName: node + linkType: hard + +"invariant@npm:^2.2.4": + version: 2.2.4 + resolution: "invariant@npm:2.2.4" + dependencies: + loose-envify: "npm:^1.0.0" + checksum: 10c0/5af133a917c0bcf65e84e7f23e779e7abc1cd49cb7fdc62d00d1de74b0d8c1b5ee74ac7766099fb3be1b05b26dfc67bab76a17030d2fe7ea2eef867434362dfc + languageName: node + linkType: hard + +"is-arrayish@npm:^0.2.1": + version: 0.2.1 + resolution: "is-arrayish@npm:0.2.1" + checksum: 10c0/e7fb686a739068bb70f860b39b67afc62acc62e36bb61c5f965768abce1873b379c563e61dd2adad96ebb7edf6651111b385e490cf508378959b0ed4cac4e729 + languageName: node + linkType: hard + +"is-bigint@npm:^1.0.1": + version: 1.0.4 + resolution: "is-bigint@npm:1.0.4" + dependencies: + has-bigints: "npm:^1.0.1" + checksum: 10c0/eb9c88e418a0d195ca545aff2b715c9903d9b0a5033bc5922fec600eb0c3d7b1ee7f882dbf2e0d5a6e694e42391be3683e4368737bd3c4a77f8ac293e7773696 + languageName: node + linkType: hard + +"is-boolean-object@npm:^1.1.0": + version: 1.1.2 + resolution: "is-boolean-object@npm:1.1.2" + dependencies: + call-bind: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/6090587f8a8a8534c0f816da868bc94f32810f08807aa72fa7e79f7e11c466d281486ffe7a788178809c2aa71fe3e700b167fe80dd96dad68026bfff8ebf39f7 + languageName: node + linkType: hard + +"is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": + version: 1.2.7 + resolution: "is-callable@npm:1.2.7" + checksum: 10c0/ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f + languageName: node + linkType: hard + +"is-core-module@npm:^2.8.1, is-core-module@npm:^2.9.0": + version: 2.11.0 + resolution: "is-core-module@npm:2.11.0" + dependencies: + has: "npm:^1.0.3" + checksum: 10c0/fd8f78ef4e243c295deafa809f89381d89aff5aaf38bb63266b17ee6e34b6a051baa5bdc2365456863336d56af6a59a4c1df1256b4eff7d6b4afac618586b004 + languageName: node + linkType: hard + +"is-date-object@npm:^1.0.1": + version: 1.0.5 + resolution: "is-date-object@npm:1.0.5" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/eed21e5dcc619c48ccef804dfc83a739dbb2abee6ca202838ee1bd5f760fe8d8a93444f0d49012ad19bb7c006186e2884a1b92f6e1c056da7fd23d0a9ad5992e + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 + languageName: node + linkType: hard + +"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a + languageName: node + linkType: hard + +"is-negative-zero@npm:^2.0.2": + version: 2.0.2 + resolution: "is-negative-zero@npm:2.0.2" + checksum: 10c0/eda024c158f70f2017f3415e471b818d314da5ef5be68f801b16314d4a4b6304a74cbed778acf9e2f955bb9c1c5f2935c1be0c7c99e1ad12286f45366217b6a3 + languageName: node + linkType: hard + +"is-number-object@npm:^1.0.4": + version: 1.0.7 + resolution: "is-number-object@npm:1.0.7" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/aad266da1e530f1804a2b7bd2e874b4869f71c98590b3964f9d06cc9869b18f8d1f4778f838ecd2a11011bce20aeecb53cb269ba916209b79c24580416b74b1b + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811 + languageName: node + linkType: hard + +"is-path-inside@npm:^3.0.3": + version: 3.0.3 + resolution: "is-path-inside@npm:3.0.3" + checksum: 10c0/cf7d4ac35fb96bab6a1d2c3598fe5ebb29aafb52c0aaa482b5a3ed9d8ba3edc11631e3ec2637660c44b3ce0e61a08d54946e8af30dec0b60a7c27296c68ffd05 + languageName: node + linkType: hard + +"is-regex@npm:^1.1.4": + version: 1.1.4 + resolution: "is-regex@npm:1.1.4" + dependencies: + call-bind: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/bb72aae604a69eafd4a82a93002058c416ace8cde95873589a97fc5dac96a6c6c78a9977d487b7b95426a8f5073969124dd228f043f9f604f041f32fcc465fc1 + languageName: node + linkType: hard + +"is-shared-array-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "is-shared-array-buffer@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.2" + checksum: 10c0/cfeee6f171f1b13e6cbc6f3b6cc44e192b93df39f3fcb31aa66ffb1d2df3b91e05664311659f9701baba62f5e98c83b0673c628e7adc30f55071c4874fcdccec + languageName: node + linkType: hard + +"is-string@npm:^1.0.5, is-string@npm:^1.0.7": + version: 1.0.7 + resolution: "is-string@npm:1.0.7" + dependencies: + has-tostringtag: "npm:^1.0.0" + checksum: 10c0/905f805cbc6eedfa678aaa103ab7f626aac9ebbdc8737abb5243acaa61d9820f8edc5819106b8fcd1839e33db21de9f0116ae20de380c8382d16dc2a601921f6 + languageName: node + linkType: hard + +"is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": + version: 1.0.4 + resolution: "is-symbol@npm:1.0.4" + dependencies: + has-symbols: "npm:^1.0.2" + checksum: 10c0/9381dd015f7c8906154dbcbf93fad769de16b4b961edc94f88d26eb8c555935caa23af88bda0c93a18e65560f6d7cca0fd5a3f8a8e1df6f1abbb9bead4502ef7 + languageName: node + linkType: hard + +"is-weakref@npm:^1.0.2": + version: 1.0.2 + resolution: "is-weakref@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.2" + checksum: 10c0/1545c5d172cb690c392f2136c23eec07d8d78a7f57d0e41f10078aa4f5daf5d7f57b6513a67514ab4f073275ad00c9822fc8935e00229d0a2089e1c02685d4b1 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d + languageName: node + linkType: hard + +"js-cookie@npm:^2.2.1": + version: 2.2.1 + resolution: "js-cookie@npm:2.2.1" + checksum: 10c0/ee67fc0f8495d0800b851910b5eb5bf49d3033adff6493d55b5c097ca6da46f7fe666b10e2ecb13cfcaf5b88d71c205ce00a7e646de791689bfd053bbb36a376 + languageName: node + linkType: hard + +"js-sdsl@npm:^4.1.4": + version: 4.1.5 + resolution: "js-sdsl@npm:4.1.5" + checksum: 10c0/d95116180b977da36ad23a4f242a8eb96da42910a3662143e07fa12a5276663564ea9102d8570b2e6b0918fe284f2924a173082b6f84d25df29fbec3f71aa42f + languageName: node + linkType: hard + +"js-sha3@npm:0.8.0": + version: 0.8.0 + resolution: "js-sha3@npm:0.8.0" + checksum: 10c0/43a21dc7967c871bd2c46cb1c2ae97441a97169f324e509f382d43330d8f75cf2c96dba7c806ab08a425765a9c847efdd4bffbac2d99c3a4f3de6c0218f40533 + languageName: node + linkType: hard + +"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed + languageName: node + linkType: hard + +"js-yaml@npm:^4.1.0": + version: 4.1.0 + resolution: "js-yaml@npm:4.1.0" + dependencies: + argparse: "npm:^2.0.1" + bin: + js-yaml: bin/js-yaml.js + checksum: 10c0/184a24b4eaacfce40ad9074c64fd42ac83cf74d8c8cd137718d456ced75051229e5061b8633c3366b8aada17945a7a356b337828c19da92b51ae62126575018f + languageName: node + linkType: hard + +"jsesc@npm:^2.5.1": + version: 2.5.2 + resolution: "jsesc@npm:2.5.2" + bin: + jsesc: bin/jsesc + checksum: 10c0/dbf59312e0ebf2b4405ef413ec2b25abb5f8f4d9bc5fb8d9f90381622ebca5f2af6a6aa9a8578f65903f9e33990a6dc798edd0ce5586894bf0e9e31803a1de88 + languageName: node + linkType: hard + +"json-parse-even-better-errors@npm:^2.3.0": + version: 2.3.1 + resolution: "json-parse-even-better-errors@npm:2.3.1" + checksum: 10c0/140932564c8f0b88455432e0f33c4cb4086b8868e37524e07e723f4eaedb9425bdc2bafd71bd1d9765bd15fd1e2d126972bc83990f55c467168c228c24d665f3 + languageName: node + linkType: hard + +"json-schema-traverse@npm:^0.4.1": + version: 0.4.1 + resolution: "json-schema-traverse@npm:0.4.1" + checksum: 10c0/108fa90d4cc6f08243aedc6da16c408daf81793bf903e9fd5ab21983cda433d5d2da49e40711da016289465ec2e62e0324dcdfbc06275a607fe3233fde4942ce + languageName: node + linkType: hard + +"json-stable-stringify-without-jsonify@npm:^1.0.1": + version: 1.0.1 + resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" + checksum: 10c0/cb168b61fd4de83e58d09aaa6425ef71001bae30d260e2c57e7d09a5fd82223e2f22a042dedaab8db23b7d9ae46854b08bb1f91675a8be11c5cffebef5fb66a5 + languageName: node + linkType: hard + +"json5@npm:^1.0.1": + version: 1.0.1 + resolution: "json5@npm:1.0.1" + dependencies: + minimist: "npm:^1.2.0" + bin: + json5: lib/cli.js + checksum: 10c0/7f75dd797151680a4e14c4224c1343b32a43272aa6e6333ddec2b0822df4ea116971689b251879a1248592da24f7929902c13f83d7390c3f3d44f18e8e9719f5 + languageName: node + linkType: hard + +"jsonfile@npm:^6.0.1": + version: 6.1.0 + resolution: "jsonfile@npm:6.1.0" + dependencies: + graceful-fs: "npm:^4.1.6" + universalify: "npm:^2.0.0" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10c0/4f95b5e8a5622b1e9e8f33c96b7ef3158122f595998114d1e7f03985649ea99cb3cd99ce1ed1831ae94c8c8543ab45ebd044207612f31a56fd08462140e46865 + languageName: node + linkType: hard + +"jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.2": + version: 3.3.3 + resolution: "jsx-ast-utils@npm:3.3.3" + dependencies: + array-includes: "npm:^3.1.5" + object.assign: "npm:^4.1.3" + checksum: 10c0/fb69ce100931e50d42c8f72a01495b7d090064824ce481cf7746449609c148a29aae6984624cf9066ac14bdf7978f8774461e120d5b50fa90b3bfe0a0e21ff77 + languageName: node + linkType: hard + +"jwt-decode@npm:^4.0.0": + version: 4.0.0 + resolution: "jwt-decode@npm:4.0.0" + checksum: 10c0/de75bbf89220746c388cf6a7b71e56080437b77d2edb29bae1c2155048b02c6b8c59a3e5e8d6ccdfd54f0b8bda25226e491a4f1b55ac5f8da04cfbadec4e546c + languageName: node + linkType: hard + +"language-subtag-registry@npm:~0.3.2": + version: 0.3.22 + resolution: "language-subtag-registry@npm:0.3.22" + checksum: 10c0/d1e09971260a7cd3b9fdeb190d33af0b6e99c8697013537d9aaa15f7856d9d83aee128ba8078e219df0a7cf4b8dd18d1a0c188f6543b500d92a2689d2d114b70 + languageName: node + linkType: hard + +"language-tags@npm:^1.0.5": + version: 1.0.5 + resolution: "language-tags@npm:1.0.5" + dependencies: + language-subtag-registry: "npm:~0.3.2" + checksum: 10c0/04215e821af9a8f1bc6c99ab5aa0a316c3fe1912ca3337eb28596316064bddd8edd22f2883d866069ebdf01b2002e504a760a336b2c728b6d30514e86744f76c + languageName: node + linkType: hard + +"levn@npm:^0.4.1": + version: 0.4.1 + resolution: "levn@npm:0.4.1" + dependencies: + prelude-ls: "npm:^1.2.1" + type-check: "npm:~0.4.0" + checksum: 10c0/effb03cad7c89dfa5bd4f6989364bfc79994c2042ec5966cb9b95990e2edee5cd8969ddf42616a0373ac49fac1403437deaf6e9050fbbaa3546093a59b9ac94e + languageName: node + linkType: hard + +"lines-and-columns@npm:^1.1.6": + version: 1.2.4 + resolution: "lines-and-columns@npm:1.2.4" + checksum: 10c0/3da6ee62d4cd9f03f5dc90b4df2540fb85b352081bee77fe4bbcd12c9000ead7f35e0a38b8d09a9bb99b13223446dd8689ff3c4959807620726d788701a83d2d + languageName: node + linkType: hard + +"locate-path@npm:^5.0.0": + version: 5.0.0 + resolution: "locate-path@npm:5.0.0" + dependencies: + p-locate: "npm:^4.1.0" + checksum: 10c0/33a1c5247e87e022f9713e6213a744557a3e9ec32c5d0b5efb10aa3a38177615bf90221a5592674857039c1a0fd2063b82f285702d37b792d973e9e72ace6c59 + languageName: node + linkType: hard + +"locate-path@npm:^6.0.0": + version: 6.0.0 + resolution: "locate-path@npm:6.0.0" + dependencies: + p-locate: "npm:^5.0.0" + checksum: 10c0/d3972ab70dfe58ce620e64265f90162d247e87159b6126b01314dd67be43d50e96a50b517bce2d9452a79409c7614054c277b5232377de50416564a77ac7aad3 + languageName: node + linkType: hard + +"lodash.merge@npm:^4.6.2": + version: 4.6.2 + resolution: "lodash.merge@npm:4.6.2" + checksum: 10c0/402fa16a1edd7538de5b5903a90228aa48eb5533986ba7fa26606a49db2572bf414ff73a2c9f5d5fd36b31c46a5d5c7e1527749c07cbcf965ccff5fbdf32c506 + languageName: node + linkType: hard + +"lodash@npm:^4.17.11, lodash@npm:^4.17.21": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c + languageName: node + linkType: hard + +"loose-envify@npm:^1.0.0, loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0": + version: 1.4.0 + resolution: "loose-envify@npm:1.4.0" + dependencies: + js-tokens: "npm:^3.0.0 || ^4.0.0" + bin: + loose-envify: cli.js + checksum: 10c0/655d110220983c1a4b9c0c679a2e8016d4b67f6e9c7b5435ff5979ecdb20d0813f4dec0a08674fcbdd4846a3f07edbb50a36811fd37930b94aaa0d9daceb017e + languageName: node + linkType: hard + +"lru-cache@npm:^6.0.0": + version: 6.0.0 + resolution: "lru-cache@npm:6.0.0" + dependencies: + yallist: "npm:^4.0.0" + checksum: 10c0/cb53e582785c48187d7a188d3379c181b5ca2a9c78d2bce3e7dee36f32761d1c42983da3fe12b55cb74e1779fa94cdc2e5367c028a9b35317184ede0c07a30a9 + languageName: node + linkType: hard + +"make-dir@npm:^3.0.2": + version: 3.1.0 + resolution: "make-dir@npm:3.1.0" + dependencies: + semver: "npm:^6.0.0" + checksum: 10c0/56aaafefc49c2dfef02c5c95f9b196c4eb6988040cf2c712185c7fe5c99b4091591a7fc4d4eafaaefa70ff763a26f6ab8c3ff60b9e75ea19876f49b18667ecaa + languageName: node + linkType: hard + +"match-sorter@npm:^6.0.2": + version: 6.3.4 + resolution: "match-sorter@npm:6.3.4" + dependencies: + "@babel/runtime": "npm:^7.23.8" + remove-accents: "npm:0.5.0" + checksum: 10c0/35d2a6b6df003c677d9ec87ecd4683657638f5bce856f43f9cf90b03e357ed2f09813ebbac759defa7e7438706936dd34dc2bfe1a18771f7d2541f14d639b4ad + languageName: node + linkType: hard + +"mdn-data@npm:2.0.14": + version: 2.0.14 + resolution: "mdn-data@npm:2.0.14" + checksum: 10c0/67241f8708c1e665a061d2b042d2d243366e93e5bf1f917693007f6d55111588b952dcbfd3ea9c2d0969fb754aad81b30fdcfdcc24546495fc3b24336b28d4bd + languageName: node + linkType: hard + +"memoize-one@npm:>=3.1.1 <6": + version: 5.2.1 + resolution: "memoize-one@npm:5.2.1" + checksum: 10c0/fd22dbe9a978a2b4f30d6a491fc02fb90792432ad0dab840dc96c1734d2bd7c9cdeb6a26130ec60507eb43230559523615873168bcbe8fafab221c30b11d54c1 + languageName: node + linkType: hard + +"merge2@npm:^1.3.0, merge2@npm:^1.4.1": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb + languageName: node + linkType: hard + +"micromatch@npm:^4.0.4": + version: 4.0.5 + resolution: "micromatch@npm:4.0.5" + dependencies: + braces: "npm:^3.0.2" + picomatch: "npm:^2.3.1" + checksum: 10c0/3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff + languageName: node + linkType: hard + +"microseconds@npm:0.2.0": + version: 0.2.0 + resolution: "microseconds@npm:0.2.0" + checksum: 10c0/59dfae1c696c0bacd79603c4df7cd0dcc9e091b7c5556aaca9b0832017d3c0b40ad8f57ca25e0ee5709ef1973404448c4a2fea6c9c1fad7d9e197ff5c1c9c2d5 + languageName: node + linkType: hard + +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2 + languageName: node + linkType: hard + +"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311 + languageName: node + linkType: hard + +"minimist@npm:^1.2.0, minimist@npm:^1.2.6": + version: 1.2.7 + resolution: "minimist@npm:1.2.7" + checksum: 10c0/8808da67ca50ee19ab2d69051d77ee78572e67297fd8a1635ecc757a15106ccdfb5b8c4d11d84750120142f1684e5329a141295728c755e5d149eedd73cc6572 + languageName: node + linkType: hard + +"moment@npm:^2.29.4": + version: 2.29.4 + resolution: "moment@npm:2.29.4" + checksum: 10c0/844c6f3ce42862ac9467c8ca4f5e48a00750078682cc5bda1bc0e50cc7ca88e2115a0f932d65a06e4a90e26cb78892be9b3ca3dd6546ca2c4d994cebb787fc2b + languageName: node + linkType: hard + +"ms@npm:2.0.0": + version: 2.0.0 + resolution: "ms@npm:2.0.0" + checksum: 10c0/f8fda810b39fd7255bbdc451c46286e549794fcc700dc9cd1d25658bbc4dc2563a5de6fe7c60f798a16a60c6ceb53f033cb353f493f0cf63e5199b702943159d + languageName: node + linkType: hard + +"ms@npm:2.1.2, ms@npm:^2.1.1": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 10c0/a437714e2f90dbf881b5191d35a6db792efbca5badf112f87b9e1c712aace4b4b9b742dd6537f3edf90fd6f684de897cec230abde57e87883766712ddda297cc + languageName: node + linkType: hard + +"nano-css@npm:^5.3.1": + version: 5.3.5 + resolution: "nano-css@npm:5.3.5" + dependencies: + css-tree: "npm:^1.1.2" + csstype: "npm:^3.0.6" + fastest-stable-stringify: "npm:^2.0.2" + inline-style-prefixer: "npm:^6.0.0" + rtl-css-js: "npm:^1.14.0" + sourcemap-codec: "npm:^1.4.8" + stacktrace-js: "npm:^2.0.2" + stylis: "npm:^4.0.6" + peerDependencies: + react: "*" + react-dom: "*" + checksum: 10c0/6f9f3b0cd68758514ac2a61ad7d846c2ba57da49a076cbaf2a4871f4c5f0f1f1bbd87ea557de4440a8ee67f1dc6314e3f0ed26805984f2f2eb819856f87a8c7c + languageName: node + linkType: hard + +"nano-time@npm:1.0.0": + version: 1.0.0 + resolution: "nano-time@npm:1.0.0" + dependencies: + big-integer: "npm:^1.6.16" + checksum: 10c0/3bd12e0bcd30867178afdbe8053b3dde5fdd1c665ecd348bf879863049344fbaf05cbb1d7806a825b91efbca011ee115eee52e76fb38b7da9c97931cd9e61f15 + languageName: node + linkType: hard + +"nanoid@npm:^3.3.4": + version: 3.3.4 + resolution: "nanoid@npm:3.3.4" + bin: + nanoid: bin/nanoid.cjs + checksum: 10c0/a0747d5c6021828fe8d38334e5afb05d3268d7d4b06024058ec894ccc47070e4e81d268a6b75488d2ff3485fa79a75c251d4b7c6f31051bb54bb662b6fd2a27d + languageName: node + linkType: hard + +"natural-compare@npm:^1.4.0": + version: 1.4.0 + resolution: "natural-compare@npm:1.4.0" + checksum: 10c0/f5f9a7974bfb28a91afafa254b197f0f22c684d4a1731763dda960d2c8e375b36c7d690e0d9dc8fba774c537af14a7e979129bca23d88d052fbeb9466955e447 + languageName: node + linkType: hard + +"next@npm:13.0.0": + version: 13.0.0 + resolution: "next@npm:13.0.0" + dependencies: + "@next/env": "npm:13.0.0" + "@next/swc-android-arm-eabi": "npm:13.0.0" + "@next/swc-android-arm64": "npm:13.0.0" + "@next/swc-darwin-arm64": "npm:13.0.0" + "@next/swc-darwin-x64": "npm:13.0.0" + "@next/swc-freebsd-x64": "npm:13.0.0" + "@next/swc-linux-arm-gnueabihf": "npm:13.0.0" + "@next/swc-linux-arm64-gnu": "npm:13.0.0" + "@next/swc-linux-arm64-musl": "npm:13.0.0" + "@next/swc-linux-x64-gnu": "npm:13.0.0" + "@next/swc-linux-x64-musl": "npm:13.0.0" + "@next/swc-win32-arm64-msvc": "npm:13.0.0" + "@next/swc-win32-ia32-msvc": "npm:13.0.0" + "@next/swc-win32-x64-msvc": "npm:13.0.0" + "@swc/helpers": "npm:0.4.11" + caniuse-lite: "npm:^1.0.30001406" + postcss: "npm:8.4.14" + styled-jsx: "npm:5.1.0" + use-sync-external-store: "npm:1.2.0" + peerDependencies: + fibers: ">= 3.1.0" + node-sass: ^6.0.0 || ^7.0.0 + react: ^18.0.0-0 + react-dom: ^18.0.0-0 + sass: ^1.3.0 + dependenciesMeta: + "@next/swc-android-arm-eabi": + optional: true + "@next/swc-android-arm64": + optional: true + "@next/swc-darwin-arm64": + optional: true + "@next/swc-darwin-x64": + optional: true + "@next/swc-freebsd-x64": + optional: true + "@next/swc-linux-arm-gnueabihf": + optional: true + "@next/swc-linux-arm64-gnu": + optional: true + "@next/swc-linux-arm64-musl": + optional: true + "@next/swc-linux-x64-gnu": + optional: true + "@next/swc-linux-x64-musl": + optional: true + "@next/swc-win32-arm64-msvc": + optional: true + "@next/swc-win32-ia32-msvc": + optional: true + "@next/swc-win32-x64-msvc": + optional: true + peerDependenciesMeta: + fibers: + optional: true + node-sass: + optional: true + sass: + optional: true + bin: + next: dist/bin/next + checksum: 10c0/7055b2c719c216a84fc10616cbc936950d21e68a0bb1b7313105fd344eda8b9c2587ca784dbcaa0304ffc343bf891fb916068f20d6e54f85817ee09a2dccf502 + languageName: node + linkType: hard + +"numeral@npm:^2.0.6": + version: 2.0.6 + resolution: "numeral@npm:2.0.6" + checksum: 10c0/5ed008d3fae05cfa4986b77a85ca10bff29ae6e1fa41a04cce05ea21f08a8a104226f88868930e2a94e3239708d6985d111b5d1291e8b9a3049ffc5365c332d4 + languageName: node + linkType: hard + +"object-assign@npm:^4.0.1, object-assign@npm:^4.1.1": + version: 4.1.1 + resolution: "object-assign@npm:4.1.1" + checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 + languageName: node + linkType: hard + +"object-inspect@npm:^1.12.2, object-inspect@npm:^1.9.0": + version: 1.12.2 + resolution: "object-inspect@npm:1.12.2" + checksum: 10c0/e1bd625f4c44a2f733bd69cfccce6469f71333fb09c6de151f4f346c16d658ef7555727b12652c108e20c2afb908ae7cd165f52ca53745a1d6cbf228cdb46ebe + languageName: node + linkType: hard + +"object-keys@npm:^1.1.1": + version: 1.1.1 + resolution: "object-keys@npm:1.1.1" + checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d + languageName: node + linkType: hard + +"object.assign@npm:^4.1.3, object.assign@npm:^4.1.4": + version: 4.1.4 + resolution: "object.assign@npm:4.1.4" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.4" + has-symbols: "npm:^1.0.3" + object-keys: "npm:^1.1.1" + checksum: 10c0/2f286118c023e557757620e647b02e7c88d3d417e0c568fca0820de8ec9cca68928304854d5b03e99763eddad6e78a6716e2930f7e6372e4b9b843f3fd3056f3 + languageName: node + linkType: hard + +"object.entries@npm:^1.1.5": + version: 1.1.5 + resolution: "object.entries@npm:1.1.5" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.3" + es-abstract: "npm:^1.19.1" + checksum: 10c0/308c07970818b0fb2b0ed92120b8fad76fb69a63c853592eac48c8437bb2385bc43f00b80d263aa2920b352c66c944018df7221099fc8e2d3bfb778566ca4ebb + languageName: node + linkType: hard + +"object.fromentries@npm:^2.0.5": + version: 2.0.5 + resolution: "object.fromentries@npm:2.0.5" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.3" + es-abstract: "npm:^1.19.1" + checksum: 10c0/a1bedcdec0e1f15fc1f9dccecf7df18ae4678fc95deb42099b649a3660511f2d1dead3b09b8f7dcf15205b0f7ce69d74e3cc3368511abf85b021d86226aa77d4 + languageName: node + linkType: hard + +"object.hasown@npm:^1.1.1": + version: 1.1.1 + resolution: "object.hasown@npm:1.1.1" + dependencies: + define-properties: "npm:^1.1.4" + es-abstract: "npm:^1.19.5" + checksum: 10c0/79f40bf3da7c689122dc38c56114fa0280cde3e6a255f95736933240d495a2556f7ca7413c08d691bfc22e743b0d3ea82620890f21155b94c18551f3909cba8d + languageName: node + linkType: hard + +"object.values@npm:^1.1.5": + version: 1.1.5 + resolution: "object.values@npm:1.1.5" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.3" + es-abstract: "npm:^1.19.1" + checksum: 10c0/9c6afa9a25ce36c27c8baef2321eaa719fc2b042ef17aa462b1fa1502ed7ce7acf18b269be2e7b0d91f228839f10a28fa30ebc8cb7e47dbf6a2e4e67cad466c1 + languageName: node + linkType: hard + +"oblivious-set@npm:1.0.0": + version: 1.0.0 + resolution: "oblivious-set@npm:1.0.0" + checksum: 10c0/ca8640474ea1e1feb3b5c98d42f5649f114ac4513ef84774e724f22fc7e529f1de3e7f26a0d9593097ab8942ca0bb8c241f7c1bd63c3e33047dd49de3aca9805 + languageName: node + linkType: hard + +"once@npm:^1.3.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 + languageName: node + linkType: hard + +"optionator@npm:^0.9.1": + version: 0.9.1 + resolution: "optionator@npm:0.9.1" + dependencies: + deep-is: "npm:^0.1.3" + fast-levenshtein: "npm:^2.0.6" + levn: "npm:^0.4.1" + prelude-ls: "npm:^1.2.1" + type-check: "npm:^0.4.0" + word-wrap: "npm:^1.2.3" + checksum: 10c0/8b574d50b032f34713dc09bfacdc351824f713c3c80773ead3a05ab977364de88f2f3962a6f15437747b93a5e0636928253949970daea3aaeeefbd3a525da6a4 + languageName: node + linkType: hard + +"p-limit@npm:^2.2.0": + version: 2.3.0 + resolution: "p-limit@npm:2.3.0" + dependencies: + p-try: "npm:^2.0.0" + checksum: 10c0/8da01ac53efe6a627080fafc127c873da40c18d87b3f5d5492d465bb85ec7207e153948df6b9cbaeb130be70152f874229b8242ee2be84c0794082510af97f12 + languageName: node + linkType: hard + +"p-limit@npm:^3.0.2": + version: 3.1.0 + resolution: "p-limit@npm:3.1.0" + dependencies: + yocto-queue: "npm:^0.1.0" + checksum: 10c0/9db675949dbdc9c3763c89e748d0ef8bdad0afbb24d49ceaf4c46c02c77d30db4e0652ed36d0a0a7a95154335fab810d95c86153105bb73b3a90448e2bb14e1a + languageName: node + linkType: hard + +"p-locate@npm:^4.1.0": + version: 4.1.0 + resolution: "p-locate@npm:4.1.0" + dependencies: + p-limit: "npm:^2.2.0" + checksum: 10c0/1b476ad69ad7f6059744f343b26d51ce091508935c1dbb80c4e0a2f397ffce0ca3a1f9f5cd3c7ce19d7929a09719d5c65fe70d8ee289c3f267cd36f2881813e9 + languageName: node + linkType: hard + +"p-locate@npm:^5.0.0": + version: 5.0.0 + resolution: "p-locate@npm:5.0.0" + dependencies: + p-limit: "npm:^3.0.2" + checksum: 10c0/2290d627ab7903b8b70d11d384fee714b797f6040d9278932754a6860845c4d3190603a0772a663c8cb5a7b21d1b16acb3a6487ebcafa9773094edc3dfe6009a + languageName: node + linkType: hard + +"p-try@npm:^2.0.0": + version: 2.2.0 + resolution: "p-try@npm:2.2.0" + checksum: 10c0/c36c19907734c904b16994e6535b02c36c2224d433e01a2f1ab777237f4d86e6289fd5fd464850491e940379d4606ed850c03e0f9ab600b0ebddb511312e177f + languageName: node + linkType: hard + +"parent-module@npm:^1.0.0": + version: 1.0.1 + resolution: "parent-module@npm:1.0.1" + dependencies: + callsites: "npm:^3.0.0" + checksum: 10c0/c63d6e80000d4babd11978e0d3fee386ca7752a02b035fd2435960ffaa7219dc42146f07069fb65e6e8bf1caef89daf9af7535a39bddf354d78bf50d8294f556 + languageName: node + linkType: hard + +"parse-json@npm:^5.0.0": + version: 5.2.0 + resolution: "parse-json@npm:5.2.0" + dependencies: + "@babel/code-frame": "npm:^7.0.0" + error-ex: "npm:^1.3.1" + json-parse-even-better-errors: "npm:^2.3.0" + lines-and-columns: "npm:^1.1.6" + checksum: 10c0/77947f2253005be7a12d858aedbafa09c9ae39eb4863adf330f7b416ca4f4a08132e453e08de2db46459256fb66afaac5ee758b44fe6541b7cdaf9d252e59585 + languageName: node + linkType: hard + +"path-exists@npm:^4.0.0": + version: 4.0.0 + resolution: "path-exists@npm:4.0.0" + checksum: 10c0/8c0bd3f5238188197dc78dced15207a4716c51cc4e3624c44fc97acf69558f5ebb9a2afff486fe1b4ee148e0c133e96c5e11a9aa5c48a3006e3467da070e5e1b + languageName: node + linkType: hard + +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078 + languageName: node + linkType: hard + +"path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c + languageName: node + linkType: hard + +"path-parse@npm:^1.0.7": + version: 1.0.7 + resolution: "path-parse@npm:1.0.7" + checksum: 10c0/11ce261f9d294cc7a58d6a574b7f1b935842355ec66fba3c3fd79e0f036462eaf07d0aa95bb74ff432f9afef97ce1926c720988c6a7451d8a584930ae7de86e1 + languageName: node + linkType: hard + +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c + languageName: node + linkType: hard + +"picocolors@npm:^1.0.0": + version: 1.0.0 + resolution: "picocolors@npm:1.0.0" + checksum: 10c0/20a5b249e331c14479d94ec6817a182fd7a5680debae82705747b2db7ec50009a5f6648d0621c561b0572703f84dbef0858abcbd5856d3c5511426afcb1961f7 + languageName: node + linkType: hard + +"picomatch@npm:^2.3.0, picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be + languageName: node + linkType: hard + +"pify@npm:^2.0.0": + version: 2.3.0 + resolution: "pify@npm:2.3.0" + checksum: 10c0/551ff8ab830b1052633f59cb8adc9ae8407a436e06b4a9718bcb27dc5844b83d535c3a8512b388b6062af65a98c49bdc0dd523d8b2617b188f7c8fee457158dc + languageName: node + linkType: hard + +"pinkie-promise@npm:^2.0.0": + version: 2.0.1 + resolution: "pinkie-promise@npm:2.0.1" + dependencies: + pinkie: "npm:^2.0.0" + checksum: 10c0/11b5e5ce2b090c573f8fad7b517cbca1bb9a247587306f05ae71aef6f9b2cd2b923c304aa9663c2409cfde27b367286179f1379bc4ec18a3fbf2bb0d473b160a + languageName: node + linkType: hard + +"pinkie@npm:^2.0.0": + version: 2.0.4 + resolution: "pinkie@npm:2.0.4" + checksum: 10c0/25228b08b5597da42dc384221aa0ce56ee0fbf32965db12ba838e2a9ca0193c2f0609c45551ee077ccd2060bf109137fdb185b00c6d7e0ed7e35006d20fdcbc6 + languageName: node + linkType: hard + +"pkg-dir@npm:^4.1.0": + version: 4.2.0 + resolution: "pkg-dir@npm:4.2.0" + dependencies: + find-up: "npm:^4.0.0" + checksum: 10c0/c56bda7769e04907a88423feb320babaed0711af8c436ce3e56763ab1021ba107c7b0cafb11cde7529f669cfc22bffcaebffb573645cbd63842ea9fb17cd7728 + languageName: node + linkType: hard + +"postcss-value-parser@npm:^4.0.2": + version: 4.2.0 + resolution: "postcss-value-parser@npm:4.2.0" + checksum: 10c0/f4142a4f56565f77c1831168e04e3effd9ffcc5aebaf0f538eee4b2d465adfd4b85a44257bb48418202a63806a7da7fe9f56c330aebb3cac898e46b4cbf49161 + languageName: node + linkType: hard + +"postcss@npm:8.4.14": + version: 8.4.14 + resolution: "postcss@npm:8.4.14" + dependencies: + nanoid: "npm:^3.3.4" + picocolors: "npm:^1.0.0" + source-map-js: "npm:^1.0.2" + checksum: 10c0/2a4cfa28e2f1bfd358313501f7771bd596e494487c7b735c492e2f8b1faf493d24fcb43e2e6ad825863fc65a77abb949ca8f228602ae46a022f02dc812c4ac8b + languageName: node + linkType: hard + +"prelude-ls@npm:^1.2.1": + version: 1.2.1 + resolution: "prelude-ls@npm:1.2.1" + checksum: 10c0/b00d617431e7886c520a6f498a2e14c75ec58f6d93ba48c3b639cf241b54232d90daa05d83a9e9b9fef6baa63cb7e1e4602c2372fea5bc169668401eb127d0cd + languageName: node + linkType: hard + +"prop-types@npm:^15.5.7, prop-types@npm:^15.6.2, prop-types@npm:^15.8.1": + version: 15.8.1 + resolution: "prop-types@npm:15.8.1" + dependencies: + loose-envify: "npm:^1.4.0" + object-assign: "npm:^4.1.1" + react-is: "npm:^16.13.1" + checksum: 10c0/59ece7ca2fb9838031d73a48d4becb9a7cc1ed10e610517c7d8f19a1e02fa47f7c27d557d8a5702bec3cfeccddc853579832b43f449e54635803f277b1c78077 + languageName: node + linkType: hard + +"proxy-from-env@npm:^1.1.0": + version: 1.1.0 + resolution: "proxy-from-env@npm:1.1.0" + checksum: 10c0/fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b + languageName: node + linkType: hard + +"punycode@npm:^2.1.0": + version: 2.1.1 + resolution: "punycode@npm:2.1.1" + checksum: 10c0/83815ca9b9177f055771f31980cbec7ffaef10257d50a95ab99b4a30f0404846e85fa6887ee1bbc0aaddb7bad6d96e2fa150a016051ff0f6b92be4ad613ddca8 + languageName: node + linkType: hard + +"push-analytics@workspace:.": + version: 0.0.0-use.local + resolution: "push-analytics@workspace:." + dependencies: + "@emotion/react": "npm:^11.10.5" + "@emotion/styled": "npm:^11.10.5" + "@mui/icons-material": "npm:^5.10.9" + "@mui/material": "npm:^5.10.12" + "@radix-ui/react-dialog": "npm:^1.1.1" + "@radix-ui/react-dropdown-menu": "npm:^2.1.1" + "@radix-ui/react-switch": "npm:^1.1.0" + "@radix-ui/react-tooltip": "npm:^1.1.1" + "@reach/combobox": "npm:^0.18.0" + "@reach/tabs": "npm:^0.18.0" + "@table-library/react-table-library": "npm:^4.1.7" + "@types/lodash": "npm:^4.14.188" + "@types/node": "npm:18.11.7" + "@types/react": "npm:18.0.24" + "@types/react-dom": "npm:18.0.8" + "@types/styled-components": "npm:^5.1.26" + apexcharts: "npm:^3.36.3" + axios: "npm:^1.1.3" + babel-plugin-styled-components: "npm:^2.0.7" + blockies: "npm:0.0.2" + blockies-react-svg: "npm:^0.0.13" + date-fns: "npm:^2.29.3" + echarts: "npm:^5.4.2" + echarts-for-react: "npm:^3.0.2" + eslint: "npm:8.26.0" + eslint-config-next: "npm:13.0.0" + ethers: "npm:^6.13.2" + gh-pages: "npm:^6.1.1" + jwt-decode: "npm:^4.0.0" + lodash: "npm:^4.17.21" + moment: "npm:^2.29.4" + next: "npm:13.0.0" + numeral: "npm:^2.0.6" + rc-pagination: "npm:^4.2.0" + react: "npm:18.2.0" + react-apexcharts: "npm:^1.4.0" + react-dom: "npm:18.2.0" + react-loader-spinner: "npm:^5.3.4" + react-loading-skeleton: "npm:^3.3.1" + react-query: "npm:^3.39.3" + react-slider: "npm:^2.0.6" + react-toastify: "npm:^9.0.8" + react-toggle-dark-mode: "npm:^1.1.0" + react-use: "npm:^17.4.0" + sonner: "npm:^1.5.0" + styled-components: "npm:^5.3.6" + typescript: "npm:4.8.4" + languageName: unknown + linkType: soft + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102 + languageName: node + linkType: hard + +"rc-pagination@npm:^4.2.0": + version: 4.2.0 + resolution: "rc-pagination@npm:4.2.0" + dependencies: + "@babel/runtime": "npm:^7.10.1" + classnames: "npm:^2.3.2" + rc-util: "npm:^5.38.0" + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + checksum: 10c0/fa5ea867a81c850df4a583f10979865420856ac50d17fc1a92824c82844580b476e333f396928e02a160e672eaec77bcc66330962f07e53bdc8b55ffd303da8c + languageName: node + linkType: hard + +"rc-util@npm:^5.38.0": + version: 5.43.0 + resolution: "rc-util@npm:5.43.0" + dependencies: + "@babel/runtime": "npm:^7.18.3" + react-is: "npm:^18.2.0" + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + checksum: 10c0/39f7904c9851f2b0a2dace5ac578f42000498412d7da5ef2063fd547db91d158dcb376bcbacf49fb7790d2721727bd38ea3483294ef51eb6099a793b2e17e9db + languageName: node + linkType: hard + +"react-apexcharts@npm:^1.4.0": + version: 1.4.0 + resolution: "react-apexcharts@npm:1.4.0" + dependencies: + prop-types: "npm:^15.5.7" + peerDependencies: + apexcharts: ^3.18.0 + react: ">=0.13" + checksum: 10c0/42157e1ec24376d81646fc185b3ff3ea97c94bbd71c8da308129e75d303f75b7453fa81e074424564db5edfce5900b3dd288a6117babaa7c4af7c127a3c78ff6 + languageName: node + linkType: hard + +"react-dom@npm:18.2.0": + version: 18.2.0 + resolution: "react-dom@npm:18.2.0" + dependencies: + loose-envify: "npm:^1.1.0" + scheduler: "npm:^0.23.0" + peerDependencies: + react: ^18.2.0 + checksum: 10c0/66dfc5f93e13d0674e78ef41f92ed21dfb80f9c4ac4ac25a4b51046d41d4d2186abc915b897f69d3d0ebbffe6184e7c5876f2af26bfa956f179225d921be713a + languageName: node + linkType: hard + +"react-is@npm:^16.13.1, react-is@npm:^16.7.0": + version: 16.13.1 + resolution: "react-is@npm:16.13.1" + checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1 + languageName: node + linkType: hard + +"react-is@npm:^18.2.0": + version: 18.2.0 + resolution: "react-is@npm:18.2.0" + checksum: 10c0/6eb5e4b28028c23e2bfcf73371e72cd4162e4ac7ab445ddae2afe24e347a37d6dc22fae6e1748632cd43c6d4f9b8f86dcf26bf9275e1874f436d129952528ae0 + languageName: node + linkType: hard + +"react-loader-spinner@npm:^5.3.4": + version: 5.3.4 + resolution: "react-loader-spinner@npm:5.3.4" + dependencies: + react-is: "npm:^18.2.0" + styled-components: "npm:^5.3.5" + styled-tools: "npm:^1.7.2" + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/929b4004d1f0ee770af7276804366bdcceb3c14610783f78b4c5d2c3e8053c0a18da58e048b49584aec2145cbafb3460c43929f4a824316a54736b44ac9dbe95 + languageName: node + linkType: hard + +"react-loading-skeleton@npm:^3.3.1": + version: 3.3.1 + resolution: "react-loading-skeleton@npm:3.3.1" + peerDependencies: + react: ">=16.8.0" + checksum: 10c0/46ae989a74c59dd3f9ecfd480883f1b7a7b083e1329b618c948b889c218192db26148dfc0632e7b55fe0f8b22ddaf97001b539a5210f37045c3fc5b0adf68edc + languageName: node + linkType: hard + +"react-query@npm:^3.39.3": + version: 3.39.3 + resolution: "react-query@npm:3.39.3" + dependencies: + "@babel/runtime": "npm:^7.5.5" + broadcast-channel: "npm:^3.4.1" + match-sorter: "npm:^6.0.2" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + checksum: 10c0/319045ef31b9b02aa9b5446169a8c6f95cfe49406466b819cc85e41c29bfe5032d3732577efe56511278db41514772375d416a3e3976e8967c6e0972ff04dd2e + languageName: node + linkType: hard + +"react-remove-scroll-bar@npm:^2.3.4": + version: 2.3.6 + resolution: "react-remove-scroll-bar@npm:2.3.6" + dependencies: + react-style-singleton: "npm:^2.2.1" + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/4e32ee04bf655a8bd3b4aacf6ffc596ae9eb1b9ba27eef83f7002632ee75371f61516ae62250634a9eae4b2c8fc6f6982d9b182de260f6c11841841e6e2e7515 + languageName: node + linkType: hard + +"react-remove-scroll@npm:2.5.7": + version: 2.5.7 + resolution: "react-remove-scroll@npm:2.5.7" + dependencies: + react-remove-scroll-bar: "npm:^2.3.4" + react-style-singleton: "npm:^2.2.1" + tslib: "npm:^2.1.0" + use-callback-ref: "npm:^1.3.0" + use-sidecar: "npm:^1.1.2" + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/dcd523ada602bd0a839c2032cadf0b3e4af55ee85acefee3760976a9cceaa4606927801b093bbb8bf3c2989c71e048f5428c2c6eb9e6681762e86356833d039b + languageName: node + linkType: hard + +"react-slider@npm:^2.0.6": + version: 2.0.6 + resolution: "react-slider@npm:2.0.6" + dependencies: + prop-types: "npm:^15.8.1" + peerDependencies: + react: ^16 || ^17 || ^18 + checksum: 10c0/15396f103d5c840822395e6fe666850c71bb0a66647204c5646c21f58fa838fe28f652810bacdd386ffa8df26895812f926f174f6f6ae67f456dbd9c5a3e5bfa + languageName: node + linkType: hard + +"react-spring@npm:^9.0.0-rc.3": + version: 9.5.5 + resolution: "react-spring@npm:9.5.5" + dependencies: + "@react-spring/core": "npm:~9.5.5" + "@react-spring/konva": "npm:~9.5.5" + "@react-spring/native": "npm:~9.5.5" + "@react-spring/three": "npm:~9.5.5" + "@react-spring/web": "npm:~9.5.5" + "@react-spring/zdog": "npm:~9.5.5" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/d784fb5555f367b044af1340ba2971536001cbaff25cde298fcf01117230fc82bd838965cae1684980a2b78ea59aa30af543a0c8de003ec0417ea4037b32d6bf + languageName: node + linkType: hard + +"react-style-singleton@npm:^2.2.1": + version: 2.2.1 + resolution: "react-style-singleton@npm:2.2.1" + dependencies: + get-nonce: "npm:^1.0.0" + invariant: "npm:^2.2.4" + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/6d66f3bdb65e1ec79089f80314da97c9a005087a04ee034255a5de129a4c0d9fd0bf99fa7bf642781ac2dc745ca687aae3de082bd8afdd0d117bc953241e15ad + languageName: node + linkType: hard + +"react-toastify@npm:^9.0.8": + version: 9.0.8 + resolution: "react-toastify@npm:9.0.8" + dependencies: + clsx: "npm:^1.1.1" + peerDependencies: + react: ">=16" + react-dom: ">=16" + checksum: 10c0/5fdb4d76848d367aa7919e0db8427f28b9463760b1b1f69ab3348353305f4b701c4066a17d3cd8a0b82d1f81f51a9bf2bbfd757deb142bfd9d4c18dbf87a2783 + languageName: node + linkType: hard + +"react-toggle-dark-mode@npm:^1.1.0": + version: 1.1.0 + resolution: "react-toggle-dark-mode@npm:1.1.0" + dependencies: + react-spring: "npm:^9.0.0-rc.3" + peerDependencies: + react: ">=16" + checksum: 10c0/1ab1c907af344113bc8ae86e2aa0ac23db7b6a9f099c171e3a882ec7c1849144841d2db8b6b8ac59de7d5df176399f39e85a01fbefba0f1b372471e675f4fc15 + languageName: node + linkType: hard + +"react-transition-group@npm:^4.4.5": + version: 4.4.5 + resolution: "react-transition-group@npm:4.4.5" + dependencies: + "@babel/runtime": "npm:^7.5.5" + dom-helpers: "npm:^5.0.1" + loose-envify: "npm:^1.4.0" + prop-types: "npm:^15.6.2" + peerDependencies: + react: ">=16.6.0" + react-dom: ">=16.6.0" + checksum: 10c0/2ba754ba748faefa15f87c96dfa700d5525054a0141de8c75763aae6734af0740e77e11261a1e8f4ffc08fd9ab78510122e05c21c2d79066c38bb6861a886c82 + languageName: node + linkType: hard + +"react-universal-interface@npm:^0.6.2": + version: 0.6.2 + resolution: "react-universal-interface@npm:0.6.2" + peerDependencies: + react: "*" + tslib: "*" + checksum: 10c0/97c32ecb7a425c3bcaa92dcf84c46146b49610d928efde9e9ee5518c475a0db942f01634dd490e4f42fcd95cc2f49657c1b96dcef96423c06f077147fe1968ab + languageName: node + linkType: hard + +"react-use@npm:^17.4.0": + version: 17.4.0 + resolution: "react-use@npm:17.4.0" + dependencies: + "@types/js-cookie": "npm:^2.2.6" + "@xobotyi/scrollbar-width": "npm:^1.9.5" + copy-to-clipboard: "npm:^3.3.1" + fast-deep-equal: "npm:^3.1.3" + fast-shallow-equal: "npm:^1.0.0" + js-cookie: "npm:^2.2.1" + nano-css: "npm:^5.3.1" + react-universal-interface: "npm:^0.6.2" + resize-observer-polyfill: "npm:^1.5.1" + screenfull: "npm:^5.1.0" + set-harmonic-interval: "npm:^1.0.1" + throttle-debounce: "npm:^3.0.1" + ts-easing: "npm:^0.2.0" + tslib: "npm:^2.1.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/9f9a56a5dbeb707186d470882a17d22e4d0845e7d77b576f4f23f07e7bc60600c7ca14bef33d62d0607f0a7ce18b465807cc9a120bdb75486985afc57d45da19 + languageName: node + linkType: hard + +"react-virtualized-auto-sizer@npm:1.0.7": + version: 1.0.7 + resolution: "react-virtualized-auto-sizer@npm:1.0.7" + peerDependencies: + react: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc + react-dom: ^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc + checksum: 10c0/91e8d7924bace7d1ba48f54580e14b2cfea71c7af6f5472d40f2d9499f85fa0e9a6712ee0ba60ff9dd3d7566593cb1e681e44aaeddd956e5a19b20a79f8c322a + languageName: node + linkType: hard + +"react-window@npm:1.8.7": + version: 1.8.7 + resolution: "react-window@npm:1.8.7" + dependencies: + "@babel/runtime": "npm:^7.0.0" + memoize-one: "npm:>=3.1.1 <6" + peerDependencies: + react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/b36a5df21aa665db4a9674d37e933025c6dabc09ee38c364a8beba334e3aec9d3ab0d30dd18972c927dfb0a8e4ee8b0bf0822759d3181c578268e3523a097c01 + languageName: node + linkType: hard + +"react@npm:18.2.0": + version: 18.2.0 + resolution: "react@npm:18.2.0" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10c0/b562d9b569b0cb315e44b48099f7712283d93df36b19a39a67c254c6686479d3980b7f013dc931f4a5a3ae7645eae6386b4aa5eea933baa54ecd0f9acb0902b8 + languageName: node + linkType: hard + +"regenerator-runtime@npm:^0.13.10": + version: 0.13.10 + resolution: "regenerator-runtime@npm:0.13.10" + checksum: 10c0/2990a7a998ff6bf5caf5597c5671751f447560c5060ae5628469620a7ce640131bf0744c506d63c2166783121535da4ed782c3383371f945fb9a37481598a761 + languageName: node + linkType: hard + +"regenerator-runtime@npm:^0.14.0": + version: 0.14.1 + resolution: "regenerator-runtime@npm:0.14.1" + checksum: 10c0/1b16eb2c4bceb1665c89de70dcb64126a22bc8eb958feef3cd68fe11ac6d2a4899b5cd1b80b0774c7c03591dc57d16631a7f69d2daa2ec98100e2f29f7ec4cc4 + languageName: node + linkType: hard + +"regexp.prototype.flags@npm:^1.4.1, regexp.prototype.flags@npm:^1.4.3": + version: 1.4.3 + resolution: "regexp.prototype.flags@npm:1.4.3" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.3" + functions-have-names: "npm:^1.2.2" + checksum: 10c0/5d797c7fb95f72a52dd9685a485faf0af3c55a4d1f2fafc1153a7be3df036cc3274b195b3ae051ee3d896a01960b446d726206e0d9a90b749e90d93445bb781f + languageName: node + linkType: hard + +"regexpp@npm:^3.2.0": + version: 3.2.0 + resolution: "regexpp@npm:3.2.0" + checksum: 10c0/d1da82385c8754a1681416b90b9cca0e21b4a2babef159099b88f640637d789c69011d0bc94705dacab85b81133e929d027d85210e8b8b03f8035164dbc14710 + languageName: node + linkType: hard + +"remove-accents@npm:0.5.0": + version: 0.5.0 + resolution: "remove-accents@npm:0.5.0" + checksum: 10c0/a75321aa1b53d9abe82637115a492770bfe42bb38ed258be748bf6795871202bc8b4badff22013494a7029f5a241057ad8d3f72adf67884dbe15a9e37e87adc4 + languageName: node + linkType: hard + +"resize-observer-polyfill@npm:^1.5.1": + version: 1.5.1 + resolution: "resize-observer-polyfill@npm:1.5.1" + checksum: 10c0/5e882475067f0b97dc07e0f37c3e335ac5bc3520d463f777cec7e894bb273eddbfecb857ae668e6fb6881fd6f6bb7148246967172139302da50fa12ea3a15d95 + languageName: node + linkType: hard + +"resolve-from@npm:^4.0.0": + version: 4.0.0 + resolution: "resolve-from@npm:4.0.0" + checksum: 10c0/8408eec31a3112ef96e3746c37be7d64020cda07c03a920f5024e77290a218ea758b26ca9529fd7b1ad283947f34b2291c1c0f6aa0ed34acfdda9c6014c8d190 + languageName: node + linkType: hard + +"resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.0": + version: 1.22.1 + resolution: "resolve@npm:1.22.1" + dependencies: + is-core-module: "npm:^2.9.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/6d58b1cb40f3fc80b9e45dd799d84cdc3829a993e4b9fa3b59d331e1dfacd0870e1851f4d0eb549d68c796e0b7087b43d1aec162653ccccff9e18191221a6e7d + languageName: node + linkType: hard + +"resolve@npm:^2.0.0-next.3": + version: 2.0.0-next.4 + resolution: "resolve@npm:2.0.0-next.4" + dependencies: + is-core-module: "npm:^2.9.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/1de92669e7c46cfe125294c66d5405e13288bb87b97e9bdab71693ceebbcc0255c789bde30e2834265257d330d8ff57414d7d88e3097d8f69951f3ce978bf045 + languageName: node + linkType: hard + +"resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.0#optional!builtin": + version: 1.22.1 + resolution: "resolve@patch:resolve@npm%3A1.22.1#optional!builtin::version=1.22.1&hash=c3c19d" + dependencies: + is-core-module: "npm:^2.9.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/0d8ccceba5537769c42aa75e4aa75ae854aac866a11d7e9ffdb1663f0158ee646a0d48fc2818ed5e7fb364d64220a1fb9092a160e11e00cbdd5fbab39a13092c + languageName: node + linkType: hard + +"resolve@patch:resolve@npm%3A^2.0.0-next.3#optional!builtin": + version: 2.0.0-next.4 + resolution: "resolve@patch:resolve@npm%3A2.0.0-next.4#optional!builtin::version=2.0.0-next.4&hash=c3c19d" + dependencies: + is-core-module: "npm:^2.9.0" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/ed2bb51d616b9cd30fe85cf49f7a2240094d9fa01a221d361918462be81f683d1855b7f192391d2ab5325245b42464ca59690db5bd5dad0a326fc0de5974dd10 + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: 10c0/c19ef26e4e188f408922c46f7ff480d38e8dfc55d448310dfb518736b23ed2c4f547fb64a6ed5bdba92cd7e7ddc889d36ff78f794816d5e71498d645ef476107 + languageName: node + linkType: hard + +"rimraf@npm:3.0.2, rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: bin.js + checksum: 10c0/9cb7757acb489bd83757ba1a274ab545eafd75598a9d817e0c3f8b164238dd90eba50d6b848bd4dcc5f3040912e882dc7ba71653e35af660d77b25c381d402e8 + languageName: node + linkType: hard + +"rtl-css-js@npm:^1.14.0": + version: 1.16.1 + resolution: "rtl-css-js@npm:1.16.1" + dependencies: + "@babel/runtime": "npm:^7.1.2" + checksum: 10c0/4b81ef50e50c97455d61c9bb576e2892651c79bac5d0c52b4123ebb9d6a2c5144590a79c9db0a3212a81b4eb83bf317e03637220f20b387a37b96cbac324d3d2 + languageName: node + linkType: hard + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39 + languageName: node + linkType: hard + +"safe-regex-test@npm:^1.0.0": + version: 1.0.0 + resolution: "safe-regex-test@npm:1.0.0" + dependencies: + call-bind: "npm:^1.0.2" + get-intrinsic: "npm:^1.1.3" + is-regex: "npm:^1.1.4" + checksum: 10c0/14a81a7e683f97b2d6e9c8be61fddcf8ed7a02f4e64a825515f96bb1738eb007145359313741d2704d28b55b703a0f6300c749dde7c1dbc13952a2b85048ede2 + languageName: node + linkType: hard + +"scheduler@npm:^0.23.0": + version: 0.23.0 + resolution: "scheduler@npm:0.23.0" + dependencies: + loose-envify: "npm:^1.1.0" + checksum: 10c0/b777f7ca0115e6d93e126ac490dbd82642d14983b3079f58f35519d992fa46260be7d6e6cede433a92db70306310c6f5f06e144f0e40c484199e09c1f7be53dd + languageName: node + linkType: hard + +"screenfull@npm:^5.1.0": + version: 5.2.0 + resolution: "screenfull@npm:5.2.0" + checksum: 10c0/86fd49983e2edc153ee2e674a570c711cb0961a9cacca659309f79636ccc8ca8a0b830ea4dacdae7403a8bb7ba6affd5bcdce053aa97782961247a49bfd2ba68 + languageName: node + linkType: hard + +"semver@npm:^6.0.0": + version: 6.3.1 + resolution: "semver@npm:6.3.1" + bin: + semver: bin/semver.js + checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d + languageName: node + linkType: hard + +"semver@npm:^6.3.0": + version: 6.3.0 + resolution: "semver@npm:6.3.0" + bin: + semver: ./bin/semver.js + checksum: 10c0/1f4959e15bcfbaf727e964a4920f9260141bb8805b399793160da4e7de128e42a7d1f79c1b7d5cd21a6073fba0d55feb9966f5fef3e5ccb8e1d7ead3d7527458 + languageName: node + linkType: hard + +"semver@npm:^7.3.7": + version: 7.3.8 + resolution: "semver@npm:7.3.8" + dependencies: + lru-cache: "npm:^6.0.0" + bin: + semver: bin/semver.js + checksum: 10c0/7e581d679530db31757301c2117721577a2bb36a301a443aac833b8efad372cda58e7f2a464fe4412ae1041cc1f63a6c1fe0ced8c57ce5aca1e0b57bb0d627b9 + languageName: node + linkType: hard + +"set-harmonic-interval@npm:^1.0.1": + version: 1.0.1 + resolution: "set-harmonic-interval@npm:1.0.1" + checksum: 10c0/49014d928a62c8418507bf66ffef7066783e8fb19f76e955318bbae5a8c4b56e1a7176b370f9040ef9de51531aa522a3f96fa5c47b1534635aa577ff7c12f9c6 + languageName: node + linkType: hard + +"shallowequal@npm:^1.1.0": + version: 1.1.0 + resolution: "shallowequal@npm:1.1.0" + checksum: 10c0/b926efb51cd0f47aa9bc061add788a4a650550bbe50647962113a4579b60af2abe7b62f9b02314acc6f97151d4cf87033a2b15fc20852fae306d1a095215396c + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 + languageName: node + linkType: hard + +"side-channel@npm:^1.0.4": + version: 1.0.4 + resolution: "side-channel@npm:1.0.4" + dependencies: + call-bind: "npm:^1.0.0" + get-intrinsic: "npm:^1.0.2" + object-inspect: "npm:^1.9.0" + checksum: 10c0/054a5d23ee35054b2c4609b9fd2a0587760737782b5d765a9c7852264710cc39c6dcb56a9bbd6c12cd84071648aea3edb2359d2f6e560677eedadce511ac1da5 + languageName: node + linkType: hard + +"size-sensor@npm:^1.0.1": + version: 1.0.1 + resolution: "size-sensor@npm:1.0.1" + checksum: 10c0/fdc80334d570ff5fee27b8415a23b4d4402aba41fd81a9f4bf6e9f932f6a68f618d7acc3ebf4a2549a09a1f1026d26cc9568c6b1f0b35d27f8e997b3866f3d8f + languageName: node + linkType: hard + +"slash@npm:^3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b + languageName: node + linkType: hard + +"sonner@npm:^1.5.0": + version: 1.5.0 + resolution: "sonner@npm:1.5.0" + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + checksum: 10c0/9561b5861bede7f874cc442e447a68c8bfa6e4eadad603bc04e38db35a8b8108741f595a12c9856742062bae230ffedf73122015940491f482c5aa9e68ee85e0 + languageName: node + linkType: hard + +"source-map-js@npm:^1.0.2": + version: 1.0.2 + resolution: "source-map-js@npm:1.0.2" + checksum: 10c0/32f2dfd1e9b7168f9a9715eb1b4e21905850f3b50cf02cf476e47e4eebe8e6b762b63a64357896aa29b37e24922b4282df0f492e0d2ace572b43d15525976ff8 + languageName: node + linkType: hard + +"source-map@npm:0.5.6": + version: 0.5.6 + resolution: "source-map@npm:0.5.6" + checksum: 10c0/beb2c5974bb58954d75e86249953d47ae16f7df1a8531abb9fcae0cd262d9fa09c2db3a134e20e99358b1adba42b6b054a32c8e16b571b3efcf6af644c329f0d + languageName: node + linkType: hard + +"source-map@npm:^0.5.7": + version: 0.5.7 + resolution: "source-map@npm:0.5.7" + checksum: 10c0/904e767bb9c494929be013017380cbba013637da1b28e5943b566031e29df04fba57edf3f093e0914be094648b577372bd8ad247fa98cfba9c600794cd16b599 + languageName: node + linkType: hard + +"source-map@npm:^0.6.1": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 + languageName: node + linkType: hard + +"sourcemap-codec@npm:^1.4.8": + version: 1.4.8 + resolution: "sourcemap-codec@npm:1.4.8" + checksum: 10c0/f099279fdaae070ff156df7414bbe39aad69cdd615454947ed3e19136bfdfcb4544952685ee73f56e17038f4578091e12b17b283ed8ac013882916594d95b9e6 + languageName: node + linkType: hard + +"stack-generator@npm:^2.0.5": + version: 2.0.10 + resolution: "stack-generator@npm:2.0.10" + dependencies: + stackframe: "npm:^1.3.4" + checksum: 10c0/c3f6f6c580488e65c0fee806a57f6ae4b79e6435f144be471c1f20328a8d9d8492d4f3beed31840f6dae03e2633325e2764fd3aca5c3126a0639e7c9ddfa45ce + languageName: node + linkType: hard + +"stackframe@npm:^1.3.4": + version: 1.3.4 + resolution: "stackframe@npm:1.3.4" + checksum: 10c0/18410f7a1e0c5d211a4effa83bdbf24adbe8faa8c34db52e1cd3e89837518c592be60b60d8b7270ac53eeeb8b807cd11b399a41667f6c9abb41059c3ccc8a989 + languageName: node + linkType: hard + +"stacktrace-gps@npm:^3.0.4": + version: 3.1.2 + resolution: "stacktrace-gps@npm:3.1.2" + dependencies: + source-map: "npm:0.5.6" + stackframe: "npm:^1.3.4" + checksum: 10c0/0dcc1aa46e364a2b4d1eabce4777fecf337576a11ee3cfc92f07b9ec79ccb76810752431eeb9771289d250d0bb58dbe19a178b96bf7b2e9f773334d03aa96bb9 + languageName: node + linkType: hard + +"stacktrace-js@npm:^2.0.2": + version: 2.0.2 + resolution: "stacktrace-js@npm:2.0.2" + dependencies: + error-stack-parser: "npm:^2.0.6" + stack-generator: "npm:^2.0.5" + stacktrace-gps: "npm:^3.0.4" + checksum: 10c0/9a10c222524ca03690bcb27437b39039885223e39320367f2be36e6f750c2d198ae99189869a22c255bf60072631eb609d47e8e33661e95133686904e01121ec + languageName: node + linkType: hard + +"string.prototype.matchall@npm:^4.0.7": + version: 4.0.7 + resolution: "string.prototype.matchall@npm:4.0.7" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.3" + es-abstract: "npm:^1.19.1" + get-intrinsic: "npm:^1.1.1" + has-symbols: "npm:^1.0.3" + internal-slot: "npm:^1.0.3" + regexp.prototype.flags: "npm:^1.4.1" + side-channel: "npm:^1.0.4" + checksum: 10c0/85bfc0c18b73b90b4a10771bd1afa4c6e42fc78885196dee680b45d023afc81cec6a9944f2f0e25d81f8e5643d5412df5a4649ea624ab375598c6dba0864c9a2 + languageName: node + linkType: hard + +"string.prototype.trimend@npm:^1.0.5": + version: 1.0.5 + resolution: "string.prototype.trimend@npm:1.0.5" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.4" + es-abstract: "npm:^1.19.5" + checksum: 10c0/efcb7d4e943366efde2786be9abf7a79ac9e427bb184aeb4c532ce81d7cb94e1a4d323b256f706dafe6ed5a4ee3d6025a65ec4337d47d07014802be5bcdd4864 + languageName: node + linkType: hard + +"string.prototype.trimstart@npm:^1.0.5": + version: 1.0.5 + resolution: "string.prototype.trimstart@npm:1.0.5" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.4" + es-abstract: "npm:^1.19.5" + checksum: 10c0/c42d2f7732a98d9402aabcfb6ac05e4e36bbc429f5aa98bd199b5e55162b19b87db941ed68382c68ec6527a200a3d01cb3d4c16f668296c383e63693d8493772 + languageName: node + linkType: hard + +"strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 + languageName: node + linkType: hard + +"strip-bom@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-bom@npm:3.0.0" + checksum: 10c0/51201f50e021ef16672593d7434ca239441b7b760e905d9f33df6e4f3954ff54ec0e0a06f100d028af0982d6f25c35cd5cda2ce34eaebccd0250b8befb90d8f1 + languageName: node + linkType: hard + +"strip-json-comments@npm:^3.1.0, strip-json-comments@npm:^3.1.1": + version: 3.1.1 + resolution: "strip-json-comments@npm:3.1.1" + checksum: 10c0/9681a6257b925a7fa0f285851c0e613cc934a50661fa7bb41ca9cbbff89686bb4a0ee366e6ecedc4daafd01e83eee0720111ab294366fe7c185e935475ebcecd + languageName: node + linkType: hard + +"strip-outer@npm:^1.0.1": + version: 1.0.1 + resolution: "strip-outer@npm:1.0.1" + dependencies: + escape-string-regexp: "npm:^1.0.2" + checksum: 10c0/c0f38e6f37563d878a221b1c76f0822f180ec5fc39be5ada30ee637a7d5b59d19418093bad2b4db1e69c40d7a7a7ac50828afce07276cf3d51ac8965cb140dfb + languageName: node + linkType: hard + +"styled-components@npm:^5.3.5, styled-components@npm:^5.3.6": + version: 5.3.6 + resolution: "styled-components@npm:5.3.6" + dependencies: + "@babel/helper-module-imports": "npm:^7.0.0" + "@babel/traverse": "npm:^7.4.5" + "@emotion/is-prop-valid": "npm:^1.1.0" + "@emotion/stylis": "npm:^0.8.4" + "@emotion/unitless": "npm:^0.7.4" + babel-plugin-styled-components: "npm:>= 1.12.0" + css-to-react-native: "npm:^3.0.0" + hoist-non-react-statics: "npm:^3.0.0" + shallowequal: "npm:^1.1.0" + supports-color: "npm:^5.5.0" + peerDependencies: + react: ">= 16.8.0" + react-dom: ">= 16.8.0" + react-is: ">= 16.8.0" + checksum: 10c0/14c0c1fa2944a753fcdaef10478c340046076163ad419eb7a4a37602e953cf63df3603961abdce7b4e780c2cc828cdf1c7a5f7d96fb07fabc24f23997980d69a + languageName: node + linkType: hard + +"styled-jsx@npm:5.1.0": + version: 5.1.0 + resolution: "styled-jsx@npm:5.1.0" + dependencies: + client-only: "npm:0.0.1" + peerDependencies: + react: ">= 16.8.0 || 17.x.x || ^18.0.0-0" + peerDependenciesMeta: + "@babel/core": + optional: true + babel-plugin-macros: + optional: true + checksum: 10c0/32caa4d0ccae0ed82d666127f9230e0608d1922ce4383572d2446de47c258eeb9ebe138271ded50a74846a41fc0e49a6894c9333ecf170231e5a8292083ccfae + languageName: node + linkType: hard + +"styled-tools@npm:^1.7.2": + version: 1.7.2 + resolution: "styled-tools@npm:1.7.2" + checksum: 10c0/486a6ecbefec4cb46d9ca533ef8b5767a7e811e9af6c0047337a7fe41732fbb50a614942d7c28f28b6c6e38490f602b7929dce45cf417c9eb755702324b0c891 + languageName: node + linkType: hard + +"stylis@npm:4.1.3, stylis@npm:^4.0.6": + version: 4.1.3 + resolution: "stylis@npm:4.1.3" + checksum: 10c0/3e4670f26f79bcfba628dcc2756d9d415edfcbf4ec51e40f3b628fd15286222257317cad57390752964eba85cca6163a7621ce90038d68dd630a674479e52334 + languageName: node + linkType: hard + +"supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": + version: 5.5.0 + resolution: "supports-color@npm:5.5.0" + dependencies: + has-flag: "npm:^3.0.0" + checksum: 10c0/6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 + languageName: node + linkType: hard + +"supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124 + languageName: node + linkType: hard + +"supports-preserve-symlinks-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "supports-preserve-symlinks-flag@npm:1.0.0" + checksum: 10c0/6c4032340701a9950865f7ae8ef38578d8d7053f5e10518076e6554a9381fa91bd9c6850193695c141f32b21f979c985db07265a758867bac95de05f7d8aeb39 + languageName: node + linkType: hard + +"svg.draggable.js@npm:^2.2.2": + version: 2.2.2 + resolution: "svg.draggable.js@npm:2.2.2" + dependencies: + svg.js: "npm:^2.0.1" + checksum: 10c0/b21be608254cb10b56de2867883b11053caab477ffc0b5bc9aab7ae640293413c5ad68bd29c6eeed62e41f424576eb5e8b2ebc50056d7b05a060720446a34556 + languageName: node + linkType: hard + +"svg.easing.js@npm:^2.0.0": + version: 2.0.0 + resolution: "svg.easing.js@npm:2.0.0" + dependencies: + svg.js: "npm:>=2.3.x" + checksum: 10c0/5c8b656d0c2956326e03e65448bd77e014b6acbe5fd50aa64ba983b40614145e66b4f27790698f4ef3e64d56498038ff5190ab5829772e823c64d5d70d8c953d + languageName: node + linkType: hard + +"svg.filter.js@npm:^2.0.2": + version: 2.0.2 + resolution: "svg.filter.js@npm:2.0.2" + dependencies: + svg.js: "npm:^2.2.5" + checksum: 10c0/c2b88f05bd2bd8cbf0b4378d8dc41567702242a92d548664893a6239ab887cc2a7cb1da016990bc099982bdb03460fa5dd05ce70cc0d8bd8f3052abf2764949c + languageName: node + linkType: hard + +"svg.js@npm:>=2.3.x, svg.js@npm:^2.0.1, svg.js@npm:^2.2.5, svg.js@npm:^2.4.0, svg.js@npm:^2.6.5": + version: 2.7.1 + resolution: "svg.js@npm:2.7.1" + checksum: 10c0/b50eecb4effdf9ad6be4ddbfd0fcf4e44bd1f6318b2dbbffe3fe639cbe556c9ac8253345f6c6e3734ba84b35472b975e359fb689c9795efb11be6cbba9d7bcfd + languageName: node + linkType: hard + +"svg.pathmorphing.js@npm:^0.1.3": + version: 0.1.3 + resolution: "svg.pathmorphing.js@npm:0.1.3" + dependencies: + svg.js: "npm:^2.4.0" + checksum: 10c0/68e7f70fc900365bdb2fdc8aeb4b3fd8e7ac753a58e4cd43f935723991ab778af91a314c94343e64d77a5374638b880ebba3e286e6be3c8debcdec220bba39ab + languageName: node + linkType: hard + +"svg.resize.js@npm:^1.4.3": + version: 1.4.3 + resolution: "svg.resize.js@npm:1.4.3" + dependencies: + svg.js: "npm:^2.6.5" + svg.select.js: "npm:^2.1.2" + checksum: 10c0/0ebdb3dd2e93cc14831e9e017c45d435ba0fdf26cd877411d2da7390a18035dd3754ffd5e1a18e50098da9ea5bb72dad49ba8f4993249bf29847efed72b0440a + languageName: node + linkType: hard + +"svg.select.js@npm:^2.1.2": + version: 2.1.2 + resolution: "svg.select.js@npm:2.1.2" + dependencies: + svg.js: "npm:^2.2.5" + checksum: 10c0/6e7dfcca97ed85b5ba0018c192dbb0d08cee9943d532749f4323ca1bde0d6c797e028f0305c8da48385b41812254d6ef237f7dabd8a4c4d3a1a13e35af8e5db2 + languageName: node + linkType: hard + +"svg.select.js@npm:^3.0.1": + version: 3.0.1 + resolution: "svg.select.js@npm:3.0.1" + dependencies: + svg.js: "npm:^2.6.5" + checksum: 10c0/c629447aa77dccdc5091adef8d2ce146d6b75c0c0ece383e6dfc14911a7faca6177a091a554f4450c4e4d80c36e18b5fd8b2b15f9f85beec3a95a67c5e87c33f + languageName: node + linkType: hard + +"tabbable@npm:^5.3.3": + version: 5.3.3 + resolution: "tabbable@npm:5.3.3" + checksum: 10c0/c6cb54be76ecff7d0132fed77ff11cedf76a2ce320f55e350f70d8f68998227e72bc3f8b1ee5e7b02dbe4b4c2ef7b6fa43c3aea7cfa82ef06e7d23746df97a35 + languageName: node + linkType: hard + +"text-table@npm:^0.2.0": + version: 0.2.0 + resolution: "text-table@npm:0.2.0" + checksum: 10c0/02805740c12851ea5982686810702e2f14369a5f4c5c40a836821e3eefc65ffeec3131ba324692a37608294b0fd8c1e55a2dd571ffed4909822787668ddbee5c + languageName: node + linkType: hard + +"throttle-debounce@npm:^3.0.1": + version: 3.0.1 + resolution: "throttle-debounce@npm:3.0.1" + checksum: 10c0/c8e558479463b7ed8bac30d6b10cc87abd1c9fc64edfce2db4109be1a04acaef5d2d0557f49c1a3845ea07d9f79e6e0389b1b60db0a77c44e5b7a1216596f285 + languageName: node + linkType: hard + +"to-fast-properties@npm:^2.0.0": + version: 2.0.0 + resolution: "to-fast-properties@npm:2.0.0" + checksum: 10c0/b214d21dbfb4bce3452b6244b336806ffea9c05297148d32ebb428d5c43ce7545bdfc65a1ceb58c9ef4376a65c0cb2854d645f33961658b3e3b4f84910ddcdd7 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892 + languageName: node + linkType: hard + +"toggle-selection@npm:^1.0.6": + version: 1.0.6 + resolution: "toggle-selection@npm:1.0.6" + checksum: 10c0/f2cf1f2c70f374fd87b0cdc8007453ba9e981c4305a8bf4eac10a30e62ecdfd28bca7d18f8f15b15a506bf8a7bfb20dbe3539f0fcf2a2c8396c1a78d53e1f179 + languageName: node + linkType: hard + +"trim-repeated@npm:^1.0.0": + version: 1.0.0 + resolution: "trim-repeated@npm:1.0.0" + dependencies: + escape-string-regexp: "npm:^1.0.2" + checksum: 10c0/89acada0142ed0cdb113615a3e82fdb09e7fdb0e3504ded62762dd935bc27debfcc38edefa497dc7145d8dc8602d40dd9eec891e0ea6c28fa0cc384200b692db + languageName: node + linkType: hard + +"ts-easing@npm:^0.2.0": + version: 0.2.0 + resolution: "ts-easing@npm:0.2.0" + checksum: 10c0/84ec20192310c697ff890ca2e0625e131a32596a7c5956326c9632faca9037abf2dd3de4d81ac358ae9f26a6a2cfe2300f13756b26995f753d882e3d0463e327 + languageName: node + linkType: hard + +"tsconfig-paths@npm:^3.14.1": + version: 3.14.1 + resolution: "tsconfig-paths@npm:3.14.1" + dependencies: + "@types/json5": "npm:^0.0.29" + json5: "npm:^1.0.1" + minimist: "npm:^1.2.6" + strip-bom: "npm:^3.0.0" + checksum: 10c0/67cd2e400119a0063514782176a9e5c3420d43b7a550804ae65d833027379c0559dec44d21c93791825a3be3c2ec593f07cba658c4167dcbbadb048cb3d36fa3 + languageName: node + linkType: hard + +"tslib@npm:2.3.0": + version: 2.3.0 + resolution: "tslib@npm:2.3.0" + checksum: 10c0/a845aed84e7e7dbb4c774582da60d7030ea39d67307250442d35c4c5dd77e4b44007098c37dd079e100029c76055f2a362734b8442ba828f8cc934f15ed9be61 + languageName: node + linkType: hard + +"tslib@npm:2.4.0, tslib@npm:^2.0.0, tslib@npm:^2.1.0, tslib@npm:^2.4.0": + version: 2.4.0 + resolution: "tslib@npm:2.4.0" + checksum: 10c0/eb19bda3ae545b03caea6a244b34593468e23d53b26bf8649fbc20fce43e9b21a71127fd6d2b9662c0fe48ee6ff668ead48fd00d3b88b2b716b1c12edae25b5d + languageName: node + linkType: hard + +"tslib@npm:^1.8.1": + version: 1.14.1 + resolution: "tslib@npm:1.14.1" + checksum: 10c0/69ae09c49eea644bc5ebe1bca4fa4cc2c82b7b3e02f43b84bd891504edf66dbc6b2ec0eef31a957042de2269139e4acff911e6d186a258fb14069cd7f6febce2 + languageName: node + linkType: hard + +"tsutils@npm:^3.21.0": + version: 3.21.0 + resolution: "tsutils@npm:3.21.0" + dependencies: + tslib: "npm:^1.8.1" + peerDependencies: + typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + checksum: 10c0/02f19e458ec78ead8fffbf711f834ad8ecd2cc6ade4ec0320790713dccc0a412b99e7fd907c4cda2a1dc602c75db6f12e0108e87a5afad4b2f9e90a24cabd5a2 + languageName: node + linkType: hard + +"type-check@npm:^0.4.0, type-check@npm:~0.4.0": + version: 0.4.0 + resolution: "type-check@npm:0.4.0" + dependencies: + prelude-ls: "npm:^1.2.1" + checksum: 10c0/7b3fd0ed43891e2080bf0c5c504b418fbb3e5c7b9708d3d015037ba2e6323a28152ec163bcb65212741fa5d2022e3075ac3c76440dbd344c9035f818e8ecee58 + languageName: node + linkType: hard + +"type-fest@npm:^0.20.2": + version: 0.20.2 + resolution: "type-fest@npm:0.20.2" + checksum: 10c0/dea9df45ea1f0aaa4e2d3bed3f9a0bfe9e5b2592bddb92eb1bf06e50bcf98dbb78189668cd8bc31a0511d3fc25539b4cd5c704497e53e93e2d40ca764b10bfc3 + languageName: node + linkType: hard + +"typescript@npm:4.8.4": + version: 4.8.4 + resolution: "typescript@npm:4.8.4" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/663bf455b21ac024e719bb8c6a07bcaaa027a9943abfb58a694b59789e7d08578badb5556170267ad480e31786b8b4c8ab3c9c0e597d3b8df39af800e43c6ed5 + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A4.8.4#optional!builtin": + version: 4.8.4 + resolution: "typescript@patch:typescript@npm%3A4.8.4#optional!builtin::version=4.8.4&hash=1a91c8" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/eecab597a5a8c6e7f14804f1447cfce02e214e32c02efcfe5219c94290e3d572490e8a0d8033fd075ac429d35babf85182541a50c50bfb0c21df33c59fb9bf82 + languageName: node + linkType: hard + +"unbox-primitive@npm:^1.0.2": + version: 1.0.2 + resolution: "unbox-primitive@npm:1.0.2" + dependencies: + call-bind: "npm:^1.0.2" + has-bigints: "npm:^1.0.2" + has-symbols: "npm:^1.0.3" + which-boxed-primitive: "npm:^1.0.2" + checksum: 10c0/81ca2e81134167cc8f75fa79fbcc8a94379d6c61de67090986a2273850989dd3bae8440c163121b77434b68263e34787a675cbdcb34bb2f764c6b9c843a11b66 + languageName: node + linkType: hard + +"universalify@npm:^2.0.0": + version: 2.0.1 + resolution: "universalify@npm:2.0.1" + checksum: 10c0/73e8ee3809041ca8b818efb141801a1004e3fc0002727f1531f4de613ea281b494a40909596dae4a042a4fb6cd385af5d4db2e137b1362e0e91384b828effd3a + languageName: node + linkType: hard + +"unload@npm:2.2.0": + version: 2.2.0 + resolution: "unload@npm:2.2.0" + dependencies: + "@babel/runtime": "npm:^7.6.2" + detect-node: "npm:^2.0.4" + checksum: 10c0/0a4f86b502e7aa35d39c27373ebeaad4f2b7da793fb3d6308e5337aab541885cfe7b339ea4a1963477bf73fddabd5d69f4f47023dad71224b4b4a25611ef7dd8 + languageName: node + linkType: hard + +"uri-js@npm:^4.2.2": + version: 4.4.1 + resolution: "uri-js@npm:4.4.1" + dependencies: + punycode: "npm:^2.1.0" + checksum: 10c0/4ef57b45aa820d7ac6496e9208559986c665e49447cb072744c13b66925a362d96dd5a46c4530a6b8e203e5db5fe849369444440cb22ecfc26c679359e5dfa3c + languageName: node + linkType: hard + +"use-callback-ref@npm:^1.3.0": + version: 1.3.2 + resolution: "use-callback-ref@npm:1.3.2" + dependencies: + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": ^16.8.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/d232c37160fe3970c99255da19b5fb5299fb5926a5d6141d928a87feb47732c323d29be2f8137d3b1e5499c70d284cd1d9cfad703cc58179db8be24d7dd8f1f2 + languageName: node + linkType: hard + +"use-sidecar@npm:^1.1.2": + version: 1.1.2 + resolution: "use-sidecar@npm:1.1.2" + dependencies: + detect-node-es: "npm:^1.1.0" + tslib: "npm:^2.0.0" + peerDependencies: + "@types/react": ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + "@types/react": + optional: true + checksum: 10c0/89f0018fd9aee1fc17c85ac18c4bf8944d460d453d0d0e04ddbc8eaddf3fa591e9c74a1f8a438a1bff368a7a2417fab380bdb3df899d2194c4375b0982736de0 + languageName: node + linkType: hard + +"use-sync-external-store@npm:1.2.0": + version: 1.2.0 + resolution: "use-sync-external-store@npm:1.2.0" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 10c0/ac4814e5592524f242921157e791b022efe36e451fe0d4fd4d204322d5433a4fc300d63b0ade5185f8e0735ded044c70bcf6d2352db0f74d097a238cebd2da02 + languageName: node + linkType: hard + +"which-boxed-primitive@npm:^1.0.2": + version: 1.0.2 + resolution: "which-boxed-primitive@npm:1.0.2" + dependencies: + is-bigint: "npm:^1.0.1" + is-boolean-object: "npm:^1.1.0" + is-number-object: "npm:^1.0.4" + is-string: "npm:^1.0.5" + is-symbol: "npm:^1.0.3" + checksum: 10c0/0a62a03c00c91dd4fb1035b2f0733c341d805753b027eebd3a304b9cb70e8ce33e25317add2fe9b5fea6f53a175c0633ae701ff812e604410ddd049777cd435e + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f + languageName: node + linkType: hard + +"word-wrap@npm:^1.2.3": + version: 1.2.3 + resolution: "word-wrap@npm:1.2.3" + checksum: 10c0/1cb6558996deb22c909330db1f01d672feee41d7f0664492912de3de282da3f28ba2d49e87b723024e99d56ba2dac2f3ab28f8db07ac199f5e5d5e2e437833de + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 + languageName: node + linkType: hard + +"ws@npm:8.17.1": + version: 8.17.1 + resolution: "ws@npm:8.17.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/f4a49064afae4500be772abdc2211c8518f39e1c959640457dcee15d4488628620625c783902a52af2dd02f68558da2868fd06e6fd0e67ebcd09e6881b1b5bfe + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a + languageName: node + linkType: hard + +"yaml@npm:^1.10.0": + version: 1.10.2 + resolution: "yaml@npm:1.10.2" + checksum: 10c0/5c28b9eb7adc46544f28d9a8d20c5b3cb1215a886609a2fd41f51628d8aaa5878ccd628b755dbcd29f6bb4921bd04ffbc6dcc370689bb96e594e2f9813d2605f + languageName: node + linkType: hard + +"yocto-queue@npm:^0.1.0": + version: 0.1.0 + resolution: "yocto-queue@npm:0.1.0" + checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f + languageName: node + linkType: hard + +"zrender@npm:5.4.3": + version: 5.4.3 + resolution: "zrender@npm:5.4.3" + dependencies: + tslib: "npm:2.3.0" + checksum: 10c0/6808e18cc87396828be07b7fcef9693e1a9bb22d77e580dbdbf9f352a573754f2ae02061b78f083f8bde0150503845807ab7e88092e7a3795dc5fc8360301c79 + languageName: node + linkType: hard From 03ba9c8204187018c2c44e0285e5963eee870ec4 Mon Sep 17 00:00:00 2001 From: abhishek-01k Date: Wed, 23 Oct 2024 15:25:10 +0530 Subject: [PATCH 35/42] Fixed all the UI issues --- blocks/icons/components/ArbitrumMonotone.tsx | 4 +- blocks/icons/components/BnbMonotone.tsx | 6 +- blocks/icons/components/CaretDown.tsx | 11 +- blocks/icons/components/CaretUp.tsx | 11 +- blocks/icons/components/CopyFilled.tsx | 39 ++ ...eriumMonotone.tsx => EthereumMonotone.tsx} | 16 +- blocks/icons/components/OptimismMonotone.tsx | 6 +- blocks/icons/components/PolygonMonotone.tsx | 4 +- blocks/icons/components/PushMonotone.tsx | 6 +- blocks/icons/components/SolanaMonotone.tsx | 44 ++ blocks/icons/index.ts | 4 +- blocks/illustrations/components/PushLogo.tsx | 90 ++-- blocks/textInput/TextInput.tsx | 27 +- common/Common.constants.ts | 9 +- components/Blocks/ConsensusInfo.tsx | 484 +++++++++--------- components/Blocks/Details.tsx | 22 +- components/Blocks/ListView.tsx | 112 ++-- components/Home/LiveBlocks.tsx | 92 ++-- components/Home/LiveTransactions.tsx | 125 +++-- components/Home/OverView.tsx | 229 +++++---- components/Navbar/index.tsx | 115 +++-- components/Reusables/AddressComponent.tsx | 62 ++- components/Reusables/Advanced.tsx | 27 +- components/Reusables/BlockHashLink.tsx | 118 ++--- components/Reusables/TxHashLink.tsx | 9 +- components/Transactions/ListView.tsx | 129 +++-- components/Transactions/TxDetails.tsx | 40 +- components/Transactions/TxTravels.tsx | 452 +++++++++------- sections/Transactions/index.tsx | 23 +- sections/Transactions/txHash.tsx | 41 +- sections/User/index.tsx | 161 ++++-- 31 files changed, 1468 insertions(+), 1050 deletions(-) create mode 100644 blocks/icons/components/CopyFilled.tsx rename blocks/icons/components/{EtheriumMonotone.tsx => EthereumMonotone.tsx} (76%) create mode 100644 blocks/icons/components/SolanaMonotone.tsx diff --git a/blocks/icons/components/ArbitrumMonotone.tsx b/blocks/icons/components/ArbitrumMonotone.tsx index df10c1e..f761e1d 100644 --- a/blocks/icons/components/ArbitrumMonotone.tsx +++ b/blocks/icons/components/ArbitrumMonotone.tsx @@ -19,13 +19,13 @@ const ArbitrumMonotone: FC = (allProps) => { diff --git a/blocks/icons/components/BnbMonotone.tsx b/blocks/icons/components/BnbMonotone.tsx index 654b4aa..ceda17d 100644 --- a/blocks/icons/components/BnbMonotone.tsx +++ b/blocks/icons/components/BnbMonotone.tsx @@ -19,15 +19,15 @@ const BnbMonotone: FC = (allProps) => { diff --git a/blocks/icons/components/CaretDown.tsx b/blocks/icons/components/CaretDown.tsx index db53082..e7b30fc 100644 --- a/blocks/icons/components/CaretDown.tsx +++ b/blocks/icons/components/CaretDown.tsx @@ -11,15 +11,18 @@ const CaretDown: FC = (allProps) => { + diff --git a/blocks/icons/components/CaretUp.tsx b/blocks/icons/components/CaretUp.tsx index dcfd556..cb26693 100644 --- a/blocks/icons/components/CaretUp.tsx +++ b/blocks/icons/components/CaretUp.tsx @@ -11,15 +11,18 @@ const CaretUp: FC = (allProps) => { + diff --git a/blocks/icons/components/CopyFilled.tsx b/blocks/icons/components/CopyFilled.tsx new file mode 100644 index 0000000..7da7e36 --- /dev/null +++ b/blocks/icons/components/CopyFilled.tsx @@ -0,0 +1,39 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const CopyFilled: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + } + {...restProps} + /> + ); +}; + +export default CopyFilled; diff --git a/blocks/icons/components/EtheriumMonotone.tsx b/blocks/icons/components/EthereumMonotone.tsx similarity index 76% rename from blocks/icons/components/EtheriumMonotone.tsx rename to blocks/icons/components/EthereumMonotone.tsx index 1600bde..3a1248f 100644 --- a/blocks/icons/components/EtheriumMonotone.tsx +++ b/blocks/icons/components/EthereumMonotone.tsx @@ -2,11 +2,11 @@ import { FC } from 'react'; import { IconWrapper } from '../IconWrapper'; import { IconProps } from '../Icons.types'; -const EtheriumMonotone: FC = (allProps) => { +const EthereumMonotone: FC = (allProps) => { const { svgProps: props, ...restProps } = allProps; return ( = (allProps) => { > } @@ -43,4 +43,4 @@ const EtheriumMonotone: FC = (allProps) => { ); }; -export default EtheriumMonotone; +export default EthereumMonotone; diff --git a/blocks/icons/components/OptimismMonotone.tsx b/blocks/icons/components/OptimismMonotone.tsx index f9471d5..dfaafd4 100644 --- a/blocks/icons/components/OptimismMonotone.tsx +++ b/blocks/icons/components/OptimismMonotone.tsx @@ -19,15 +19,15 @@ const OptimismMonotone: FC = (allProps) => { diff --git a/blocks/icons/components/PolygonMonotone.tsx b/blocks/icons/components/PolygonMonotone.tsx index 54dbfe5..c9fc933 100644 --- a/blocks/icons/components/PolygonMonotone.tsx +++ b/blocks/icons/components/PolygonMonotone.tsx @@ -19,11 +19,11 @@ const PolygonMonotone: FC = (allProps) => { diff --git a/blocks/icons/components/PushMonotone.tsx b/blocks/icons/components/PushMonotone.tsx index 6034537..c73c9c1 100644 --- a/blocks/icons/components/PushMonotone.tsx +++ b/blocks/icons/components/PushMonotone.tsx @@ -19,15 +19,15 @@ const PushMonotone: FC = (allProps) => { diff --git a/blocks/icons/components/SolanaMonotone.tsx b/blocks/icons/components/SolanaMonotone.tsx new file mode 100644 index 0000000..83d3467 --- /dev/null +++ b/blocks/icons/components/SolanaMonotone.tsx @@ -0,0 +1,44 @@ +import { FC } from 'react'; +import { IconWrapper } from '../IconWrapper'; +import { IconProps } from '../Icons.types'; + +const SolanaMonotone: FC = (allProps) => { + const { svgProps: props, ...restProps } = allProps; + return ( + + + + + + + + + + + + } + {...restProps} + /> + ); +}; + +export default SolanaMonotone; diff --git a/blocks/icons/index.ts b/blocks/icons/index.ts index be0c06e..8eef860 100644 --- a/blocks/icons/index.ts +++ b/blocks/icons/index.ts @@ -44,6 +44,7 @@ export { default as CircleFilled } from './components/CircleFilled'; export { default as CloudUpload } from './components/CloudUpload'; export { default as Copy } from './components/Copy'; +export { default as CopyFilled } from './components/CopyFilled'; export { default as Cross } from './components/Cross'; export { default as CrossFilled } from './components/CrossFilled'; @@ -60,7 +61,7 @@ export { default as Discord } from './components/Discord'; export { default as EditProfile } from './components/EditProfile'; -export { default as EtheriumMonotone } from './components/EtheriumMonotone'; +export { default as EthereumMonotone } from './components/EthereumMonotone'; export { default as Ellipse } from './components/Ellipse'; @@ -153,6 +154,7 @@ export { default as SendNotification } from './components/SendNotification'; export { default as SendNotificationFilled } from './components/SendNotificationFilled'; export { default as Smiley } from './components/Smiley'; +export { default as SolanaMonotone } from './components/SolanaMonotone'; export { default as Star } from './components/Star'; diff --git a/blocks/illustrations/components/PushLogo.tsx b/blocks/illustrations/components/PushLogo.tsx index 33d21b1..2a91e62 100644 --- a/blocks/illustrations/components/PushLogo.tsx +++ b/blocks/illustrations/components/PushLogo.tsx @@ -1,4 +1,4 @@ -import React , { FC } from 'react'; +import React, { FC } from 'react'; import { IllustrationWrapper } from '../IllustrationWrapper'; import { IllustrationProps } from '../Illustrations.types'; @@ -9,44 +9,44 @@ const PushLogo: FC = (allProps) => { componentName="PushDev" illustration={ @@ -59,11 +59,11 @@ const PushLogo: FC = (allProps) => { @@ -76,11 +76,11 @@ const PushLogo: FC = (allProps) => { @@ -93,11 +93,11 @@ const PushLogo: FC = (allProps) => { @@ -110,11 +110,11 @@ const PushLogo: FC = (allProps) => { @@ -127,11 +127,11 @@ const PushLogo: FC = (allProps) => { diff --git a/blocks/textInput/TextInput.tsx b/blocks/textInput/TextInput.tsx index 3e3f75f..e04cc86 100644 --- a/blocks/textInput/TextInput.tsx +++ b/blocks/textInput/TextInput.tsx @@ -38,7 +38,13 @@ const StyledTextInput = styled.div<{ disabled?: boolean; }>` ${({ success, error, disabled }) => { - const defaultState = error ? 'danger' : success ? 'success' : disabled ? 'disabled' : 'default'; + const defaultState = error + ? 'danger' + : success + ? 'success' + : disabled + ? 'disabled' + : 'default'; const focusState = error ? 'danger' : success ? 'success' : 'focus'; return css` align-self: stretch; @@ -58,7 +64,7 @@ const StyledTextInput = styled.div<{ gap: var(--spacing-xxs, 8px); - padding: var(--spacing-xs, 12px); + padding: var(--spacing-xxs, 8px); [role='img'] { width: 24px; height: 24px; @@ -156,7 +162,11 @@ export const TextInput = forwardRef( {label && ( @@ -166,7 +176,11 @@ export const TextInput = forwardRef( {totalCount && ( {`${value?.length || 0} / ${totalCount}`} @@ -210,10 +224,7 @@ export const TextInput = forwardRef( )} {errorMessage && ( - + {errorMessage} )} diff --git a/common/Common.constants.ts b/common/Common.constants.ts index 333b40a..26c0779 100644 --- a/common/Common.constants.ts +++ b/common/Common.constants.ts @@ -2,18 +2,19 @@ import { FC } from 'react'; import { ArbitrumMonotone, BnbMonotone, - EtheriumMonotone, + EthereumMonotone, IconProps, OptimismMonotone, PolygonMonotone, PushMonotone, + SolanaMonotone, } from '../blocks/icons'; export const CHAIN_LOGO: { [x: number | string]: FC; } = { - 1: EtheriumMonotone, - 11155111: EtheriumMonotone, + 1: EthereumMonotone, + 11155111: EthereumMonotone, 137: PolygonMonotone, 80002: PolygonMonotone, 97: BnbMonotone, @@ -24,6 +25,6 @@ export const CHAIN_LOGO: { 10: OptimismMonotone, 2442: PolygonMonotone, 1101: PolygonMonotone, - '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': OptimismMonotone, + '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp': SolanaMonotone, devnet: PushMonotone, }; diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index 539e64e..5c44222 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -1,272 +1,250 @@ import React, { useState } from 'react'; import { Box, Text, Tooltip, Copy } from '../../blocks'; -import { BlockDetails } from '../../types/block' -import { buildNodeVotes } from '../../utils/helpers' -import { PushMonotone } from '../../blocks/icons' +import { BlockDetails } from '../../types/block'; +import { buildNodeVotes } from '../../utils/helpers'; +import { PushMonotone } from '../../blocks/icons'; +import { css } from 'styled-components'; interface IProps { - data: BlockDetails | null | undefined, - isLoading: boolean + data: BlockDetails | null | undefined; + isLoading: boolean; } -const MAX_DISPLAY_NODES = 5 +const MAX_DISPLAY_NODES = 5; const MAX_DISPLAY_CHARS = 700; const ConsensusInfo = (props: IProps) => { - const [showAll, setShowAll] = useState(false); - const [showAllPayload, setShowAllPayload] = useState(false); - const [tooltipText, setToolTipText] = useState('Copy Payload'); - - const toggleShowAll = () => { - setShowAll(!showAll); - }; - - const toggleShowAllPayload = () => { - setShowAllPayload(!showAllPayload); - }; - - - const nodes = buildNodeVotes(props.data?.blockDataAsJson) - - const displayedNodes = showAll ? nodes : nodes.slice(0, MAX_DISPLAY_NODES); - const showMoreButton = nodes.length > MAX_DISPLAY_NODES; - - const payload = props.data?.blockData || ""; - const displayedPayload = showAllPayload ? payload : payload.substring(0, MAX_DISPLAY_CHARS); - const showMorePayloadButton = payload.length > MAX_DISPLAY_CHARS; - - const copyPayload = () => { - if (payload) { - navigator.clipboard.writeText(payload); - setToolTipText('Copied'); - } - setTimeout(() => { - setToolTipText('Copy Payload'); - }, 1000); - }; - - return ( - <> - { + setShowAll(!showAll); + }; + + const toggleShowAllPayload = () => { + setShowAllPayload(!showAllPayload); + }; + + const nodes = buildNodeVotes(props.data?.blockDataAsJson); + + const displayedNodes = showAll ? nodes : nodes.slice(0, MAX_DISPLAY_NODES); + const showMoreButton = nodes.length > MAX_DISPLAY_NODES; + + const payload = props.data?.blockData || ''; + const displayedPayload = showAllPayload + ? payload + : payload.substring(0, MAX_DISPLAY_CHARS); + const showMorePayloadButton = payload.length > MAX_DISPLAY_CHARS; + + const copyPayload = () => { + if (payload) { + navigator.clipboard.writeText(payload); + setToolTipText('Copied'); + } + setTimeout(() => { + setToolTipText('Copy Payload'); + }, 1000); + }; + + return ( + <> + + + + + Consensus Info + + + + + {displayedNodes.map((node, index) => ( + + + + {node.node} + + + ))} + + {showMoreButton && ( + + + {showAll ? 'Show Less' : 'Show More'} + + + )} + + + + + + + Payload Data + + + + - - - Consensus Info - - - - {displayedNodes.map((node, index) => ( - - - {node.node} - - ))} - - {showMoreButton && ( - - - {showAll ? 'Show Less' : 'Show More'} - - - )} - - - - - - - Payload Data - - - - - {displayedPayload} - - - {showMorePayloadButton && ( - - - {showAllPayload ? "Show Less" : "Show More"} - - - )} - - - - - - - - + {payload} + + + + + + + - - + + + + + + + + + Consensus Info + + + + + {displayedNodes.map((node, index) => ( + + - - Consensus Info - - - - {displayedNodes.map((node, index) => ( - - - - {node.node} - - - ))} - - {showMoreButton && ( - - - {showAll ? 'Show Less' : 'Show More'} - - - )} - + + {node.node} + - - - Payload Data - - - - {displayedPayload} - - - {showMorePayloadButton && ( - - - {showAllPayload ? 'Show Less' : 'Show More'} - - - )} - - - - - - - - - + + ))} + + {showMoreButton && ( + + + {showAll ? 'Show Less' : 'Show More'} + + + )} + + + + + + Payload Data + + + + + {payload} + + + + + + + - - ); + + + + + ); }; -export default ConsensusInfo; \ No newline at end of file +export default ConsensusInfo; diff --git a/components/Blocks/Details.tsx b/components/Blocks/Details.tsx index 591e501..b0860b7 100644 --- a/components/Blocks/Details.tsx +++ b/components/Blocks/Details.tsx @@ -6,7 +6,7 @@ import { css } from 'styled-components'; import moment from 'moment'; // Internal Components imports -import { Box, Text, Tooltip, Copy } from '../../blocks'; +import { Box, Text, Tooltip, TickCircleFilled, CopyFilled } from '../../blocks'; import { BlockDetails } from '../../types/block'; import { getValidatorNode } from '../../utils/helpers'; @@ -58,12 +58,20 @@ const Details = (props: IProps) => { - copyData(props.data?.blockHash)} - autoSize - size={24} - color="icon-tertiary" - /> + {tooltipText === 'Copied' ? ( + + ) : ( + copyData(props.data?.blockHash)} + autoSize + size={16} + color="icon-tertiary" + /> + )} diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx index ba3f5d8..1d914c7 100644 --- a/components/Blocks/ListView.tsx +++ b/components/Blocks/ListView.tsx @@ -1,14 +1,18 @@ import React, { useState, useEffect } from 'react'; import { Box, Text, Table, Pagination } from '../../blocks'; import { useLiveBlocks } from '../../hooks/useBlocks'; -import { PerPageItems } from '../../utils/constants' -import { useRouter } from 'next/router' -import { getValidatorNode, fromNow, centerMaskString } from '../../utils/helpers' +import { PerPageItems } from '../../utils/constants'; +import { useRouter } from 'next/router'; +import { + getValidatorNode, + fromNow, + centerMaskString, +} from '../../utils/helpers'; import { useTheme } from 'styled-components'; -import BlockHashLink from '../Reusables/BlockHashLink' +import BlockHashLink from '../Reusables/BlockHashLink'; const Blocks = () => { - const router = useRouter() + const router = useRouter(); const [page, setPage] = useState(1); const [cachedTotalPages, setCachedTotalPages] = useState(0); // State for caching totalPages @@ -21,53 +25,70 @@ const Blocks = () => { { title: 'BLOCK HASH', dataIndex: 'blockHash', - render: (text) => , + render: (text) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '310px' + width: '310px', }, { title: 'VALIDATOR', dataIndex: 'validator', - render: (text) => {centerMaskString(text)}, + render: (text) => ( + + {centerMaskString(text)} + + ), cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '310px' + width: '310px', }, { title: 'TXN', dataIndex: 'totalNumberOfTxns', - render: (text) => {text}, + render: (text) => ( + + {text} + + ), cellAlignment: 'center', headerAlignment: 'center', - width: '200px' + width: '200px', }, { title: 'SIZE (IN BYTES)', dataIndex: 'blockSize', - render: (text) => {text}, + render: (text) => ( + + {text} + + ), cellAlignment: 'center', headerAlignment: 'center', - width: '200px' + width: '200px', }, { title: 'AGE', dataIndex: 'ts', - render: (text) => {fromNow(text)}, + render: (text) => ( + + {fromNow(text)} + + ), cellAlignment: 'center', headerAlignment: 'center', - width: '80px' + width: '80px', }, ]; - const dataSource = data?.blocks?.map(block => ({ - id: block.blockHash, - blockHash: block.blockHash, - validator: getValidatorNode(block.blockDataAsJson), // Define this function or update data mapping accordingly - totalNumberOfTxns: block.totalNumberOfTxns, - blockSize: block.blockSize, - ts: block.ts - })) || []; + const dataSource = + data?.blocks?.map((block) => ({ + id: block.blockHash, + blockHash: block.blockHash, + validator: getValidatorNode(block.blockDataAsJson), // Define this function or update data mapping accordingly + totalNumberOfTxns: block.totalNumberOfTxns, + blockSize: block.blockSize, + ts: block.ts, + })) || []; // Cache totalPages when new data is fetched useEffect(() => { @@ -80,31 +101,32 @@ const Blocks = () => { const totalPages = data?.totalPages ?? cachedTotalPages; return ( - + +

+ + - -
- - - { - totalPages > 1 && setPage(page)} - /> - } - + justifyContent="flex-end" + alignItems={{ initial: 'flex-end', ml: 'center' }} + > + {totalPages > 1 && ( + setPage(page)} + /> + )} + ); }; -export default Blocks; \ No newline at end of file +export default Blocks; diff --git a/components/Home/LiveBlocks.tsx b/components/Home/LiveBlocks.tsx index 10b13b2..d2c95e1 100644 --- a/components/Home/LiveBlocks.tsx +++ b/components/Home/LiveBlocks.tsx @@ -1,7 +1,7 @@ // React, NextJS imports import React from 'react'; -import Link from 'next/link' -import { useRouter } from 'next/router' +import Link from 'next/link'; +import { useRouter } from 'next/router'; // External Components imports import { css, useTheme } from 'styled-components'; @@ -9,13 +9,16 @@ import { css, useTheme } from 'styled-components'; // Internal Components imports import { Box, Text, Front, Table } from '../../blocks'; import { useLiveBlocks } from '../../hooks/useBlocks'; -import { getValidatorNode } from '../../utils/helpers' -import { centerMaskString, fromNow } from '../../utils/helpers' -import BlockHashLink from '../Reusables/BlockHashLink' +import { getValidatorNode } from '../../utils/helpers'; +import { centerMaskString, fromNow } from '../../utils/helpers'; +import BlockHashLink from '../Reusables/BlockHashLink'; export default function LiveBlocks() { - const router = useRouter() - const { data, error, isLoading, isError } = useLiveBlocks({ page: 1, perPageItems: 6 }); + const router = useRouter(); + const { data, error, isLoading, isError } = useLiveBlocks({ + page: 1, + perPageItems: 6, + }); const theme = useTheme(); const isDarkMode = theme.scheme === 'dark'; @@ -24,68 +27,85 @@ export default function LiveBlocks() { { title: 'BLOCK HASH', dataIndex: 'blockHash', - render: (text) => , + render: (text) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '125px' + width: '125px', }, { title: 'VALIDATOR', dataIndex: 'validator', - render: (text) => {centerMaskString(text)}, + render: (text) => ( + + {centerMaskString(text)} + + ), cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '135px' + width: '135px', }, { title: 'TX', dataIndex: 'totalNumberOfTxns', - render: (text) => {text}, + render: (text) => ( + + {text} + + ), cellAlignment: 'center', headerAlignment: 'center', - width: '65px' + width: '65px', }, { title: 'AGE', dataIndex: 'ts', - render: (text) => {fromNow(text)}, + render: (text) => ( + + {fromNow(text)} + + ), cellAlignment: 'center', headerAlignment: 'center', - width: '65px' + width: '65px', }, ]; - const dataSource = data?.blocks?.map(block => ({ - id: block.blockHash, - blockHash: block.blockHash, - validator: getValidatorNode(block.blockDataAsJson), // Define this function or update data mapping accordingly - totalNumberOfTxns: block.totalNumberOfTxns, - ts: block.ts - })) || []; + const dataSource = + data?.blocks?.map((block) => ({ + id: block.blockHash, + blockHash: block.blockHash, + validator: getValidatorNode(block.blockDataAsJson), // Define this function or update data mapping accordingly + totalNumberOfTxns: block.totalNumberOfTxns, + ts: block.ts, + })) || []; return ( - - Live Blocks - -
+ + + Live Blocks + + +
- + - View All Blocks - + + View All Blocks + + - ) + ); } diff --git a/components/Home/LiveTransactions.tsx b/components/Home/LiveTransactions.tsx index a388011..bc6726a 100644 --- a/components/Home/LiveTransactions.tsx +++ b/components/Home/LiveTransactions.tsx @@ -1,19 +1,23 @@ // React, NextJS imports import React from 'react'; -import { Box, Text, Front, Tag, Table } from '../../blocks'; -import { Tick } from '../../blocks/icons' -import { useRouter } from 'next/router' -import Link from 'next/link' -import { useLiveTransactions } from '../../hooks/useLiveTransactions'; +import Link from 'next/link'; +import { useRouter } from 'next/router'; + +// External imports import moment from 'moment'; -import { fromNow, capitalizeStr } from '../../utils/helpers' -import { TagVariant } from '../../blocks/tag'; import { useTheme } from 'styled-components'; -import Address from '../Reusables/AddressComponent' -import TxHashLink from '../Reusables/TxHashLink' + +// Internal imports +import { Box, Text, Front, Tag, Table } from '../../blocks'; +import { Tick } from '../../blocks/icons'; +import { TagVariant } from '../../blocks/tag'; +import { useLiveTransactions } from '../../hooks/useLiveTransactions'; +import { fromNow, capitalizeStr } from '../../utils/helpers'; +import Address from '../Reusables/AddressComponent'; +import TxHashLink from '../Reusables/TxHashLink'; export default function LiveTransactions() { - const router = useRouter() + const router = useRouter(); const { data, isLoading } = useLiveTransactions({ page: 1, perPageItems: 6 }); const theme = useTheme(); @@ -23,10 +27,16 @@ export default function LiveTransactions() { { title: 'STATUS', dataIndex: 'status', - render: (status: string) => } label={capitalizeStr(status)} variant={status.toLowerCase() as TagVariant}>, + render: (status: string) => ( + } + label={capitalizeStr(status)} + variant={status.toLowerCase() as TagVariant} + > + ), cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '100px' + width: '100px', }, { title: 'TX HASH', @@ -34,56 +44,64 @@ export default function LiveTransactions() { render: (txHash: string) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '135px' + width: '135px', }, { title: 'FROM', dataIndex: 'from', - render: (params) => { + render: (params) => { const from = JSON.parse(params); - return
+ return
; }, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '175px' + width: '175px', }, { title: 'TO', dataIndex: 'recipients', render: (recipients: string) => { - const reci = recipients.split(',') + const reci = recipients.split(','); return ( - +
- { reci.length > 1 && {`+ ${reci.length - 1} more`}} + {reci.length > 1 && ( + {`+ ${ + reci.length - 1 + } more`} + )} - )}, + ); + }, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '175px' + width: '175px', }, { title: 'AGE', dataIndex: 'ts', - render: (ts: number) => {fromNow(ts)}, + render: (ts: number) => ( + + {fromNow(ts)} + + ), cellAlignment: 'center', headerAlignment: 'center', - width: '75px' + width: '75px', }, ]; - const dataSource = data?.transactions.map((dt) => ({ - id: dt.txnHash, - status: dt.status, - txHash: dt.txnHash, - from: JSON.stringify({ from: dt.from, source: dt.source }), - recipients: dt.recipients, - ts: dt.ts, - })) || []; + const dataSource = + data?.transactions.map((dt) => ({ + id: dt.txnHash, + status: dt.status, + txHash: dt.txnHash, + from: JSON.stringify({ from: dt.from, source: dt.source }), + recipients: dt.recipients, + ts: dt.ts, + })) || []; return ( - Live Transactions -
- - - View All Transactions - - - + + Live Transactions + + +
+ + + + + View All Transactions + + + + - ) + ); } diff --git a/components/Home/OverView.tsx b/components/Home/OverView.tsx index 8cb8088..6cbc92d 100644 --- a/components/Home/OverView.tsx +++ b/components/Home/OverView.tsx @@ -6,110 +6,141 @@ import { useCounts } from '../../hooks/useCounts'; export type OverViewProps = {}; const OverView: FC = () => { - const { data, isLoading } = useCounts(); - return ( - - - - Transactions - {data?.totalTransactions} - + const { data, isLoading } = useCounts(); - + + + + Transactions + + + {data?.totalTransactions.toLocaleString()} + + - > - Transactions - {data?.totalTransactions} - - - + + + Transactions + + + {data?.totalTransactions.toLocaleString()} + + + - - - Total Blocks - {data?.totalBlocks} - - - Total Blocks - {data?.totalBlocks} - - + + + + Total Blocks + + + {data?.totalBlocks.toLocaleString()} + + + + + Total Blocks + + + {data?.totalBlocks.toLocaleString()} + + + - - - Daily Transactions - {data?.dailyTransactions} - + + + + Daily Transactions + + + {data?.dailyTransactions.toLocaleString()} + + - - Total Transactions - {data?.dailyTransactions} - - + + + Total Transactions + + + {data?.dailyTransactions.toLocaleString()} + - ) -} + + + ); +}; export default OverView; diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx index def99b7..31b180d 100644 --- a/components/Navbar/index.tsx +++ b/components/Navbar/index.tsx @@ -13,7 +13,7 @@ import { useTheme as Theme } from '../../contexts/ThemeContext'; import { useData } from '../../contexts/DataContext'; import { ROUTES, CREDENTIALKEYS } from '../../utils/constants'; import { ThemeType } from '../../types/theme'; -import { Box, Text, Lozenge,PushLogo } from '../../blocks'; +import { Box, Text, Lozenge, PushLogo } from '../../blocks'; import SearchBar from '../Home/SearchBar'; export default function Navbar() { @@ -36,6 +36,7 @@ export default function Navbar() { return ( router.push('/home')} + gap="spacing-xs" > - - - PushScan - - - router.push('/home')} > - ALPHA - + + + PushScan + + + + ALPHA + + - - - {asPath !== '/dashboard' && ( - - - Analytics - - - )} + + {asPath !== '/dashboard' && ( + + + Analytics + + + )} - + - {asPath !== '/home' && ( - - - + {asPath !== '/home' && ( + + + + )} + + + + {asPath === '/home' && ( + + Push Blockchain Explorer + )} + ); diff --git a/components/Reusables/AddressComponent.tsx b/components/Reusables/AddressComponent.tsx index 087f535..ceceb02 100644 --- a/components/Reusables/AddressComponent.tsx +++ b/components/Reusables/AddressComponent.tsx @@ -1,16 +1,22 @@ +// React, NextJS imports import React, { useState } from 'react'; -import { Box, Text, Tooltip } from '../../blocks'; -import { - PushMonotone, - TickCircleFilled, - Copy, -} from '../../blocks/icons'; -import { convertCaipToObject, centerMaskString } from '../../utils/helpers'; import Link from 'next/link'; -import styled from 'styled-components'; + +// External Components imports +import styled, { css } from 'styled-components'; + +// Internal Components imports +import { Box, Text, Tooltip } from '../../blocks'; +import { PushMonotone, TickCircleFilled, CopyFilled } from '../../blocks/icons'; import { CHAIN_LOGO } from '../../common'; +import { convertCaipToObject, centerMaskString } from '../../utils/helpers'; -const Address = ({ address, wrap = false, masking = true, allowCopy=false }) => { +const Address = ({ + address, + wrap = false, + masking = true, + allowCopy = false, +}) => { function getChainIcon(chainId) { try { if (!chainId) { @@ -30,16 +36,17 @@ const Address = ({ address, wrap = false, masking = true, allowCopy=false }) => ? centerMaskString(result.address) : result.address; - const [tooltipText, setToolTipText] = useState('Copy'); + const [tooltipText, setToolTipText] = useState('Copy'); + + const copyData = () => { + const addressToCopy = result.address ?? address; + navigator.clipboard.writeText(addressToCopy); + setToolTipText('Copied'); - const copyData = () => { - navigator.clipboard.writeText(address); - setToolTipText('Copied'); - - setTimeout(() => { - setToolTipText('Copy'); - }, 1000); - }; + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; return ( @@ -50,8 +57,13 @@ const Address = ({ address, wrap = false, masking = true, allowCopy=false }) => {allowCopy && ( - - + + {tooltipText === 'Copied' ? ( color="icon-state-success-bold" /> ) : ( - + )} - - + + )} ); @@ -108,10 +120,6 @@ const AddressContainer = styled(Box)` opacity: 1; pointer-events: auto; } - - `; - - export default Address; diff --git a/components/Reusables/Advanced.tsx b/components/Reusables/Advanced.tsx index d92e80e..18a4785 100644 --- a/components/Reusables/Advanced.tsx +++ b/components/Reusables/Advanced.tsx @@ -2,22 +2,33 @@ import React from 'react'; import { Box, Text, CaretDown, CaretUp } from '../../blocks'; interface IProps { - showConsensusInfo: boolean - toggleConsensusInfo: (value: boolean) => void + showConsensusInfo: boolean; + toggleConsensusInfo: (value: boolean) => void; } const Advanced = ({ showConsensusInfo, toggleConsensusInfo }: IProps) => { return ( + + + Advanced + toggleConsensusInfo(!showConsensusInfo)} > - Advanced - { showConsensusInfo ? : } + {!showConsensusInfo ? ( + + ) : ( + + )} + ); }; -export default Advanced; \ No newline at end of file +export default Advanced; diff --git a/components/Reusables/BlockHashLink.tsx b/components/Reusables/BlockHashLink.tsx index 1edb1cd..0aaa788 100644 --- a/components/Reusables/BlockHashLink.tsx +++ b/components/Reusables/BlockHashLink.tsx @@ -1,81 +1,83 @@ +// React, NextJS imports import React, { useState } from 'react'; -import { Box, Text, Tooltip, Copy } from '../../blocks'; -import { rightMaskString } from '../../utils/helpers'; import Link from 'next/link'; + +// External Components imports import styled from 'styled-components'; -const BlockHashLinkComponent = ({ blockHash, masking = false, allowCopy = false }) => { - const [tooltipText, setToolTipText] = useState('Copy'); +// Internal Components imports +import { Box, Text, Tooltip, Copy } from '../../blocks'; +import { rightMaskString } from '../../utils/helpers'; - const maskedBlockHash = masking ? rightMaskString(blockHash) : blockHash; +const BlockHashLinkComponent = ({ + blockHash, + masking = false, + allowCopy = false, +}) => { + const [tooltipText, setToolTipText] = useState('Copy'); - const copyData = () => { - navigator.clipboard.writeText(blockHash); - setToolTipText('Copied'); - - setTimeout(() => { - setToolTipText('Copy'); - }, 1000); - }; + const maskedBlockHash = masking ? rightMaskString(blockHash) : blockHash; - return ( - - - - {maskedBlockHash} - - - {allowCopy && - - - - } - - ); -}; + const copyData = () => { + navigator.clipboard.writeText(blockHash); + setToolTipText('Copied'); + + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; + return ( + + + {maskedBlockHash} + + {allowCopy && ( + + + + + + )} + + ); +}; const CopyIconButton = styled.button` - opacity: 0; - pointer-events: none; - transition: opacity 0.2s ease-in-out; - display: flex; - align-items: center; - background: none; - border: none; - cursor: pointer; - padding: 0; + opacity: 0; + pointer-events: none; + transition: opacity 0.2s ease-in-out; + display: flex; + align-items: center; + background: none; + border: none; + cursor: pointer; + padding: 0; `; const BlockHashLink = styled(Link)` - text-decoration: none; + text-decoration: none; `; const BlockHashText = styled(Text)` - color: var(--text-primary); - transition: color 0.2s ease-in-out; + color: var(--text-primary); + transition: color 0.2s ease-in-out; `; const BlockHashContainer = styled(Box)` - display: flex; - flex-direction: row; - gap: spacing-xxs; - align-items: center; - - &:hover ${CopyIconButton}, - &:focus-within ${CopyIconButton} { - opacity: 1; - pointer-events: auto; - } + display: flex; + flex-direction: row; + gap: spacing-xxs; + align-items: center; + + &:hover ${CopyIconButton}, &:focus-within ${CopyIconButton} { + opacity: 1; + pointer-events: auto; + } - &:hover ${BlockHashText}, - &:focus-within ${BlockHashText} { - color: var(--text-brand-medium); - } + &:hover ${BlockHashText}, &:focus-within ${BlockHashText} { + color: var(--text-brand-medium); + } `; export default BlockHashLinkComponent; diff --git a/components/Reusables/TxHashLink.tsx b/components/Reusables/TxHashLink.tsx index bfb8852..abe42f1 100644 --- a/components/Reusables/TxHashLink.tsx +++ b/components/Reusables/TxHashLink.tsx @@ -1,9 +1,14 @@ +// React, NextJS imports import React, { useState } from 'react'; -import { Box, Text, Tooltip, Copy, TickCircleFilled } from '../../blocks'; -import { rightMaskString } from '../../utils/helpers'; import Link from 'next/link'; + +// External Components imports import styled from 'styled-components'; +// Internal Components imports +import { Box, Text, Tooltip, Copy, TickCircleFilled } from '../../blocks'; +import { rightMaskString } from '../../utils/helpers'; + const TxHashLinkComponent = ({ txHash, allowCopy = false }) => { const [tooltipText, setToolTipText] = useState('Copy'); diff --git a/components/Transactions/ListView.tsx b/components/Transactions/ListView.tsx index 647ff5c..a4e7ac2 100644 --- a/components/Transactions/ListView.tsx +++ b/components/Transactions/ListView.tsx @@ -1,27 +1,32 @@ +// React, NextJS imports import React from 'react'; +import { useRouter } from 'next/router'; + +// External Components imports +import { useTheme } from 'styled-components'; + +// Internal Components imports import { Box, Text, Tag, Table } from '../../blocks'; -import { Tick } from '../../blocks/icons' -import { fromNow, capitalizeStr} from '../../utils/helpers' -import { useRouter } from 'next/router' +import { Tick } from '../../blocks/icons'; +import { fromNow, capitalizeStr } from '../../utils/helpers'; import { TagVariant } from '../../blocks/tag'; import { Transaction } from '../../types/transaction'; -import { useTheme } from 'styled-components'; -import Address from '../Reusables/AddressComponent' -import TxHashLink from '../Reusables/TxHashLink' -import BlockHashLink from '../Reusables/BlockHashLink' +import Address from '../Reusables/AddressComponent'; +import TxHashLink from '../Reusables/TxHashLink'; +import BlockHashLink from '../Reusables/BlockHashLink'; interface dataProps { - transactions: Transaction[], - totalPages: number, - lastTs: number + transactions: Transaction[]; + totalPages: number; + lastTs: number; } interface IProps { - data?: dataProps - isLoading?: boolean + data?: dataProps; + isLoading?: boolean; } const ListView = (props: IProps) => { - const router = useRouter() + const router = useRouter(); const theme = useTheme(); const isDarkMode = theme.scheme === 'dark'; @@ -32,91 +37,115 @@ const ListView = (props: IProps) => { { title: 'STATUS', dataIndex: 'status', - render: (status: string) => } label={capitalizeStr(status)} variant={status.toLowerCase() as TagVariant}>, + render: (status: string) => ( + } + label={capitalizeStr(status)} + variant={status.toLowerCase() as TagVariant} + > + ), cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '110px' + width: '110px', }, { title: 'TX HASH', dataIndex: 'txHash', - render: (txHash: string) => , + render: (txHash: string) => , cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '165px' + width: '165px', }, { title: 'BLOCK HASH', dataIndex: 'blockHash', - render: (blockHash: string) => , + render: (blockHash: string) => ( + + ), cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '165px' + width: '165px', }, { title: 'FROM', dataIndex: 'from', - render: (params) => { + render: (params) => { const from = JSON.parse(params); - return
+ return
; }, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '220px' + width: '220px', }, { title: 'TO', dataIndex: 'recipients', render: (recipients: string) => { - const reci = recipients.split(',') + const reci = recipients.split(','); + if (!recipients) return; return ( - -
- { reci.length > 1 && {`+ ${reci.length - 1} more`}} - - )}, + +
+ {reci.length > 1 && ( + {`+ ${ + reci.length - 1 + } more`} + )} + + ); + }, cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '240px' + width: '240px', }, { title: 'CATEGORY', dataIndex: 'category', - render: (category: string) => {category}, + render: (category: string) => ( + + {category} + + ), cellAlignment: 'flex-start', headerAlignment: 'flex-start', - width: '125px' + width: '125px', }, { title: 'AGE', dataIndex: 'ts', - render: (ts: number) => {fromNow(ts)}, + render: (ts: number) => ( + + {fromNow(ts)} + + ), cellAlignment: 'center', headerAlignment: 'center', - width: '75px' + width: '75px', }, ]; - const dataSource = data?.transactions.map((dt) => ({ - id: dt.txnHash, - status: dt.status, - txHash: dt.txnHash, - blockHash: dt.blockHash, - category: dt.category, - from: JSON.stringify({ from: dt.from, source: dt.source }), - recipients: dt.recipients, - ts: dt.ts, - })) || []; - + const dataSource = + data?.transactions.map((dt) => ({ + id: dt.txnHash, + status: dt.status, + txHash: dt.txnHash, + blockHash: dt.blockHash, + category: dt.category, + from: JSON.stringify({ from: dt.from, source: dt.source }), + recipients: dt.recipients, + ts: dt.ts, + })) || []; return ( - -
+ +
); }; -export default ListView; \ No newline at end of file +export default ListView; diff --git a/components/Transactions/TxDetails.tsx b/components/Transactions/TxDetails.tsx index bc1ebce..0591661 100644 --- a/components/Transactions/TxDetails.tsx +++ b/components/Transactions/TxDetails.tsx @@ -7,7 +7,7 @@ import moment from 'moment'; // Internal Components imports import { Box, Text, Tag, Tooltip, Copy } from '../../blocks'; -import { Tick } from '../../blocks/icons'; +import { CopyFilled, Tick, TickCircleFilled } from '../../blocks/icons'; import { TagVariant } from '../../blocks/tag'; import { Transaction } from '../../types/transaction'; import BlockHashLink from '../Reusables/BlockHashLink'; @@ -66,18 +66,26 @@ const TXDetails = (props: IProps) => { alignItems="center" gap="spacing-xxs" > - + {props.data?.txnHash} - copyData(props.data?.txnHash)} - autoSize - size={24} - color="icon-tertiary" - /> + {tooltipText === 'Copied' ? ( + + ) : ( + copyData(props.data?.txnHash)} + autoSize + size={16} + color="icon-tertiary" + /> + )} @@ -140,14 +148,20 @@ const TXDetails = (props: IProps) => { {props.data?.txnHash} - - + ) : ( + copyData(props.data?.txnHash)} autoSize - size={24} + size={16} color="icon-tertiary" /> - + )} @@ -207,7 +221,7 @@ const DetailRow = ({ label, children }) => ( flex: 1; `} > - + {label} diff --git a/components/Transactions/TxTravels.tsx b/components/Transactions/TxTravels.tsx index c44a1bf..02a0b6b 100644 --- a/components/Transactions/TxTravels.tsx +++ b/components/Transactions/TxTravels.tsx @@ -1,213 +1,295 @@ import React, { useState } from 'react'; -import { Add, Box, Text, Tooltip, Copy } from '../../blocks'; +import { + Add, + Box, + Text, + Tooltip, + Copy, + TickCircleFilled, + CopyFilled, +} from '../../blocks'; import { Transaction } from '../../types/transaction'; -import Address from '../Reusables/AddressComponent' +import Address from '../Reusables/AddressComponent'; +import { css } from 'styled-components'; +import { convertCaipToObject } from '../../utils/helpers'; const MAX_DISPLAY = 5; interface IProps { - data: Transaction | null | undefined, - isLoading: boolean + data: Transaction | null | undefined; + isLoading: boolean; } const TxTravels = (props: IProps) => { - const [showAll, setShowAll] = useState(false); - const [tooltipText, setToolTipText] = useState('Copy'); - - const toggleShowAll = () => { - setShowAll(!showAll); - }; - - const recipients = props.data?.recipients?.recipients || []; - const displayedRecipients = showAll ? recipients : recipients.slice(0, MAX_DISPLAY); - const showMoreButton = recipients.length > MAX_DISPLAY; - - const copyData = (value) => { - navigator.clipboard.writeText(value); - setToolTipText('Copied'); - - setTimeout(() => { - setToolTipText('Copy'); - }, 1000); - }; - - return ( - <> - - - From - To - + const [showAll, setShowAll] = useState(false); + const [tooltipText, setToolTipText] = useState('Copy'); - - - -
- - - - copyData(props.data?.from)} - autoSize - size={24} - color="icon-tertiary" - /> - - - - + const toggleShowAll = () => { + setShowAll(!showAll); + }; + + const recipients = props.data?.recipients?.recipients || []; + const displayedRecipients = showAll + ? recipients + : recipients.slice(0, MAX_DISPLAY); + const showMoreButton = recipients.length > MAX_DISPLAY; + + const copyData = (value) => { + const { result } = convertCaipToObject(value); + const addressToCopy = result.address ?? value; + + navigator.clipboard.writeText(addressToCopy); + setToolTipText('Copied'); + + setTimeout(() => { + setToolTipText('Copy'); + }, 1000); + }; + + return ( + <> + + + +
+ + + + {tooltipText === 'Copied' ? ( + + ) : ( + copyData(props.data?.from)} + autoSize + size={16} + color="icon-tertiary" + /> + )} + + + + + + + + {displayedRecipients.map((recipient, index) => ( + +
+ + - {displayedRecipients.map((recipient, index) => ( - -
- - - - copyData(recipient.address)} - autoSize - size={24} - color="icon-tertiary" - /> - - - - - ))} - - {showMoreButton && ( - - - - {showAll ? 'Show Less' : 'Show More'} - - - )} + copyData(recipient.address)} + autoSize + size={16} + color="icon-tertiary" + /> + - + + ))} + + {showMoreButton && ( + + + + {showAll ? 'Show Less' : 'Show More'} + + + )} + + + + + + + From + + - - From - -
- - - - copyData(props.data?.from)} - autoSize - size={24} - color="icon-tertiary" - /> - - - - - +
+ + + + + copyData(props.data?.from)} + autoSize + size={16} + color="icon-tertiary" + /> + + + + + + + To + + + {displayedRecipients.map((recipient, index) => ( + - To +
+ + + - {displayedRecipients.map((recipient, index) => ( - - -
- - - - - copyData(recipient.address)} - autoSize - size={24} - color="icon-tertiary" - /> - - - - - - - ))} - - {showMoreButton && ( - - - - {showAll ? 'Show Less' : 'Show More'} - - - )} + copyData(recipient.address)} + autoSize + size={16} + color="icon-tertiary" + /> + - - - ); + + ))} + + {showMoreButton && ( + + + + {showAll ? 'Show Less' : 'Show More'} + + + )} + + + + + ); }; -export default TxTravels; \ No newline at end of file +export default TxTravels; + +const DetailRow = ({ label, children }) => ( + + + + {label} + + + + {children} + + +); diff --git a/sections/Transactions/index.tsx b/sections/Transactions/index.tsx index 10c213a..ab85aa3 100644 --- a/sections/Transactions/index.tsx +++ b/sections/Transactions/index.tsx @@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'; import { Box, Text, Spinner, Pagination } from '../../blocks'; import ListView from '../../components/Transactions/ListView'; import { useLiveTransactions } from '../../hooks/useLiveTransactions'; -import { PerPageItems } from '../../utils/constants' +import { PerPageItems } from '../../utils/constants'; const Transactions = () => { const [page, setPage] = useState(1); @@ -21,31 +21,28 @@ const Transactions = () => { const totalPages = data?.totalPages ?? cachedTotalPages; return ( - - Transactions + + + Transactions + - { - totalPages > 1 && 1 && ( + setPage(page)} /> - } + )} ); }; -export default Transactions; \ No newline at end of file +export default Transactions; diff --git a/sections/Transactions/txHash.tsx b/sections/Transactions/txHash.tsx index c2cbdf1..664b062 100644 --- a/sections/Transactions/txHash.tsx +++ b/sections/Transactions/txHash.tsx @@ -5,25 +5,25 @@ import { useRouter } from 'next/router'; import { Box, Text, Spinner } from '../../blocks'; import Advanced from '../../components/Reusables/Advanced'; import ConsensusInfo from '../../components/Transactions/ConsensusInfo'; -import TXDetails from '../../components/Transactions/TxDetails' -import TxTravels from '../../components/Transactions/TxTravels' +import TXDetails from '../../components/Transactions/TxDetails'; +import TxTravels from '../../components/Transactions/TxTravels'; import { useLiveTxByHash } from '../../hooks/useLiveTxByHash'; const Details = () => { const router = useRouter(); const { txHash } = router.query; - + const [showConsensusInfo, setConsensusInfo] = useState(false); - - const { data, isLoading } = useLiveTxByHash({ txHash }); - const showLoading = !txHash || isLoading + + const { data, isLoading } = useLiveTxByHash({ txHash }); + const showLoading = !txHash || isLoading; if (showLoading) { return ( - + - ) + ); } return ( @@ -32,27 +32,26 @@ const Details = () => { display="flex" flexDirection="column" justifyContent="flex-start" - gap={{initial: "spacing-sm", ml: "spacing-md"}} + gap={{ initial: 'spacing-sm', ml: 'spacing-md' }} > - Transaction Details - - + Transaction Details + + + + - - { showConsensusInfo && + {showConsensusInfo && ( - } + )} ); }; -export default Details; \ No newline at end of file +export default Details; diff --git a/sections/User/index.tsx b/sections/User/index.tsx index 7dd36c7..64e8c00 100644 --- a/sections/User/index.tsx +++ b/sections/User/index.tsx @@ -1,11 +1,21 @@ import React, { useState } from 'react'; -import { Box, Text, Copy, Tooltip, Spinner, Pagination } from '../../blocks'; +import { + Box, + Text, + Copy, + Tooltip, + Spinner, + Pagination, + TickCircleFilled, + CopyFilled, +} from '../../blocks'; import ListView from '../../components/Transactions/ListView'; import { centerMaskString, convertCaipToObject } from '../../utils/helpers'; -import { useGetTransactionsByUser } from '../../hooks/useGetTransactionsByUser' +import { useGetTransactionsByUser } from '../../hooks/useGetTransactionsByUser'; import { useRouter } from 'next/router'; -import { PerPageItems } from '../../utils/constants' +import { PerPageItems } from '../../utils/constants'; import BlockiesSvg from 'blockies-react-svg'; +import Address from '../../components/Reusables/AddressComponent'; const Search = () => { const router = useRouter(); @@ -13,8 +23,8 @@ const Search = () => { const [tooltipText, setToolTipText] = useState('Copy Address'); const [page, setPage] = useState(1); - - address = Array.isArray(address) ? address[0] : address + + address = Array.isArray(address) ? address[0] : address; const copyAddress = () => { if (address) { @@ -26,32 +36,30 @@ const Search = () => { }, 1000); }; - const { data, isLoading } = useGetTransactionsByUser({ address, page: page }) - - const showLoading = !address || isLoading - - + const { data, isLoading } = useGetTransactionsByUser({ address, page: page }); + + const showLoading = !address || isLoading; + if (showLoading) { return ( - + - ) + ); } // address = address && convertCaipToObject(address).result.address - + if (!address) { - return null + return null; } + const { result } = convertCaipToObject(address); + const maskedAddress = result.address; + + const showPagination = data?.totalPages > 1; return ( - + { gap="spacing-md" > - Address + + Address + { alignItems="center" > - + - {address} + + {maskedAddress} + - - + {tooltipText === 'Copied' ? ( + + ) : ( + + )} - Transactions for {centerMaskString(address)} + + + + + + + Address + + + + + + {maskedAddress} + + + + {tooltipText === 'Copied' ? ( + + ) : ( + + )} + + + + + + Transactions for {centerMaskString(maskedAddress)} + - - setPage(page)} - /> - + {showPagination && ( + + setPage(page)} + /> + + )} - ); }; -export default Search; \ No newline at end of file +export default Search; From 6ca97f9ae7b8e85a1105349ab391714fd4dc2280 Mon Sep 17 00:00:00 2001 From: abhishek-01k Date: Wed, 23 Oct 2024 15:31:54 +0530 Subject: [PATCH 36/42] Changed the time interval from 30s to 5s --- utils/constants.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/constants.js b/utils/constants.js index e868e20..41fd245 100644 --- a/utils/constants.js +++ b/utils/constants.js @@ -8,7 +8,7 @@ import ArbitrumIcon from '../public/static/arbitrum.svg'; import FuseIcon from '../public/static/fuse.svg'; import CyberIcon from '../public/static/cyber.svg'; -export const POLL_INTERVAL = 30 * 1000 // 30 seconds +export const POLL_INTERVAL = 5 * 1000 // 5 seconds export const PerPageItems = 15 export const ROUTES = { From b2b9ddca4cba42fedcfc492bde310dd5cde90e67 Mon Sep 17 00:00:00 2001 From: abhishek-01k Date: Wed, 23 Oct 2024 20:21:43 +0530 Subject: [PATCH 37/42] Fixed the consensus info in the advanced section --- utils/helpers.ts | 158 ++++++++++++++++++++++++----------------------- 1 file changed, 81 insertions(+), 77 deletions(-) diff --git a/utils/helpers.ts b/utils/helpers.ts index a9cc7a5..9283210 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -2,8 +2,8 @@ import { format, formatDistanceToNow } from 'date-fns'; import { replace } from 'lodash'; import numeral from 'numeral'; -import { Signer } from '../types/block' -import { ethers } from 'ethers' +import { Signer } from '../types/block'; +import { ethers } from 'ethers'; export function fDate(date) { return format(new Date(date), 'dd MMMM yyyy'); @@ -68,13 +68,15 @@ export default function getDatesArray({ return dateArray; } -export function isErrorWithMessage(error: unknown): error is { message: string } { +export function isErrorWithMessage( + error: unknown +): error is { message: string } { return typeof error === 'object' && error !== null && 'message' in error; } export function getValidatorNode(blockDataAsJson) { - const nodes = buildNodeVotes(blockDataAsJson) - return nodes[0]?.node ?? "" + const nodes = buildNodeVotes(blockDataAsJson); + return nodes[0]?.node ?? ''; } export function centerMaskString(str, len = 15) { @@ -90,9 +92,9 @@ export function centerMaskString(str, len = 15) { export function rightMaskString(str, len = 13) { // Check if the string length is more than 15 to mask the remaining characters if (str && str.length > len) { - const visiblePart = str.substring(0, len); - const maskedPart = '...'; - return visiblePart + maskedPart; + const visiblePart = str.substring(0, len); + const maskedPart = '...'; + return visiblePart + maskedPart; } // If the string is too short to mask after 15 characters, return it as is return str; @@ -103,86 +105,87 @@ export function capitalizeStr(string) { return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); } -export const convertCaipToAddress = function (addressinCAIP: string): string | null { - const addressComponent = addressinCAIP.split(':') - if ( - addressComponent.length === 3 && - addressComponent[0] === 'eip155' - ) { - return addressComponent[2] +export const convertCaipToAddress = function ( + addressinCAIP: string +): string | null { + const addressComponent = addressinCAIP.split(':'); + if (addressComponent.length === 3 && addressComponent[0] === 'eip155') { + return addressComponent[2]; } // Wallet can be in the new caip10 format used in w2w: eip155:walletAddress - else if ( - addressComponent.length === 2 && - addressComponent[0] === 'eip155' - ) { - return addressComponent[1] + else if (addressComponent.length === 2 && addressComponent[0] === 'eip155') { + return addressComponent[1]; } else { - return addressinCAIP + return addressinCAIP; } -} +}; export function isValidAddress(address: string): boolean { - return ethers.isAddress(address.toLowerCase()) + return ethers.isAddress(address.toLowerCase()); } export const caip10ToWallet = (wallet: string) => { if (wallet.split(':').length === 2) { - wallet = wallet.replace('eip155:', '') - return isValidAddress(wallet) ? wallet : null + wallet = wallet.replace('eip155:', ''); + return isValidAddress(wallet) ? wallet : null; } else { - return null + return null; } -} +}; -export const convertCaipToObject = (addressinCAIP: string): { - result: { chainId: string | null; chain: string | null; address: string | null } +export const convertCaipToObject = ( + addressinCAIP: string +): { + result: { + chainId: string | null; + chain: string | null; + address: string | null; + }; } => { - // Check if the input is a valid non-empty string - if (!addressinCAIP || typeof addressinCAIP !== 'string') { - return { - result: { - chain: null, - chainId: null, - address: null, - }, - }; - } - - const addressComponent = addressinCAIP.split(':'); - - // Handle cases where there are exactly three components (chain, chainId, address) - if (addressComponent.length === 3) { - return { - result: { - chain: addressComponent[0], - chainId: addressComponent[1], - address: addressComponent[2], - }, - }; - } - // Handle cases where there are exactly two components (chain, address) - else if (addressComponent.length === 2) { - return { - result: { - chain: addressComponent[0], - chainId: null, - address: addressComponent[1], - }, - }; - } - // If the input doesn't match the expected format, return the address only - else { - return { - result: { - chain: null, - chainId: null, - address: addressinCAIP, - }, - }; - } -}; + // Check if the input is a valid non-empty string + if (!addressinCAIP || typeof addressinCAIP !== 'string') { + return { + result: { + chain: null, + chainId: null, + address: null, + }, + }; + } + const addressComponent = addressinCAIP.split(':'); + + // Handle cases where there are exactly three components (chain, chainId, address) + if (addressComponent.length === 3) { + return { + result: { + chain: addressComponent[0], + chainId: addressComponent[1], + address: addressComponent[2], + }, + }; + } + // Handle cases where there are exactly two components (chain, address) + else if (addressComponent.length === 2) { + return { + result: { + chain: addressComponent[0], + chainId: null, + address: addressComponent[1], + }, + }; + } + // If the input doesn't match the expected format, return the address only + else { + return { + result: { + chain: null, + chainId: null, + address: addressinCAIP, + }, + }; + } +}; export const fromNow = (timestamp: number): string => { const now = Date.now(); @@ -219,7 +222,7 @@ export const fromNow = (timestamp: number): string => { const diffInYears = Math.floor(diffInMonths / 12); return `${diffInYears}y ago`; -} +}; function generateRandomHash() { const randomPart = Math.random().toString(16).substr(2, 8); // 8 random hex characters @@ -234,18 +237,19 @@ interface Vote { } // Function to decode a base64 string -const decodeBase64 = (data: string) => atob(data) +const decodeBase64 = (data: string) => atob(data); // Function to calculate votes and build the result array export const buildNodeVotes = (blockDataAsJson: any): Vote[] => { try { // Step 1: Base64 decode the attesttoken and then JWT decode it - const decodedBase64 = decodeBase64(decodeBase64(blockDataAsJson.attesttoken)); + const decodedBase64 = decodeBase64( + decodeBase64(blockDataAsJson.attesttoken).slice(3) + ); // Retrieve the nodes array from the decoded JWT const nodes = JSON.parse(decodedBase64).nodes; - // Step 2: Initialize the votes array with the correct type const votes: Vote[] = []; From 72dadb713b4d130bfeafdac1eddfc3018779aed1 Mon Sep 17 00:00:00 2001 From: rozaso Date: Thu, 24 Oct 2024 06:49:07 -0700 Subject: [PATCH 38/42] fix: Test commit to trigger deploy. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b72a328..cb9ba91 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ src="https://res.cloudinary.com/drdjegqln/image/upload/v1686227558/Push-Logo-Sta


-Push Analytics

+Push Analytics and Push Scan

Push Analytics Dashboard is a comprehensive tool designed to provide in-depth insights into the performance and usage of the Push Protocol. This repository hosts the code that powers the analytics component of the Push Protocol, offering a detailed view of various metrics such as the number of subscribers, notifications, channels, and more. The dashboard is an essential tool for understanding the reach and impact of the Push Protocol, providing valuable data that can help guide future development and improvements. The dashboard is designed with a user-friendly interface, making it easy to navigate and understand the data presented. It provides real-time updates, ensuring you have the most accurate and up-to-date information at your fingertips. Whether you're a developer looking to monitor the performance of your channels, or a user interested in understanding more about your subscriptions, the Push Analytics Dashboard is a powerful resource for all things related to the Push Protocol.

From 68f814108422d0aeead912c2447c9e11aa0d3b3c Mon Sep 17 00:00:00 2001 From: abhishek-01k Date: Thu, 24 Oct 2024 20:43:29 +0530 Subject: [PATCH 39/42] Fixed client side error UI breaking page --- components/Blocks/ListView.tsx | 7 +-- components/Reusables/AddressComponent.tsx | 14 +++--- components/Transactions/ListView.tsx | 22 ++++++--- components/Transactions/TxTravels.tsx | 60 ++++++++++++++++------- 4 files changed, 67 insertions(+), 36 deletions(-) diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx index 1d914c7..653408c 100644 --- a/components/Blocks/ListView.tsx +++ b/components/Blocks/ListView.tsx @@ -10,6 +10,7 @@ import { } from '../../utils/helpers'; import { useTheme } from 'styled-components'; import BlockHashLink from '../Reusables/BlockHashLink'; +import Address from '../Reusables/AddressComponent'; const Blocks = () => { const router = useRouter(); @@ -33,11 +34,7 @@ const Blocks = () => { { title: 'VALIDATOR', dataIndex: 'validator', - render: (text) => ( - - {centerMaskString(text)} - - ), + render: (text) =>
, cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '310px', diff --git a/components/Reusables/AddressComponent.tsx b/components/Reusables/AddressComponent.tsx index ceceb02..604eebe 100644 --- a/components/Reusables/AddressComponent.tsx +++ b/components/Reusables/AddressComponent.tsx @@ -18,14 +18,14 @@ const Address = ({ allowCopy = false, }) => { function getChainIcon(chainId) { - try { - if (!chainId) { - return ; - } - - const IconComponent = CHAIN_LOGO[chainId]; + if (!chainId) { + return ; + } + const IconComponent = CHAIN_LOGO[chainId]; + if (IconComponent) { return ; - } catch (err) { + } else { + // TO Bypass some test cases addresses return ; } } diff --git a/components/Transactions/ListView.tsx b/components/Transactions/ListView.tsx index a4e7ac2..29b3da8 100644 --- a/components/Transactions/ListView.tsx +++ b/components/Transactions/ListView.tsx @@ -101,11 +101,21 @@ const ListView = (props: IProps) => { { title: 'CATEGORY', dataIndex: 'category', - render: (category: string) => ( - - {category} - - ), + render: (category: string) => { + const customPrefix = 'CUSTOM:'; + if (category.startsWith(customPrefix)) { + return ( + + {category.replace(customPrefix, '')} + + ); + } + return ( + + {category} + + ); + }, cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '125px', @@ -137,7 +147,7 @@ const ListView = (props: IProps) => { })) || []; return ( - +
{ justifyContent="flex-end" cursor="pointer" > - copyData(recipient.address)} - autoSize - size={16} - color="icon-tertiary" - /> + {tooltipText === 'Copied' ? ( + + ) : ( + copyData(recipient.address)} + autoSize + size={16} + color="icon-tertiary" + /> + )} @@ -183,12 +191,20 @@ const TxTravels = (props: IProps) => { - copyData(props.data?.from)} - autoSize - size={16} - color="icon-tertiary" - /> + {tooltipText === 'Copied' ? ( + + ) : ( + copyData(props.data?.from)} + autoSize + size={16} + color="icon-tertiary" + /> + )} @@ -232,12 +248,20 @@ const TxTravels = (props: IProps) => { justifyContent="flex-end" cursor="pointer" > - copyData(recipient.address)} - autoSize - size={16} - color="icon-tertiary" - /> + {tooltipText === 'Copied' ? ( + + ) : ( + copyData(recipient.address)} + autoSize + size={16} + color="icon-tertiary" + /> + )} From 9816daddc33d605212e73945feec1f0ef3917c25 Mon Sep 17 00:00:00 2001 From: rozaso Date: Thu, 24 Oct 2024 08:57:27 -0700 Subject: [PATCH 40/42] Test commit. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cb9ba91..eff1d2f 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ src="https://res.cloudinary.com/drdjegqln/image/upload/v1686227558/Push-Logo-Sta


-Push Analytics and Push Scan

+Push Analytics and Push Scan

Push Analytics Dashboard is a comprehensive tool designed to provide in-depth insights into the performance and usage of the Push Protocol. This repository hosts the code that powers the analytics component of the Push Protocol, offering a detailed view of various metrics such as the number of subscribers, notifications, channels, and more. The dashboard is an essential tool for understanding the reach and impact of the Push Protocol, providing valuable data that can help guide future development and improvements. The dashboard is designed with a user-friendly interface, making it easy to navigate and understand the data presented. It provides real-time updates, ensuring you have the most accurate and up-to-date information at your fingertips. Whether you're a developer looking to monitor the performance of your channels, or a user interested in understanding more about your subscriptions, the Push Analytics Dashboard is a powerful resource for all things related to the Push Protocol.

From 33ef3c423771f37cb4393c6c0863f2300d3d26e4 Mon Sep 17 00:00:00 2001 From: abhishek-01k Date: Fri, 25 Oct 2024 15:22:23 +0530 Subject: [PATCH 41/42] Added support for responsiveness and fixed the age category --- components/Blocks/BlockTxDetails.tsx | 157 +++--- components/Blocks/ConsensusInfo.tsx | 62 ++- components/Blocks/Details.tsx | 8 +- components/Blocks/ListView.tsx | 15 +- components/Home/LiveBlocks.tsx | 8 +- components/Home/LiveTransactions.tsx | 5 +- components/Home/OverView.tsx | 7 +- components/Reusables/Advanced.tsx | 3 + components/Transactions/ConsensusInfo.tsx | 557 ++++++++++++---------- components/Transactions/TxDetails.tsx | 8 +- components/Transactions/TxTravels.tsx | 8 +- pages/blocks/[blockHash].tsx | 14 +- pages/blocks/index.tsx | 6 +- pages/home/index.tsx | 7 +- pages/transactions/[txHash].tsx | 14 +- pages/users/[address].tsx | 5 +- sections/Blocks/blockHash.tsx | 42 +- sections/Blocks/index.tsx | 16 +- sections/Home/index.tsx | 22 +- sections/Transactions/txHash.tsx | 3 +- sections/User/index.tsx | 11 +- utils/helpers.ts | 2 +- 22 files changed, 573 insertions(+), 407 deletions(-) diff --git a/components/Blocks/BlockTxDetails.tsx b/components/Blocks/BlockTxDetails.tsx index 0f7ca62..ff67c69 100644 --- a/components/Blocks/BlockTxDetails.tsx +++ b/components/Blocks/BlockTxDetails.tsx @@ -1,76 +1,103 @@ +// React, NextJS imports import React from 'react'; + +// External Components imports +import { css } from 'styled-components'; + +// Internal Components imports import { Box, Text } from '../../blocks'; -import { BlockDetails } from '../../types/block' +import { BlockDetails } from '../../types/block'; interface IProps { - data: BlockDetails | null | undefined, - isLoading: boolean + data: BlockDetails | null | undefined; + isLoading: boolean; } const BlockTXDetails = (props: IProps) => { - return ( - <> - - - Transactions - Block Size - - - - { props.data?.totalNumberOfTxns } - { props.data?.blockSize } - - + return ( + <> + + + <> + + {props.data?.totalNumberOfTxns} + + + + + <> + + {props.data?.blockSize.toLocaleString()} + + + + - - - Transactions - { props.data?.totalNumberOfTxns } - + + + + Transactions + + + {props.data?.totalNumberOfTxns} + + - - - Block Size - { props.data?.blockSize } - - - - ); + + + Block Size + + + {props.data?.blockSize.toLocaleString()} + + + + + ); }; -export default BlockTXDetails; \ No newline at end of file +export default BlockTXDetails; + +const DetailRow = ({ label, children }) => ( + + + + {label} + + + + {children} + + +); diff --git a/components/Blocks/ConsensusInfo.tsx b/components/Blocks/ConsensusInfo.tsx index 5c44222..08c9214 100644 --- a/components/Blocks/ConsensusInfo.tsx +++ b/components/Blocks/ConsensusInfo.tsx @@ -1,9 +1,14 @@ +// React, NextJS imports import React, { useState } from 'react'; + +// External Components imports +import { css } from 'styled-components'; + +// Internal Components imports import { Box, Text, Tooltip, Copy } from '../../blocks'; import { BlockDetails } from '../../types/block'; import { buildNodeVotes } from '../../utils/helpers'; import { PushMonotone } from '../../blocks/icons'; -import { css } from 'styled-components'; interface IProps { data: BlockDetails | null | undefined; @@ -59,26 +64,40 @@ const ConsensusInfo = (props: IProps) => { padding="spacing-md" gap="spacing-md" > - - + + Consensus Info - + {displayedNodes.map((node, index) => ( - - - - {node.node} - + + + + + {node.node} + + ))} @@ -99,8 +118,13 @@ const ConsensusInfo = (props: IProps) => { - - + + Payload Data @@ -113,10 +137,12 @@ const ConsensusInfo = (props: IProps) => { borderRadius="radius-xs" padding="spacing-sm" width="100%" - maxWidth="750px" /* Adjust as per your layout */ maxHeight="196px" overflow="auto" customScrollbar + css={css` + flex: 3; + `} > { > <> - + {props.data?.blockHash} diff --git a/components/Blocks/ListView.tsx b/components/Blocks/ListView.tsx index 653408c..355e2cc 100644 --- a/components/Blocks/ListView.tsx +++ b/components/Blocks/ListView.tsx @@ -1,14 +1,15 @@ +// React, NextJS imports import React, { useState, useEffect } from 'react'; +import { useRouter } from 'next/router'; + +// External Components imports +import { useTheme } from 'styled-components'; + +// Internal Components imports import { Box, Text, Table, Pagination } from '../../blocks'; import { useLiveBlocks } from '../../hooks/useBlocks'; import { PerPageItems } from '../../utils/constants'; -import { useRouter } from 'next/router'; -import { - getValidatorNode, - fromNow, - centerMaskString, -} from '../../utils/helpers'; -import { useTheme } from 'styled-components'; +import { getValidatorNode, fromNow } from '../../utils/helpers'; import BlockHashLink from '../Reusables/BlockHashLink'; import Address from '../Reusables/AddressComponent'; diff --git a/components/Home/LiveBlocks.tsx b/components/Home/LiveBlocks.tsx index d2c95e1..f2dc535 100644 --- a/components/Home/LiveBlocks.tsx +++ b/components/Home/LiveBlocks.tsx @@ -80,7 +80,13 @@ export default function LiveBlocks() { })) || []; return ( - + Live Blocks diff --git a/components/Home/LiveTransactions.tsx b/components/Home/LiveTransactions.tsx index bc6726a..17f9142 100644 --- a/components/Home/LiveTransactions.tsx +++ b/components/Home/LiveTransactions.tsx @@ -5,7 +5,7 @@ import { useRouter } from 'next/router'; // External imports import moment from 'moment'; -import { useTheme } from 'styled-components'; +import { css, useTheme } from 'styled-components'; // Internal imports import { Box, Text, Front, Tag, Table } from '../../blocks'; @@ -105,10 +105,11 @@ export default function LiveTransactions() { return ( Live Transactions diff --git a/components/Home/OverView.tsx b/components/Home/OverView.tsx index 6cbc92d..8544eea 100644 --- a/components/Home/OverView.tsx +++ b/components/Home/OverView.tsx @@ -1,6 +1,11 @@ +// React, NextJS imports import React, { FC } from 'react'; + +// External Components imports import { css } from 'styled-components'; -import { Box, Text, Separator, Skeleton } from '../../blocks'; + +// Internal Components imports +import { Box, Text, Skeleton } from '../../blocks'; import { useCounts } from '../../hooks/useCounts'; export type OverViewProps = {}; diff --git a/components/Reusables/Advanced.tsx b/components/Reusables/Advanced.tsx index 18a4785..dd5bbf1 100644 --- a/components/Reusables/Advanced.tsx +++ b/components/Reusables/Advanced.tsx @@ -1,4 +1,7 @@ +// React, NextJS imports import React from 'react'; + +// Internal Components imports import { Box, Text, CaretDown, CaretUp } from '../../blocks'; interface IProps { diff --git a/components/Transactions/ConsensusInfo.tsx b/components/Transactions/ConsensusInfo.tsx index ec4c76e..ec07eca 100644 --- a/components/Transactions/ConsensusInfo.tsx +++ b/components/Transactions/ConsensusInfo.tsx @@ -1,287 +1,344 @@ +// React, NextJS imports import React, { useState } from 'react'; -import { Box, Text, Tooltip, Copy, Tag } from '../../blocks'; + +// External Components imports +import { css } from 'styled-components'; + +// Internal Components imports +import { + Box, + Text, + Tooltip, + Copy, + Tag, + PushMonotone, + Tick, +} from '../../blocks'; import { Transaction } from '../../types/transaction'; import { BlockDetails } from '../../types/block'; -import { Tick } from '../../blocks/icons' -import { buildNodeVotes } from '../../utils/helpers' -import { PushMonotone } from '../../blocks/icons' +import { buildNodeVotes } from '../../utils/helpers'; interface IProps { - blockDetails: BlockDetails | null | undefined, - transaction: Transaction | null | undefined, - isLoading: boolean + blockDetails: BlockDetails | null | undefined; + transaction: Transaction | null | undefined; + isLoading: boolean; } -const MAX_DISPLAY_NODES = 5;4 +const MAX_DISPLAY_NODES = 5; const MAX_DISPLAY_CHARS = 700; const ConsensusInfo = (props: IProps) => { - const [showAll, setShowAll] = useState(false); - const [showAllPayload, setShowAllPayload] = useState(false); - const [tooltipText, setToolTipText] = useState('Copy Payload'); + const [showAll, setShowAll] = useState(false); + const [showAllPayload, setShowAllPayload] = useState(false); + const [tooltipText, setToolTipText] = useState('Copy Payload'); + + const toggleShowAll = () => { + setShowAll(!showAll); + }; - const toggleShowAll = () => { - setShowAll(!showAll); - }; + const toggleShowAllPayload = () => { + setShowAllPayload(!showAllPayload); + }; - const toggleShowAllPayload = () => { - setShowAllPayload(!showAllPayload); - }; + const nodes = buildNodeVotes(props.blockDetails?.blockDataAsJson); - const nodes = buildNodeVotes(props.blockDetails?.blockDataAsJson) + const displayedNodes = showAll ? nodes : nodes.slice(0, MAX_DISPLAY_NODES); + const showMoreButton = nodes.length > MAX_DISPLAY_NODES; + const payload = props.transaction?.txnData || ''; + const displayedPayload = showAllPayload + ? payload + : payload.substring(0, MAX_DISPLAY_CHARS); + const showMorePayloadButton = payload.length > MAX_DISPLAY_CHARS; + const copyPayload = () => { + if (payload) { + navigator.clipboard.writeText(payload); + setToolTipText('Copied'); + } + setTimeout(() => { + setToolTipText('Copy Payload'); + }, 1000); + }; - const displayedNodes = showAll ? nodes : nodes.slice(0, MAX_DISPLAY_NODES); - const showMoreButton = nodes.length > MAX_DISPLAY_NODES; - const payload = props.transaction?.txnData || ""; - const displayedPayload = showAllPayload ? payload : payload.substring(0, MAX_DISPLAY_CHARS); - const showMorePayloadButton = payload.length > MAX_DISPLAY_CHARS; + return ( + <> + + + + + Consensus Info + + + + {displayedNodes.map((node, index) => ( + + + + + + {node.node} + + + } + label={`${node.vote}`} + variant={node.vote === 'Accepted' ? 'success' : 'danger'} + > + + + ))} - const copyPayload = () => { - if (payload) { - navigator.clipboard.writeText(payload); - setToolTipText('Copied'); - } - setTimeout(() => { - setToolTipText('Copy Payload'); - }, 1000); - }; + {showMoreButton && ( + + + {showAll ? 'Show Less' : 'Show More'} + + + )} + + - return ( - <> + {displayedPayload && ( + + + Payload Data + + + + + {displayedPayload} + + + {showMorePayloadButton && ( + + {showAllPayload ? 'Show Less' : 'Show More'} + + + )} + + + + + + + + + + )} + + + + + + + Consensus Info + + + + {displayedNodes.map((node, index) => ( + + + + - - Consensus Info - - - {displayedNodes.map((node, index) => ( - - - {node.node} - }label={`${node.vote}`} variant={node.vote === 'Accepted' ? 'success' : 'danger'}> - - ))} - - {showMoreButton && ( - - - {showAll ? 'Show Less' : 'Show More'} - - - )} - + + {node.node} + - { displayedPayload && - - - Payload Data - - - - - {displayedPayload} - + + } + label={`${node.vote}`} + variant={node.vote === 'Accepted' ? 'success' : 'danger'} + > + + + ))} - {showMorePayloadButton && ( - - - {showAllPayload ? "Show Less" : "Show More"} - - - )} - - - - - - - - - } - + {showMoreButton && ( + + + {showAll ? 'Show Less' : 'Show More'} + + + )} + + + {displayedPayload && ( + + + + Payload Data + + + + {displayedPayload} + + + {showMorePayloadButton && ( - - Consensus Info - - - {displayedNodes.map((node, index) => ( - - - - - - {node.node} - - - - - }label={`${node.vote}`} variant={node.vote === 'Accepted' ? 'success' : 'danger'}> - - - - ))} - - {showMoreButton && ( - - - {showAll ? 'Show Less' : 'Show More'} - - - )} - + + {showAllPayload ? 'Show Less' : 'Show More'} + - - { displayedPayload && - - - Payload Data - - + )} + {displayedPayload && ( + + - - {displayedPayload} - - - {showMorePayloadButton && ( - - - {showAllPayload ? "Show Less" : "Show More"} - - - )} - { displayedPayload && - - - - - - } + - } + + + )} - - ); + + )} + + + ); }; -export default ConsensusInfo; \ No newline at end of file +export default ConsensusInfo; diff --git a/components/Transactions/TxDetails.tsx b/components/Transactions/TxDetails.tsx index 0591661..86f701f 100644 --- a/components/Transactions/TxDetails.tsx +++ b/components/Transactions/TxDetails.tsx @@ -66,7 +66,13 @@ const TXDetails = (props: IProps) => { alignItems="center" gap="spacing-xxs" > - + {props.data?.txnHash} diff --git a/components/Transactions/TxTravels.tsx b/components/Transactions/TxTravels.tsx index 8fa74e6..c844bba 100644 --- a/components/Transactions/TxTravels.tsx +++ b/components/Transactions/TxTravels.tsx @@ -1,16 +1,20 @@ +// React, NextJS imports import React, { useState } from 'react'; + +// External Components imports +import { css } from 'styled-components'; + +// Internal Components imports import { Add, Box, Text, Tooltip, - Copy, TickCircleFilled, CopyFilled, } from '../../blocks'; import { Transaction } from '../../types/transaction'; import Address from '../Reusables/AddressComponent'; -import { css } from 'styled-components'; import { convertCaipToObject } from '../../utils/helpers'; const MAX_DISPLAY = 5; diff --git a/pages/blocks/[blockHash].tsx b/pages/blocks/[blockHash].tsx index 53d78c3..ae62fd0 100644 --- a/pages/blocks/[blockHash].tsx +++ b/pages/blocks/[blockHash].tsx @@ -1,13 +1,19 @@ +// React, NextJS imports import React from 'react'; import dynamic from 'next/dynamic'; import Head from 'next/head'; -import { Spinner } from '../../blocks' + +// Internal Components imports +import { Spinner } from '../../blocks'; const Layout = dynamic(() => import('../../layout')); -const BlocksDetailsView = dynamic(() => import('../../sections/Blocks/blockHash'), { - loading: () => , -}); +const BlocksDetailsView = dynamic( + () => import('../../sections/Blocks/blockHash'), + { + loading: () => , + } +); const BlocksDetailsPage = () => { return ( diff --git a/pages/blocks/index.tsx b/pages/blocks/index.tsx index fb75278..aed72d0 100644 --- a/pages/blocks/index.tsx +++ b/pages/blocks/index.tsx @@ -2,10 +2,12 @@ import React from 'react'; import Head from 'next/head'; import dynamic from 'next/dynamic'; -import { Spinner } from '../../blocks' + +// Internal Components imports +import { Spinner } from '../../blocks'; const BlocksView = dynamic(() => import('../../sections/Blocks'), { - loading: () => , + loading: () => , }); const Layout = dynamic(() => import('../../layout')); diff --git a/pages/home/index.tsx b/pages/home/index.tsx index a6d706a..308dffd 100644 --- a/pages/home/index.tsx +++ b/pages/home/index.tsx @@ -1,10 +1,13 @@ +// React, NextJS imports import React from 'react'; import Head from 'next/head'; import dynamic from 'next/dynamic'; -import { Spinner } from '../../blocks' + +// Internal Components imports +import { Spinner } from '../../blocks'; const HomeView = dynamic(() => import('../../sections/Home'), { - loading: () => , + loading: () => , }); const Layout = dynamic(() => import('../../layout')); diff --git a/pages/transactions/[txHash].tsx b/pages/transactions/[txHash].tsx index 9b752e8..04ad3a1 100644 --- a/pages/transactions/[txHash].tsx +++ b/pages/transactions/[txHash].tsx @@ -1,13 +1,19 @@ +// React, NextJS imports import React from 'react'; import dynamic from 'next/dynamic'; import Head from 'next/head'; -import { Spinner } from '../../blocks' + +// Internal Components imports +import { Spinner } from '../../blocks'; const Layout = dynamic(() => import('../../layout')); -const TransactionDetailsView = dynamic(() => import('../../sections/Transactions/txHash'), { - loading: () => , -}); +const TransactionDetailsView = dynamic( + () => import('../../sections/Transactions/txHash'), + { + loading: () => , + } +); const TransactionDetailsPage = () => { return ( diff --git a/pages/users/[address].tsx b/pages/users/[address].tsx index 4bd6d38..c01581b 100644 --- a/pages/users/[address].tsx +++ b/pages/users/[address].tsx @@ -2,11 +2,12 @@ import React, { useEffect, useState } from 'react'; import Head from 'next/head'; import dynamic from 'next/dynamic'; + import { Spinner, Box } from '../../blocks'; const UserTransactionsView = dynamic(() => import('../../sections/User'), { - loading: () => - }); + loading: () => , +}); const Layout = dynamic(() => import('../../layout')); diff --git a/sections/Blocks/blockHash.tsx b/sections/Blocks/blockHash.tsx index 98a8074..e7d154a 100644 --- a/sections/Blocks/blockHash.tsx +++ b/sections/Blocks/blockHash.tsx @@ -1,11 +1,14 @@ +// React, NextJS imports import React, { useState } from 'react'; +import { useRouter } from 'next/router'; + +// Internal Components imports import { Box, Text, Spinner } from '../../blocks'; import Advanced from '../../components/Reusables/Advanced'; import ConsensusInfo from '../../components/Blocks/ConsensusInfo'; -import BlockDetails from '../../components/Blocks/Details' -import BlockTxDetails from '../../components/Blocks/BlockTxDetails' +import BlockDetails from '../../components/Blocks/Details'; +import BlockTxDetails from '../../components/Blocks/BlockTxDetails'; import { useLiveBlockByHash } from '../../hooks/useLiveBlockByHash'; -import { useRouter } from 'next/router'; const Details = () => { const router = useRouter(); @@ -14,14 +17,14 @@ const Details = () => { const [showConsensusInfo, setConsensusInfo] = useState(false); const { data, isLoading } = useLiveBlockByHash({ blockHash }); - const showLoading = !blockHash || isLoading + const showLoading = !blockHash || isLoading; if (showLoading) { return ( - + - ) + ); } return ( @@ -32,24 +35,21 @@ const Details = () => { justifyContent="flex-start" gap="spacing-sm" > - Block Details - - + Block Details + + + + - - { showConsensusInfo && - } + {showConsensusInfo && ( + + )} ); }; -export default Details; \ No newline at end of file +export default Details; diff --git a/sections/Blocks/index.tsx b/sections/Blocks/index.tsx index dc1700e..aa1daf4 100644 --- a/sections/Blocks/index.tsx +++ b/sections/Blocks/index.tsx @@ -1,19 +1,19 @@ +// React, NextJS imports import React from 'react'; + +// Internal Components imports import { Box, Text } from '../../blocks'; import BlocksListView from '../../components/Blocks/ListView'; const Blocks = () => { return ( - - Blocks + + + Blocks + ); }; -export default Blocks; \ No newline at end of file +export default Blocks; diff --git a/sections/Home/index.tsx b/sections/Home/index.tsx index 021d4ab..2ec65dc 100644 --- a/sections/Home/index.tsx +++ b/sections/Home/index.tsx @@ -3,10 +3,10 @@ import React from 'react'; // Internal Components imports import { Box, Text } from '../../blocks'; -import SearchBar from '../../components/Home/SearchBar' -import OverView from '../../components/Home/OverView' -import LiveBlocks from '../../components/Home/LiveBlocks' -import LiveTransactions from '../../components/Home/LiveTransactions' +import SearchBar from '../../components/Home/SearchBar'; +import OverView from '../../components/Home/OverView'; +import LiveBlocks from '../../components/Home/LiveBlocks'; +import LiveTransactions from '../../components/Home/LiveTransactions'; const Home = () => { return ( @@ -17,11 +17,13 @@ const Home = () => { gap="spacing-xxxl" > - Push Blockchain Explorer + + Push Blockchain Explorer + @@ -30,15 +32,15 @@ const Home = () => { flexDirection="column" justifyContent="flex-start" alignItems="flex-start" - gap={{ ml: "spacing-lg", initial: "spacing-xxl" }} + gap={{ ml: 'spacing-lg', initial: 'spacing-xxl' }} > @@ -48,4 +50,4 @@ const Home = () => { ); }; -export default Home; \ No newline at end of file +export default Home; diff --git a/sections/Transactions/txHash.tsx b/sections/Transactions/txHash.tsx index 664b062..2a871c0 100644 --- a/sections/Transactions/txHash.tsx +++ b/sections/Transactions/txHash.tsx @@ -1,7 +1,8 @@ +// React, NextJS imports import React, { useState } from 'react'; - import { useRouter } from 'next/router'; +// Internal Components imports import { Box, Text, Spinner } from '../../blocks'; import Advanced from '../../components/Reusables/Advanced'; import ConsensusInfo from '../../components/Transactions/ConsensusInfo'; diff --git a/sections/User/index.tsx b/sections/User/index.tsx index 64e8c00..c811605 100644 --- a/sections/User/index.tsx +++ b/sections/User/index.tsx @@ -1,8 +1,14 @@ +// React, NextJS imports import React, { useState } from 'react'; +import { useRouter } from 'next/router'; + +// External Components imports +import BlockiesSvg from 'blockies-react-svg'; + +// Internal Components imports import { Box, Text, - Copy, Tooltip, Spinner, Pagination, @@ -12,10 +18,7 @@ import { import ListView from '../../components/Transactions/ListView'; import { centerMaskString, convertCaipToObject } from '../../utils/helpers'; import { useGetTransactionsByUser } from '../../hooks/useGetTransactionsByUser'; -import { useRouter } from 'next/router'; import { PerPageItems } from '../../utils/constants'; -import BlockiesSvg from 'blockies-react-svg'; -import Address from '../../components/Reusables/AddressComponent'; const Search = () => { const router = useRouter(); diff --git a/utils/helpers.ts b/utils/helpers.ts index 9283210..5545835 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -215,7 +215,7 @@ export const fromNow = (timestamp: number): string => { return `${diffInWeeks}w ago`; } - const diffInMonths = Math.floor(diffInDays / 30); + const diffInMonths = Math.floor(diffInWeeks / 4); if (diffInMonths < 12) { return `${diffInMonths}m ago`; } From 5459bf1a898494ee8be04edd7226da21a7392cdd Mon Sep 17 00:00:00 2001 From: abhishek-01k Date: Sat, 2 Nov 2024 21:54:34 +0530 Subject: [PATCH 42/42] Fixed the UI issue related to copy and transactions and blocks --- blocks/icons/components/CopyFilled.tsx | 15 ++-- components/Blocks/BlockTxDetails.tsx | 39 +++----- components/Blocks/ConsensusInfo.tsx | 104 ++++++++-------------- components/Blocks/Details.tsx | 54 +++++------ components/Blocks/ListView.tsx | 2 +- components/Home/LiveBlocks.tsx | 20 ++--- components/Home/LiveTransactions.tsx | 11 +++ components/Home/SearchBar.tsx | 41 +++++---- components/Reusables/AddressComponent.tsx | 7 +- components/Reusables/CopyTooltip.tsx | 31 +++++++ components/Transactions/ConsensusInfo.tsx | 34 ++----- components/Transactions/ListView.tsx | 18 +++- pages/transactions/index.tsx | 7 +- sections/Transactions/index.tsx | 3 + 14 files changed, 190 insertions(+), 196 deletions(-) create mode 100644 components/Reusables/CopyTooltip.tsx diff --git a/blocks/icons/components/CopyFilled.tsx b/blocks/icons/components/CopyFilled.tsx index 7da7e36..6ab7e70 100644 --- a/blocks/icons/components/CopyFilled.tsx +++ b/blocks/icons/components/CopyFilled.tsx @@ -9,24 +9,25 @@ const CopyFilled: FC = (allProps) => { componentName="CopyFilled" icon={ diff --git a/components/Blocks/BlockTxDetails.tsx b/components/Blocks/BlockTxDetails.tsx index ff67c69..c3db2f6 100644 --- a/components/Blocks/BlockTxDetails.tsx +++ b/components/Blocks/BlockTxDetails.tsx @@ -1,9 +1,6 @@ // React, NextJS imports import React from 'react'; -// External Components imports -import { css } from 'styled-components'; - // Internal Components imports import { Box, Text } from '../../blocks'; import { BlockDetails } from '../../types/block'; @@ -26,20 +23,16 @@ const BlockTXDetails = (props: IProps) => { gap="spacing-sm" padding="spacing-md" > - - <> - - {props.data?.totalNumberOfTxns} - - - - - <> - - {props.data?.blockSize.toLocaleString()} - - - + + + {props.data?.totalNumberOfTxns} + + + + + {props.data?.blockSize.toLocaleString()} + + { export default BlockTXDetails; -const DetailRow = ({ label, children }) => ( +const DetailsOutline = ({ label, children }) => ( - + {label} { gap="spacing-md" > - + Consensus Info @@ -80,9 +76,7 @@ const ConsensusInfo = (props: IProps) => { display="flex" flexDirection="column" gap="spacing-xs" - css={css` - flex: 3; - `} + width="75%" > {displayedNodes.map((node, index) => ( @@ -93,7 +87,7 @@ const ConsensusInfo = (props: IProps) => { alignItems="center" gap="spacing-xxs" > - + {node.node} @@ -119,12 +113,7 @@ const ConsensusInfo = (props: IProps) => { - + Payload Data @@ -132,40 +121,29 @@ const ConsensusInfo = (props: IProps) => { - - {payload} - + + + {payload} + + - - - - - + @@ -234,37 +212,31 @@ const ConsensusInfo = (props: IProps) => { - - {payload} - + + + {payload} + + - - - - - + diff --git a/components/Blocks/Details.tsx b/components/Blocks/Details.tsx index f579408..0b44a0c 100644 --- a/components/Blocks/Details.tsx +++ b/components/Blocks/Details.tsx @@ -9,6 +9,7 @@ import moment from 'moment'; import { Box, Text, Tooltip, TickCircleFilled, CopyFilled } from '../../blocks'; import { BlockDetails } from '../../types/block'; import { getValidatorNode } from '../../utils/helpers'; +import { CopyTooltip } from '../Reusables/CopyTooltip'; interface IProps { data: BlockDetails | null | undefined; @@ -50,7 +51,7 @@ const Details = (props: IProps) => { gap="spacing-sm" padding="spacing-md" > - + <> { {props.data?.blockHash} - - - {tooltipText === 'Copied' ? ( - - ) : ( - copyData(props.data?.blockHash)} - autoSize - size={16} - color="icon-tertiary" - /> - )} - - + copyData(props.data?.blockHash)} + /> - - + + {getValidatorNode(props.data?.blockDataAsJson)} - - + + {dateTime} - + {/* Mobile View */} @@ -116,10 +103,17 @@ const Details = (props: IProps) => { word-break: break-all; overflow-wrap: break-word; `} + display="flex" + gap="spacing-xxs" + alignItems="center" > {props.data?.blockHash} + copyData(props.data?.blockHash)} + /> @@ -154,21 +148,15 @@ const Details = (props: IProps) => { export default Details; -const DetailRow = ({ label, children }) => ( +const DetailOutline = ({ label, children }) => ( - + {label} { dataIndex: 'totalNumberOfTxns', render: (text) => ( - {text} + {text === '' ? '-' : text} ), cellAlignment: 'center', diff --git a/components/Home/LiveBlocks.tsx b/components/Home/LiveBlocks.tsx index f2dc535..5f7a5a1 100644 --- a/components/Home/LiveBlocks.tsx +++ b/components/Home/LiveBlocks.tsx @@ -12,6 +12,7 @@ import { useLiveBlocks } from '../../hooks/useBlocks'; import { getValidatorNode } from '../../utils/helpers'; import { centerMaskString, fromNow } from '../../utils/helpers'; import BlockHashLink from '../Reusables/BlockHashLink'; +import Address from '../Reusables/AddressComponent'; export default function LiveBlocks() { const router = useRouter(); @@ -35,11 +36,7 @@ export default function LiveBlocks() { { title: 'VALIDATOR', dataIndex: 'validator', - render: (text) => ( - - {centerMaskString(text)} - - ), + render: (text) =>
, cellAlignment: 'flex-start', headerAlignment: 'flex-start', width: '135px', @@ -47,11 +44,14 @@ export default function LiveBlocks() { { title: 'TX', dataIndex: 'totalNumberOfTxns', - render: (text) => ( - - {text} - - ), + render: (text) => { + console.log('Text', text); + return ( + + {text === '' ? '-' : text} + + ); + }, cellAlignment: 'center', headerAlignment: 'center', width: '65px', diff --git a/components/Home/LiveTransactions.tsx b/components/Home/LiveTransactions.tsx index 17f9142..66a0942 100644 --- a/components/Home/LiveTransactions.tsx +++ b/components/Home/LiveTransactions.tsx @@ -62,6 +62,17 @@ export default function LiveTransactions() { dataIndex: 'recipients', render: (recipients: string) => { const reci = recipients.split(','); + if (!recipients) + return ( + + - + + ); return ( diff --git a/components/Home/SearchBar.tsx b/components/Home/SearchBar.tsx index 394464c..b70eb7b 100644 --- a/components/Home/SearchBar.tsx +++ b/components/Home/SearchBar.tsx @@ -1,6 +1,6 @@ // React, NextJS imports import React, { useCallback, useState, useEffect } from 'react'; -import { useRouter } from 'next/router' +import { useRouter } from 'next/router'; import { useDebounce } from 'react-use'; import { ethers } from 'ethers'; @@ -10,7 +10,7 @@ import { TextInput, Search } from '../../blocks'; import { useSearchByAddress } from '../../hooks/useSearchByAddress'; export default function SearchBar() { - const router = useRouter() + const router = useRouter(); const [query, setQuery] = useState(''); const [debouncedQuery, setDebouncedQuery] = useState(''); @@ -22,15 +22,19 @@ export default function SearchBar() { }, []); // Debounce the query - useDebounce(() => { - setDebouncedQuery(query); - }, 500, [query]) + useDebounce( + () => { + setDebouncedQuery(query); + }, + 500, + [query] + ); // Conditionally call the useSearchByAddress hook if debouncedQuery is not empty const { data, isLoading } = useSearchByAddress({ address: debouncedQuery || '', page: 1, - }) + }); // Log the data or loading state useEffect(() => { @@ -38,30 +42,35 @@ export default function SearchBar() { if (!isLoading && data) { const blocks = data?.blocks; const transactions = blocks.flatMap((block) => block.transactions); // Use flatMap to flatten the transactions - - const isSearchedTransaction = transactions.find((tx) => tx.txnHash === debouncedQuery); + + const isSearchedTransaction = transactions.find( + (tx) => tx.txnHash === debouncedQuery + ); if (isSearchedTransaction) { - router.push(`/transactions/${debouncedQuery}`) - return + router.push(`/transactions/${debouncedQuery}`); + return; } - const isSearchedBlock = blocks.some(block => block.blockHash === debouncedQuery); + const isSearchedBlock = blocks.some( + (block) => block.blockHash === debouncedQuery + ); if (isSearchedBlock) { - router.push(`/blocks/${debouncedQuery}`) - return + router.push(`/blocks/${debouncedQuery}`); + return; } if (blocks.length >= 1) { - router.push(`/users/${debouncedQuery}`) - return + router.push(`/users/${debouncedQuery}`); + return; } } } }, [debouncedQuery, data, isLoading]); + console.log('debouncedQuery', debouncedQuery, query); + return ( } value={query} diff --git a/components/Reusables/AddressComponent.tsx b/components/Reusables/AddressComponent.tsx index 604eebe..e1d5119 100644 --- a/components/Reusables/AddressComponent.tsx +++ b/components/Reusables/AddressComponent.tsx @@ -10,6 +10,7 @@ import { Box, Text, Tooltip } from '../../blocks'; import { PushMonotone, TickCircleFilled, CopyFilled } from '../../blocks/icons'; import { CHAIN_LOGO } from '../../common'; import { convertCaipToObject, centerMaskString } from '../../utils/helpers'; +import { CopyTooltip } from './CopyTooltip'; const Address = ({ address, @@ -19,14 +20,14 @@ const Address = ({ }) => { function getChainIcon(chainId) { if (!chainId) { - return ; + return ; } const IconComponent = CHAIN_LOGO[chainId]; if (IconComponent) { - return ; + return ; } else { // TO Bypass some test cases addresses - return ; + return ; } } diff --git a/components/Reusables/CopyTooltip.tsx b/components/Reusables/CopyTooltip.tsx new file mode 100644 index 0000000..d67f65b --- /dev/null +++ b/components/Reusables/CopyTooltip.tsx @@ -0,0 +1,31 @@ +import React, { FC } from 'react'; +import { Box, CopyFilled, TickCircleFilled, Tooltip } from '../../blocks'; + +type CopyToolTipProps = { + tooltipText: string; + copyFunc: () => void; +}; +const CopyTooltip: FC = ({ tooltipText, copyFunc }) => { + return ( + + + {tooltipText === 'Copied' ? ( + + ) : ( + + )} + + + ); +}; + +export { CopyTooltip }; diff --git a/components/Transactions/ConsensusInfo.tsx b/components/Transactions/ConsensusInfo.tsx index ec07eca..a3ad582 100644 --- a/components/Transactions/ConsensusInfo.tsx +++ b/components/Transactions/ConsensusInfo.tsx @@ -17,6 +17,7 @@ import { import { Transaction } from '../../types/transaction'; import { BlockDetails } from '../../types/block'; import { buildNodeVotes } from '../../utils/helpers'; +import { CopyTooltip } from '../Reusables/CopyTooltip'; interface IProps { blockDetails: BlockDetails | null | undefined; @@ -182,20 +183,7 @@ const ConsensusInfo = (props: IProps) => { )} - - - - - + @@ -317,20 +305,10 @@ const ConsensusInfo = (props: IProps) => { )} {displayedPayload && ( - - - - - + )} diff --git a/components/Transactions/ListView.tsx b/components/Transactions/ListView.tsx index 29b3da8..7e7d6ab 100644 --- a/components/Transactions/ListView.tsx +++ b/components/Transactions/ListView.tsx @@ -8,7 +8,7 @@ import { useTheme } from 'styled-components'; // Internal Components imports import { Box, Text, Tag, Table } from '../../blocks'; import { Tick } from '../../blocks/icons'; -import { fromNow, capitalizeStr } from '../../utils/helpers'; +import { fromNow, capitalizeStr, rightMaskString } from '../../utils/helpers'; import { TagVariant } from '../../blocks/tag'; import { Transaction } from '../../types/transaction'; import Address from '../Reusables/AddressComponent'; @@ -82,7 +82,17 @@ const ListView = (props: IProps) => { dataIndex: 'recipients', render: (recipients: string) => { const reci = recipients.split(','); - if (!recipients) return; + if (!recipients) + return ( + + - + + ); return (
@@ -106,13 +116,13 @@ const ListView = (props: IProps) => { if (category.startsWith(customPrefix)) { return ( - {category.replace(customPrefix, '')} + {rightMaskString(category.replace(customPrefix, ''), 10)} ); } return ( - {category} + {rightMaskString(category, 10)} ); }, diff --git a/pages/transactions/index.tsx b/pages/transactions/index.tsx index f801b90..9b8f974 100644 --- a/pages/transactions/index.tsx +++ b/pages/transactions/index.tsx @@ -1,10 +1,13 @@ +// React, NextJS imports import React from 'react'; import Head from 'next/head'; import dynamic from 'next/dynamic'; -import { Spinner } from '../../blocks' + +// Internal Components imports +import { Spinner } from '../../blocks'; const TransactionView = dynamic(() => import('../../sections/Transactions'), { - loading: () => , + loading: () => , }); const Layout = dynamic(() => import('../../layout')); diff --git a/sections/Transactions/index.tsx b/sections/Transactions/index.tsx index ab85aa3..ec84599 100644 --- a/sections/Transactions/index.tsx +++ b/sections/Transactions/index.tsx @@ -1,4 +1,7 @@ +// React, NextJS imports import React, { useState, useEffect } from 'react'; + +// Internal Components imports import { Box, Text, Spinner, Pagination } from '../../blocks'; import ListView from '../../components/Transactions/ListView'; import { useLiveTransactions } from '../../hooks/useLiveTransactions';