Files
goldenChart/frontend/src/contexts/VerificationIssueNotificationContext.tsx
T
2026-05-27 15:41:19 +09:00

83 lines
2.3 KiB
TypeScript

/**
* 검증 이슈 등록·단계 변경 실시간 알림 (STOMP)
*/
import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
import { subscribeStompTopic } from '../utils/stompChartBroker';
import {
VERIFICATION_ISSUE_EVENT_TOPIC,
eventToToast,
parseVerificationIssueEvent,
shouldShowVerificationIssueEvent,
type VerificationIssueToastItem,
} from '../utils/verificationIssueEvents';
interface ContextValue {
toasts: VerificationIssueToastItem[];
dismissToast: (id: string) => void;
dismissAll: () => void;
}
const VerificationIssueNotificationContext = createContext<ContextValue | null>(null);
interface ProviderProps {
/** 검증게시판 메뉴 접근 가능 */
enabled: boolean;
/** 일반 설정 — 검증 이슈 알림 ON */
notifyEnabled: boolean;
children: React.ReactNode;
}
export const VerificationIssueNotificationProvider: React.FC<ProviderProps> = ({
enabled,
notifyEnabled,
children,
}) => {
const [toasts, setToasts] = useState<VerificationIssueToastItem[]>([]);
const active = enabled && notifyEnabled;
const dismissToast = useCallback((id: string) => {
setToasts(prev => prev.filter(t => t.id !== id));
}, []);
const dismissAll = useCallback(() => {
setToasts([]);
}, []);
useEffect(() => {
if (!active) {
setToasts([]);
return;
}
return subscribeStompTopic(VERIFICATION_ISSUE_EVENT_TOPIC, msg => {
const event = parseVerificationIssueEvent(msg.body);
if (!event || !shouldShowVerificationIssueEvent(event)) return;
const toast = eventToToast(event);
setToasts(prev => {
const withoutDup = prev.filter(t => t.id !== toast.id);
return [toast, ...withoutDup].slice(0, 8);
});
});
}, [active]);
const value = useMemo(
() => ({ toasts, dismissToast, dismissAll }),
[toasts, dismissToast, dismissAll],
);
return (
<VerificationIssueNotificationContext.Provider value={value}>
{children}
</VerificationIssueNotificationContext.Provider>
);
};
export function useVerificationIssueNotification(): ContextValue {
const ctx = useContext(VerificationIssueNotificationContext);
if (!ctx) {
throw new Error('useVerificationIssueNotification must be used within VerificationIssueNotificationProvider');
}
return ctx;
}