// Mock authentication service for development when Supabase is not available interface MockUser { id: string; email: string; created_at: string; } interface MockSession { user: MockUser; access_token: string; } interface MockProfile { id: string; username: string; email: string; role: string; onboarded: boolean; full_name?: string; bio?: string; level: number; total_xp: number; avatar_url?: string; created_at: string; updated_at: string; } class MockAuthService { private currentUser: MockUser | null = null; private currentSession: MockSession | null = null; private profiles: Map = new Map(); constructor() { // Load from localStorage if available const savedUser = localStorage.getItem('mock_user'); const savedProfile = localStorage.getItem('mock_profile'); if (savedUser) { this.currentUser = JSON.parse(savedUser); if (this.currentUser) { this.currentSession = { user: this.currentUser, access_token: 'mock_token_' + Date.now() }; } } if (savedProfile) { const profile = JSON.parse(savedProfile); this.profiles.set(profile.id, profile); } } async signInWithPassword(email: string, password: string) { // Mock validation - accept any email/password for demo if (!email || !password) { throw new Error('Email and password are required'); } const user: MockUser = { id: 'mock_user_' + email.replace(/[^a-z0-9]/gi, '_'), email, created_at: new Date().toISOString() }; this.currentUser = user; this.currentSession = { user, access_token: 'mock_token_' + Date.now() }; // Save to localStorage localStorage.setItem('mock_user', JSON.stringify(user)); // Notify auth state change setTimeout(() => this.notifyAuthChange('SIGNED_IN'), 50); return { data: { user, session: this.currentSession }, error: null }; } async signOut() { this.currentUser = null; this.currentSession = null; localStorage.removeItem('mock_user'); localStorage.removeItem('mock_profile'); // Notify auth state change setTimeout(() => this.notifyAuthChange('SIGNED_OUT'), 50); return { error: null }; } async getUser() { return { data: { user: this.currentUser }, error: null }; } async getSession() { return { data: { session: this.currentSession }, error: null }; } // Mock database operations async getUserProfile(userId: string): Promise { return this.profiles.get(userId) || null; } async updateProfile(userId: string, updates: Partial): Promise { let profile = this.profiles.get(userId); if (!profile) { // Create new profile profile = { id: userId, username: updates.username || this.currentUser?.email?.split('@')[0] || 'user', email: this.currentUser?.email || '', role: 'member', onboarded: true, level: 1, total_xp: 0, created_at: new Date().toISOString(), updated_at: new Date().toISOString(), ...updates }; } else { // Update existing profile = { ...profile, ...updates, updated_at: new Date().toISOString() }; } this.profiles.set(userId, profile); localStorage.setItem('mock_profile', JSON.stringify(profile)); return profile; } onAuthStateChange(callback: (event: string, session: MockSession | null) => void) { // Store callback for later use this.authCallback = callback; // Immediately call with current state setTimeout(() => { if (this.currentSession) { callback('SIGNED_IN', this.currentSession); } else { callback('SIGNED_OUT', null); } }, 100); // Return unsubscribe function return { data: { subscription: { unsubscribe: () => { this.authCallback = null; } } } }; } private authCallback: ((event: string, session: MockSession | null) => void) | null = null; private notifyAuthChange(event: string) { if (this.authCallback) { this.authCallback(event, this.currentSession); } } } export const mockAuth = new MockAuthService();