bae705aa97
- Add NFC ePassport roadmap (ICAO 9303, eIDAS) - Add TensorFlow.js edge face detection (BlazeFace) - Add structured audit logger (GDPR-compliant) - Risk scoring support Part of KYC Apple Native UX v1.1.0
134 lines
2.5 KiB
JavaScript
134 lines
2.5 KiB
JavaScript
/**
|
|
* 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;
|