create-cen-app
Version:
create an client-engineering-style app
115 lines (98 loc) • 2.81 kB
text/typescript
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useNavigate } from "@tanstack/react-router";
import { useState } from "react";
import { AxiosError } from "axios";
import { toast } from "@/components/common/Toaster";
import {
type Body_login_login_access_token as AccessToken,
ApiError,
LoginService,
type UserPublic,
type UserRegister,
UsersService,
} from "../client";
const isLoggedIn = () => {
return localStorage.getItem("access_token") !== null;
};
const useAuth = () => {
const [error, setError] = useState<string | null>(null);
const navigate = useNavigate();
const queryClient = useQueryClient();
const { data: user, isLoading } = useQuery<UserPublic | null, Error>({
queryKey: ["currentUser"],
queryFn: async () => {
try {
return await UsersService.readUserMe();
} catch (err) {
if (
err instanceof ApiError &&
(err.status === 404 || err.status === 403)
) {
// If user not found (404), log them out
localStorage.removeItem("access_token");
navigate({ to: "/login" });
return null;
}
throw err; // Re-throw other errors
}
},
enabled: isLoggedIn(),
});
const signUpMutation = useMutation({
mutationFn: (data: UserRegister) =>
UsersService.registerUser({ requestBody: data }),
onSuccess: () => {
navigate({ to: "/login" });
toast.success("Your account has been created successfully.");
},
onError: (err: ApiError) => {
let errDetail = (err.body as any)?.detail;
if (err instanceof AxiosError) {
errDetail = err.message;
}
toast.error("Something went wrong.", {
caption: errDetail,
});
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: ["users"] });
},
});
const login = async (data: AccessToken) => {
const response = await LoginService.loginAccessToken({
formData: data,
});
localStorage.setItem("access_token", response.access_token);
};
const loginMutation = useMutation({
mutationFn: login,
onSuccess: () => {
navigate({ to: "/" });
},
onError: (err: ApiError) => {
let errDetail = (err.body as any)?.detail;
if (err instanceof AxiosError) {
errDetail = err.message;
}
if (Array.isArray(errDetail)) {
errDetail = "Something went wrong";
}
setError(errDetail);
},
});
const logout = () => {
localStorage.removeItem("access_token");
navigate({ to: "/login" });
};
return {
signUpMutation,
loginMutation,
logout,
user,
isLoading,
error,
resetError: () => setError(null),
};
};
export { isLoggedIn };
export default useAuth;