/** * LandveX Finance — Global State Management * Sprint 3: UI-refaktorering * * Förenklad Redux-pattern för vanilla JS. */ const S = { // Period period: '2026-06', periodMode: 'month', // month | quarter | custom fiscalYear: 2026, // Navigation tab: 'overview', previousTab: null, // Data cache (per tab) data: { overview: null, transactions: null, invoices: null, vat: null, payroll: null, period: null, tasks: null, forecast: null, }, // UI-state filters: { transactions: { search: '', status: 'all', account: '' }, invoices: { status: 'all' }, }, // Onboarding onboarding: { completed: false, step: 0, profile: null, }, // Användare user: null, tenant: 'landvex', // Loading loading: new Set(), // Errors lastError: null, }; const listeners = new Set(); export const state = { get: () => ({ ...S }), set: (patch) => { Object.assign(S, patch); listeners.forEach(fn => { try { fn(S); } catch (e) { console.error('[state] listener error:', e); } }); }, subscribe: (fn) => { listeners.add(fn); return () => listeners.delete(fn); }, // Helpers setTab: (tab) => { S.previousTab = S.tab; S.tab = tab; listeners.forEach(fn => fn(S)); }, setPeriod: (period) => { S.period = period; // Rensa cache vid periodändring Object.keys(S.data).forEach(k => S.data[k] = null); listeners.forEach(fn => fn(S)); }, setLoading: (key, isLoading) => { if (isLoading) S.loading.add(key); else S.loading.delete(key); listeners.forEach(fn => fn(S)); }, setData: (key, data) => { S.data[key] = data; listeners.forEach(fn => fn(S)); }, setError: (error) => { S.lastError = error; listeners.forEach(fn => fn(S)); }, }; // Persistens i localStorage function loadFromStorage() { try { const raw = localStorage.getItem('landvex:state'); if (raw) { const saved = JSON.parse(raw); Object.assign(S, { period: saved.period || S.period, periodMode: saved.periodMode || S.periodMode, onboarding: saved.onboarding || S.onboarding, }); } } catch { /* ignore */ } } function saveToStorage() { try { localStorage.setItem('landvex:state', JSON.stringify({ period: S.period, periodMode: S.periodMode, onboarding: S.onboarding, })); } catch { /* ignore */ } } // Auto-save vid ändringar state.subscribe(() => saveToStorage()); // Init loadFromStorage(); export default state;