@@ -3,13 +3,13 @@ import { computed } from "vue";
33import { useRouter } from " vue-router" ;
44import { useQuery } from " @pinia/colada" ;
55import { getMyNotifications } from " @/api/notifications" ;
6- import { getSpeakerById } from " @/api/speakers" ;
7- import { getCompanyById } from " @/api/companies" ;
86import {
97 useDeleteNotificationMutation ,
108 useDeleteAllNotificationsMutation ,
119} from " @/mutations/notifications" ;
12- import type { EnrichedActor , EnrichedNotification } from " @/dto/notifications" ;
10+ import type { Notification } from " @/dto/notifications" ;
11+ import type { Speaker } from " @/dto/speakers" ;
12+ import type { Company } from " @/dto/companies" ;
1313import { Bell , Trash } from " lucide-vue-next" ;
1414import {
1515 Popover ,
@@ -19,8 +19,36 @@ import {
1919import Badge from " ../ui/badge/Badge.vue" ;
2020import Image from " ../Image.vue" ;
2121
22- const makeMessage = (kind : string , actor : EnrichedActor ) => {
23- const actorName = actor .name ;
22+ const getActor = (notification : Notification ) => {
23+ if (notification .speaker && typeof notification .speaker === " object" ) {
24+ return {
25+ id: (notification .speaker as Speaker ).id ,
26+ name: (notification .speaker as Speaker ).name ,
27+ avatar:
28+ (notification .speaker as Speaker ).imgs .internal ||
29+ (notification .speaker as Speaker ).imgs .speaker ,
30+ };
31+ }
32+ if (notification .company && typeof notification .company === " object" ) {
33+ return {
34+ id: (notification .company as Company ).id ,
35+ name: (notification .company as Company ).name ,
36+ avatar:
37+ (notification .company as Company ).imgs ?.internal ||
38+ (notification .company as Company ).imgs ?.public ,
39+ };
40+ }
41+ return null ;
42+ };
43+
44+ const makeMessage = (notification : Notification ) => {
45+ const thread = notification .thread ;
46+ const kind = notification .kind ;
47+ // Actor is the entity (company/speaker) related to the notification
48+ const actor = getActor (notification );
49+ const actorName = actor ? actor .name : " " ;
50+ const isActorPresent = actorName .length > 0 ;
51+
2452 switch (kind ) {
2553 case " UPDATED_PARTICIPATION" :
2654 return " Participation updated" ;
@@ -37,70 +65,45 @@ const makeMessage = (kind: string, actor: EnrichedActor) => {
3765 case " UPDATED_PRIVATE_IMAGE" :
3866 return " Private image updated" ;
3967 case " UPDATED" :
68+ if (thread ) {
69+ if (isActorPresent ) {
70+ return " Communication updated" ;
71+ }
72+ return " Thread updated" ;
73+ }
74+
4075 return " Updated details" ;
4176 case " CREATED" :
77+ if (thread ) {
78+ if (isActorPresent ) {
79+ return " New communication created" ;
80+ }
81+ return " Thread created" ;
82+ }
83+
4284 return " Created" ;
4385 case " DELETED" :
44- return actorName ? ` ${actorName } deleted ` : " Deleted" ;
86+ if (thread ) {
87+ if (isActorPresent ) {
88+ return " Communication deleted" ;
89+ }
90+ return " Thread deleted" ;
91+ }
92+ return " Deleted" ;
4593 case " TAGGED" :
4694 return " You were tagged in a post" ;
4795 default :
48- return actorName ? ` ${ kind } - ${ actorName } ` : kind ;
96+ return kind ;
4997 }
5098};
5199
52- const fetchEnrichedNotifications = async () => {
53- const res = await getMyNotifications ();
54- const data = await Promise .all (
55- (res .data || []).map (async (n ) => {
56- const enriched: EnrichedNotification = { ... n };
57- try {
58- const speakerId = n .speaker ;
59- const companyId = n .company ;
60-
61- if (speakerId ) {
62- const spRes = await getSpeakerById (speakerId );
63- const sp = spRes ?.data || spRes ;
64- if (sp ) {
65- enriched .actor = {
66- type: " speaker" ,
67- id: sp .id ,
68- name: sp .name ,
69- avatar: sp .imgs ?.speaker || sp .imgs ?.internal || undefined ,
70- };
71- enriched .message = makeMessage (n .kind , enriched .actor );
72- }
73- } else if (companyId ) {
74- const coRes = await getCompanyById (companyId );
75- const co = coRes ?.data || coRes ;
76- if (co ) {
77- enriched .actor = {
78- type: " company" ,
79- id: co .id ,
80- name: co .name ,
81- avatar: co .imgs ?.public || co .imgs ?.internal || undefined ,
82- };
83- enriched .message = makeMessage (n .kind , enriched .actor );
84- }
85- }
86- } catch {
87- // ignore enrichment errors
88- }
89- if (! enriched .message && enriched .actor )
90- enriched .message = makeMessage (n .kind , enriched .actor );
91- return enriched ;
92- }),
93- );
94- return { ... res , data };
95- };
96-
97100const { data : notifications } = useQuery ({
98101 key: [" notifications" ],
99- query: fetchEnrichedNotifications ,
102+ query: getMyNotifications ,
100103});
101104
102105const notificationItems = computed (() => {
103- const items = (notifications .value ?.data as EnrichedNotification []) || [];
106+ const items = (notifications .value ?.data as Notification []) || [];
104107 // sort newest first — try common timestamp fields (date, createdAt, created_at)
105108 return items .slice ().sort ((a , b ) => b .date ?.localeCompare (a .date ?? " " ) || 0 );
106109});
@@ -119,19 +122,26 @@ const removeAllNotifications = async () => {
119122};
120123
121124const router = useRouter ();
122- const navigateNotification = (n : EnrichedNotification ) => {
123- const actor = n .actor ;
124- if (actor ?.type === " speaker" && actor ?.id ) {
125- router .push ({ name: " speaker" , params: { speakerId: actor .id } });
125+ const navigateNotification = (n : Notification ) => {
126+ // ensure speaker is an object (not a string) before accessing .id
127+ if (n .speaker && typeof n .speaker === " object" && (n .speaker as Speaker ).id ) {
128+ router .push ({
129+ name: " speaker" ,
130+ params: { speakerId: (n .speaker as Speaker ).id },
131+ });
126132 return ;
127133 }
128- if (actor ?.type === " company" && actor ?.id ) {
129- router .push ({ name: " company" , params: { companyId: actor .id } });
134+ // ensure company is an object (not a string) before accessing .id
135+ if (n .company && typeof n .company === " object" && (n .company as Company ).id ) {
136+ router .push ({
137+ name: " company" ,
138+ params: { companyId: (n .company as Company ).id },
139+ });
130140 return ;
131141 }
132142};
133143
134- const onNotificationClick = async (n : EnrichedNotification ) => {
144+ const onNotificationClick = async (n : Notification ) => {
135145 if (! n || ! n .id ) return ;
136146 try {
137147 await removeNotification (n .id );
@@ -186,15 +196,15 @@ const onNotificationClick = async (n: EnrichedNotification) => {
186196 >
187197 <div class =" flex items-center gap-3" >
188198 <Image
189- v-if =" n.actor && n.actor .avatar"
190- :src =" n.actor .avatar"
199+ v-if =" getActor(n)? .avatar"
200+ :src =" getActor(n)? .avatar"
191201 alt =" actor"
192202 class =" h-8 w-8 rounded-full object-cover"
193203 />
194204 <div class =" text-sm" >
195- <div class =" font-medium" >{{ n.message || n.kind }}</div >
205+ <div class =" font-medium" >{{ makeMessage(n) }}</div >
196206 <div class =" text-xs text-gray-500" >
197- {{ n.actor ?.name || n.date }}
207+ {{ getActor(n) ?.name || n.date }}
198208 </div >
199209 </div >
200210 </div >
0 commit comments