Initial commit
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
'use client';
|
||||
|
||||
import React, {
|
||||
createContext,
|
||||
useContext,
|
||||
useState,
|
||||
useEffect,
|
||||
ReactNode,
|
||||
} from 'react';
|
||||
import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword, updateProfile, signOut } from 'firebase/auth';
|
||||
import { app } from '@/lib/firebase';
|
||||
|
||||
interface User {
|
||||
uid: string;
|
||||
email: string | null;
|
||||
name: string | null;
|
||||
}
|
||||
|
||||
interface AuthContextType {
|
||||
user: User | null;
|
||||
isLoading: boolean;
|
||||
isAuthenticated: boolean;
|
||||
login: (email: string, password: string) => Promise<void>;
|
||||
register: (email: string, password: string, name: string) => Promise<void>;
|
||||
logout: () => Promise<void>;
|
||||
}
|
||||
|
||||
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
||||
|
||||
interface AuthProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export const AuthProvider = ({ children }: AuthProviderProps) => {
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const auth = getAuth(app);
|
||||
|
||||
useEffect(() => {
|
||||
// Listen to auth state changes
|
||||
const unsubscribe = auth.onAuthStateChanged((firebaseUser) => {
|
||||
if (firebaseUser) {
|
||||
setUser({
|
||||
uid: firebaseUser.uid,
|
||||
email: firebaseUser.email,
|
||||
name: firebaseUser.displayName,
|
||||
});
|
||||
} else {
|
||||
setUser(null);
|
||||
}
|
||||
setIsLoading(false);
|
||||
});
|
||||
|
||||
return () => unsubscribe();
|
||||
}, [auth]);
|
||||
|
||||
const login = async (email: string, password: string) => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
await signInWithEmailAndPassword(auth, email, password);
|
||||
} catch (error: any) {
|
||||
setIsLoading(false);
|
||||
throw new Error(error.message || 'Login failed');
|
||||
}
|
||||
};
|
||||
|
||||
const register = async (email: string, password: string, name: string) => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const userCredential = await createUserWithEmailAndPassword(auth, email, password);
|
||||
await updateProfile(userCredential.user, { displayName: name });
|
||||
// User state will be updated by onAuthStateChanged listener
|
||||
} catch (error: any) {
|
||||
setIsLoading(false);
|
||||
throw new Error(error.message || 'Registration failed');
|
||||
}
|
||||
};
|
||||
|
||||
const logout = async () => {
|
||||
await signOut(auth);
|
||||
};
|
||||
|
||||
const value: AuthContextType = {
|
||||
user,
|
||||
isLoading,
|
||||
isAuthenticated: !!user,
|
||||
login,
|
||||
register,
|
||||
logout,
|
||||
};
|
||||
|
||||
return (
|
||||
<AuthContext.Provider value={value}>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useAuth = () => {
|
||||
const ctx = useContext(AuthContext);
|
||||
if (!ctx) throw new Error('useAuth must be used within AuthProvider');
|
||||
return ctx;
|
||||
};
|
||||
Reference in New Issue
Block a user