diff --git a/apps/browser-extension-wallet/src/assets/icons/loader.component.svg b/apps/browser-extension-wallet/src/assets/icons/loader.component.svg new file mode 100644 index 000000000..3cea0311b --- /dev/null +++ b/apps/browser-extension-wallet/src/assets/icons/loader.component.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/browser-extension-wallet/src/assets/icons/notifications-bell.component.svg b/apps/browser-extension-wallet/src/assets/icons/notifications-bell.component.svg new file mode 100644 index 000000000..45f77ec9e --- /dev/null +++ b/apps/browser-extension-wallet/src/assets/icons/notifications-bell.component.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/apps/browser-extension-wallet/src/assets/icons/smiley-face.component.svg b/apps/browser-extension-wallet/src/assets/icons/smiley-face.component.svg new file mode 100644 index 000000000..35595ae19 --- /dev/null +++ b/apps/browser-extension-wallet/src/assets/icons/smiley-face.component.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/EmptyState.module.scss b/apps/browser-extension-wallet/src/components/NotificationsCenter/EmptyState.module.scss new file mode 100644 index 000000000..270d1ae4d --- /dev/null +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/EmptyState.module.scss @@ -0,0 +1,7 @@ +@import '../../../../../packages/core/src/ui/styles/theme.scss'; +@import '../../../../../packages/common/src/ui/styles/theme.scss'; + +.icon { + width: size_unit(10.5); + height: size_unit(10.5); +} diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/EmptyState.tsx b/apps/browser-extension-wallet/src/components/NotificationsCenter/EmptyState.tsx new file mode 100644 index 000000000..1b092654f --- /dev/null +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/EmptyState.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Flex, Text } from '@input-output-hk/lace-ui-toolkit'; +import { useTranslation } from 'react-i18next'; +import styles from './EmptyState.module.scss'; +import SmileyFaceIcon from '../../assets/icons/smiley-face.component.svg'; + +export const EmptyState = (): React.ReactElement => { + const { t } = useTranslation(); + + return ( + + + + {t('notificationsCenter.emptyState.title')} + {t('notificationsCenter.emptyState.description')} + + + ); +}; diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationListItem.tsx b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationListItem.tsx index b08f7b888..5a933cfec 100644 --- a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationListItem.tsx +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationListItem.tsx @@ -5,17 +5,32 @@ import TrashOutlineComponent from '../../assets/icons/browser-view/trash-icon.co import { useTranslation } from 'react-i18next'; import classnames from 'classnames'; +export type LaceMessage = { + id: string; + topic: string; + title: string; + body: string; + format: string; +}; + +export type LaceNotification = { + message: LaceMessage; + read?: boolean; +}; + export interface NotificationListItemProps { + id: string; title: string; isRead?: boolean; popupView?: boolean; publisher: string; - onRemove?: () => void; + onRemove?: (id: string) => void; onClick: () => void; withBorder?: boolean; } export const NotificationListItem = ({ + id, title, isRead = false, popupView = false, @@ -28,7 +43,7 @@ export const NotificationListItem = ({ const handleRemove = (e: React.MouseEvent) => { e.stopPropagation(); - onRemove(); + onRemove?.(id); }; const PublisherTextComponent = popupView ? Text.Label : Text.Body.Small; @@ -55,6 +70,7 @@ export const NotificationListItem = ({ onClick={onClick} className={classnames(styles.container, withBorder && styles.withBorder)} p="$20" + w="$fill" > diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/Notifications.tsx b/apps/browser-extension-wallet/src/components/NotificationsCenter/Notifications.tsx new file mode 100644 index 000000000..b6019628d --- /dev/null +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/Notifications.tsx @@ -0,0 +1,84 @@ +/* eslint-disable unicorn/no-useless-undefined */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types, promise/catch-or-return, sonarjs/cognitive-complexity, no-magic-numbers, unicorn/no-null */ +import React, { useState } from 'react'; +import { ContentLayout } from '@src/components/Layout'; +import { useTranslation } from 'react-i18next'; +import { WarningModal } from '@src/views/browser-view/components'; +import { useNotificationsCenter } from '@hooks/useNotificationsCenter'; +import { NotificationsList } from './NotificationsList'; +import { EmptyState } from './EmptyState'; +import { Box, Flex } from '@input-output-hk/lace-ui-toolkit'; +import { NavigationButton } from '@lace/common'; +import { useHistory } from 'react-router'; +import { SectionTitle } from '@components/Layout/SectionTitle'; + +export const NotificationsCenter = (): React.ReactElement => { + const { t } = useTranslation(); + const [isRemoveNotificationModalVisible, setIsRemoveNotificationModalVisible] = useState(false); + const { notifications, loadMore, remove, unreadNotifications, isLoading } = useNotificationsCenter(); + const [notificationIdToRemove, setNotificationIdToRemove] = useState(); + const history = useHistory(); + + const onShowRemoveNotificationModal = (id: string) => { + setNotificationIdToRemove(id); + setIsRemoveNotificationModalVisible(true); + }; + + const onHideRemoveNotificationModal = () => { + setNotificationIdToRemove(undefined); + setIsRemoveNotificationModalVisible(false); + }; + + const isInitialLoad = typeof notifications === 'undefined'; + + return ( + + history.goBack()} /> + {t('notificationsCenter.title')} + + } + sideText={`(${unreadNotifications})`} + data-testid="notifications-center-title" + /> + } + isLoading={isInitialLoad} + > +
+ {notifications?.length > 0 ? ( + + ) : ( + + + + )} +
+ { + remove(notificationIdToRemove); + onHideRemoveNotificationModal(); + }} + isPopupView + /> + + ); +}; diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsAllClear.tsx b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsAllClear.tsx deleted file mode 100644 index 31815dabe..000000000 --- a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsAllClear.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import { useTranslation } from 'react-i18next'; - -import { Flex, Text } from '@input-output-hk/lace-ui-toolkit'; - -import styles from './NotificationsAllClear.module.scss'; - -import HappyFaceIcon from '@lace/core/src/ui/assets/icons/happy-face.component.svg'; - -export const NotificationsAllClear = (): React.ReactElement => { - const { t } = useTranslation(); - - return ( - - - {t('notificationsCenter.allClear.title')} - {t('notificationsCenter.allClear.description')} - - ); -}; diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBell.module.scss b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBell.module.scss index 636e74c9e..4c0905678 100644 --- a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBell.module.scss +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBell.module.scss @@ -25,3 +25,8 @@ padding: size_unit(1) size_unit(2.75) !important; position: relative; } + +.icon { + width: size_unit(2); + height: size_unit(2); +} diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBell.tsx b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBell.tsx index 7778f2aa4..8f7d107b7 100644 --- a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBell.tsx +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBell.tsx @@ -4,10 +4,11 @@ import { Button } from '@lace/common'; import styles from './NotificationsBell.module.scss'; -import NotificationBellIcon from '@lace/core/src/ui/assets/icons/notifications-bell.component.svg'; +import NotificationBellIcon from '../../assets/icons/notifications-bell.component.svg'; -// eslint-disable-next-line no-magic-numbers -const formatNotificationCount = (count: number) => (count < 10 ? count.toString() : '9+'); +const MAX_NOTIFICATION_COUNT = 9; +const formatNotificationCount = (count: number) => + count < MAX_NOTIFICATION_COUNT ? count.toString() : `${MAX_NOTIFICATION_COUNT}+`; export interface NotificationsBellProps { onClick: () => void; @@ -16,7 +17,7 @@ export interface NotificationsBellProps { export const NotificationsBell = ({ onClick, unreadNotifications }: NotificationsBellProps): React.ReactElement => ( ); diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBellContainer.tsx b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBellContainer.tsx index 5fceb5dbf..beaa7f75d 100644 --- a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBellContainer.tsx +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsBellContainer.tsx @@ -15,10 +15,14 @@ export interface NotificationsCenterContainerProps { export const NotificationsBellContainer = ({ popupView }: NotificationsCenterContainerProps): React.ReactElement => { const { isNotificationsCenterEnabled } = useNotificationsCenterConfig(); - const { markAsRead, notifications, unreadNotifications } = useNotificationsCenter(); + const { unreadNotifications } = useNotificationsCenter(); const history = useHistory(); const [isOpen, setIsOpen] = useState(false); + const handleDropdownState = (openDropdown: boolean) => { + setIsOpen(openDropdown); + }; + const handleViewAll = () => { setIsOpen(false); history.push(walletRoutePaths.notifications); @@ -27,18 +31,9 @@ export const NotificationsBellContainer = ({ popupView }: NotificationsCenterCon return ( isNotificationsCenterEnabled && ( ( - markAsRead()} - onMarkAsRead={(id: string) => markAsRead(id)} - onViewAll={handleViewAll} - popupView={popupView} - unreadNotifications={unreadNotifications} - /> - )} + onOpenChange={handleDropdownState} + dropdownRender={() => } placement="bottomRight" trigger={['click']} > diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenter.module.scss b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenter.module.scss index 7feec7c01..8dd669bc8 100644 --- a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenter.module.scss +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenter.module.scss @@ -4,3 +4,27 @@ .button { max-width: size_unit(25); } + +.sectionTitle { + margin-bottom: size_unit(0) !important; +} + +.scrollContainer { + &::-webkit-scrollbar { + width: 6px; + } + + &::-webkit-scrollbar-track { + background: var(--bg-color-secondary, #f5f5f5); + border-radius: 3px; + } + + &::-webkit-scrollbar-thumb { + background: var(--text-color-tertiary, #ccc); + border-radius: 3px; + + &:hover { + background: var(--text-color-secondary, #999); + } + } +} diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenter.tsx b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenter.tsx index 4adaafbf4..257bec4b9 100644 --- a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenter.tsx +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenter.tsx @@ -1,37 +1,37 @@ +/* eslint-disable unicorn/no-useless-undefined */ import React, { useState } from 'react'; import { useTranslation } from 'react-i18next'; import { Box, Flex } from '@input-output-hk/lace-ui-toolkit'; import { Button, NavigationButton } from '@lace/common'; import { SectionTitle } from '@components/Layout/SectionTitle'; -import { LaceNotification, NotificationsTopic } from '@src/types/notifications-center'; +import { NotificationsList } from './NotificationsList'; +import { useNotificationsCenter } from '@hooks/useNotificationsCenter'; import styles from './NotificationsCenter.module.scss'; import { WarningModal } from '@src/views/browser-view/components/WarningModal/WarningModal'; +import { LACE_APP_ID } from '@src/utils/constants'; +import { EmptyState } from './EmptyState'; +import { useHistory } from 'react-router'; -export interface NotificationsCenterProps { - notifications: LaceNotification[]; - onBack: () => void; - onMarkAllAsRead: () => void; - onMarkAsRead: (id: string) => void; - popupView?: boolean; - topics: NotificationsTopic[]; - unreadNotifications: number; -} - -export const NotificationsCenter = ({ - onBack, - onMarkAllAsRead, - popupView, - unreadNotifications -}: NotificationsCenterProps): React.ReactElement => { +export const NotificationsCenter = (): React.ReactElement => { const { t } = useTranslation(); + const history = useHistory(); const [isRemoveNotificationModalVisible, setIsRemoveNotificationModalVisible] = useState(false); + const { notifications, loadMore, markAsRead, remove, unreadNotifications, isLoading } = useNotificationsCenter(); + const [notificationIdToRemove, setNotificationIdToRemove] = useState(); + + const onBack = () => { + history.goBack(); + }; + + const onShowRemoveNotificationModal = (id: string) => { + setNotificationIdToRemove(id); + setIsRemoveNotificationModalVisible(true); + }; - const onRemoveNotification = () => { - // TODO: implement remove notification - // eslint-disable-next-line no-console - console.log('remove notification'); + const onHideRemoveNotificationModal = () => { + setNotificationIdToRemove(undefined); setIsRemoveNotificationModalVisible(false); }; @@ -41,39 +41,57 @@ export const NotificationsCenter = ({ visible={isRemoveNotificationModalVisible} header={t('notificationsCenter.removeNotification')} content={t('notificationsCenter.removeNotification.description')} - onCancel={() => setIsRemoveNotificationModalVisible(false)} + onCancel={onHideRemoveNotificationModal} cancelLabel={t('notificationsCenter.removeNotification.cancel')} confirmLabel={t('notificationsCenter.removeNotification.confirm')} - onConfirm={onRemoveNotification} - isPopupView={popupView} + onConfirm={() => { + remove(notificationIdToRemove); + onHideRemoveNotificationModal(); + }} /> - - - - 0 ? `(${unreadNotifications})` : undefined} - title={ - - - {t('notificationsCenter.title')} - - } - /> +
+ + + + + + {t('notificationsCenter.title')} + + } + /> + + {unreadNotifications > 0 && ( + + )} + + + {notifications?.length > 0 ? ( + + ) : ( + + - {!popupView && ( - - )} - - Notifications Center (Placeholder content) - + )} +
); }; diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenterContainer.tsx b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenterContainer.tsx index f25f2eea6..f9c9e37c0 100644 --- a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenterContainer.tsx +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsCenterContainer.tsx @@ -1,26 +1,5 @@ import React from 'react'; -import { useHistory } from 'react-router'; - -import { useWalletStore } from '@stores'; -import { APP_MODE_POPUP } from '@src/utils/constants'; -import { useNotificationsCenter } from '@hooks/useNotificationsCenter'; import { NotificationsCenter } from './NotificationsCenter'; -export const NotificationsCenterContainer = (): React.ReactElement => { - const history = useHistory(); - const { walletUI } = useWalletStore(); - const { markAsRead, notifications, topics, unreadNotifications } = useNotificationsCenter(); - - return ( - history.goBack()} - onMarkAllAsRead={() => markAsRead()} - onMarkAsRead={(id: string) => void markAsRead(id)} - popupView={walletUI.appMode === APP_MODE_POPUP} - topics={topics} - unreadNotifications={unreadNotifications} - /> - ); -}; +export const NotificationsCenterContainer = (): React.ReactElement => ; diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsDropDown.module.scss b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsDropDown.module.scss index 4a9000417..99a6a3143 100644 --- a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsDropDown.module.scss +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsDropDown.module.scss @@ -2,6 +2,7 @@ @import '../../../../../packages/common/src/ui/styles/theme.scss'; @import '../../../../../packages/common/src/ui/styles/abstracts/mixins'; + .container { background-color: var(--bg-color-container, #ffffff) !important; border: 1px var(--light-mode-light-grey) solid !important; @@ -12,6 +13,12 @@ padding: size_unit(1) !important; width: 310px; + &.isEmpty { + display: flex; + justify-content: center; + align-items: center; + } + &.popupView { left: size_unit(-4); } @@ -23,3 +30,12 @@ overflow-y: scroll; @include scroll-bar-style; } + +.notificationsListContainer { + background-color: var(--bg-color-container, #ffffff) !important; + border-radius: 0 !important; +} + +.btn { + cursor: pointer; +} diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsDropDown.tsx b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsDropDown.tsx index f88847ace..807a8da6f 100644 --- a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsDropDown.tsx +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsDropDown.tsx @@ -3,48 +3,58 @@ import classnames from 'classnames'; import { useTranslation } from 'react-i18next'; import { Menu } from 'antd'; -import { Divider, Flex, Text } from '@input-output-hk/lace-ui-toolkit'; +import { Box, Divider, Flex, Text } from '@input-output-hk/lace-ui-toolkit'; -import { LaceNotification } from '@src/types/notifications-center'; - -import { NotificationsAllClear } from './NotificationsAllClear'; +import { EmptyState } from './EmptyState'; +import { NotificationsList } from './NotificationsList'; +import { useNotificationsCenter } from '@hooks/useNotificationsCenter'; import styles from './NotificationsDropDown.module.scss'; export interface NotificationsDropDownProps { - notifications: LaceNotification[]; - onMarkAllAsRead: () => void; - onMarkAsRead: (id: string) => void; onViewAll: () => void; popupView?: boolean; - unreadNotifications: number; } -export const NotificationsDropDown = ({ - notifications, - onMarkAllAsRead, - onViewAll, - popupView, - unreadNotifications -}: NotificationsDropDownProps): React.ReactElement => { +export const NotificationsDropDown = ({ onViewAll, popupView }: NotificationsDropDownProps): React.ReactElement => { const { t } = useTranslation(); + const { notifications, loadMore, isLoading, markAsRead, unreadNotifications } = useNotificationsCenter(); return ( -
- {notifications.length > 0 ?
Placeholder content
: } +
+ {notifications?.length > 0 ? ( + + ) : ( + + )}
- - - {t(`notificationsCenter.${notifications.length > 0 ? 'viewAll' : 'manageSubscriptions'}`)} - - - {unreadNotifications > 0 && ( - - {t('notificationsCenter.markAllAsRead')} + + + {t(`notificationsCenter.${notifications?.length > 0 ? 'viewAll' : 'manageSubscriptions'}`)} + + {unreadNotifications > 0 && ( + markAsRead()} p="$8"> + + {t('notificationsCenter.markAllAsRead')} + + )}
diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsList.module.scss b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsList.module.scss new file mode 100644 index 000000000..58e93091b --- /dev/null +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsList.module.scss @@ -0,0 +1,71 @@ +@import '../../../../../packages/core/src/ui/styles/theme.scss'; +@import '../../../../../packages/common/src/ui/styles/theme.scss'; + +.infitineScroll { + background: var(--bg-color-body, #ffffff); + &::-webkit-scrollbar { + width: 0 !important; + } +} + +.notificationsContainer { + background: var(--bg-color-body, #ffffff); + padding: 0 !important; + border-radius: 12px; + margin-bottom: 30px !important; + @media (max-width: $breakpoint-popup) { + margin-bottom: 0; + } + :global(.ant-list-header) { + border: none !important; + padding: 0 !important; + } +} + + +.listItem { + border-bottom: none !important; + padding-bottom: 8px !important; + padding-top: 8px !important; + + &.withBorder { + border-bottom: 1px solid var(--light-mode-light-grey-plus, var(--dark-mode-mid-grey)) !important; + &:last-child { + border-bottom: none !important; + } + } + + &:first-child { + padding-top: 0 !important; + } + + &:last-child { + padding-bottom: 0 !important; + } +} + +:global(.ant-list-split) :local(.listItemWrapper) { + border-bottom: none !important; + padding: size_unit(2) size_unit(1); + margin-left: -#{size_unit(1)}; + margin-right: -#{size_unit(1)}; + &:hover { + background: var(--dark-mode-mid-grey, var(--data-light-grey, #f9f9f9)); + border-radius: 16px; + } +} + +@keyframes rotating { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.loader { + animation: rotating 2s linear infinite; + width: 18px; + height: 18px; +} diff --git a/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsList.tsx b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsList.tsx new file mode 100644 index 000000000..75ab7512f --- /dev/null +++ b/apps/browser-extension-wallet/src/components/NotificationsCenter/NotificationsList.tsx @@ -0,0 +1,98 @@ +/* eslint-disable unicorn/no-null */ +import { List, Skeleton } from 'antd'; +import cn from 'classnames'; +import React, { useState, useCallback, useMemo } from 'react'; +import InfiniteScroll from 'react-infinite-scroll-component'; +import { NotificationListItem, NotificationListItemProps } from './NotificationListItem'; +import styles from './NotificationsList.module.scss'; +import isNumber from 'lodash/isNumber'; +import Loader from '../../assets/icons/loader.component.svg'; +import { Flex } from '@input-output-hk/lace-ui-toolkit'; + +const ESTIMATED_MIN_ITEM_HEIGHT = 96; + +export const useItemsPageSize = (estimatedItemHeight = ESTIMATED_MIN_ITEM_HEIGHT): number => { + // workaround for bug in react-infinite-scroll-component + // related to not loading more elements if the height of the container is less than the height of the window + // see: https://github.com/ankeetmaini/react-infinite-scroll-component/issues/380 + // ticket for proper fix on our end: https://input-output.atlassian.net/browse/LW-8986 + // initialWindowHeight state needed to ensure that page size remains the same if window is resized + const [initialWindowHeight] = useState(window.innerHeight); + // eslint-disable-next-line no-magic-numbers + return Math.max(5, Math.floor(initialWindowHeight / estimatedItemHeight)); +}; + +export interface NotificationsListProps { + className?: string; + notifications: NotificationListItemProps[]; + scrollableTarget: string; + endMessage?: React.ReactNode; + dataLength: number; + popupView?: boolean; + loadMore: () => void; + hasMore?: boolean; + onRemove?: (id: string) => void; + isLoading?: boolean; + withBorder?: boolean; + withDivider?: boolean; +} + +export const NotificationsList = ({ + className, + notifications, + scrollableTarget, + endMessage, + dataLength, + popupView, + loadMore, + hasMore = true, + onRemove, + isLoading = false, + withBorder = true, + withDivider +}: NotificationsListProps): React.ReactElement => { + const next = useCallback(() => { + loadMore(); + }, [loadMore]); + + const loader = useMemo( + () => + isLoading ? ( + + + + ) : null, + [isLoading] + ); + + return ( + + {!isNumber(notifications.length) ? ( + + ) : ( + ( + + + + )} + /> + )} + + ); +}; diff --git a/apps/browser-extension-wallet/src/hooks/useNotificationsCenter.ts b/apps/browser-extension-wallet/src/hooks/useNotificationsCenter.ts index 7b5bcf511..63c2418c9 100644 --- a/apps/browser-extension-wallet/src/hooks/useNotificationsCenter.ts +++ b/apps/browser-extension-wallet/src/hooks/useNotificationsCenter.ts @@ -31,13 +31,34 @@ export const useNotificationsCenter = () => { [notifications] ); + const mappedNotifications = useMemo( + () => + notifications?.map((template) => ({ + id: template.message.id, + title: template.message.title, + publisher: template.message.topic, + isRead: template.read, + onClick: () => { + // eslint-disable-next-line no-console + console.log(`Clicked notification ${template.message.id}`); + } + })), + [notifications] + ); + return { - notifications, + notifications: mappedNotifications, unreadNotifications, topics, subscribe, unsubscribe, markAsRead, - remove + remove, + // TODO: Implement loadMore and isLoading + loadMore: () => { + // eslint-disable-next-line no-console + console.log('loadMore'); + }, + isLoading: false }; }; diff --git a/apps/browser-extension-wallet/src/routes/ExtensionRoutes.tsx b/apps/browser-extension-wallet/src/routes/ExtensionRoutes.tsx index c93020dbb..20ea6161b 100644 --- a/apps/browser-extension-wallet/src/routes/ExtensionRoutes.tsx +++ b/apps/browser-extension-wallet/src/routes/ExtensionRoutes.tsx @@ -15,7 +15,7 @@ import { NftDetail, Nfts } from '@src/features/nfts'; import { useWalletStore } from '@stores'; import { config } from '@src/config'; import { Voting } from '@src/features/voting-beta/components'; -import { NotificationsCenterContainer } from '@src/components/NotificationsCenter'; +import { NotificationsCenter } from '@src/components/NotificationsCenter/Notifications'; import { useNotificationsCenterConfig } from '@hooks/useNotificationsCenterConfig'; const { GOV_TOOLS_URLS } = config(); @@ -34,7 +34,7 @@ export const ExtensionRoutes = (): React.ReactElement => { {isNotificationsCenterEnabled && ( - + )} {!isSharedWallet && } diff --git a/packages/translation/src/lib/translations/browser-extension-wallet/en.json b/packages/translation/src/lib/translations/browser-extension-wallet/en.json index d8c9541d7..de110382e 100644 --- a/packages/translation/src/lib/translations/browser-extension-wallet/en.json +++ b/packages/translation/src/lib/translations/browser-extension-wallet/en.json @@ -794,6 +794,8 @@ "notificationsCenter.removeNotification.description": "Are you sure you wish to remove this notification? it will not be possible to revert this action", "notificationsCenter.removeNotification.confirm": "Remove", "notificationsCenter.removeNotification.cancel": "Cancel", + "notificationsCenter.emptyState.title": "All clear", + "notificationsCenter.emptyState.description": "You don't have any notifications currently", "poolDetails.delegate": "Delegate to this pool", "poolDetails.sectionTitle": "Pool detail", "qrInfo.publicKey": "Show public key",