This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

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}