Initial project bootstrap
This commit is contained in:
84
client/src/_core/hooks/useAuth.ts
Normal file
84
client/src/_core/hooks/useAuth.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { getLoginUrl } from "@/const";
|
||||
import { trpc } from "@/lib/trpc";
|
||||
import { TRPCClientError } from "@trpc/client";
|
||||
import { useCallback, useEffect, useMemo } from "react";
|
||||
|
||||
type UseAuthOptions = {
|
||||
redirectOnUnauthenticated?: boolean;
|
||||
redirectPath?: string;
|
||||
};
|
||||
|
||||
export function useAuth(options?: UseAuthOptions) {
|
||||
const { redirectOnUnauthenticated = false, redirectPath = getLoginUrl() } =
|
||||
options ?? {};
|
||||
const utils = trpc.useUtils();
|
||||
|
||||
const meQuery = trpc.auth.me.useQuery(undefined, {
|
||||
retry: false,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
|
||||
const logoutMutation = trpc.auth.logout.useMutation({
|
||||
onSuccess: () => {
|
||||
utils.auth.me.setData(undefined, null);
|
||||
},
|
||||
});
|
||||
|
||||
const logout = useCallback(async () => {
|
||||
try {
|
||||
await logoutMutation.mutateAsync();
|
||||
} catch (error: unknown) {
|
||||
if (
|
||||
error instanceof TRPCClientError &&
|
||||
error.data?.code === "UNAUTHORIZED"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
throw error;
|
||||
} finally {
|
||||
utils.auth.me.setData(undefined, null);
|
||||
await utils.auth.me.invalidate();
|
||||
}
|
||||
}, [logoutMutation, utils]);
|
||||
|
||||
const state = useMemo(() => {
|
||||
localStorage.setItem(
|
||||
"manus-runtime-user-info",
|
||||
JSON.stringify(meQuery.data)
|
||||
);
|
||||
return {
|
||||
user: meQuery.data ?? null,
|
||||
loading: meQuery.isLoading || logoutMutation.isPending,
|
||||
error: meQuery.error ?? logoutMutation.error ?? null,
|
||||
isAuthenticated: Boolean(meQuery.data),
|
||||
};
|
||||
}, [
|
||||
meQuery.data,
|
||||
meQuery.error,
|
||||
meQuery.isLoading,
|
||||
logoutMutation.error,
|
||||
logoutMutation.isPending,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!redirectOnUnauthenticated) return;
|
||||
if (meQuery.isLoading || logoutMutation.isPending) return;
|
||||
if (state.user) return;
|
||||
if (typeof window === "undefined") return;
|
||||
if (window.location.pathname === redirectPath) return;
|
||||
|
||||
window.location.href = redirectPath
|
||||
}, [
|
||||
redirectOnUnauthenticated,
|
||||
redirectPath,
|
||||
logoutMutation.isPending,
|
||||
meQuery.isLoading,
|
||||
state.user,
|
||||
]);
|
||||
|
||||
return {
|
||||
...state,
|
||||
refresh: () => meQuery.refetch(),
|
||||
logout,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user