Replace all console.log/warn/error statements with unified logger utility. Changes: - Replaced console in lib/hooks/use-stories.ts - Replaced console in lib/signalr/SignalRContext.tsx - Replaced console in lib/hooks/useProjectHub.ts - Replaced console in lib/hooks/use-tasks.ts - Replaced console in lib/hooks/useNotificationHub.ts - Replaced console in lib/hooks/use-projects.ts - Replaced console in app/(dashboard)/projects/[id]/kanban/page.tsx Logger respects NODE_ENV (debug disabled in production). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
81 lines
2.2 KiB
TypeScript
81 lines
2.2 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState, useCallback, useRef } from 'react';
|
|
import { SignalRConnectionManager } from '@/lib/signalr/ConnectionManager';
|
|
import { SIGNALR_CONFIG } from '@/lib/signalr/config';
|
|
import { useAuthStore } from '@/stores/authStore';
|
|
import { logger } from '@/lib/utils/logger';
|
|
|
|
export interface Notification {
|
|
message: string;
|
|
type: 'info' | 'success' | 'warning' | 'error' | 'test';
|
|
timestamp: string;
|
|
}
|
|
|
|
export function useNotificationHub() {
|
|
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
|
|
const [connectionState, setConnectionState] = useState<
|
|
'disconnected' | 'connecting' | 'connected' | 'reconnecting'
|
|
>('disconnected');
|
|
const [notifications, setNotifications] = useState<Notification[]>([]);
|
|
const managerRef = useRef<SignalRConnectionManager | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (!isAuthenticated) return;
|
|
|
|
const manager = new SignalRConnectionManager(
|
|
SIGNALR_CONFIG.HUB_URLS.NOTIFICATION
|
|
);
|
|
managerRef.current = manager;
|
|
|
|
// 监听连接状态
|
|
const unsubscribe = manager.onStateChange(setConnectionState);
|
|
|
|
// 监听通知事件
|
|
manager.on('Notification', (notification: Notification) => {
|
|
logger.debug('[NotificationHub] Received notification:', notification);
|
|
setNotifications((prev) => [notification, ...prev].slice(0, 50)); // 保留最近 50 条
|
|
});
|
|
|
|
manager.on(
|
|
'NotificationRead',
|
|
(data: { NotificationId: string; ReadAt: string }) => {
|
|
logger.debug('[NotificationHub] Notification read:', data);
|
|
}
|
|
);
|
|
|
|
// 启动连接
|
|
manager.start();
|
|
|
|
return () => {
|
|
unsubscribe();
|
|
manager.stop();
|
|
};
|
|
}, [isAuthenticated]);
|
|
|
|
const markAsRead = useCallback(async (notificationId: string) => {
|
|
if (!managerRef.current) return;
|
|
|
|
try {
|
|
await managerRef.current.invoke('MarkAsRead', notificationId);
|
|
} catch (error) {
|
|
logger.error(
|
|
'[NotificationHub] Error marking notification as read:',
|
|
error
|
|
);
|
|
}
|
|
}, []);
|
|
|
|
const clearNotifications = useCallback(() => {
|
|
setNotifications([]);
|
|
}, []);
|
|
|
|
return {
|
|
connectionState,
|
|
notifications,
|
|
markAsRead,
|
|
clearNotifications,
|
|
isConnected: connectionState === 'connected',
|
|
};
|
|
}
|