- {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",