Files
blackcanyontickets/reactrebuild0825/src/contexts/FirebaseAuthContext.tsx
dzinesco aa81eb5adb feat: add advanced analytics and territory management system
- Add comprehensive analytics components with export functionality
- Implement territory management with manager performance tracking
- Add seatmap components for venue layout management
- Create customer management features with modal interface
- Add advanced hooks for dashboard flags and territory data
- Implement seat selection and venue management utilities
- Add type definitions for ticketing and seatmap systems

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 09:25:10 -06:00

203 lines
5.6 KiB
TypeScript

// 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<void>;
signInGoogle: () => Promise<void>;
signUpEmail: (email: string, password: string) => Promise<void>;
signOut: () => Promise<void>;
// Utility methods
hasRole: (role: User['role'] | User['role'][]) => boolean;
hasPermission: (permission: string) => boolean;
}
const FirebaseAuthContext = createContext<FirebaseAuthContextType | null>(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<User | null>(null);
const [firebaseUser, setFirebaseUser] = useState<FirebaseUser | null>(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<void> => {
setLoading(true);
try {
await signInWithEmailAndPassword(auth, email, password);
} catch (error) {
setLoading(false);
throw error;
}
};
// Sign in with Google
const signInGoogle = async (): Promise<void> => {
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<void> => {
setLoading(true);
try {
await createUserWithEmailAndPassword(auth, email, password);
} catch (error) {
setLoading(false);
throw error;
}
};
// Sign out
const handleSignOut = async (): Promise<void> => {
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 (
<FirebaseAuthContext.Provider value={value}>
{children}
</FirebaseAuthContext.Provider>
);
};
// 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;