| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| import { useState, useEffect } from 'react';
|
|
|
| export const useNotifications = (statusState) => {
|
| const [noticeVisible, setNoticeVisible] = useState(false);
|
| const [unreadCount, setUnreadCount] = useState(0);
|
|
|
| const announcements = statusState?.status?.announcements || [];
|
|
|
|
|
| const getAnnouncementKey = (a) =>
|
| `${a?.publishDate || ''}-${(a?.content || '').slice(0, 30)}`;
|
|
|
| const calculateUnreadCount = () => {
|
| if (!announcements.length) return 0;
|
| let readKeys = [];
|
| try {
|
| readKeys = JSON.parse(localStorage.getItem('notice_read_keys')) || [];
|
| } catch (_) {
|
| readKeys = [];
|
| }
|
| const readSet = new Set(readKeys);
|
| return announcements.filter((a) => !readSet.has(getAnnouncementKey(a)))
|
| .length;
|
| };
|
|
|
| const getUnreadKeys = () => {
|
| if (!announcements.length) return [];
|
| let readKeys = [];
|
| try {
|
| readKeys = JSON.parse(localStorage.getItem('notice_read_keys')) || [];
|
| } catch (_) {
|
| readKeys = [];
|
| }
|
| const readSet = new Set(readKeys);
|
| return announcements
|
| .filter((a) => !readSet.has(getAnnouncementKey(a)))
|
| .map(getAnnouncementKey);
|
| };
|
|
|
|
|
| useEffect(() => {
|
| setUnreadCount(calculateUnreadCount());
|
| }, [announcements]);
|
|
|
|
|
| const handleNoticeOpen = () => {
|
| setNoticeVisible(true);
|
| };
|
|
|
| const handleNoticeClose = () => {
|
| setNoticeVisible(false);
|
| if (announcements.length) {
|
| let readKeys = [];
|
| try {
|
| readKeys = JSON.parse(localStorage.getItem('notice_read_keys')) || [];
|
| } catch (_) {
|
| readKeys = [];
|
| }
|
| const mergedKeys = Array.from(
|
| new Set([...readKeys, ...announcements.map(getAnnouncementKey)]),
|
| );
|
| localStorage.setItem('notice_read_keys', JSON.stringify(mergedKeys));
|
| }
|
| setUnreadCount(0);
|
| };
|
|
|
| return {
|
| noticeVisible,
|
| unreadCount,
|
| announcements,
|
| handleNoticeOpen,
|
| handleNoticeClose,
|
| getUnreadKeys,
|
| };
|
| };
|
|
|