import { supabase } from "@/lib/supabase";
import type { Session } from "@supabase/supabase-js";
import { type ReactNode, createContext, useContext, useEffect, useState } from "react";
type AuthResult = { error: Error | null };
type SignUpResult = AuthResult & { needsConfirmation?: boolean };
type AuthState = {
session: Session | null;
loading: boolean;
signIn: (email: string, password: string) => Promise<AuthResult>;
signUp: (email: string, password: string) => Promise<SignUpResult>;
signOut: () => Promise<void>;
};
const AuthContext = createContext<AuthState | null>(null);
export function AuthProvider({ children }: { children: ReactNode }) {
const [session, setSession] = useState<Session | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
if (!supabase) {
setLoading(false);
return;
}
supabase.auth.getSession().then(({ data }) => {
setSession(data.session);
setLoading(false);
});
const { data: sub } = supabase.auth.onAuthStateChange((_event, s) => {
setSession(s);
});
return () => sub.subscription.unsubscribe();
}, []);
const signIn = async (email: string, password: string): Promise<AuthResult> => {
if (!supabase) return { error: new Error("Supabase not configured") };
const { error } = await supabase.auth.signInWithPassword({ email, password });
return { error };
};
const signUp = async (email: string, password: string): Promise<SignUpResult> => {
if (!supabase) return { error: new Error("Supabase not configured") };
const { data, error } = await supabase.auth.signUp({
email,
password,
options: { emailRedirectTo: window.location.origin },
});
// If Supabase's "Confirm email" setting is on, no session is returned —
// the user must click the link in the confirmation email first.
return { error, needsConfirmation: !error && !data.session };
};
const signOut = async () => {
if (!supabase) return;
await supabase.auth.signOut();
};
return (
<AuthContext.Provider value={{ session, loading, signIn, signUp, signOut }}>
{children}
</AuthContext.Provider>
);
}
export function useAuth() {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error("useAuth must be used inside AuthProvider");
return ctx;
}