Shortlist / frontend /src /components /auth-provider.tsx
Eren-Sama
Fix Google OAuth: add /auth/callback route, redirect to / instead of /login
aaa2d62
"use client";
import {
createContext,
useContext,
useEffect,
useState,
type ReactNode,
} from "react";
import { createClient } from "@/lib/supabase";
import { api } from "@/lib/api";
import type { User, Session } from "@supabase/supabase-js";
interface AuthContextType {
user: User | null;
session: Session | null;
loading: boolean;
signInWithEmail: (email: string, password: string) => Promise<void>;
signUpWithEmail: (email: string, password: string) => Promise<void>;
signInWithGoogle: () => Promise<void>;
signOut: () => Promise<void>;
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [session, setSession] = useState<Session | null>(null);
const [loading, setLoading] = useState(true);
const supabase = createClient();
useEffect(() => {
// Get initial session
supabase.auth.getSession().then(({ data: { session } }) => {
setSession(session);
setUser(session?.user ?? null);
api.setToken(session?.access_token ?? null);
setLoading(false);
});
// Listen for auth changes
const {
data: { subscription },
} = supabase.auth.onAuthStateChange((_event, session) => {
setSession(session);
setUser(session?.user ?? null);
api.setToken(session?.access_token ?? null);
});
return () => subscription.unsubscribe();
}, []);
const signInWithEmail = async (email: string, password: string) => {
const { error } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) throw error;
};
const signUpWithEmail = async (email: string, password: string) => {
const { error } = await supabase.auth.signUp({ email, password });
if (error) throw error;
};
const signOut = async () => {
const { error } = await supabase.auth.signOut();
if (error) throw error;
};
const signInWithGoogle = async () => {
const { error } = await supabase.auth.signInWithOAuth({
provider: "google",
options: {
redirectTo: `${window.location.origin}/auth/callback?next=/dashboard`,
},
});
if (error) throw error;
};
return (
<AuthContext.Provider
value={{ user, session, loading, signInWithEmail, signUpWithEmail, signInWithGoogle, signOut }}
>
{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;
}