/** * state.js - Centralized state management for the dashboard * * This module maintains the application state and provides getters/setters * to allow other modules to interact with the state in a controlled manner. */ import { formatDateForAPI } from './dateUtils.js'; // Import from dateUtils // State container - private to this module const state = { // Current view/period currentPeriod: 'daily', // 'daily', 'weekly', 'monthly' selectedDate: formatDateForAPI(new Date()), // Current date in YYYY-MM-DD format currentDate: new Date(), // Date object for the selected date selectedWeekDay: null, // Selected day within weekly view // Table data and filtering reportData: [], // Currently displayed report data currentStateFilter: 'all', // 'all', 'working', 'not_working' userFilterText: '', // Text entered in the user filter input // Sorting currentSortColumn: 'duration', // Which column is being sorted - default to duration (real work hours) currentSortDirection: 'desc', // 'asc' or 'desc' - default to descending // User states userStates: {}, // Cache of user states {username: state} userStatesLastUpdate: 0, // Timestamp of last update STATE_CACHE_DURATION: 5000, // 5 seconds // Auto-refresh autoRefreshEnabled: true, // Auto-refresh enabled by default autoRefreshInterval: 60000, // Default refresh interval (60 seconds). Aligns with client-side 1-minute reporting. autoRefreshTimer: null, // Holds the timer reference lastRefreshTime: Date.now(), // Last time data was refreshed countdownTimer: null, // Timer for updating countdown display }; // Exported getters and setters export default { // Period/view getters and setters getCurrentPeriod: () => state.currentPeriod, setCurrentPeriod: (period) => { state.currentPeriod = period; return state.currentPeriod; }, getSelectedDate: () => state.selectedDate, setSelectedDate: (dateStr) => { state.selectedDate = dateStr; // Parse YYYY-MM-DD as local date to avoid timezone interpretation issues if (dateStr && typeof dateStr === 'string' && dateStr.includes('-')) { const parts = dateStr.split('-'); if (parts.length === 3) { const year = parseInt(parts[0], 10); const month = parseInt(parts[1], 10) - 1; // JavaScript months are 0-indexed const day = parseInt(parts[2], 10); // Check if parts are valid numbers before creating date if (!isNaN(year) && !isNaN(month) && !isNaN(day)) { state.currentDate = new Date(year, month, day); } else { console.warn(`Invalid date parts in setSelectedDate: ${dateStr}`); state.currentDate = new Date(); // Fallback or handle error appropriately } } else { console.warn(`Invalid date string format in setSelectedDate: ${dateStr}`); state.currentDate = new Date(); // Fallback } } else { console.warn(`Invalid dateStr input to setSelectedDate: ${dateStr}`); state.currentDate = new Date(); // Fallback for null or non-string input } return state.selectedDate; }, getCurrentDate: () => state.currentDate, setCurrentDate: (date) => { state.currentDate = date; state.selectedDate = formatDateForAPI(date); return state.currentDate; }, getSelectedWeekDay: () => state.selectedWeekDay, setSelectedWeekDay: (day) => { state.selectedWeekDay = day; return state.selectedWeekDay; }, // Report data getters and setters getReportData: () => state.reportData, setReportData: (data) => { state.reportData = [...data]; return state.reportData; }, // Filter getters and setters getCurrentStateFilter: () => state.currentStateFilter, setCurrentStateFilter: (filter) => { state.currentStateFilter = filter; return state.currentStateFilter; }, getUserFilterText: () => state.userFilterText, setUserFilterText: (text) => { state.userFilterText = text; return state.userFilterText; }, // Sort getters and setters getCurrentSortColumn: () => state.currentSortColumn, setCurrentSortColumn: (column) => { state.currentSortColumn = column; return state.currentSortColumn; }, getCurrentSortDirection: () => state.currentSortDirection, setCurrentSortDirection: (direction) => { state.currentSortDirection = direction; return state.currentSortDirection; }, // User states getters and setters getUserStates: () => state.userStates, setUserStates: (states) => { state.userStates = {...states}; state.userStatesLastUpdate = Date.now(); return state.userStates; }, getUserStatesLastUpdate: () => state.userStatesLastUpdate, getStateCacheDuration: () => state.STATE_CACHE_DURATION, // Auto-refresh getters and setters isAutoRefreshEnabled: () => state.autoRefreshEnabled, setAutoRefreshEnabled: (enabled) => { state.autoRefreshEnabled = enabled; return state.autoRefreshEnabled; }, getAutoRefreshInterval: () => state.autoRefreshInterval, setAutoRefreshInterval: (interval) => { state.autoRefreshInterval = interval; return state.autoRefreshInterval; }, getAutoRefreshTimer: () => state.autoRefreshTimer, setAutoRefreshTimer: (timer) => { state.autoRefreshTimer = timer; return state.autoRefreshTimer; }, getLastRefreshTime: () => state.lastRefreshTime, setLastRefreshTime: (time) => { state.lastRefreshTime = time; return state.lastRefreshTime; }, getCountdownTimer: () => state.countdownTimer, setCountdownTimer: (timer) => { state.countdownTimer = timer; return state.countdownTimer; } };