This repository has no description
semble
/
src
/
webapp
/
features
/
notifications
/
components
/
notificationItem
/
NotificationItem.tsx
5.1 kB
138 lines
1import type { NotificationItem as NotificationItemType } from '@/api-client';
2import { NotificationType } from '@/api-client';
3import { Stack, Indicator, Group, Scroller, Box } from '@mantine/core';
4import UrlCard from '@/features/cards/components/urlCard/UrlCard';
5import CollectionCard from '@/features/collections/components/collectionCard/CollectionCard';
6import NotificationActivityStatus from '../notificationActivityStatus/NotificationActivityStatus';
7import ConnectionCard from '@/features/connections/components/connectionCard/ConnectionCard';
8import FollowButton from '@/features/follows/components/followButton/FollowButton';
9import { CardSaveAnalyticsContext } from '@/features/analytics/types';
10import { classifyNotification } from '../../lib/utils';
11
12interface Props {
13 item: NotificationItemType;
14 analyticsContext?: CardSaveAnalyticsContext;
15}
16
17export default function NotificationItem(props: Props) {
18 const notification = classifyNotification(props.item);
19
20 // Connection notification - render similar to feed item
21 if (notification.kind === 'connection') {
22 return (
23 <Indicator
24 disabled={notification.item.read}
25 color="tangerine"
26 size={8}
27 offset={3}
28 position="top-start"
29 >
30 <Stack gap={'xs'} align="stretch" h={'100%'}>
31 <NotificationActivityStatus
32 user={notification.item.user}
33 createdAt={notification.item.createdAt}
34 type={notification.item.type}
35 note={notification.item.connection.connection.note}
36 iconColor="green"
37 />
38 <ConnectionCard connection={notification.item.connection} />
39 </Stack>
40 </Indicator>
41 );
42 }
43
44 // Follow notification
45 if (notification.kind === 'follow') {
46 return (
47 <Indicator
48 disabled={notification.item.read}
49 color="tangerine"
50 size={8}
51 offset={3}
52 position="top-start"
53 >
54 <Stack gap={'xs'} align="stretch" h={'100%'}>
55 <NotificationActivityStatus
56 user={notification.item.user}
57 collections={notification.item.collections}
58 createdAt={notification.item.createdAt}
59 type={notification.item.type}
60 iconColor="gray"
61 followButton={
62 notification.item.type === NotificationType.USER_FOLLOWED_YOU ? (
63 <FollowButton
64 targetId={notification.item.user.id}
65 targetType="USER"
66 targetHandle={notification.item.user.handle}
67 initialIsFollowing={notification.item.user.isFollowing}
68 />
69 ) : undefined
70 }
71 />
72 {notification.item.type ===
73 NotificationType.USER_FOLLOWED_YOUR_COLLECTION &&
74 notification.item.collections &&
75 notification.item.collections.length > 0 &&
76 (notification.item.collections.length === 1 ? (
77 <Box miw={'100%'} w={'100%'}>
78 <CollectionCard
79 collection={notification.item.collections[0]}
80 size="compact"
81 />
82 </Box>
83 ) : (
84 <Scroller>
85 <Group gap="xs" wrap="nowrap">
86 {notification.item.collections.map((collection) => (
87 <Box key={collection.id} miw={'100%'} w={'100%'}>
88 <CollectionCard collection={collection} size="compact" />
89 </Box>
90 ))}
91 </Group>
92 </Scroller>
93 ))}
94 </Stack>
95 </Indicator>
96 );
97 }
98
99 // Card/collection notification
100 if (notification.kind === 'cardCollection') {
101 return (
102 <Indicator
103 disabled={notification.item.read}
104 color="tangerine"
105 size={8}
106 offset={3}
107 position="top-start"
108 >
109 <Stack gap={'xs'} align="stretch" h={'100%'}>
110 <NotificationActivityStatus
111 user={notification.item.user}
112 collections={notification.item.collections}
113 createdAt={notification.item.createdAt}
114 type={notification.item.type}
115 />
116 <UrlCard
117 id={notification.item.card.id}
118 url={notification.item.card.url}
119 uri={notification.item.card.uri}
120 note={notification.item.card.note}
121 cardAuthor={notification.item.card.author}
122 cardContent={notification.item.card.cardContent}
123 urlLibraryCount={notification.item.card.urlLibraryCount}
124 urlIsInLibrary={notification.item.card.urlInLibrary}
125 urlConnectionCount={notification.item.card.urlConnectionCount ?? 0}
126 urlIsConnected={notification.item.card.urlIsConnected}
127 authorHandle={notification.item.user.handle}
128 viaCardId={notification.item.card.id}
129 analyticsContext={props.analyticsContext}
130 />
131 </Stack>
132 </Indicator>
133 );
134 }
135
136 // Fallback (should never reach here if all notification types are handled)
137 return null;
138}