interface StorageData { calculations: any[]; reports: any[]; settings: Record; } class LocalStorage { private dbName = 'PrithviGuardianDB'; private version = 1; private db: IDBDatabase | null = null; async init(): Promise { return new Promise((resolve, reject) => { const request = indexedDB.open(this.dbName, this.version); request.onerror = () => reject(request.error); request.onsuccess = () => { this.db = request.result; resolve(); }; request.onupgradeneeded = (event) => { const db = (event.target as IDBOpenDBRequest).result; // Create object stores if (!db.objectStoreNames.contains('calculations')) { const calculationStore = db.createObjectStore('calculations', { keyPath: 'id', autoIncrement: true }); calculationStore.createIndex('module', 'module', { unique: false }); calculationStore.createIndex('timestamp', 'timestamp', { unique: false }); } if (!db.objectStoreNames.contains('reports')) { const reportStore = db.createObjectStore('reports', { keyPath: 'id', autoIncrement: true }); reportStore.createIndex('title', 'title', { unique: false }); reportStore.createIndex('timestamp', 'timestamp', { unique: false }); } if (!db.objectStoreNames.contains('settings')) { db.createObjectStore('settings', { keyPath: 'key' }); } if (!db.objectStoreNames.contains('history')) { const historyStore = db.createObjectStore('history', { keyPath: 'id', autoIncrement: true }); historyStore.createIndex('type', 'type', { unique: false }); historyStore.createIndex('timestamp', 'timestamp', { unique: false }); } }; }); } async saveCalculation(module: string, type: string, inputs: any, results: any): Promise { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const transaction = this.db!.transaction(['calculations'], 'readwrite'); const store = transaction.objectStore('calculations'); const calculation = { module, type, inputs, results, timestamp: new Date().toISOString() }; const request = store.add(calculation); request.onsuccess = () => resolve(request.result as number); request.onerror = () => reject(request.error); }); } async getCalculations(module?: string): Promise { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const transaction = this.db!.transaction(['calculations'], 'readonly'); const store = transaction.objectStore('calculations'); let request: IDBRequest; if (module) { const index = store.index('module'); request = index.getAll(module); } else { request = store.getAll(); } request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); } async saveReport(title: string, content: any, pdfData?: string): Promise { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const transaction = this.db!.transaction(['reports'], 'readwrite'); const store = transaction.objectStore('reports'); const report = { title, content, pdfData, timestamp: new Date().toISOString() }; const request = store.add(report); request.onsuccess = () => resolve(request.result as number); request.onerror = () => reject(request.error); }); } async getReports(): Promise { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const transaction = this.db!.transaction(['reports'], 'readonly'); const store = transaction.objectStore('reports'); const request = store.getAll(); request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); } async saveSetting(key: string, value: any): Promise { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const transaction = this.db!.transaction(['settings'], 'readwrite'); const store = transaction.objectStore('settings'); const request = store.put({ key, value }); request.onsuccess = () => resolve(); request.onerror = () => reject(request.error); }); } async getSetting(key: string): Promise { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const transaction = this.db!.transaction(['settings'], 'readonly'); const store = transaction.objectStore('settings'); const request = store.get(key); request.onsuccess = () => resolve(request.result?.value); request.onerror = () => reject(request.error); }); } async addToHistory(type: string, action: string, data: any): Promise { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const transaction = this.db!.transaction(['history'], 'readwrite'); const store = transaction.objectStore('history'); const historyEntry = { type, action, data, timestamp: new Date().toISOString() }; const request = store.add(historyEntry); request.onsuccess = () => resolve(); request.onerror = () => reject(request.error); }); } async getHistory(type?: string): Promise { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const transaction = this.db!.transaction(['history'], 'readonly'); const store = transaction.objectStore('history'); let request: IDBRequest; if (type) { const index = store.index('type'); request = index.getAll(type); } else { request = store.getAll(); } request.onsuccess = () => resolve(request.result); request.onerror = () => reject(request.error); }); } async clearData(storeName?: string): Promise { if (!this.db) await this.init(); return new Promise((resolve, reject) => { const storeNames = storeName ? [storeName] : ['calculations', 'reports', 'history']; const transaction = this.db!.transaction(storeNames, 'readwrite'); let completed = 0; const total = storeNames.length; storeNames.forEach(name => { const store = transaction.objectStore(name); const request = store.clear(); request.onsuccess = () => { completed++; if (completed === total) resolve(); }; request.onerror = () => reject(request.error); }); }); } async getStorageStats(): Promise<{ calculations: number; reports: number; size: string }> { if (!this.db) await this.init(); try { const [calculations, reports] = await Promise.all([ this.getCalculations(), this.getReports() ]); // Estimate storage size const dataSize = JSON.stringify({ calculations, reports }).length; const sizeInMB = (dataSize / (1024 * 1024)).toFixed(1); return { calculations: calculations.length, reports: reports.length, size: sizeInMB }; } catch (error) { return { calculations: 0, reports: 0, size: '0.0' }; } } async exportData(): Promise { if (!this.db) await this.init(); const [calculations, reports, history] = await Promise.all([ this.getCalculations(), this.getReports(), this.getHistory() ]); const exportData = { version: this.version, timestamp: new Date().toISOString(), data: { calculations, reports, history } }; return JSON.stringify(exportData, null, 2); } async importData(jsonData: string): Promise { if (!this.db) await this.init(); try { const importData = JSON.parse(jsonData); if (!importData.data) { throw new Error('Invalid data format'); } // Clear existing data await this.clearData(); // Import calculations if (importData.data.calculations) { for (const calc of importData.data.calculations) { await this.saveCalculation(calc.module, calc.type, calc.inputs, calc.results); } } // Import reports if (importData.data.reports) { for (const report of importData.data.reports) { await this.saveReport(report.title, report.content, report.pdfData); } } // Import history if (importData.data.history) { for (const entry of importData.data.history) { await this.addToHistory(entry.type, entry.action, entry.data); } } } catch (error) { throw new Error('Failed to import data: ' + (error as Error).message); } } } // Singleton instance export const localStorage = new LocalStorage(); // Initialize on first import localStorage.init().catch(console.error); // Utility functions for common operations export const storage = { // Calculations saveCalculation: (module: string, type: string, inputs: any, results: any) => localStorage.saveCalculation(module, type, inputs, results), getCalculations: (module?: string) => localStorage.getCalculations(module), // Reports saveReport: (title: string, content: any, pdfData?: string) => localStorage.saveReport(title, content, pdfData), getReports: () => localStorage.getReports(), // Settings saveSetting: (key: string, value: any) => localStorage.saveSetting(key, value), getSetting: (key: string) => localStorage.getSetting(key), // History addToHistory: (type: string, action: string, data: any) => localStorage.addToHistory(type, action, data), getHistory: (type?: string) => localStorage.getHistory(type), // Utilities getStorageStats: () => localStorage.getStorageStats(), clearData: (storeName?: string) => localStorage.clearData(storeName), exportData: () => localStorage.exportData(), importData: (jsonData: string) => localStorage.importData(jsonData) }; export default storage;