Spaces:
Running
Running
File size: 3,580 Bytes
dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e 76fb273 dc1f75e | 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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | 'use client';
import { createContext, useContext, useEffect, useState, type ReactNode } from 'react';
import type { User } from '@supabase/supabase-js';
import { getSupabase } from '@/lib/supabase';
interface AuthContextType {
user: User | null;
loading: boolean;
isGuest: boolean;
signIn: () => Promise<void>;
signOut: () => Promise<void>;
upgradeToAccount: () => Promise<void>;
getToken: () => Promise<string | null>;
}
const AuthContext = createContext<AuthContextType>({
user: null,
loading: true,
isGuest: false,
signIn: async () => {},
signOut: async () => {},
upgradeToAccount: async () => {},
getToken: async () => null,
});
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const [isGuest, setIsGuest] = useState(false);
const restoreOrCreateSession = async () => {
try {
const supabase = getSupabase();
const { data: { session } } = await supabase.auth.getSession();
if (session?.user) {
setUser(session.user);
setIsGuest(session.user.is_anonymous ?? false);
} else {
const { data, error } = await supabase.auth.signInAnonymously();
if (error) {
console.error('Anonymous sign-in failed:', error.message);
}
if (data?.user) {
setUser(data.user);
setIsGuest(true);
}
}
} catch (err) {
console.error('Session restore failed:', err);
} finally {
setLoading(false);
}
};
useEffect(() => {
restoreOrCreateSession();
}, []);
useEffect(() => {
try {
const supabase = getSupabase();
const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => {
setUser(session?.user ?? null);
setIsGuest(session?.user?.is_anonymous ?? false);
});
return () => subscription.unsubscribe();
} catch {}
}, []);
const signIn = async () => {
try {
const supabase = getSupabase();
const { error } = await supabase.auth.signInWithOAuth({
provider: 'google',
options: {
redirectTo: `${window.location.origin}/auth/callback`,
},
});
if (error) {
console.error('Sign in error:', error.message);
}
} catch {
console.error('Sign in failed');
}
};
const upgradeToAccount = async () => {
try {
const supabase = getSupabase();
const { error } = await supabase.auth.linkIdentity({
provider: 'google',
options: {
redirectTo: `${window.location.origin}/auth/callback`,
},
});
if (error) {
console.error('Upgrade failed:', error.message);
throw error;
}
} catch {
console.error('Upgrade failed');
}
};
const signOut = async () => {
try {
const supabase = getSupabase();
await supabase.auth.signOut();
setUser(null);
setIsGuest(false);
} catch {
console.error('Sign out failed');
}
};
const getToken = async (): Promise<string | null> => {
try {
const supabase = getSupabase();
const { data: { session } } = await supabase.auth.getSession();
return session?.access_token ?? null;
} catch {
return null;
}
};
return (
<AuthContext.Provider value={{ user, loading, isGuest, signIn, signOut, upgradeToAccount, getToken }}>
{children}
</AuthContext.Provider>
);
}
export const useAuth = () => useContext(AuthContext);
|