| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| 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, |
| }; |
| }; |
|
|