PrithviGuardian / client /src /lib /offlineStorage.ts
Varad Bakshi
Fresh upload
e7427b5
Raw
History Blame Contribute Delete
8.66 kB
// Offline storage system for PWA using IndexedDB
interface UserProfile {
id: string;
name: string;
phone: string;
organization?: string;
role: 'engineer' | 'student' | 'researcher' | 'government' | 'farmer' | 'consultant';
lastLogin: Date;
createdAt: Date;
}
interface Project {
id: number;
name: string;
description?: string;
type: string;
location?: string;
status: string;
data: any;
createdAt: Date;
updatedAt: Date;
}
interface GovernmentReport {
id: number;
projectId?: number;
reportType: string;
title: string;
content: any;
status: string;
generatedData: any;
createdAt: Date;
}
interface CropPlan {
id: number;
projectId?: number;
farmName: string;
location: string;
soilType: string;
climate: string;
area: number;
cropRotation: any;
waterRequirement: any;
fertilizerPlan: any;
season: string;
createdAt: Date;
}
interface CoastalProject {
id: number;
projectId?: number;
siteName: string;
coordinates: string;
coastlineLength?: number;
mangroveData: any;
erosionRisk: any;
crzMapping: any;
protectionMeasures: any;
createdAt: Date;
}
interface CommunityPost {
id: number;
title: string;
description: string;
category: string;
projectData?: any;
tags: string[];
likes: number;
isPublic: boolean;
createdAt: Date;
}
class OfflineStorage {
private dbName = 'PrithviGuardianDB';
private version = 1;
private db: IDBDatabase | null = null;
async init(): Promise<void> {
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('projects')) {
const projectStore = db.createObjectStore('projects', { keyPath: 'id', autoIncrement: true });
projectStore.createIndex('type', 'type', { unique: false });
}
if (!db.objectStoreNames.contains('governmentReports')) {
const reportStore = db.createObjectStore('governmentReports', { keyPath: 'id', autoIncrement: true });
reportStore.createIndex('reportType', 'reportType', { unique: false });
}
if (!db.objectStoreNames.contains('cropPlans')) {
const cropStore = db.createObjectStore('cropPlans', { keyPath: 'id', autoIncrement: true });
cropStore.createIndex('season', 'season', { unique: false });
}
if (!db.objectStoreNames.contains('coastalProjects')) {
const coastalStore = db.createObjectStore('coastalProjects', { keyPath: 'id', autoIncrement: true });
}
if (!db.objectStoreNames.contains('communityPosts')) {
const communityStore = db.createObjectStore('communityPosts', { keyPath: 'id', autoIncrement: true });
communityStore.createIndex('category', 'category', { unique: false });
}
};
});
}
private async getStore(storeName: string, mode: IDBTransactionMode = 'readonly'): Promise<IDBObjectStore> {
if (!this.db) await this.init();
const transaction = this.db!.transaction([storeName], mode);
return transaction.objectStore(storeName);
}
// Projects
async getProjects(): Promise<Project[]> {
const store = await this.getStore('projects');
return new Promise((resolve, reject) => {
const request = store.getAll();
request.onsuccess = () => resolve(request.result || []);
request.onerror = () => reject(request.error);
});
}
async createProject(project: Omit<Project, 'id' | 'createdAt' | 'updatedAt'>): Promise<Project> {
const store = await this.getStore('projects', 'readwrite');
const newProject = {
...project,
createdAt: new Date(),
updatedAt: new Date()
};
return new Promise((resolve, reject) => {
const request = store.add(newProject);
request.onsuccess = () => {
resolve({ ...newProject, id: request.result as number });
};
request.onerror = () => reject(request.error);
});
}
// Government Reports
async getGovernmentReports(): Promise<GovernmentReport[]> {
const store = await this.getStore('governmentReports');
return new Promise((resolve, reject) => {
const request = store.getAll();
request.onsuccess = () => resolve(request.result || []);
request.onerror = () => reject(request.error);
});
}
async createGovernmentReport(report: Omit<GovernmentReport, 'id' | 'createdAt'>): Promise<GovernmentReport> {
const store = await this.getStore('governmentReports', 'readwrite');
const newReport = {
...report,
createdAt: new Date()
};
return new Promise((resolve, reject) => {
const request = store.add(newReport);
request.onsuccess = () => {
resolve({ ...newReport, id: request.result as number });
};
request.onerror = () => reject(request.error);
});
}
// Crop Plans
async getCropPlans(): Promise<CropPlan[]> {
const store = await this.getStore('cropPlans');
return new Promise((resolve, reject) => {
const request = store.getAll();
request.onsuccess = () => resolve(request.result || []);
request.onerror = () => reject(request.error);
});
}
async createCropPlan(plan: Omit<CropPlan, 'id' | 'createdAt'>): Promise<CropPlan> {
const store = await this.getStore('cropPlans', 'readwrite');
const newPlan = {
...plan,
createdAt: new Date()
};
return new Promise((resolve, reject) => {
const request = store.add(newPlan);
request.onsuccess = () => {
resolve({ ...newPlan, id: request.result as number });
};
request.onerror = () => reject(request.error);
});
}
// Coastal Projects
async getCoastalProjects(): Promise<CoastalProject[]> {
const store = await this.getStore('coastalProjects');
return new Promise((resolve, reject) => {
const request = store.getAll();
request.onsuccess = () => resolve(request.result || []);
request.onerror = () => reject(request.error);
});
}
async createCoastalProject(project: Omit<CoastalProject, 'id' | 'createdAt'>): Promise<CoastalProject> {
const store = await this.getStore('coastalProjects', 'readwrite');
const newProject = {
...project,
createdAt: new Date()
};
return new Promise((resolve, reject) => {
const request = store.add(newProject);
request.onsuccess = () => {
resolve({ ...newProject, id: request.result as number });
};
request.onerror = () => reject(request.error);
});
}
// Community Posts
async getCommunityPosts(category?: string): Promise<CommunityPost[]> {
const store = await this.getStore('communityPosts');
return new Promise((resolve, reject) => {
let request: IDBRequest;
if (category && category !== 'all') {
const index = store.index('category');
request = index.getAll(category);
} else {
request = store.getAll();
}
request.onsuccess = () => resolve(request.result || []);
request.onerror = () => reject(request.error);
});
}
async createCommunityPost(post: Omit<CommunityPost, 'id' | 'createdAt' | 'likes'>): Promise<CommunityPost> {
const store = await this.getStore('communityPosts', 'readwrite');
const newPost = {
...post,
likes: 0,
createdAt: new Date()
};
return new Promise((resolve, reject) => {
const request = store.add(newPost);
request.onsuccess = () => {
resolve({ ...newPost, id: request.result as number });
};
request.onerror = () => reject(request.error);
});
}
async likeCommunityPost(id: number): Promise<void> {
const store = await this.getStore('communityPosts', 'readwrite');
return new Promise((resolve, reject) => {
const getRequest = store.get(id);
getRequest.onsuccess = () => {
const post = getRequest.result;
if (post) {
post.likes = (post.likes || 0) + 1;
const updateRequest = store.put(post);
updateRequest.onsuccess = () => resolve();
updateRequest.onerror = () => reject(updateRequest.error);
} else {
resolve();
}
};
getRequest.onerror = () => reject(getRequest.error);
});
}
}
export const offlineStorage = new OfflineStorage();