This repository has no description
semble
/
src
/
webapp
/
features
/
notifications
/
components
/
notificationItem
/
NotificationItem.tsx
5.2 kB
142 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 miw={'100%'} w={'100%'}>
88 <CollectionCard
89 key={collection.id}
90 collection={collection}
91 size="compact"
92 />
93 </Box>
94 ))}
95 </Group>
96 </Scroller>
97 ))}
98 </Stack>
99 </Indicator>
100 );
101 }
102
103 // Card/collection notification
104 if (notification.kind === 'cardCollection') {
105 return (
106 <Indicator
107 disabled={notification.item.read}
108 color="tangerine"
109 size={8}
110 offset={3}
111 position="top-start"
112 >
113 <Stack gap={'xs'} align="stretch" h={'100%'}>
114 <NotificationActivityStatus
115 user={notification.item.user}
116 collections={notification.item.collections}
117 createdAt={notification.item.createdAt}
118 type={notification.item.type}
119 />
120 <UrlCard
121 id={notification.item.card.id}
122 url={notification.item.card.url}
123 uri={notification.item.card.uri}
124 note={notification.item.card.note}
125 cardAuthor={notification.item.card.author}
126 cardContent={notification.item.card.cardContent}
127 urlLibraryCount={notification.item.card.urlLibraryCount}
128 urlIsInLibrary={notification.item.card.urlInLibrary}
129 urlConnectionCount={notification.item.card.urlConnectionCount ?? 0}
130 urlIsConnected={notification.item.card.urlIsConnected}
131 authorHandle={notification.item.user.handle}
132 viaCardId={notification.item.card.id}
133 analyticsContext={props.analyticsContext}
134 />
135 </Stack>
136 </Indicator>
137 );
138 }
139
140 // Fallback (should never reach here if all notification types are handled)
141 return null;
142}