50 lines
1.1 KiB
TypeScript
50 lines
1.1 KiB
TypeScript
export type NotificationScope = 'photos' | 'guests' | 'gallery' | 'events' | 'package' | 'general';
|
|
|
|
export type ScopedNotification = {
|
|
scope: NotificationScope;
|
|
is_read?: boolean;
|
|
};
|
|
|
|
export type NotificationGroup<T extends ScopedNotification> = {
|
|
scope: NotificationScope;
|
|
items: T[];
|
|
unread: number;
|
|
};
|
|
|
|
const SCOPE_ORDER: NotificationScope[] = [
|
|
'photos',
|
|
'guests',
|
|
'gallery',
|
|
'events',
|
|
'package',
|
|
'general',
|
|
];
|
|
|
|
export function groupNotificationsByScope<T extends ScopedNotification>(items: T[]): NotificationGroup<T>[] {
|
|
const groups = new Map<NotificationScope, NotificationGroup<T>>();
|
|
|
|
items.forEach((item) => {
|
|
const scope = item.scope ?? 'general';
|
|
const existing = groups.get(scope);
|
|
if (existing) {
|
|
existing.items.push(item);
|
|
if (!item.is_read) {
|
|
existing.unread += 1;
|
|
}
|
|
return;
|
|
}
|
|
|
|
groups.set(scope, {
|
|
scope,
|
|
items: [item],
|
|
unread: item.is_read ? 0 : 1,
|
|
});
|
|
});
|
|
|
|
return Array.from(groups.values()).sort((a, b) => {
|
|
const aIndex = SCOPE_ORDER.indexOf(a.scope);
|
|
const bIndex = SCOPE_ORDER.indexOf(b.scope);
|
|
return aIndex - bIndex;
|
|
});
|
|
}
|