diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 8132153a..fa940d49 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -11,23 +11,15 @@ import { Layout } from './layout/Layout' import { NotFoundScreen } from './components/NotFoundScreen' import { routes } from './routes' import './i18n/init' -import { silenceLiveKitLogs } from '@/utils/livekit.ts' import { queryClient } from '@/api/queryClient' -import { useAnalytics } from '@/features/analytics/hooks/useAnalytics' -import { useSupport } from '@/features/support/hooks/useSupport' +import { AppInitialization } from '@/components/AppInitialization' function App() { const { i18n } = useTranslation() useLang(i18n.language) - - const isProduction = import.meta.env.PROD - silenceLiveKitLogs(isProduction) - - useAnalytics() - useSupport() - return ( + diff --git a/src/frontend/src/api/queryKeys.ts b/src/frontend/src/api/queryKeys.ts index 21bb39de..17fa2dc9 100644 --- a/src/frontend/src/api/queryKeys.ts +++ b/src/frontend/src/api/queryKeys.ts @@ -1,4 +1,5 @@ export const keys = { user: 'user', room: 'room', + config: 'config', } diff --git a/src/frontend/src/api/useConfig.ts b/src/frontend/src/api/useConfig.ts new file mode 100644 index 00000000..c0ca2090 --- /dev/null +++ b/src/frontend/src/api/useConfig.ts @@ -0,0 +1,26 @@ +import { fetchApi } from './fetchApi' +import { keys } from './queryKeys' +import { useQuery } from '@tanstack/react-query' + +export interface ApiConfig { + analytics?: { + id: string + host: string + } + support?: { + id: string + } + silence_livekit_debug_logs?: boolean +} + +const fetchConfig = (): Promise => { + return fetchApi(`config/`) +} + +export const useConfig = () => { + return useQuery({ + queryKey: [keys.config], + queryFn: fetchConfig, + staleTime: Infinity, + }) +} diff --git a/src/frontend/src/components/AppInitialization.tsx b/src/frontend/src/components/AppInitialization.tsx new file mode 100644 index 00000000..1882a292 --- /dev/null +++ b/src/frontend/src/components/AppInitialization.tsx @@ -0,0 +1,20 @@ +import { silenceLiveKitLogs } from '@/utils/livekit' +import { useConfig } from '@/api/useConfig' +import { useAnalytics } from '@/features/analytics/hooks/useAnalytics' +import { useSupport } from '@/features/support/hooks/useSupport' + +export const AppInitialization = () => { + const { data } = useConfig() + + const { + analytics = {}, + support = {}, + silence_livekit_debug_logs = false, + } = data || {} + + useAnalytics(analytics) + useSupport(support) + silenceLiveKitLogs(silence_livekit_debug_logs) + + return null +} diff --git a/src/frontend/src/features/analytics/hooks/useAnalytics.tsx b/src/frontend/src/features/analytics/hooks/useAnalytics.tsx index 23f213bd..ed0f87a4 100644 --- a/src/frontend/src/features/analytics/hooks/useAnalytics.tsx +++ b/src/frontend/src/features/analytics/hooks/useAnalytics.tsx @@ -3,9 +3,6 @@ import { useLocation } from 'wouter' import posthog from 'posthog-js' import { ApiUser } from '@/features/auth/api/ApiUser' -const ANALYTICS_ID = 'phc_RPYko028Oqtj0c9exLIWwrlrjLxSdxT0ntW0Lam4iom' -const ANALYTICS_HOST = 'https://eu.i.posthog.com' - export const startAnalyticsSession = (data: ApiUser) => { if (posthog._isIdentified()) return const { id, email } = data @@ -17,21 +14,21 @@ export const terminateAnalyticsSession = () => { posthog.reset() } -export const useAnalytics = () => { +export type useAnalyticsProps = { + id?: string + host?: string +} + +export const useAnalytics = ({ id, host }: useAnalyticsProps) => { const [location] = useLocation() - - const isProduction = import.meta.env.PROD - useEffect(() => { - // We're on a free tier, so we need to limit the number of events we send to PostHog. - // Be frugal with event tracking, even though we could filter them out later if necessary. - if (!isProduction) return + if (!id || !host) return if (posthog.__loaded) return - posthog.init(ANALYTICS_ID, { - api_host: ANALYTICS_HOST, + posthog.init(id, { + api_host: host, person_profiles: 'always', }) - }, [isProduction]) + }, [id, host]) // From PostHog tutorial on PageView tracking in a Single Page Application (SPA) context. useEffect(() => { diff --git a/src/frontend/src/features/support/hooks/useSupport.tsx b/src/frontend/src/features/support/hooks/useSupport.tsx index 2676c29c..3bff2a0d 100644 --- a/src/frontend/src/features/support/hooks/useSupport.tsx +++ b/src/frontend/src/features/support/hooks/useSupport.tsx @@ -2,8 +2,6 @@ import { useEffect } from 'react' import { Crisp } from 'crisp-sdk-web' import { ApiUser } from '@/features/auth/api/ApiUser' -const SUPPORT_ID = '58ea6697-8eba-4492-bc59-ad6562585041' - export const initializeSupportSession = (user: ApiUser) => { if (!Crisp.isCrispInjected()) return const { id, email } = user @@ -17,17 +15,17 @@ export const terminateSupportSession = () => { Crisp.session.reset() } +export type useSupportProps = { + id?: string +} + // Configure Crisp chat for real-time support across all pages. -export const useSupport = () => { +export const useSupport = ({ id }: useSupportProps) => { useEffect(() => { - if (!SUPPORT_ID) { - console.warn('Crisp Website ID is not set') - return - } - if (Crisp.isCrispInjected()) return - Crisp.configure(SUPPORT_ID) + if (!id || Crisp.isCrispInjected()) return + Crisp.configure(id) Crisp.setHideOnMobile(true) - }, []) + }, [id]) return null }