mirror of https://github.com/buster-so/buster.git
Added posthog provider
This commit is contained in:
parent
7dfdb61c28
commit
e1fb3e0454
|
@ -68,10 +68,13 @@ export const prefetchGetUserAttributes = async (userId: string, queryClientProp?
|
|||
|
||||
export const useGetUserTeams = ({ userId }: { userId: string }) => {
|
||||
const queryFn = async () => getUserTeams({ userId });
|
||||
return useQuery({
|
||||
const { data } = useQuery({
|
||||
...userQueryKeys.userGetUserTeams(userId),
|
||||
queryFn,
|
||||
enabled: !!userId,
|
||||
notifyOnChangeProps: ['data'],
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
export const prefetchGetUserTeams = async (userId: string, queryClientProp?: QueryClient) => {
|
||||
|
|
|
@ -38,7 +38,7 @@ const parseGenericUrl: EmbedUrlParser = (url: string) => {
|
|||
|
||||
const urlParsers: EmbedUrlParser[] = [parseTwitterUrl, parseVideoUrl, parseGenericUrl];
|
||||
const ACCEPTED_DOMAINS = [
|
||||
process.env.NEXT_PUBLIC_URL,
|
||||
process.env.VITE_PUBLIC_URL,
|
||||
'twitter.com',
|
||||
'x.com',
|
||||
'youtube.com',
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
import { isServer } from '@tanstack/react-query';
|
||||
import { ClientOnly } from '@tanstack/react-router';
|
||||
import type { PostHogConfig } from 'posthog-js';
|
||||
import React, { type PropsWithChildren, useEffect, useState } from 'react';
|
||||
import { useGetUserTeams } from '@/api/buster_rest/users';
|
||||
import {
|
||||
useGetUserBasicInfo,
|
||||
useGetUserOrganization,
|
||||
} from '@/api/buster_rest/users/useGetUserInfo';
|
||||
import { isDev } from '@/config/dev';
|
||||
|
||||
const POSTHOG_KEY = process.env.VITE_PUBLIC_POSTHOG_KEY;
|
||||
const DEBUG_POSTHOG = false;
|
||||
|
||||
export const BusterPosthogProvider: React.FC<PropsWithChildren> = ({ children }) => {
|
||||
if ((isDev && !DEBUG_POSTHOG) || !POSTHOG_KEY) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
return <PosthogWrapper>{children}</PosthogWrapper>;
|
||||
};
|
||||
BusterPosthogProvider.displayName = 'BusterPosthogProvider';
|
||||
|
||||
const options: Partial<PostHogConfig> = {
|
||||
api_host: process.env.VITE_PUBLIC_POSTHOG_HOST,
|
||||
person_profiles: 'always',
|
||||
session_recording: {
|
||||
recordBody: true,
|
||||
},
|
||||
|
||||
loaded: () => {
|
||||
console.log(
|
||||
'%c🚀 Welcome to Buster',
|
||||
'background: linear-gradient(to right, #a21caf, #8b1cb1, #6b21a8); color: white; font-size: 16px; font-weight: bold; padding: 10px; border-radius: 5px;'
|
||||
);
|
||||
console.log(
|
||||
'%cBuster is your open-source data analytics platform. Found a bug? The code is open-source! Report it at https://github.com/buster-so/buster. Better yet, fix it yourself and send a PR.',
|
||||
'background: #6b21a8; color: white; font-size: 10px; font-weight: normal; padding: 8px; border-radius: 4px;'
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
const PosthogWrapper: React.FC<PropsWithChildren> = ({ children }) => {
|
||||
const user = useGetUserBasicInfo();
|
||||
const userTeams = useGetUserTeams({ userId: user?.id ?? '' });
|
||||
const userOrganizations = useGetUserOrganization();
|
||||
const team = userTeams?.[0];
|
||||
|
||||
const [posthogModules, setPosthogModules] = useState<{
|
||||
posthog: typeof import('posthog-js').default;
|
||||
PostHogProvider: typeof import('posthog-js/react').PostHogProvider;
|
||||
} | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
// Async load posthog-js dependencies
|
||||
useEffect(() => {
|
||||
const loadPosthogModules = async () => {
|
||||
try {
|
||||
const [{ default: posthog }, { PostHogProvider }] = await Promise.all([
|
||||
import('posthog-js'),
|
||||
import('posthog-js/react'),
|
||||
]);
|
||||
|
||||
setPosthogModules({ posthog, PostHogProvider });
|
||||
} catch (error) {
|
||||
console.error('Failed to load PostHog modules:', error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadPosthogModules();
|
||||
}, []);
|
||||
|
||||
// Initialize PostHog when modules are loaded and user data is available
|
||||
useEffect(() => {
|
||||
if (POSTHOG_KEY && !isServer && user && posthogModules?.posthog && team) {
|
||||
const { posthog } = posthogModules;
|
||||
|
||||
if (posthog.__loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
posthog.init(POSTHOG_KEY, options);
|
||||
|
||||
const email = user.email;
|
||||
posthog.identify(email, {
|
||||
user,
|
||||
organization: userOrganizations,
|
||||
team,
|
||||
});
|
||||
posthog.group(team?.id, team?.name);
|
||||
}
|
||||
}, [user?.id, team?.id, posthogModules]);
|
||||
|
||||
// Show children while loading or if modules failed to load
|
||||
if (isLoading || !posthogModules) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
const { PostHogProvider } = posthogModules;
|
||||
|
||||
if (isServer) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
<ClientOnly>
|
||||
<PostHogProvider client={posthogModules.posthog}>{children}</PostHogProvider>
|
||||
</ClientOnly>
|
||||
);
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export * from './BusterPosthogProvider';
|
|
@ -1,6 +1,7 @@
|
|||
import type { QueryClient } from '@tanstack/react-query';
|
||||
import type React from 'react';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
import { BusterPosthogProvider } from '@/context/Posthog';
|
||||
import { BusterStyleProvider } from './BusterStyles';
|
||||
import { QueryPersister } from './Query/QueryProvider';
|
||||
import {
|
||||
|
@ -8,22 +9,6 @@ import {
|
|||
type SupabaseContextType,
|
||||
} from './Supabase/SupabaseContextProvider';
|
||||
|
||||
// import type { UseSupabaseUserContextType } from '@/lib/supabase';
|
||||
// import { BusterAssetsProvider } from './Assets/BusterAssetsProvider';
|
||||
// import { AppLayoutProvider } from './BusterAppLayout';
|
||||
// import { BusterReactQueryProvider } from './BusterReactQuery/BusterReactQueryAndApi';
|
||||
// import { BusterNewChatProvider } from './Chats';
|
||||
// import { BusterPosthogProvider } from './Posthog';
|
||||
// import { RoutePrefetcher } from './RoutePrefetcher';
|
||||
// import { SupabaseContextProvider } from './Supabase/SupabaseContextProvider';
|
||||
// import { BusterUserConfigProvider } from './Users/BusterUserConfigProvider';
|
||||
|
||||
// scan({
|
||||
// enabled: true,
|
||||
// log: true, // logs render info to console (default: false)
|
||||
// clearLog: false // clears the console per group of renders (default: false)
|
||||
// });
|
||||
|
||||
type RootProvidersProps = PropsWithChildren<SupabaseContextType & { queryClient: QueryClient }>;
|
||||
|
||||
export const RootProviders: React.FC<RootProvidersProps> = ({
|
||||
|
@ -35,21 +20,9 @@ export const RootProviders: React.FC<RootProvidersProps> = ({
|
|||
return (
|
||||
<QueryPersister queryClient={queryClient}>
|
||||
<SupabaseContextProvider user={user} accessToken={accessToken}>
|
||||
<BusterStyleProvider>{children}</BusterStyleProvider>
|
||||
{/* <BusterReactQueryProvider>
|
||||
<HydrationBoundary state={dehydrate(queryClient)}>
|
||||
<AppLayoutProvider>
|
||||
<BusterUserConfigProvider>
|
||||
<BusterAssetsProvider>
|
||||
<BusterNewChatProvider>
|
||||
<BusterPosthogProvider>{children}</BusterPosthogProvider>
|
||||
<RoutePrefetcher />
|
||||
</BusterNewChatProvider>
|
||||
</BusterAssetsProvider>
|
||||
</BusterUserConfigProvider>
|
||||
</AppLayoutProvider>
|
||||
</HydrationBoundary>
|
||||
</BusterReactQueryProvider> */}
|
||||
<BusterStyleProvider>
|
||||
<BusterPosthogProvider>{children}</BusterPosthogProvider>
|
||||
</BusterStyleProvider>
|
||||
</SupabaseContextProvider>
|
||||
</QueryPersister>
|
||||
);
|
||||
|
|
|
@ -15,7 +15,6 @@ export const env = createEnv({
|
|||
clientPrefix: 'VITE_',
|
||||
|
||||
client: {
|
||||
VITE_APP_TITLE: z.string().min(1).optional(),
|
||||
VITE_PUBLIC_API_URL: z.string().url(),
|
||||
VITE_PUBLIC_API2_URL: z.string().url(),
|
||||
VITE_PUBLIC_WEB_SOCKET_URL: z.string().url().optional(),
|
||||
|
|
Loading…
Reference in New Issue