UNPKG

naim-firebase-auth-wrapper

Version:

React components and hooks for Firebase Authentication and Firestore with Mantine UI

164 lines 6.29 kB
'use client'; import { jsx as _jsx } from "react/jsx-runtime"; import { createContext, useEffect, useState, useRef } from 'react'; import { signOut, } from 'firebase/auth'; import { MantineProvider } from '@mantine/core'; import { initializeFirebase } from '../firebase/config'; import { StylesProvider } from './StylesProvider'; import '@mantine/core/styles.css'; import { getUserOrganizations, setCurrentOrganization, createSession, clearSession, validateSession, updateSessionActivity, getUserProfile } from '../services/firestore'; export const AuthContext = createContext(null); export const AuthProvider = ({ config, children }) => { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [currentOrganization, setCurrentOrgState] = useState(null); const [organizations, setOrganizations] = useState([]); const authRef = useRef(null); const appRef = useRef(null); const dbRef = useRef(null); // Initialize Firebase useEffect(() => { try { // Initialize Firebase with provided config const { app, auth, db } = initializeFirebase(config); if (!app || !auth || !db) { console.error('[AuthProvider] Failed to initialize Firebase'); setError(new Error('Failed to initialize Firebase')); setLoading(false); return () => { }; // Return empty cleanup function } // Store auth reference for later use authRef.current = auth; appRef.current = app; dbRef.current = db; // Set up auth listener const unsubscribe = auth.onAuthStateChanged(async (user) => { if (user) { try { await createSession(user.uid); } catch (error) { console.error('[AuthProvider] Error creating session:', error); } } else { try { await clearSession(); } catch (error) { console.error('[AuthProvider] Error clearing session:', error); } } setUser(user); setLoading(false); }); return () => unsubscribe(); } catch (err) { console.error('[AuthProvider] Error in Firebase initialization effect:', err); setError(err instanceof Error ? err : new Error('Unknown error during initialization')); setLoading(false); return () => { }; // Return empty cleanup function } }, [config]); // Load user organizations when user changes useEffect(() => { if (!user || loading) { return; } loadOrganizations(); }, [user, loading]); // Load organizations for a user const loadOrganizations = async () => { if (user?.uid) { try { const orgs = await getUserOrganizations(user.uid); setOrganizations(orgs); // Set current organization if exists in user profile or default to first org const userProfile = await getUserProfile(user.uid); if (userProfile?.currentOrganization) { setCurrentOrgState(userProfile.currentOrganization); } else if (orgs.length > 0) { setCurrentOrgState(orgs[0].id); await setCurrentOrganization(user.uid, orgs[0].id); } } catch (error) { console.error('Error loading organizations:', error); } } }; // Set current organization handler const setCurrentOrganizationHandler = async (orgId) => { if (!user?.uid) return; try { await setCurrentOrganization(user.uid, orgId); setCurrentOrgState(orgId); } catch (error) { console.error('Error setting current organization:', error); } }; // Session activity update interval useEffect(() => { if (!user) return; // Validate session on load validateSession().catch(console.error); // Update session activity every 5 minutes const intervalId = setInterval(() => { const sessionId = localStorage.getItem('sessionId'); if (sessionId) { updateSessionActivity(sessionId).catch(console.error); } }, 5 * 60 * 1000); return () => clearInterval(intervalId); }, [user]); // Sign out handler const signOutHandler = async () => { if (!authRef.current) { console.error('Auth is not available'); return; } try { // Clear session before signing out await clearSession(); await signOut(authRef.current); } catch (error) { console.error('Error signing out:', error); throw error; } }; // Create a context value object to avoid recreating it on each render const contextValue = { user, loading, error, auth: authRef, // Expose auth instance app: appRef, // Expose app instance db: dbRef, // Expose db instance signInWithGoogle: async () => { // Implementation in useAuth hook }, signInWithEmail: async () => { // Implementation in useAuth hook }, signUp: async () => { // Implementation in useAuth hook }, signOut: signOutHandler, forgotPassword: async () => { // Implementation in useAuth hook }, currentOrganization, setCurrentOrganization: setCurrentOrganizationHandler, organizations, loadOrganizations }; return (_jsx(StylesProvider, { children: _jsx(MantineProvider, { children: _jsx(AuthContext.Provider, { value: contextValue, children: children }) }) })); }; //# sourceMappingURL=AuthProvider.js.map