This commit is contained in:
Bastien COIGNOUX
2026-05-03 20:18:33 +02:00
parent ffc2e6b895
commit bd325fe456
113 changed files with 29532 additions and 220 deletions

View File

@ -0,0 +1,121 @@
import type { Session, User } from '@supabase/supabase-js';
import { useRouter, useSegments } from 'expo-router';
import React, {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';
import { supabase } from '@/services/supabase';
type AuthContextValue = {
initialized: boolean;
session: Session | null;
user: User | null;
signIn: (email: string, password: string) => Promise<{ error?: string }>;
signUp: (params: {
email: string;
password: string;
firstName: string;
lastName: string;
}) => Promise<{ error?: string }>;
signOut: () => Promise<void>;
};
const AuthContext = createContext<AuthContextValue | null>(null);
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [initialized, setInitialized] = useState(false);
const [session, setSession] = useState<Session | null>(null);
const segments = useSegments();
const router = useRouter();
useEffect(() => {
let cancelled = false;
void supabase.auth.getSession().then(({ data }) => {
if (!cancelled) {
setSession(data.session ?? null);
setInitialized(true);
}
});
const {
data: { subscription },
} = supabase.auth.onAuthStateChange((_event, nextSession) => {
setSession(nextSession);
});
return () => {
cancelled = true;
subscription.unsubscribe();
};
}, []);
useEffect(() => {
if (!initialized) return;
const root = segments[0];
if (!session?.user && root === '(tabs)') {
router.replace('/auth/login');
return;
}
if (session?.user && root === 'auth') {
router.replace('/(tabs)');
}
}, [initialized, session?.user, segments, router]);
const signIn = useCallback(async (email: string, password: string) => {
const { error } = await supabase.auth.signInWithPassword({ email, password });
if (error) return { error: error.message };
return {};
}, []);
const signUp = useCallback(
async (params: {
email: string;
password: string;
firstName: string;
lastName: string;
}) => {
const { error } = await supabase.auth.signUp({
email: params.email,
password: params.password,
options: {
data: {
first_name: params.firstName,
last_name: params.lastName,
full_name: `${params.firstName} ${params.lastName}`.trim(),
},
},
});
if (error) return { error: error.message };
return {};
},
[],
);
const signOut = useCallback(async () => {
await supabase.auth.signOut();
}, []);
const value = useMemo<AuthContextValue>(
() => ({
initialized,
session,
user: session?.user ?? null,
signIn,
signUp,
signOut,
}),
[initialized, session, signIn, signUp, signOut],
);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}
export function useAuth(): AuthContextValue {
const ctx = useContext(AuthContext);
if (!ctx) {
throw new Error('useAuth doit être utilisé dans un AuthProvider');
}
return ctx;
}