'use client'; import React, { createContext, useContext, useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { Session, User } from '@supabase/supabase-js'; import supabase from './supabase'; // Define user type export type AuthUser = User | null; // Define auth context type export type AuthContextType = { user: AuthUser; session: Session | null; isLoading: boolean; signIn: (email: string, password: string) => Promise<{ error?: unknown }>; signInWithGoogle: () => Promise<{ error?: unknown }>; signInWithGitHub: () => Promise<{ error?: unknown }>; signUp: (email: string, password: string) => Promise; signOut: () => Promise; }; // Create auth context const AuthContext = createContext(undefined); // Auth provider component export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { const [user, setUser] = useState(null); const [session, setSession] = useState(null); const [isLoading, setIsLoading] = useState(true); const router = useRouter(); // Initialize auth state useEffect(() => { const getSession = async () => { setIsLoading(true); try { // Try to get session from Supabase const { data: { session }, error } = await supabase.auth.getSession(); if (error) { console.error('Error getting session:', error); return; } // Print session info for debugging console.log('Supabase session loaded:', session ? 'Found' : 'Not found'); if (session) { console.log('User authenticated:', session.user.email); if (session.expires_at) { console.log('Session expires at:', new Date(session.expires_at * 1000).toLocaleString()); } } setSession(session); setUser(session?.user || null); } catch (error) { console.error('Unexpected error during getSession:', error); } finally { setIsLoading(false); } }; getSession(); // Listen for auth state changes const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => { console.log('Auth state changed, event:', _event); console.log('New session:', session ? 'Valid' : 'None'); setSession(session); setUser(session?.user || null); }); // Cleanup function return () => { subscription.unsubscribe(); }; }, []); // Sign in function const signIn = async (email: string, password: string) => { setIsLoading(true); try { console.log('Attempting to sign in:', { email }); // Try to sign in with Supabase const { data, error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) { console.error('Sign in error:', error); return { error }; } // Sign in successful, set session and user info console.log('Sign in successful, user:', data.user?.email); setSession(data.session); setUser(data.user); // Use hard redirect instead of router.push to ensure full page refresh console.log('Preparing to redirect to analytics page'); // Add short delay to ensure state is updated, then redirect setTimeout(() => { window.location.href = '/analytics'; }, 100); return {}; } catch (error) { console.error('Error during sign in process:', error); return { error }; } finally { setIsLoading(false); } }; // Google sign in function const signInWithGoogle = async () => { setIsLoading(true); try { // Try to sign in with Google via Supabase const { error } = await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: `${window.location.origin}/auth/callback`, queryParams: { access_type: 'offline', prompt: 'consent', } }, }); if (error) { console.error('Google sign in error:', error); return { error }; } return {}; // Return empty object when successful } catch (error) { console.error('Error during Google sign in process:', error); return { error }; } finally { setIsLoading(false); } }; // GitHub sign in function const signInWithGitHub = async () => { setIsLoading(true); try { // Try to sign in with GitHub via Supabase const { error } = await supabase.auth.signInWithOAuth({ provider: 'github', options: { redirectTo: `${window.location.origin}/auth/callback`, }, }); if (error) { console.error('GitHub login error:', error); return { error }; } return {}; // Return empty object when successful } catch (error) { console.error('GitHub login process error:', error); return { error }; } finally { setIsLoading(false); } }; // Sign up function const signUp = async (email: string, password: string) => { setIsLoading(true); try { // Try to sign up via Supabase const { error } = await supabase.auth.signUp({ email, password, options: { emailRedirectTo: `${window.location.origin}/auth/callback`, } }); if (error) { console.error('Sign up error:', error); throw error; } // After successful registration, redirect to login page with confirmation message router.push('/login?message=Registration successful! Please check your email to verify your account before logging in.'); } catch (error) { console.error('Error during sign up process:', error); throw error; } finally { setIsLoading(false); } }; // Sign out function const signOut = async () => { setIsLoading(true); try { // Try to sign out via Supabase const { error } = await supabase.auth.signOut(); if (error) { console.error('Sign out error:', error); throw error; } setSession(null); setUser(null); router.push('/login'); } catch (error) { console.error('Error during sign out process:', error); throw error; } finally { setIsLoading(false); } }; const contextValue: AuthContextType = { user, session, isLoading, signIn, signInWithGoogle, signInWithGitHub, signUp, signOut, }; return ( {children} ); }; // Custom hook export const useAuth = () => { const context = useContext(AuthContext); if (context === undefined) { throw new Error('useAuth must be used within an AuthProvider'); } return context; }; // Protected route component export const ProtectedRoute: React.FC<{ children: React.ReactNode }> = ({ children }) => { const { user, isLoading } = useAuth(); const router = useRouter(); useEffect(() => { if (!isLoading && !user) { router.push('/login'); } }, [user, isLoading, router]); if (isLoading) { return (

Loading...

); } if (!user) { return null; } return <>{children}; }; export default AuthContext;