PrithviGuardian / client /src /lib /userStorage.ts
Varad Bakshi
Fresh upload
e7427b5
Raw
History Blame Contribute Delete
7.26 kB
// 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<UserProfile, 'id' | 'createdAt' | 'lastLogin'>): Promise<UserProfile> {
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<UserProfile | null> {
const users = this.getUsers();
return users.find(user => user.phone === phone) || null;
}
// Update user information
async updateUser(updatedUser: UserProfile): Promise<UserProfile> {
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<UserProfile[]> {
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<string, number>;
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<string, number>);
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 };