180 lines
4.5 KiB
TypeScript
180 lines
4.5 KiB
TypeScript
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { useState } from "react";
|
|
import { match } from "ts-pattern";
|
|
import { toast } from "../ui-library/toast/toast-queue";
|
|
import {
|
|
User as SupabaseUser,
|
|
Session,
|
|
createClient,
|
|
} from "@supabase/supabase-js";
|
|
import { queryClient } from "../lib/api";
|
|
|
|
export type User = SupabaseUser & {
|
|
user_metadata: {
|
|
email: string;
|
|
email_verified: boolean;
|
|
first_name: string;
|
|
last_name: string;
|
|
business_name: string;
|
|
};
|
|
};
|
|
|
|
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
|
|
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
|
|
|
|
if (!supabaseUrl || !supabaseAnonKey) {
|
|
throw new Error("Missing Supabase environment variables");
|
|
}
|
|
|
|
export const supabase = createClient(supabaseUrl, supabaseAnonKey);
|
|
|
|
interface SignUpData {
|
|
email: string;
|
|
password: string;
|
|
confirm_password: string;
|
|
first_name: string;
|
|
last_name: string;
|
|
business_name: string;
|
|
}
|
|
|
|
interface LoginData {
|
|
email: string;
|
|
password: string;
|
|
}
|
|
|
|
interface AuthResponse {
|
|
user: SupabaseUser | null;
|
|
session: Session | null;
|
|
}
|
|
|
|
export function useSignUp() {
|
|
const navigate = useNavigate();
|
|
const [errors, setErrors] = useState<Record<string, string>>({});
|
|
const { mutate, isPending } = useMutation<
|
|
AuthResponse,
|
|
{ message: string; code: string },
|
|
SignUpData
|
|
>({
|
|
mutationFn: async (data: SignUpData) => {
|
|
const { data: response, error } = await supabase.auth.signUp({
|
|
email: data.email,
|
|
password: data.password,
|
|
options: {
|
|
data: {
|
|
first_name: data.first_name,
|
|
last_name: data.last_name,
|
|
business_name: data.business_name,
|
|
},
|
|
},
|
|
});
|
|
if (error) throw error;
|
|
return response;
|
|
},
|
|
onSuccess: () => {
|
|
navigate("/");
|
|
},
|
|
onError: (error) => {
|
|
const errMap: Record<string, string> = {};
|
|
|
|
match(error.code)
|
|
.with("user_already_exists", () => {
|
|
errMap["email"] = "Cette adresse email est déjà utilisée";
|
|
})
|
|
.otherwise(() => {
|
|
toast.add({
|
|
title: "Erreur",
|
|
description: error.message,
|
|
type: "error",
|
|
position: "top-left",
|
|
});
|
|
});
|
|
|
|
setErrors(errMap);
|
|
},
|
|
});
|
|
return { mutate, isPending, errors };
|
|
}
|
|
|
|
export function useLoginEmail() {
|
|
const navigate = useNavigate();
|
|
const [errors, setErrors] = useState<Record<string, string>>({});
|
|
const { mutate, isPending } = useMutation<
|
|
AuthResponse,
|
|
{ message: string; code: string },
|
|
LoginData
|
|
>({
|
|
mutationFn: async (data: LoginData) => {
|
|
const { data: response, error } = await supabase.auth.signInWithPassword({
|
|
email: data.email.trim(),
|
|
password: data.password.trim(),
|
|
});
|
|
if (error) throw error;
|
|
return response;
|
|
},
|
|
onSuccess: () => {
|
|
navigate("/");
|
|
},
|
|
onError: (error) => {
|
|
match(error.code)
|
|
.with("invalid_credentials", () => {
|
|
setErrors({ email: "Email ou mot de passe incorrect" });
|
|
})
|
|
.otherwise(() => {
|
|
toast.add({
|
|
title: "Erreur",
|
|
description: error.message,
|
|
type: "error",
|
|
position: "top-left",
|
|
});
|
|
});
|
|
},
|
|
});
|
|
return { mutate, isPending, errors };
|
|
}
|
|
|
|
export function useLoginGoogle() {
|
|
const { mutate } = useMutation({
|
|
mutationFn: async () => {
|
|
const { data, error } = await supabase.auth.signInWithOAuth({
|
|
provider: "google",
|
|
options: {
|
|
redirectTo: "http://localhost:5173/",
|
|
},
|
|
});
|
|
if (error) throw error;
|
|
return data;
|
|
},
|
|
});
|
|
return { loginWithGoogle: mutate };
|
|
}
|
|
|
|
export function useGetCurrentUser() {
|
|
const { data: user } = useQuery({
|
|
queryKey: ["currentUser"],
|
|
queryFn: async () => {
|
|
const { data } = await supabase.auth.getSession();
|
|
if (!data.session) {
|
|
throw new Error("No session found");
|
|
}
|
|
return data.session?.user;
|
|
},
|
|
retryDelay: 1000,
|
|
refetchInterval: 1000 * 60 * 10,
|
|
});
|
|
return { user: user as User | null };
|
|
}
|
|
export function useLogout() {
|
|
const navigate = useNavigate();
|
|
return useMutation({
|
|
mutationFn: async () => {
|
|
const { error } = await supabase.auth.signOut();
|
|
if (error) throw error;
|
|
},
|
|
onSuccess: () => {
|
|
console.log("logout");
|
|
queryClient.invalidateQueries({ queryKey: ["currentUser"] });
|
|
navigate("/login");
|
|
},
|
|
});
|
|
}
|