forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAuthProvider.tsx
More file actions
118 lines (101 loc) · 3.12 KB
/
Copy pathAuthProvider.tsx
File metadata and controls
118 lines (101 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
'use client';
import { createContext, useContext, useEffect, useState, ReactNode, useRef, useCallback } from 'react';
import { User } from 'firebase/auth';
import {
auth,
onAuthStateChange,
signInWithGoogle,
signInWithApple,
signOutUser,
getIdToken,
} from '@/lib/firebase';
import { MixpanelManager } from '@/lib/analytics/mixpanel';
interface AuthContextType {
user: User | null;
loading: boolean;
signInWithGoogle: () => Promise<void>;
signInWithApple: () => Promise<void>;
signOut: () => Promise<void>;
getToken: () => Promise<string | null>;
// Login panel state
isLoginPanelOpen: boolean;
openLoginPanel: () => void;
closeLoginPanel: () => void;
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const [isLoginPanelOpen, setIsLoginPanelOpen] = useState(false);
const previousUserRef = useRef<User | null>(null);
const openLoginPanel = useCallback(() => setIsLoginPanelOpen(true), []);
const closeLoginPanel = useCallback(() => setIsLoginPanelOpen(false), []);
useEffect(() => {
// Initialize Mixpanel
MixpanelManager.init();
// Subscribe to auth state changes
const unsubscribe = onAuthStateChange((user) => {
setUser(user);
setLoading(false);
// Identify user with Mixpanel when authenticated
if (user && !previousUserRef.current) {
MixpanelManager.identify(user.uid, {
name: user.displayName || undefined,
email: user.email || undefined,
});
}
previousUserRef.current = user;
});
return () => unsubscribe();
}, []);
const handleSignInWithGoogle = async () => {
try {
await signInWithGoogle();
MixpanelManager.track('Sign In Completed', { method: 'google' });
} catch (error) {
console.error('Failed to sign in with Google:', error);
throw error;
}
};
const handleSignInWithApple = async () => {
try {
await signInWithApple();
MixpanelManager.track('Sign In Completed', { method: 'apple' });
} catch (error) {
console.error('Failed to sign in with Apple:', error);
throw error;
}
};
const handleSignOut = async () => {
try {
MixpanelManager.track('Sign Out');
MixpanelManager.reset();
await signOutUser();
} catch (error) {
console.error('Failed to sign out:', error);
throw error;
}
};
const handleGetToken = async () => {
return getIdToken();
};
const value: AuthContextType = {
user,
loading,
signInWithGoogle: handleSignInWithGoogle,
signInWithApple: handleSignInWithApple,
signOut: handleSignOut,
getToken: handleGetToken,
isLoginPanelOpen,
openLoginPanel,
closeLoginPanel,
};
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}
export function useAuth() {
const context = useContext(AuthContext);
if (context === undefined) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
}