mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 08:03:13 +00:00
47 lines
1.7 KiB
TypeScript
47 lines
1.7 KiB
TypeScript
import { useMemo } from "react";
|
|
import { useNavigate } from "react-router";
|
|
import type { NotificationItem } from "@/domain/notifications/types/notification-feed";
|
|
import { useNotificationSession } from "@/domain/notifications/session/notification-session-context";
|
|
import { useNotificationFeed } from "@/domain/notifications/use-cases/use-notification-feed";
|
|
import { notificationTargetUrl } from "@/domain/notifications/utils/notification-target-url";
|
|
import {
|
|
isDismissable,
|
|
visibleNotificationSections,
|
|
} from "@/domain/notifications/utils/visible-notification-sections";
|
|
|
|
export function useNotificationCenter(onNavigate?: () => void) {
|
|
const navigate = useNavigate();
|
|
const feed = useNotificationFeed();
|
|
const { dismissedIds, readIds, dismiss, markRead } = useNotificationSession();
|
|
|
|
const sections = useMemo(
|
|
() => visibleNotificationSections(feed.data?.sections ?? [], dismissedIds),
|
|
[feed.data, dismissedIds],
|
|
);
|
|
const items = useMemo(() => sections.flatMap((section) => section.items), [sections]);
|
|
const unreadIds = useMemo(
|
|
() => new Set(items.filter((item) => !readIds.has(item.id)).map((item) => item.id)),
|
|
[items, readIds],
|
|
);
|
|
|
|
const open = (item: NotificationItem, url = notificationTargetUrl(item)) => {
|
|
markRead([item.id]);
|
|
if (url == null) return;
|
|
onNavigate?.();
|
|
navigate(url);
|
|
};
|
|
|
|
return {
|
|
sections,
|
|
unreadIds,
|
|
isLoading: feed.isLoading,
|
|
hasData: feed.data != null,
|
|
error: feed.error,
|
|
open,
|
|
dismiss: (item: NotificationItem) => dismiss([item.id]),
|
|
dismissAll: () => dismiss(items.filter(isDismissable).map((item) => item.id)),
|
|
markAllRead: () => markRead(items.map((item) => item.id)),
|
|
};
|
|
}
|
|
|
|
export type NotificationCenter = ReturnType<typeof useNotificationCenter>;
|