import { useTranslation } from "next-i18next";
import posthog from "posthog-js";
import React from "react";
import { useMount } from "react-use";
import { UserSession } from "@/utils/auth";
import { trpcNext } from "../utils/trpc";
import { useRequiredContext } from "./use-required-context";
export const UserContext =
React.createContext<{
user: UserSession & { shortName: string };
refresh: () => void;
logout: () => void;
ownsObject: (obj: { userId: string | null }) => boolean;
} | null>(null);
export const useUser = () => {
return useRequiredContext(UserContext, "UserContext");
};
export const useAuthenticatedUser = () => {
const { user, ...rest } = useRequiredContext(UserContext, "UserContext");
if (user.isGuest) {
throw new Error("Forget to prefetch user identity");
}
return { user, ...rest };
};
export const IfAuthenticated = (props: { children?: React.ReactNode }) => {
const { user } = useUser();
if (user.isGuest) {
return null;
}
return <>{props.children}>;
};
export const IfGuest = (props: { children?: React.ReactNode }) => {
const { user } = useUser();
if (!user.isGuest) {
return null;
}
return <>{props.children}>;
};
export const UserProvider = (props: { children?: React.ReactNode }) => {
const { t } = useTranslation("app");
const queryClient = trpcNext.useContext();
const { data: user, isFetching } = trpcNext.whoami.get.useQuery();
const logout = trpcNext.whoami.destroy.useMutation({
onSuccess: () => {
queryClient.whoami.invalidate();
},
});
useMount(() => {
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_API_KEY ?? "fake token", {
api_host: process.env.NEXT_PUBLIC_POSTHOG_API_HOST,
opt_out_capturing_by_default: false,
capture_pageview: false,
capture_pageleave: false,
autocapture: false,
loaded: (posthog) => {
if (!process.env.NEXT_PUBLIC_POSTHOG_API_KEY) {
posthog.opt_out_capturing();
}
if (user && posthog.get_distinct_id() !== user.id) {
posthog.identify(
user.id,
!user.isGuest
? { email: user.email, name: user.name }
: { name: user.id },
);
}
},
});
});
const shortName = isFetching
? t("loading")
: user
? user.isGuest === false
? user.name
: user.id.substring(0, 10)
: t("guest");
if (!user) {
return null;
}
return (
( component: React.ComponentType
, ) => { const ComposedComponent: React.VoidFunctionComponent
= (props: P) => {
const Component = component;
return (