|
import { createContext, useState, useEffect, useContext, ReactNode } from "react"; |
|
import { supabase } from "@/integrations/supabase/client"; |
|
import { Session, User } from "@supabase/supabase-js"; |
|
|
|
type AuthContextType = { |
|
session: Session | null; |
|
user: User | null; |
|
loading: boolean; |
|
signIn: (email: string, password: string) => Promise<{ |
|
error: Error | null; |
|
success: boolean; |
|
}>; |
|
signUp: (email: string, password: string) => Promise<{ |
|
error: Error | null; |
|
success: boolean; |
|
}>; |
|
signInWithGoogle: () => Promise<{ |
|
error: Error | null; |
|
success: boolean; |
|
}>; |
|
signInWithGitHub: () => Promise<{ |
|
error: Error | null; |
|
success: boolean; |
|
}>; |
|
signOut: () => Promise<void>; |
|
}; |
|
|
|
const AuthContext = createContext<AuthContextType | undefined>(undefined); |
|
|
|
export const AuthProvider = ({ children }: { children: ReactNode }) => { |
|
const [session, setSession] = useState<Session | null>(null); |
|
const [user, setUser] = useState<User | null>(null); |
|
const [loading, setLoading] = useState(true); |
|
|
|
useEffect(() => { |
|
|
|
const { data: { subscription } } = supabase.auth.onAuthStateChange( |
|
(event, session) => { |
|
setSession(session); |
|
setUser(session?.user ?? null); |
|
} |
|
); |
|
|
|
|
|
supabase.auth.getSession().then(({ data: { session } }) => { |
|
setSession(session); |
|
setUser(session?.user ?? null); |
|
setLoading(false); |
|
}); |
|
|
|
return () => subscription.unsubscribe(); |
|
}, []); |
|
|
|
const signIn = async (email: string, password: string) => { |
|
try { |
|
const { error } = await supabase.auth.signInWithPassword({ |
|
email, |
|
password, |
|
}); |
|
return { error, success: !error }; |
|
} catch (error) { |
|
return { error: error as Error, success: false }; |
|
} |
|
}; |
|
|
|
const signUp = async (email: string, password: string) => { |
|
try { |
|
const { error } = await supabase.auth.signUp({ |
|
email, |
|
password, |
|
}); |
|
return { error, success: !error }; |
|
} catch (error) { |
|
return { error: error as Error, success: false }; |
|
} |
|
}; |
|
|
|
const signInWithGoogle = async () => { |
|
try { |
|
const { data, error } = await supabase.auth.signInWithOAuth({ |
|
provider: 'google', |
|
options: { |
|
queryParams: { |
|
access_type: 'offline', |
|
prompt: 'consent', |
|
}, |
|
}, |
|
}); |
|
return { error, success: !error }; |
|
} catch (error) { |
|
return { error: error as Error, success: false }; |
|
} |
|
}; |
|
|
|
const signInWithGitHub = async () => { |
|
try { |
|
const { data, error } = await supabase.auth.signInWithOAuth({ |
|
provider: 'github', |
|
}); |
|
return { error, success: !error }; |
|
} catch (error) { |
|
return { error: error as Error, success: false }; |
|
} |
|
}; |
|
|
|
const signOut = async () => { |
|
await supabase.auth.signOut(); |
|
}; |
|
|
|
return ( |
|
<AuthContext.Provider |
|
value={{ |
|
session, |
|
user, |
|
loading, |
|
signIn, |
|
signUp, |
|
signInWithGoogle, |
|
signInWithGitHub, |
|
signOut, |
|
}} |
|
> |
|
{children} |
|
</AuthContext.Provider> |
|
); |
|
}; |
|
|
|
export const useAuth = () => { |
|
const context = useContext(AuthContext); |
|
if (context === undefined) { |
|
throw new Error("useAuth must be used within an AuthProvider"); |
|
} |
|
return context; |
|
}; |
|
|