| |
| "use client"; |
| import { useQuery, useQueryClient } from "@tanstack/react-query"; |
| import { useCookie } from "react-use"; |
| import { useRouter } from "next/navigation"; |
|
|
| import { ProjectType, User } from "@/types"; |
| import { api } from "@/lib/api"; |
| import { toast } from "sonner"; |
| import { |
| storeAuthDataFallback, |
| getAuthDataFallback, |
| clearAuthDataFallback, |
| isInIframe, |
| isMobileDevice |
| } from "@/lib/iframe-storage"; |
|
|
|
|
| export const useUser = (initialData?: { |
| user: User | null; |
| errCode: number | null; |
| projects: ProjectType[]; |
| }) => { |
| const client = useQueryClient(); |
| const router = useRouter(); |
| const [currentRoute, setCurrentRoute, removeCurrentRoute] = useCookie("deepsite-currentRoute"); |
|
|
| const { data: { user, errCode } = { user: null, errCode: null }, isLoading } = |
| useQuery({ |
| queryKey: ["user.me"], |
| queryFn: async () => { |
| |
| if (!initialData && isInIframe()) { |
| const fallbackData = getAuthDataFallback(); |
| if (fallbackData.user && fallbackData.token) { |
| return { user: fallbackData.user, errCode: null }; |
| } |
| } |
| return { user: initialData?.user || null, errCode: initialData?.errCode || null }; |
| }, |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| retry: false, |
| initialData: initialData |
| ? { user: initialData?.user, errCode: initialData?.errCode } |
| : undefined, |
| enabled: false, |
| }); |
|
|
| const { data: loadingAuth } = useQuery({ |
| queryKey: ["loadingAuth"], |
| queryFn: async () => false, |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| }); |
| const setLoadingAuth = (value: boolean) => { |
| client.setQueryData(["setLoadingAuth"], value); |
| }; |
|
|
| const { data: projects } = useQuery({ |
| queryKey: ["me.projects"], |
| queryFn: async () => [], |
| refetchOnWindowFocus: false, |
| refetchOnReconnect: false, |
| refetchOnMount: false, |
| initialData: initialData?.projects || [], |
| }); |
| const setProjects = (projects: ProjectType[]) => { |
| client.setQueryData(["me.projects"], projects); |
| }; |
|
|
| const openLoginWindow = async () => { |
| setCurrentRoute(window.location.pathname); |
| |
| if (isInIframe()) { |
| try { |
| const response = await api.get("/auth/login-url"); |
| const { loginUrl } = response.data; |
| |
| window.open(loginUrl, "_blank", "noopener,noreferrer"); |
| |
| toast.info("Login opened in new tab. Please complete authentication and return to this page."); |
| return; |
| } catch (error) { |
| console.error("Failed to open login in new tab:", error); |
| } |
| } |
| |
| return router.push("/auth"); |
| }; |
|
|
| const loginFromCode = async (code: string) => { |
| setLoadingAuth(true); |
| if (loadingAuth) return; |
| await api |
| .post("/auth", { code }) |
| .then(async (res: any) => { |
| if (res.data) { |
| if (res.data.useLocalStorageFallback) { |
| storeAuthDataFallback(res.data.access_token, res.data.user); |
| } |
| |
| client.setQueryData(["user.me"], { |
| user: res.data.user, |
| errCode: null, |
| }); |
| if (currentRoute) { |
| router.push(currentRoute); |
| removeCurrentRoute(); |
| } else { |
| router.push("/"); |
| } |
| toast.success("Login successful"); |
| } |
| }) |
| .catch((err: any) => { |
| toast.error(err?.data?.message ?? err.message ?? "An error occurred"); |
| }) |
| .finally(() => { |
| setLoadingAuth(false); |
| }); |
| }; |
|
|
| const logout = async () => { |
| try { |
| await api.post("/auth/logout"); |
| clearAuthDataFallback(); |
| removeCurrentRoute(); |
| client.clear(); |
| toast.success("Logout successful"); |
| window.location.reload(); |
| } catch (error) { |
| console.error("Logout error:", error); |
| clearAuthDataFallback(); |
| removeCurrentRoute(); |
| client.clear() |
| toast.success("Logout successful"); |
| window.location.reload(); |
| } |
| }; |
|
|
| return { |
| user, |
| projects, |
| setProjects, |
| errCode, |
| loading: isLoading || loadingAuth, |
| openLoginWindow, |
| loginFromCode, |
| logout, |
| }; |
| }; |
|
|