// Local user authentication and storage system interface UserProfile { id: string; name: string; phone: string; organization?: string; role: 'engineer' | 'student' | 'researcher' | 'government' | 'farmer' | 'consultant'; lastLogin: Date; createdAt: Date; } interface UserSession { user: UserProfile; loginTime: Date; isActive: boolean; } class UserStorageManager { private storageKey = 'prithvi_users'; private sessionKey = 'prithvi_session'; private currentSession: UserSession | null = null; // Get all users from localStorage private getUsers(): UserProfile[] { try { const stored = localStorage.getItem(this.storageKey); return stored ? JSON.parse(stored) : []; } catch (error) { console.warn('Could not load users from storage:', error); return []; } } // Save users to localStorage private saveUsers(users: UserProfile[]): void { try { localStorage.setItem(this.storageKey, JSON.stringify(users)); } catch (error) { console.error('Could not save users to storage:', error); } } // Create new user async createUser(userData: Omit): Promise { const users = this.getUsers(); // Check if phone number already exists const existingUser = users.find(user => user.phone === userData.phone); if (existingUser) { throw new Error('Phone number already registered'); } const newUser: UserProfile = { ...userData, id: `user_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, createdAt: new Date(), lastLogin: new Date() }; users.push(newUser); this.saveUsers(users); return newUser; } // Get user by phone number async getUserByPhone(phone: string): Promise { const users = this.getUsers(); return users.find(user => user.phone === phone) || null; } // Update user information async updateUser(updatedUser: UserProfile): Promise { const users = this.getUsers(); const userIndex = users.findIndex(user => user.id === updatedUser.id); if (userIndex === -1) { throw new Error('User not found'); } users[userIndex] = updatedUser; this.saveUsers(users); return updatedUser; } // Get recent users (for quick login) async getRecentUsers(limit: number = 5): Promise { const users = this.getUsers(); return users .sort((a, b) => new Date(b.lastLogin).getTime() - new Date(a.lastLogin).getTime()) .slice(0, limit); } // Create user session createSession(user: UserProfile): UserSession { const session: UserSession = { user: { ...user, lastLogin: new Date() }, loginTime: new Date(), isActive: true }; this.currentSession = session; try { localStorage.setItem(this.sessionKey, JSON.stringify(session)); // Update user's last login time this.updateUser(session.user); } catch (error) { console.warn('Could not save session to storage:', error); } return session; } // Get current session getCurrentSession(): UserSession | null { if (this.currentSession && this.currentSession.isActive) { return this.currentSession; } try { const stored = localStorage.getItem(this.sessionKey); if (stored) { const session = JSON.parse(stored) as UserSession; session.user.lastLogin = new Date(session.user.lastLogin); session.user.createdAt = new Date(session.user.createdAt); session.loginTime = new Date(session.loginTime); // Check if session is still valid (24 hours) const sessionAge = Date.now() - session.loginTime.getTime(); const maxAge = 24 * 60 * 60 * 1000; // 24 hours if (sessionAge < maxAge && session.isActive) { this.currentSession = session; return session; } else { this.clearSession(); } } } catch (error) { console.warn('Could not load session from storage:', error); this.clearSession(); } return null; } // Clear current session (logout) clearSession(): void { this.currentSession = null; try { localStorage.removeItem(this.sessionKey); } catch (error) { console.warn('Could not clear session from storage:', error); } } // Check if user is logged in isLoggedIn(): boolean { const session = this.getCurrentSession(); return session !== null && session.isActive; } // Get current user getCurrentUser(): UserProfile | null { const session = this.getCurrentSession(); return session ? session.user : null; } // Export user data for backup exportUserData(): string { const users = this.getUsers(); const currentSession = this.getCurrentSession(); const exportData = { users, currentSession, exportDate: new Date().toISOString(), version: '1.0' }; return JSON.stringify(exportData, null, 2); } // Import user data from backup importUserData(jsonData: string): boolean { try { const importData = JSON.parse(jsonData); if (importData.users && Array.isArray(importData.users)) { this.saveUsers(importData.users); if (importData.currentSession) { localStorage.setItem(this.sessionKey, JSON.stringify(importData.currentSession)); } return true; } } catch (error) { console.error('Could not import user data:', error); } return false; } // Get user statistics getUserStats(): { totalUsers: number; activeUsers: number; usersByRole: Record; recentActivity: number; } { const users = this.getUsers(); const now = Date.now(); const weekAgo = now - (7 * 24 * 60 * 60 * 1000); const usersByRole = users.reduce((acc, user) => { acc[user.role] = (acc[user.role] || 0) + 1; return acc; }, {} as Record); const recentActivity = users.filter(user => new Date(user.lastLogin).getTime() > weekAgo ).length; return { totalUsers: users.length, activeUsers: this.isLoggedIn() ? 1 : 0, usersByRole, recentActivity }; } // Validate phone number format validatePhoneNumber(phone: string): boolean { // Indian phone number validation (10 digits starting with 6-9) const phoneRegex = /^[6-9]\d{9}$/; const cleanPhone = phone.replace(/[\s\-\(\)]/g, ''); return phoneRegex.test(cleanPhone); } // Clean up old data (remove users not active for 90 days) cleanupOldData(): number { const users = this.getUsers(); const cutoffDate = Date.now() - (90 * 24 * 60 * 60 * 1000); // 90 days ago const activeUsers = users.filter(user => new Date(user.lastLogin).getTime() > cutoffDate ); const removedCount = users.length - activeUsers.length; if (removedCount > 0) { this.saveUsers(activeUsers); } return removedCount; } } // Export singleton instance export const userStorage = new UserStorageManager(); // Export types export type { UserProfile, UserSession };