import { create } from 'zustand'; import { devtools, persist } from 'zustand/middleware'; // Tipos para notificações export interface Notification { id: string; type: 'success' | 'error' | 'warning' | 'info'; title: string; message: string; timestamp: string; read: boolean; autoClose?: boolean; duration?: number; } // Tipos para configurações export interface AppSettings { theme: 'light' | 'dark' | 'system'; language: 'pt-BR' | 'en-US'; autoSync: boolean; syncInterval: number; // em minutos offlineMode: boolean; notifications: { push: boolean; email: boolean; sound: boolean; }; display: { density: 'compact' | 'comfortable' | 'spacious'; animations: boolean; reducedMotion: boolean; }; } // Estado da aplicação focado em UI e configurações interface AppState { // Estado de conectividade e sincronização isOnline: boolean; isSyncing: boolean; lastSync: string | null; syncError: string | null; // Estado de UI isLoading: boolean; sidebarCollapsed: boolean; currentView: string; // Notificações notifications: Notification[]; // Configurações settings: AppSettings; // Filtros e estado de navegação filters: { users: Record; obras: Record; tasks: Record; rdos: Record; }; // Ações para conectividade setOnline: (online: boolean) => void; setConnectivity: (online: boolean) => void; setSyncing: (syncing: boolean) => void; setLastSync: (timestamp: string) => void; setSyncError: (error: string | null) => void; // Ações para UI setLoading: (loading: boolean) => void; setSidebarCollapsed: (collapsed: boolean) => void; setCurrentView: (view: string) => void; // Ações para notificações addNotification: (notification: Omit) => void; removeNotification: (id: string) => void; markNotificationAsRead: (id: string) => void; clearNotifications: () => void; // Ações para configurações updateSettings: (settings: Partial) => void; resetSettings: () => void; // Ações para filtros setFilter: (entity: keyof AppState['filters'], filters: Record) => void; clearFilters: (entity?: keyof AppState['filters']) => void; // Utilitários initializeApp: () => void; reset: () => void; } const defaultSettings: AppSettings = { theme: 'system', language: 'pt-BR', autoSync: true, syncInterval: 5, offlineMode: false, notifications: { push: true, email: false, sound: true, }, display: { density: 'comfortable', animations: true, reducedMotion: false, }, }; const initialState = { isOnline: navigator.onLine, isSyncing: false, lastSync: null, syncError: null, isLoading: false, sidebarCollapsed: false, currentView: 'dashboard', notifications: [], settings: defaultSettings, filters: { users: {}, obras: {}, tasks: {}, rdos: {}, }, }; export const useAppStateStore = create()( devtools( persist( (set, get) => ({ ...initialState, // Ações para conectividade setOnline: (online) => set({ isOnline: online }, false, 'setOnline'), setConnectivity: (online) => set({ isOnline: online }, false, 'setConnectivity'), setSyncing: (syncing) => set({ isSyncing: syncing }, false, 'setSyncing'), setLastSync: (timestamp) => set({ lastSync: timestamp }, false, 'setLastSync'), setSyncError: (error) => set({ syncError: error }, false, 'setSyncError'), // Ações para UI setLoading: (loading) => set({ isLoading: loading }, false, 'setLoading'), setSidebarCollapsed: (collapsed) => set({ sidebarCollapsed: collapsed }, false, 'setSidebarCollapsed'), setCurrentView: (view) => set({ currentView: view }, false, 'setCurrentView'), // Ações para notificações addNotification: (notification) => { const newNotification: Notification = { ...notification, id: crypto.randomUUID(), timestamp: new Date().toISOString(), read: false, }; set( (state) => ({ notifications: [newNotification, ...state.notifications].slice(0, 50), // Manter apenas 50 notificações }), false, 'addNotification' ); }, removeNotification: (id) => { set( (state) => ({ notifications: state.notifications.filter(n => n.id !== id), }), false, 'removeNotification' ); }, markNotificationAsRead: (id) => { set( (state) => ({ notifications: state.notifications.map(n => n.id === id ? { ...n, read: true } : n ), }), false, 'markNotificationAsRead' ); }, clearNotifications: () => set({ notifications: [] }, false, 'clearNotifications'), // Ações para configurações updateSettings: (newSettings) => { set( (state) => ({ settings: { ...state.settings, ...newSettings }, }), false, 'updateSettings' ); }, resetSettings: () => set({ settings: defaultSettings }, false, 'resetSettings'), // Ações para filtros setFilter: (entity, filters) => { set( (state) => ({ filters: { ...state.filters, [entity]: filters, }, }), false, 'setFilter' ); }, clearFilters: (entity) => { if (entity) { set( (state) => ({ filters: { ...state.filters, [entity]: {}, }, }), false, 'clearFilter' ); } else { set( { filters: { users: {}, obras: {}, tasks: {}, rdos: {}, }, }, false, 'clearAllFilters' ); } }, // Utilitários initializeApp: () => { // Inicializar estado da aplicação set({ isOnline: navigator.onLine, isLoading: false, lastSync: null, syncError: null }, false, 'initializeApp'); }, reset: () => set(initialState, false, 'reset'), }), { name: 'app-state-store', partialize: (state) => ({ settings: state.settings, sidebarCollapsed: state.sidebarCollapsed, filters: state.filters, }), } ), { name: 'app-state-store', } ) ); // Seletores otimizados export const useIsOnline = () => useAppStateStore((state) => state.isOnline); export const useIsSyncing = () => useAppStateStore((state) => state.isSyncing); export const useIsLoading = () => useAppStateStore((state) => state.isLoading); export const useTheme = () => useAppStateStore((state) => state.settings.theme); export const useLanguage = () => useAppStateStore((state) => state.settings.language); export const useNotifications = () => useAppStateStore((state) => state.notifications); export const useUnreadNotifications = () => useAppStateStore((state) => state.notifications.filter(n => !n.read) ); export const useSettings = () => useAppStateStore((state) => state.settings); export const useSidebarCollapsed = () => useAppStateStore((state) => state.sidebarCollapsed); export const useCurrentView = () => useAppStateStore((state) => state.currentView); export const useFilters = (entity: keyof AppState['filters']) => useAppStateStore((state) => state.filters[entity]); // Configurar listeners para eventos do sistema if (typeof window !== 'undefined') { // Listener para mudanças de conectividade window.addEventListener('online', () => { useAppStateStore.getState().setOnline(true); }); window.addEventListener('offline', () => { useAppStateStore.getState().setOnline(false); }); // Listener para mudanças de tema do sistema const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); mediaQuery.addEventListener('change', () => { // Trigger re-render se o tema for 'system' const { settings } = useAppStateStore.getState(); if (settings.theme === 'system') { // Force update para aplicar o novo tema useAppStateStore.getState().updateSettings({ theme: 'system' }); } }); }