xtablo-source/ui/src/hooks/useAuth.ts
2025-03-23 10:57:30 +01:00

132 lines
3.5 KiB
TypeScript

import { useMutation } from "@tanstack/react-query";
import { api } from "../lib/api";
import { useNavigate } from "react-router-dom";
import { useState } from "react";
import { match } from "ts-pattern";
import { toast } from "../ui-library/toast/toast-queue";
interface SignUpData {
email: string;
password: string;
confirm_password: string;
first_name: string;
last_name: string;
business_name: string;
}
interface LoginData {
email: string;
password: string;
}
type SignUpErrorCodes = "user_already_exists";
type LoginErrorCodes = "invalid_credentials" | "user_not_found";
export function useSignUp() {
const [errors, setErrors] = useState<Record<string, string>>({});
const { mutate, isPending } = useMutation<
unknown,
{
response: {
data:
| { human_error: string; form_location: string }[]
| { detail: string };
headers: {
"x-error-code": SignUpErrorCodes;
"x-error-message": string;
};
};
},
SignUpData
>({
mutationFn: async (data: SignUpData) => {
const response = await api.post("/auth/register", data);
return response.data;
},
onSuccess: (data) => {
console.log("data", data);
},
onError: (error) => {
console.log("error", error);
const errMap: Record<string, string> = {};
if (Array.isArray(error.response.data)) {
error.response.data.forEach(
({
human_error,
form_location,
}: {
human_error: string;
form_location: string;
}) => {
errMap[form_location] = human_error;
}
);
} else {
match(error.response.headers["x-error-code"])
.with("user_already_exists", () => {
errMap["email"] = error.response.headers["x-error-message"];
})
.otherwise(() => {
toast.add({
title: "Erreur",
description: error.response.headers["x-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<
unknown,
{
response: {
data: { access_token: string };
headers: { "x-error-code": LoginErrorCodes; "x-error-message": string };
};
},
LoginData
>({
mutationFn: async (data: LoginData) => {
const response = await api.post("/auth/login", data);
return response.data;
},
onSuccess: (data) => {
console.log("data", data);
navigate("/");
},
onError: (error) => {
match(error.response.headers["x-error-code"])
.with("invalid_credentials", () => {
setErrors({ email: error.response.headers["x-error-message"] });
})
.otherwise(() => {
toast.add({
title: "Erreur",
description: error.response.headers["x-error-message"],
type: "error",
position: "top-left",
});
});
},
});
return { mutate, isPending, errors };
}
export function useLoginWithGoogle() {
return useMutation({
mutationFn: async () => {
const response = await api.get("/auth/login/google");
const { auth_url } = response.data;
return auth_url;
},
onSuccess: (data) => {
window.location.href = data;
},
});
}