Skip to content

Commit 7e97a0d

Browse files
authored
feat: implement notification item component (#2007)
1 parent b93a636 commit 7e97a0d

File tree

5 files changed

+195
-28
lines changed

5 files changed

+195
-28
lines changed
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
@import '../../../../../packages/core/src/ui/styles/theme.scss';
2+
@import '../../../../../packages/common/src/ui/styles/theme.scss';
3+
4+
.container {
5+
display: flex;
6+
border-radius: size_unit(2);
7+
border: none;
8+
background: var(--bg-color-container);
9+
color: var(--text-color-primary);
10+
gap: size_unit(2);
11+
12+
&.withBorder {
13+
border: 1px solid var(--light-mode-light-grey-plus, var(--dark-mode-mid-grey)) !important;
14+
}
15+
16+
&:hover {
17+
color: var(--text-color-primary);
18+
cursor: pointer;
19+
background-color: var(--light-mode-light-grey-56, var(--dark-mode-grey));
20+
21+
.actions {
22+
display: flex;
23+
}
24+
}
25+
}
26+
27+
.dot {
28+
width: 6px;
29+
height: 6px;
30+
border-radius: 50%;
31+
background: var(--primary-default);
32+
}
33+
34+
.content {
35+
flex: 1;
36+
overflow: hidden;
37+
}
38+
39+
.actions {
40+
display: none;
41+
flex-shrink: 0;
42+
:hover {
43+
.icon {
44+
color: var(--text-color-primary);
45+
}
46+
}
47+
}
48+
49+
.copy {
50+
overflow: hidden;
51+
text-overflow: ellipsis;
52+
white-space: nowrap;
53+
width: 100%;
54+
}
55+
56+
.icon {
57+
width: size_unit(2);
58+
height: size_unit(2);
59+
color: var(--text-color-secondary);
60+
path {
61+
fill: none !important;
62+
}
63+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import React from 'react';
2+
import styles from './NotificationListItem.module.scss';
3+
import { Flex, Text, Button, Box, IconButton } from '@input-output-hk/lace-ui-toolkit';
4+
import TrashOutlineComponent from '../../assets/icons/browser-view/trash-icon.component.svg';
5+
import { useTranslation } from 'react-i18next';
6+
import classnames from 'classnames';
7+
8+
export interface NotificationListItemProps {
9+
title: string;
10+
isRead?: boolean;
11+
popupView?: boolean;
12+
publisher: string;
13+
onRemove?: () => void;
14+
onClick: () => void;
15+
withBorder?: boolean;
16+
}
17+
18+
export const NotificationListItem = ({
19+
title,
20+
isRead = false,
21+
popupView = false,
22+
publisher,
23+
onRemove,
24+
onClick,
25+
withBorder = true
26+
}: NotificationListItemProps): React.ReactElement => {
27+
const { t } = useTranslation();
28+
29+
const handleRemove = (e: React.MouseEvent<HTMLButtonElement>) => {
30+
e.stopPropagation();
31+
onRemove();
32+
};
33+
34+
const PublisherTextComponent = popupView ? Text.Label : Text.Body.Small;
35+
const TitleTextComponent = popupView ? Text.Label : Text.Body.Large;
36+
const removeButton = popupView ? (
37+
<IconButton.Primary
38+
icon={<TrashOutlineComponent className={styles.icon} />}
39+
onClick={handleRemove}
40+
color="secondary"
41+
/>
42+
) : (
43+
<Button.Secondary
44+
size="small"
45+
icon={<TrashOutlineComponent className={styles.icon} />}
46+
label={popupView ? '' : t('notificationsCenter.notificationListItem.remove')}
47+
color="secondary"
48+
onClick={handleRemove}
49+
/>
50+
);
51+
52+
return (
53+
<Box
54+
h={popupView ? '$80' : '$96'}
55+
onClick={onClick}
56+
className={classnames(styles.container, withBorder && styles.withBorder)}
57+
p="$20"
58+
>
59+
<Flex className={styles.content} justifyContent="center" alignItems="flex-start" flexDirection="column" gap="$8">
60+
<Flex alignItems="center" gap="$4" className={styles.copy}>
61+
{!isRead && <div className={styles.dot} />}
62+
<PublisherTextComponent weight="$medium" color="secondary">
63+
{publisher}
64+
</PublisherTextComponent>
65+
</Flex>
66+
<TitleTextComponent weight="$semibold" className={styles.copy}>
67+
{title}
68+
</TitleTextComponent>
69+
</Flex>
70+
<Flex className={styles.actions} alignItems="center" justifyContent="center">
71+
{typeof onRemove === 'function' && removeButton}
72+
</Flex>
73+
</Box>
74+
);
75+
};
Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import React from 'react';
1+
import React, { useState } from 'react';
22
import { useTranslation } from 'react-i18next';
33
import { Box, Flex } from '@input-output-hk/lace-ui-toolkit';
44

55
import { Button, NavigationButton } from '@lace/common';
66
import { SectionTitle } from '@components/Layout/SectionTitle';
77

88
import styles from './NotificationsCenter.module.scss';
9+
import { WarningModal } from '@src/views/browser-view/components/WarningModal/WarningModal';
910

1011
export interface NotificationsCenterProps {
1112
onBack: () => void;
@@ -19,34 +20,54 @@ export const NotificationsCenter = ({
1920
popupView
2021
}: NotificationsCenterProps): React.ReactElement => {
2122
const { t } = useTranslation();
23+
const [isRemoveNotificationModalVisible, setIsRemoveNotificationModalVisible] = useState(false);
24+
25+
const onRemoveNotification = () => {
26+
// TODO: implement remove notification
27+
// eslint-disable-next-line no-console
28+
console.log('remove notification');
29+
setIsRemoveNotificationModalVisible(false);
30+
};
2231

2332
return (
24-
<Box p="$24">
25-
<Flex justifyContent="space-between" mb={'$44'}>
26-
<Box mb={'$0'}>
27-
<SectionTitle
28-
sideText={`(${1})`}
29-
title={
30-
<Flex alignItems="center" gap="$8">
31-
<NavigationButton icon="arrow" onClick={onBack} />
32-
{t('notificationsCenter.title')}
33-
</Flex>
34-
}
35-
/>
36-
</Box>
37-
{!popupView && (
38-
<Button
39-
className={styles.button}
40-
block
41-
color="gradient"
42-
data-testid="notifications-bell"
43-
onClick={onMarkAllAsRead}
44-
>
45-
{t('notificationsCenter.markAllAsRead')}
46-
</Button>
47-
)}
48-
</Flex>
49-
Notifications Center (Placeholder content)
50-
</Box>
33+
<>
34+
<WarningModal
35+
visible={isRemoveNotificationModalVisible}
36+
header={t('notificationsCenter.removeNotification')}
37+
content={t('notificationsCenter.removeNotification.description')}
38+
onCancel={() => setIsRemoveNotificationModalVisible(false)}
39+
cancelLabel={t('notificationsCenter.removeNotification.cancel')}
40+
confirmLabel={t('notificationsCenter.removeNotification.confirm')}
41+
onConfirm={onRemoveNotification}
42+
isPopupView={popupView}
43+
/>
44+
<Box p="$24">
45+
<Flex justifyContent="space-between" mb={'$44'}>
46+
<Box mb={'$0'}>
47+
<SectionTitle
48+
sideText={`(${1})`}
49+
title={
50+
<Flex alignItems="center" gap="$8">
51+
<NavigationButton icon="arrow" onClick={onBack} />
52+
{t('notificationsCenter.title')}
53+
</Flex>
54+
}
55+
/>
56+
</Box>
57+
{!popupView && (
58+
<Button
59+
className={styles.button}
60+
block
61+
color="gradient"
62+
data-testid="notifications-bell"
63+
onClick={onMarkAllAsRead}
64+
>
65+
{t('notificationsCenter.markAllAsRead')}
66+
</Button>
67+
)}
68+
</Flex>
69+
Notifications Center (Placeholder content)
70+
</Box>
71+
</>
5172
);
5273
};

packages/translation/src/lib/translations/browser-extension-wallet/en.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,11 @@
789789
"notificationsCenter.markAllAsRead": "Mark all as read",
790790
"notificationsCenter.title": "Notifications",
791791
"notificationsCenter.viewAll": "View all",
792+
"notificationsCenter.notificationListItem.remove": "Remove",
793+
"notificationsCenter.removeNotification": "Remove notification",
794+
"notificationsCenter.removeNotification.description": "Are you sure you wish to remove this notification? it will not be possible to revert this action",
795+
"notificationsCenter.removeNotification.confirm": "Remove",
796+
"notificationsCenter.removeNotification.cancel": "Cancel",
792797
"poolDetails.delegate": "Delegate to this pool",
793798
"poolDetails.sectionTitle": "Pool detail",
794799
"qrInfo.publicKey": "Show public key",

0 commit comments

Comments
 (0)