// Firebase Authentication Context for Black Canyon Tickets React Rebuild // This is a mock authentication context for learning purposes only import React, { createContext, useContext, useEffect, useState } from 'react'; import { onAuthStateChanged, signOut, signInWithEmailAndPassword, GoogleAuthProvider, signInWithPopup, createUserWithEmailAndPassword } from 'firebase/auth'; import { auth } from '@/lib/firebase'; import type { User} from '@/types/auth'; import { MOCK_USERS, ROLE_PERMISSIONS } from '@/types/auth'; import type { User as FirebaseUser} from 'firebase/auth'; interface FirebaseAuthContextType { // Authentication state user: User | null; firebaseUser: FirebaseUser | null; loading: boolean; // Authentication methods signInEmail: (email: string, password: string) => Promise; signInGoogle: () => Promise; signUpEmail: (email: string, password: string) => Promise; signOut: () => Promise; // Utility methods hasRole: (role: User['role'] | User['role'][]) => boolean; hasPermission: (permission: string) => boolean; } const FirebaseAuthContext = createContext(null); // Google Auth Provider setup const googleProvider = new GoogleAuthProvider(); googleProvider.setCustomParameters({ prompt: 'select_account' }); export const FirebaseAuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { const [user, setUser] = useState(null); const [firebaseUser, setFirebaseUser] = useState(null); const [loading, setLoading] = useState(true); // Map Firebase user to our User type using mock data const mapFirebaseUserToUser = (firebaseUser: FirebaseUser): User => { // In a real app, this would fetch user data from Firestore // For learning purposes, we'll use mock data based on email const mockUser = MOCK_USERS[firebaseUser.email || ''] || MOCK_USERS['organizer@example.com']; if (!mockUser) { throw new Error('Mock user not found'); } // Filter out problematic photo URLs that cause 404 errors const getValidAvatar = (photoURL: string | null, fallback?: string): string | undefined => { if (!photoURL) return fallback; // Block known problematic Unsplash URLs if (photoURL.includes('photo-1494790108755-2616b612b786')) { return fallback; } // Add other URL validations if needed return photoURL; }; return { ...mockUser, id: firebaseUser.uid, email: firebaseUser.email || mockUser.email, name: firebaseUser.displayName || mockUser.name, avatar: getValidAvatar(firebaseUser.photoURL, mockUser.avatar), metadata: { ...mockUser.metadata, lastLogin: new Date().toISOString(), emailVerified: firebaseUser.emailVerified, }, }; }; // Listen for authentication state changes useEffect(() => { const unsubscribe = onAuthStateChanged(auth, (firebaseUser) => { setFirebaseUser(firebaseUser); if (firebaseUser) { const mappedUser = mapFirebaseUserToUser(firebaseUser); setUser(mappedUser); } else { setUser(null); } setLoading(false); }); return () => unsubscribe(); }, []); // Sign in with email and password const signInEmail = async (email: string, password: string): Promise => { setLoading(true); try { await signInWithEmailAndPassword(auth, email, password); } catch (error) { setLoading(false); throw error; } }; // Sign in with Google const signInGoogle = async (): Promise => { setLoading(true); try { await signInWithPopup(auth, googleProvider); } catch (error) { setLoading(false); throw error; } }; // Sign up with email and password const signUpEmail = async (email: string, password: string): Promise => { setLoading(true); try { await createUserWithEmailAndPassword(auth, email, password); } catch (error) { setLoading(false); throw error; } }; // Sign out const handleSignOut = async (): Promise => { setLoading(true); try { await signOut(auth); } catch (error) { setLoading(false); throw error; } }; // Check if user has specific role(s) const hasRole = (role: User['role'] | User['role'][]): boolean => { if (!user) {return false;} if (Array.isArray(role)) { return role.includes(user.role); } return user.role === role; }; // Check if user has specific permission const hasPermission = (permission: string): boolean => { if (!user) {return false;} const userPermissions = ROLE_PERMISSIONS[user.role] || []; // Check for wildcard permissions (admin:* grants all admin permissions) return userPermissions.some(userPerm => { if (userPerm.endsWith(':*')) { const prefix = userPerm.slice(0, -1); // Remove the '*' return permission.startsWith(prefix); } return userPerm === permission; }); }; const value: FirebaseAuthContextType = { user, firebaseUser, loading, signInEmail, signInGoogle, signUpEmail, signOut: handleSignOut, hasRole, hasPermission, }; return ( {children} ); }; // Custom hook to use Firebase Auth context export const useFirebaseAuth = (): FirebaseAuthContextType => { const context = useContext(FirebaseAuthContext); if (!context) { throw new Error('useFirebaseAuth must be used within a FirebaseAuthProvider'); } return context; }; export default FirebaseAuthContext;