Skip to content

Commit 14c4eb9

Browse files
committed
fix: added more information on notification cards
1 parent f4a6519 commit 14c4eb9

File tree

3 files changed

+525
-349
lines changed

3 files changed

+525
-349
lines changed

src/app/routes/_app.notifications/route.tsx

Lines changed: 197 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,19 @@ import { Fragment } from 'react/jsx-runtime';
2626
import {
2727
alertLoadingSelector,
2828
alertsSelector,
29+
markAllAsRead,
2930
markAsRead,
3031
NotificationObject,
3132
NotificationType,
3233
} from '@/store/notifications/slice';
3334
import { useStore } from 'react-redux';
35+
import { compactFormat } from '@/utils/number';
36+
import {
37+
getBgClassNameOfAuraRatingObject,
38+
getTextClassNameOfAuraRatingObject,
39+
} from '@/constants';
40+
import { useMemo } from 'react';
41+
import Tooltip from '@/components/Shared/Tooltip';
3442

3543
// Define icons for evaluation categories
3644
export const subjectViewAsIconColored: {
@@ -92,6 +100,7 @@ export function parseTitleAndDescription(
92100
resolve: (key: string) => BrightIdBackupConnection,
93101
brightId: string | undefined,
94102
to?: string | null,
103+
newState?: any,
95104
) {
96105
switch (type) {
97106
case NotificationType.Evaluation:
@@ -108,39 +117,38 @@ export function parseTitleAndDescription(
108117
);
109118
case NotificationType.LevelIncrease:
110119
if (profileId === brightId) {
111-
return 'Your ' + description;
120+
return 'Your Level increased';
112121
}
113122
return (
114123
(resolve(profileId)?.name ?? shortenBrightIdName(profileId)) +
115124
' ' +
116-
description
125+
'Leveled up'
117126
);
118127
case NotificationType.LevelDecrease:
119128
if (profileId === brightId) {
120-
return 'Your ' + description;
129+
return 'Your Level decreased';
121130
}
122131
return (
123132
(resolve(profileId)?.name ?? shortenBrightIdName(profileId)) +
124-
' ' +
125-
description
133+
' Level Decreased'
126134
);
127135
case NotificationType.ScoreDecrease:
128136
if (profileId === brightId) {
129-
return 'Your ' + description;
137+
return 'Your Score dropped to ' + compactFormat(newState);
130138
}
131139
return (
132140
(resolve(profileId)?.name ?? shortenBrightIdName(profileId)) +
133-
' ' +
134-
description
141+
' Score dropped to ' +
142+
compactFormat(newState)
135143
);
136144
case NotificationType.ScoreIncrease:
137145
if (profileId === brightId) {
138-
return 'Your ' + description;
146+
return 'Your Score increased to ' + compactFormat(newState);
139147
}
140148
return (
141149
(resolve(profileId)?.name ?? shortenBrightIdName(profileId)) +
142-
' ' +
143-
description
150+
' Score increased to ' +
151+
compactFormat(newState)
144152
);
145153
}
146154

@@ -206,6 +214,17 @@ export default function NotificationsPage() {
206214
>
207215
<RefreshCcwIcon className={isLoading ? 'animate-spin' : ''} />
208216
</Button> */}
217+
{notifications.filter((item) => !item.viewed).length > 0 && (
218+
<div className="flex justify-end">
219+
<Button
220+
size="sm"
221+
className=""
222+
onClick={() => dispatch(markAllAsRead())}
223+
>
224+
Mark all as read
225+
</Button>
226+
</div>
227+
)}
209228
<section className="mt-8 flex w-full flex-col gap-4">
210229
<Tabs defaultValue={categories[0]}>
211230
<TabsList className="w-full">
@@ -291,7 +310,7 @@ function NotificationCard({
291310
<Link to={`/subject/${notification.from}?viewas=${notification.category}`}>
292311
<Card
293312
className={cn(
294-
'my-2 flex items-center gap-4 rounded-lg p-4',
313+
'my-2 flex gap-4 rounded-lg p-4',
295314
!notification.viewed && 'bg-muted',
296315
notification.viewed && 'opacity-50',
297316
)}
@@ -311,25 +330,179 @@ function NotificationCard({
311330
resolve,
312331
brightId,
313332
notification.to,
333+
notification.newState,
314334
)}
315335
</div>
316336
<div className="mt-1 text-xs text-muted-foreground">
317337
{new Date(notification.timestamp).toLocaleString()}
318338
</div>
319339
</div>
320-
{!notification.viewed && (
321-
<Button
322-
size="sm"
323-
variant="outline"
324-
onClick={(e) => {
325-
e.stopPropagation();
326-
dispatch(markAsRead(notification.id));
327-
}}
328-
>
329-
Mark as read
330-
</Button>
331-
)}
340+
<div className="flex flex-col justify-end">
341+
<div className="mb-5">
342+
{notification.type === NotificationType.Evaluation &&
343+
notification.extraPayloads ? (
344+
<EvaluationInfo
345+
impact={notification.newState! as number}
346+
rating={Number(notification.extraPayloads?.rating)}
347+
/>
348+
) : [
349+
NotificationType.LevelDecrease,
350+
NotificationType.LevelIncrease,
351+
].includes(notification.type) ? (
352+
<LevelInfo
353+
previousLevel={Number(notification.previousState)}
354+
newLevel={Number(notification.newState)}
355+
/>
356+
) : [
357+
NotificationType.ScoreDecrease,
358+
NotificationType.ScoreIncrease,
359+
].includes(notification.type) ? (
360+
<ScoreInfo
361+
previousScore={Number(notification.previousState)}
362+
newScore={Number(notification.newState)}
363+
/>
364+
) : null}
365+
</div>
366+
{!notification.viewed && (
367+
<div className="">
368+
<Button
369+
size="sm"
370+
variant="outline"
371+
onClick={(e) => {
372+
e.preventDefault();
373+
e.stopPropagation();
374+
dispatch(markAsRead(notification.id));
375+
}}
376+
>
377+
Mark as read
378+
</Button>
379+
</div>
380+
)}
381+
</div>
332382
</Card>
333383
</Link>
334384
);
335385
}
386+
387+
function LevelInfo({
388+
previousLevel,
389+
newLevel,
390+
}: {
391+
previousLevel: number;
392+
newLevel: number;
393+
}) {
394+
const diff = useMemo(
395+
() => newLevel - previousLevel,
396+
[previousLevel, newLevel],
397+
);
398+
399+
const bgColor = getBgClassNameOfAuraRatingObject({
400+
rating: (newLevel - previousLevel).toString(),
401+
});
402+
403+
return (
404+
<div
405+
className={`${bgColor} ml-auto block w-fit rounded-md p-1 text-center text-sm font-semibold`}
406+
>
407+
{diff >= 0 ? '+' : ''} {diff}
408+
</div>
409+
);
410+
}
411+
412+
function ScoreInfo({
413+
previousScore,
414+
newScore,
415+
}: {
416+
previousScore: number;
417+
newScore: number;
418+
}) {
419+
const diff = newScore - previousScore;
420+
const scoreScaledChange = useMemo(() => {
421+
const percentChange =
422+
previousScore !== 0 ? (newScore / previousScore) * 100 : 0;
423+
const scaled = (percentChange / 100) * 4;
424+
return (previousScore < newScore ? 1 : -1) * scaled;
425+
}, [newScore, previousScore]);
426+
427+
const bgColor = getBgClassNameOfAuraRatingObject({
428+
rating: Math.floor(scoreScaledChange).toString(),
429+
});
430+
431+
return (
432+
<span
433+
className={`${bgColor} ml-auto block w-fit rounded-md p-1 text-center text-sm font-semibold`}
434+
>
435+
{diff >= 0 ? '+' : ''} {compactFormat(diff)}
436+
</span>
437+
);
438+
}
439+
440+
function EvaluationInfo({
441+
rating,
442+
impact,
443+
}: {
444+
rating: number;
445+
impact: number;
446+
}) {
447+
const bgColor = useMemo(() => {
448+
if (rating && Number(rating) !== 0) {
449+
return getBgClassNameOfAuraRatingObject({ rating: rating.toString() });
450+
}
451+
if (rating >= 2) {
452+
return 'bg-pl4';
453+
}
454+
if (rating <= 0) {
455+
return 'bg-nl4';
456+
}
457+
return 'bg-pl1';
458+
}, [rating]);
459+
460+
return (
461+
<>
462+
<div className={`flex flex-col gap-0.5 ${bgColor} rounded-md py-1.5`}>
463+
<div className="flex items-center justify-center gap-0.5">
464+
{inboundConnectionInfo &&
465+
connectionLevelIcons[inboundConnectionInfo.level] && (
466+
<Tooltip
467+
content={`You connected with "${inboundConnectionInfo?.level}" to ${name}`}
468+
position="right"
469+
tooltipClassName="!whitespace-normal !w-40"
470+
>
471+
<img
472+
src={`/assets/images/Shared/${
473+
connectionLevelIcons[inboundConnectionInfo.level]
474+
}.svg`}
475+
className="h-[18px] w-[18px]"
476+
alt=""
477+
/>
478+
</Tooltip>
479+
)}
480+
{!!rating && Number(rating?.rating) !== 0 && (
481+
<Tooltip
482+
position="right"
483+
content={`You evaluated ${name} ${
484+
Number(rating.rating) > 0 ? `+${rating.rating}` : rating.rating
485+
} (${ratingToText[rating.rating]})`}
486+
>
487+
<p
488+
className={`text-sm font-bold ${getTextClassNameOfAuraRatingObject(
489+
rating,
490+
)}`}
491+
>
492+
{Number(rating.rating) < 0 ? '-' : '+'}
493+
{Math.abs(Number(rating.rating))}
494+
</p>
495+
</Tooltip>
496+
)}
497+
</div>
498+
<p
499+
className={`impact-percentage ${getTextClassNameOfAuraRatingObject({
500+
rating: rating.toString(),
501+
})} w-full text-center text-[11px] font-bold`}
502+
>
503+
{impact > 0 ? '+' : '-'} {compactFormat(impact)}
504+
</p>
505+
</div>
506+
</>
507+
);
508+
}

0 commit comments

Comments
 (0)