mirror of
https://github.com/temetro/temetro.git
synced 2026-07-26 11:58:14 +00:00
288d14758f
Auto-generate notifications on patient record create/update (fan out to the other clinic members, pushed live), and wire the sidebar bell to real data via a useNotifications hook over the shared socket: live unread badge, real list, mark-all-read on open. Drops the hardcoded sample array and the dead "View all" link. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
53 lines
1.3 KiB
TypeScript
53 lines
1.3 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
|
|
import {
|
|
type Notification,
|
|
listNotifications,
|
|
markAllNotificationsRead,
|
|
} from "@/lib/notifications";
|
|
import { getSocket } from "@/lib/socket";
|
|
|
|
// Loads the signed-in user's notifications and keeps them live via the shared
|
|
// socket ("notification:new"). Exposes a markAllRead action for the popover.
|
|
export function useNotifications() {
|
|
const [items, setItems] = useState<Notification[]>([]);
|
|
const [unread, setUnread] = useState(0);
|
|
|
|
useEffect(() => {
|
|
let active = true;
|
|
listNotifications()
|
|
.then((res) => {
|
|
if (active) {
|
|
setItems(res.notifications);
|
|
setUnread(res.unread);
|
|
}
|
|
})
|
|
.catch(() => {
|
|
/* api-client redirects on 401 */
|
|
});
|
|
|
|
const socket = getSocket();
|
|
const onNew = (n: Notification) => {
|
|
setItems((prev) => [n, ...prev].slice(0, 30));
|
|
setUnread((u) => u + 1);
|
|
};
|
|
socket.on("notification:new", onNew);
|
|
return () => {
|
|
active = false;
|
|
socket.off("notification:new", onNew);
|
|
};
|
|
}, []);
|
|
|
|
const markAllRead = async () => {
|
|
setItems((prev) => prev.map((n) => ({ ...n, read: true })));
|
|
setUnread(0);
|
|
try {
|
|
await markAllNotificationsRead();
|
|
} catch {
|
|
/* best-effort */
|
|
}
|
|
};
|
|
|
|
return { items, unread, markAllRead };
|
|
}
|