mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 06:42:03 +00:00
- Fix 75 ESLint errors by updating eslint.config.mjs: - Add missing browser globals (MouseEvent, AbortController, Response, etc.) - Add Vite define global (__APP_VERSION__) - Configure @ts-nocheck to require descriptions - Add no-unused-vars rule for .mjs scripts - Fix runtime bug in agent-output-modal.tsx (setOutput -> setStreamedContent) - Remove ~120 unused variable warnings across 97 files: - Remove unused imports (React hooks, lucide icons, types) - Remove unused constants and variables - Remove unused function definitions - Prefix intentionally unused parameters with underscore - Add descriptions to all @ts-nocheck comments (25 files) - Clean up misc issues: - Remove invalid deprecation plugin comments - Fix eslint-disable comment placement - Add missing RefreshCw import in code-view.tsx Reduces lint warnings from ~300 to 67 (all remaining are no-explicit-any) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
130 lines
3.7 KiB
TypeScript
130 lines
3.7 KiB
TypeScript
/**
|
|
* Notifications Store - State management for project-level notifications
|
|
*/
|
|
|
|
import { create } from 'zustand';
|
|
import type { Notification } from '@automaker/types';
|
|
|
|
// ============================================================================
|
|
// State Interface
|
|
// ============================================================================
|
|
|
|
interface NotificationsState {
|
|
// Notifications for the current project
|
|
notifications: Notification[];
|
|
unreadCount: number;
|
|
isLoading: boolean;
|
|
error: string | null;
|
|
|
|
// Popover state
|
|
isPopoverOpen: boolean;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Actions Interface
|
|
// ============================================================================
|
|
|
|
interface NotificationsActions {
|
|
// Data management
|
|
setNotifications: (notifications: Notification[]) => void;
|
|
setUnreadCount: (count: number) => void;
|
|
addNotification: (notification: Notification) => void;
|
|
markAsRead: (notificationId: string) => void;
|
|
markAllAsRead: () => void;
|
|
dismissNotification: (notificationId: string) => void;
|
|
dismissAll: () => void;
|
|
|
|
// Loading state
|
|
setLoading: (loading: boolean) => void;
|
|
setError: (error: string | null) => void;
|
|
|
|
// Popover state
|
|
setPopoverOpen: (open: boolean) => void;
|
|
|
|
// Reset
|
|
reset: () => void;
|
|
}
|
|
|
|
// ============================================================================
|
|
// Initial State
|
|
// ============================================================================
|
|
|
|
const initialState: NotificationsState = {
|
|
notifications: [],
|
|
unreadCount: 0,
|
|
isLoading: false,
|
|
error: null,
|
|
isPopoverOpen: false,
|
|
};
|
|
|
|
// ============================================================================
|
|
// Store
|
|
// ============================================================================
|
|
|
|
export const useNotificationsStore = create<NotificationsState & NotificationsActions>(
|
|
(set, _get) => ({
|
|
...initialState,
|
|
|
|
// Data management
|
|
setNotifications: (notifications) =>
|
|
set({
|
|
notifications,
|
|
unreadCount: notifications.filter((n) => !n.read).length,
|
|
}),
|
|
|
|
setUnreadCount: (count) => set({ unreadCount: count }),
|
|
|
|
addNotification: (notification) =>
|
|
set((state) => ({
|
|
notifications: [notification, ...state.notifications],
|
|
unreadCount: notification.read ? state.unreadCount : state.unreadCount + 1,
|
|
})),
|
|
|
|
markAsRead: (notificationId) =>
|
|
set((state) => {
|
|
const notification = state.notifications.find((n) => n.id === notificationId);
|
|
if (!notification || notification.read) return state;
|
|
|
|
return {
|
|
notifications: state.notifications.map((n) =>
|
|
n.id === notificationId ? { ...n, read: true } : n
|
|
),
|
|
unreadCount: Math.max(0, state.unreadCount - 1),
|
|
};
|
|
}),
|
|
|
|
markAllAsRead: () =>
|
|
set((state) => ({
|
|
notifications: state.notifications.map((n) => ({ ...n, read: true })),
|
|
unreadCount: 0,
|
|
})),
|
|
|
|
dismissNotification: (notificationId) =>
|
|
set((state) => {
|
|
const notification = state.notifications.find((n) => n.id === notificationId);
|
|
if (!notification) return state;
|
|
|
|
return {
|
|
notifications: state.notifications.filter((n) => n.id !== notificationId),
|
|
unreadCount: notification.read ? state.unreadCount : Math.max(0, state.unreadCount - 1),
|
|
};
|
|
}),
|
|
|
|
dismissAll: () =>
|
|
set({
|
|
notifications: [],
|
|
unreadCount: 0,
|
|
}),
|
|
|
|
// Loading state
|
|
setLoading: (loading) => set({ isLoading: loading }),
|
|
setError: (error) => set({ error }),
|
|
|
|
// Popover state
|
|
setPopoverOpen: (open) => set({ isPopoverOpen: open }),
|
|
|
|
// Reset
|
|
reset: () => set(initialState),
|
|
})
|
|
);
|