From 812016d09c4577c04925e0cf1d4cd4f9ee31a04e Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Mon, 23 Sep 2024 19:57:52 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(frontend)=20add=20user=20support=20fe?= =?UTF-8?q?ature=20using=20Crisp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement a chat feature that allows users to communicate directly with an engineer for assistance with issues. We use Crisp for consistency, as it’s already utilized in all other LaSuite products. Additionally, we need to configure an environment variable in the frontend for better flexibility. This is the initial implementation, and session handling will be refined in future updates. --- src/frontend/src/App.tsx | 2 ++ .../src/features/auth/api/useUser.tsx | 2 ++ .../src/features/support/hooks/useSupport.tsx | 33 +++++++++++++++++++ src/frontend/src/layout/Header.tsx | 2 ++ 4 files changed, 39 insertions(+) create mode 100644 src/frontend/src/features/support/hooks/useSupport.tsx diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 47f6f351..8132153a 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -14,6 +14,7 @@ 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' function App() { const { i18n } = useTranslation() @@ -23,6 +24,7 @@ function App() { silenceLiveKitLogs(isProduction) useAnalytics() + useSupport() return ( diff --git a/src/frontend/src/features/auth/api/useUser.tsx b/src/frontend/src/features/auth/api/useUser.tsx index 5c7b06df..f58d58cc 100644 --- a/src/frontend/src/features/auth/api/useUser.tsx +++ b/src/frontend/src/features/auth/api/useUser.tsx @@ -4,6 +4,7 @@ import { fetchUser } from './fetchUser' import { type ApiUser } from './ApiUser' import { useEffect } from 'react' import { startAnalyticsSession } from '@/features/analytics/hooks/useAnalytics' +import { initializeSupportSession } from '@/features/support/hooks/useSupport' /** * returns info about currently logged-in user @@ -20,6 +21,7 @@ export const useUser = () => { useEffect(() => { if (query?.data) { startAnalyticsSession(query.data) + initializeSupportSession(query.data) } }, [query.data]) diff --git a/src/frontend/src/features/support/hooks/useSupport.tsx b/src/frontend/src/features/support/hooks/useSupport.tsx new file mode 100644 index 00000000..2676c29c --- /dev/null +++ b/src/frontend/src/features/support/hooks/useSupport.tsx @@ -0,0 +1,33 @@ +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 + Crisp.setTokenId(`meet-${id}`) + Crisp.user.setEmail(email) +} + +export const terminateSupportSession = () => { + if (!Crisp.isCrispInjected()) return + Crisp.setTokenId() + Crisp.session.reset() +} + +// Configure Crisp chat for real-time support across all pages. +export const useSupport = () => { + useEffect(() => { + if (!SUPPORT_ID) { + console.warn('Crisp Website ID is not set') + return + } + if (Crisp.isCrispInjected()) return + Crisp.configure(SUPPORT_ID) + Crisp.setHideOnMobile(true) + }, []) + + return null +} diff --git a/src/frontend/src/layout/Header.tsx b/src/frontend/src/layout/Header.tsx index 09f8918a..a037c9e5 100644 --- a/src/frontend/src/layout/Header.tsx +++ b/src/frontend/src/layout/Header.tsx @@ -11,6 +11,7 @@ import { Menu } from '@/primitives/Menu' import { MenuList } from '@/primitives/MenuList' import { ProConnectButton } from '@/components/ProConnectButton' import { terminateAnalyticsSession } from '@/features/analytics/hooks/useAnalytics' +import { terminateSupportSession } from '@/features/support/hooks/useSupport' export const Header = () => { const { t } = useTranslation() @@ -82,6 +83,7 @@ export const Header = () => { onAction={(value) => { if (value === 'logout') { terminateAnalyticsSession() + terminateSupportSession() window.location.href = logoutUrl() } }}