From 29ceaee8d25e2a4e6a8e9e340c5a18375f461aa5 Mon Sep 17 00:00:00 2001 From: Nafees Nazik <84864519+G3root@users.noreply.github.com> Date: Wed, 8 Mar 2023 17:00:24 +0530 Subject: [PATCH] feat: Add fresh chat to list of support integration (#7448) * chore: add fresh chat configs to env.example * feat: add fresh chat menu item and render * refactor: remove some event listeners * chore: make popover closed after the click * refactor the code and fix some bugs * feat: auto open chat --------- Co-authored-by: Peer Richelsen --- .env.example | 4 + .../ee/support/components/ContactMenuItem.tsx | 15 +- .../ee/support/components/HelpMenuItem.tsx | 16 +- .../lib/freshchat/FreshChatMenuItem.tsx | 30 +++ .../lib/freshchat/FreshChatProvider.tsx | 25 +++ .../support/lib/freshchat/FreshChatScript.tsx | 40 ++++ .../lib/helpscout/HelpscoutMenuItem.tsx | 31 ++- .../support/lib/intercom/IntercomMenuItem.tsx | 31 ++- .../support/lib/zendesk/ZendeskMenuItem.tsx | 39 ++-- packages/features/shell/Shell.tsx | 205 +++++++++--------- 10 files changed, 289 insertions(+), 147 deletions(-) create mode 100644 packages/features/ee/support/lib/freshchat/FreshChatMenuItem.tsx create mode 100644 packages/features/ee/support/lib/freshchat/FreshChatProvider.tsx create mode 100644 packages/features/ee/support/lib/freshchat/FreshChatScript.tsx diff --git a/.env.example b/.env.example index df8d9a8430..d1492290c4 100644 --- a/.env.example +++ b/.env.example @@ -78,6 +78,10 @@ NEXT_PUBLIC_ZENDESK_KEY= # Help Scout Config NEXT_PUBLIC_HELPSCOUT_KEY= +# Fresh Chat Config +NEXT_PUBLIC_FRESHCHAT_TOKEN= +NEXT_PUBLIC_FRESHCHAT_HOST= + # Inbox to send user feedback SEND_FEEDBACK_EMAIL= diff --git a/packages/features/ee/support/components/ContactMenuItem.tsx b/packages/features/ee/support/components/ContactMenuItem.tsx index 66d005c401..8fd8df6cb8 100644 --- a/packages/features/ee/support/components/ContactMenuItem.tsx +++ b/packages/features/ee/support/components/ContactMenuItem.tsx @@ -1,13 +1,20 @@ +import FreshChatMenuItem from "../lib/freshchat/FreshChatMenuItem"; import HelpscoutMenuItem from "../lib/helpscout/HelpscoutMenuItem"; import IntercomMenuItem from "../lib/intercom/IntercomMenuItem"; import ZendeskMenuItem from "../lib/zendesk/ZendeskMenuItem"; -export default function HelpMenuItem() { +interface ContactMenuItem { + onHelpItemSelect: () => void; +} + +export default function ContactMenuItem(props: ContactMenuItem) { + const { onHelpItemSelect } = props; return ( <> - - - + + + + ); } diff --git a/packages/features/ee/support/components/HelpMenuItem.tsx b/packages/features/ee/support/components/HelpMenuItem.tsx index 06ee567533..fbcf0aa9b2 100644 --- a/packages/features/ee/support/components/HelpMenuItem.tsx +++ b/packages/features/ee/support/components/HelpMenuItem.tsx @@ -7,6 +7,8 @@ import { trpc } from "@calcom/trpc/react"; import { Button, showToast } from "@calcom/ui"; import { FiExternalLink, FiAlertTriangle } from "@calcom/ui/components/icon"; +import { useFreshChat } from "../lib/freshchat/FreshChatProvider"; +import { isFreshChatEnabled } from "../lib/freshchat/FreshChatScript"; import ContactMenuItem from "./ContactMenuItem"; interface HelpMenuItemProps { @@ -21,6 +23,8 @@ export default function HelpMenuItem({ onHelpItemSelect }: HelpMenuItemProps) { const [, loadChat] = useChat(); const { t } = useLocale(); + const { setActive: setFreshChat } = useFreshChat(); + const mutation = trpc.viewer.submitFeedback.useMutation({ onSuccess: () => { setDisableSubmit(true); @@ -43,7 +47,6 @@ export default function HelpMenuItem({ onHelpItemSelect }: HelpMenuItemProps) {

{t("resources").toUpperCase()}

onHelpItemSelect()} href="https://docs.cal.com/" target="_blank" className="flex w-full px-5 py-2 pr-4 text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-gray-900" @@ -57,7 +60,6 @@ export default function HelpMenuItem({ onHelpItemSelect }: HelpMenuItemProps) { /> onHelpItemSelect()} href="https://developer.cal.com/" target="_blank" className="flex w-full px-5 py-2 pr-4 text-sm font-medium text-gray-700 hover:bg-gray-100 hover:text-gray-900" @@ -70,8 +72,8 @@ export default function HelpMenuItem({ onHelpItemSelect }: HelpMenuItemProps) { )} /> -
onHelpItemSelect()}> - +
+
@@ -202,7 +204,11 @@ export default function HelpMenuItem({ onHelpItemSelect }: HelpMenuItemProps) { className="font-medium underline hover:text-gray-700" onClick={() => { setActive(true); - loadChat({ open: true }); + if (isFreshChatEnabled) { + setFreshChat(true); + } else { + loadChat({ open: true }); + } onHelpItemSelect(); }}> {t("contact_support")} diff --git a/packages/features/ee/support/lib/freshchat/FreshChatMenuItem.tsx b/packages/features/ee/support/lib/freshchat/FreshChatMenuItem.tsx new file mode 100644 index 0000000000..4d51ae89be --- /dev/null +++ b/packages/features/ee/support/lib/freshchat/FreshChatMenuItem.tsx @@ -0,0 +1,30 @@ +import { useLocale } from "@calcom/lib/hooks/useLocale"; + +import { useFreshChat } from "./FreshChatProvider"; +import { isFreshChatEnabled } from "./FreshChatScript"; + +interface FreshChatMenuItemProps { + onHelpItemSelect: () => void; +} + +export default function FreshChatMenuItem(props: FreshChatMenuItemProps) { + const { onHelpItemSelect } = props; + const { t } = useLocale(); + + const { setActive } = useFreshChat(); + + if (!isFreshChatEnabled) return null; + + return ( + <> + + + ); +} diff --git a/packages/features/ee/support/lib/freshchat/FreshChatProvider.tsx b/packages/features/ee/support/lib/freshchat/FreshChatProvider.tsx new file mode 100644 index 0000000000..dd369acaf5 --- /dev/null +++ b/packages/features/ee/support/lib/freshchat/FreshChatProvider.tsx @@ -0,0 +1,25 @@ +import type { ReactNode, Dispatch, SetStateAction } from "react"; +import { createContext, useState, useContext } from "react"; + +import FreshChatScript from "./FreshChatScript"; + +type FreshChatContextType = { active: boolean; setActive: Dispatch> }; + +const FreshChatContext = createContext({ active: false, setActive: () => undefined }); + +interface FreshChatProviderProps { + children: ReactNode; +} + +export const useFreshChat = () => useContext(FreshChatContext); + +export default function FreshChatProvider(props: FreshChatProviderProps) { + const [active, setActive] = useState(false); + + return ( + + {props.children} + {active && } + + ); +} diff --git a/packages/features/ee/support/lib/freshchat/FreshChatScript.tsx b/packages/features/ee/support/lib/freshchat/FreshChatScript.tsx new file mode 100644 index 0000000000..b85263bf91 --- /dev/null +++ b/packages/features/ee/support/lib/freshchat/FreshChatScript.tsx @@ -0,0 +1,40 @@ +import Script from "next/script"; + +import { trpc } from "@calcom/trpc/react"; + +declare global { + interface Window { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + fcWidget: any; + } +} + +// eslint-disable-next-line turbo/no-undeclared-env-vars +const host = process.env.NEXT_PUBLIC_FRESHCHAT_HOST; +// eslint-disable-next-line turbo/no-undeclared-env-vars +const token = process.env.NEXT_PUBLIC_FRESHCHAT_TOKEN; + +export const isFreshChatEnabled = host !== "undefined" && token !== "undefined"; + +export default function FreshChatScript() { + const { data } = trpc.viewer.me.useQuery(); + return ( +