From 9e7cb2c0b83e29bd30c37ad32b9f6788f408d613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Omar=20L=C3=B3pez?= Date: Fri, 24 Sep 2021 14:02:03 -0600 Subject: [PATCH] CAL-469 Adds intercom dynamically (#762) * Adds react-use-intercom * Adds intercom env var * Loads intercom dynamically if env is set * CAL-473 Fixes client-side routing for authed pages * Moves intercom code to ee Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .env.example | 3 +++ components/Shell.tsx | 3 +++ ee/lib/intercom/HelpMenuItem.tsx | 35 +++++++++++++++++++++++++ ee/lib/intercom/HelpMenuItemDynamic.tsx | 8 ++++++ ee/lib/intercom/provider.tsx | 8 ++++++ ee/lib/intercom/providerDynamic.tsx | 8 ++++++ lib/app-providers.tsx | 10 ++++--- package.json | 1 + pages/event-types/index.tsx | 4 +-- yarn.lock | 5 ++++ 10 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 ee/lib/intercom/HelpMenuItem.tsx create mode 100644 ee/lib/intercom/HelpMenuItemDynamic.tsx create mode 100644 ee/lib/intercom/provider.tsx create mode 100644 ee/lib/intercom/providerDynamic.tsx diff --git a/.env.example b/.env.example index 06dc08d075..a7335b31e8 100644 --- a/.env.example +++ b/.env.example @@ -51,3 +51,6 @@ PAYMENT_FEE_FIXED=10 # Take 10 additional cents commission # Application Key for symmetric encryption and decryption # must be 32 bytes for AES256 encryption algorithm CALENDSO_ENCRYPTION_KEY= + +# Intercom Config +NEXT_PUBLIC_INTERCOM_APP_ID= diff --git a/components/Shell.tsx b/components/Shell.tsx index 1d44e38eb3..4670a9e9b0 100644 --- a/components/Shell.tsx +++ b/components/Shell.tsx @@ -17,6 +17,8 @@ import { useRouter } from "next/router"; import React, { Fragment, useEffect, useState } from "react"; import { Toaster } from "react-hot-toast"; +import HelpMenuItemDynamic from "@ee/lib/intercom/HelpMenuItemDynamic"; + import classNames from "@lib/classNames"; import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry"; @@ -315,6 +317,7 @@ function UserDropdown({ small, bottom }: { small?: boolean; bottom?: boolean }) )} +
diff --git a/ee/lib/intercom/HelpMenuItem.tsx b/ee/lib/intercom/HelpMenuItem.tsx new file mode 100644 index 0000000000..053393a3b1 --- /dev/null +++ b/ee/lib/intercom/HelpMenuItem.tsx @@ -0,0 +1,35 @@ +import { Menu } from "@headlessui/react"; +import { ChatAltIcon } from "@heroicons/react/solid"; +import { useIntercom } from "react-use-intercom"; + +import classNames from "@lib/classNames"; + +const HelpMenuItem = () => { + const { boot, show } = useIntercom(); + return ( + + {({ active }) => ( + + )} + + ); +}; + +export default HelpMenuItem; diff --git a/ee/lib/intercom/HelpMenuItemDynamic.tsx b/ee/lib/intercom/HelpMenuItemDynamic.tsx new file mode 100644 index 0000000000..e1bee9370f --- /dev/null +++ b/ee/lib/intercom/HelpMenuItemDynamic.tsx @@ -0,0 +1,8 @@ +import dynamic from "next/dynamic"; +import { Fragment } from "react"; + +const HelpMenuItemDynamic = process.env.NEXT_PUBLIC_INTERCOM_APP_ID + ? dynamic(() => import("./HelpMenuItem")) + : Fragment; + +export default HelpMenuItemDynamic; diff --git a/ee/lib/intercom/provider.tsx b/ee/lib/intercom/provider.tsx new file mode 100644 index 0000000000..2c077b6c28 --- /dev/null +++ b/ee/lib/intercom/provider.tsx @@ -0,0 +1,8 @@ +import { FC } from "react"; +import { IntercomProvider } from "react-use-intercom"; + +const Provider: FC = ({ children }) => ( + {children} +); + +export default Provider; diff --git a/ee/lib/intercom/providerDynamic.tsx b/ee/lib/intercom/providerDynamic.tsx new file mode 100644 index 0000000000..bd5ddfc2a4 --- /dev/null +++ b/ee/lib/intercom/providerDynamic.tsx @@ -0,0 +1,8 @@ +import dynamic from "next/dynamic"; +import { Fragment } from "react"; + +const DynamicIntercomProvider = process.env.NEXT_PUBLIC_INTERCOM_APP_ID + ? dynamic(() => import("./provider")) + : Fragment; + +export default DynamicIntercomProvider; diff --git a/lib/app-providers.tsx b/lib/app-providers.tsx index 200e76a0c8..79d5983ccb 100644 --- a/lib/app-providers.tsx +++ b/lib/app-providers.tsx @@ -3,6 +3,8 @@ import React from "react"; import { HydrateProps, QueryClient, QueryClientProvider } from "react-query"; import { Hydrate } from "react-query/hydration"; +import DynamicIntercomProvider from "@ee/lib/intercom/providerDynamic"; + import { Session } from "@lib/auth"; import { createTelemetryClient, TelemetryProvider } from "@lib/telemetry"; @@ -19,9 +21,11 @@ const AppProviders: React.FC = ({ pageProps, children }) => { return ( - - {children} - + + + {children} + + ); diff --git a/package.json b/package.json index 0a581eed31..9271b2ed24 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "react-query": "^3.21.0", "react-select": "^4.3.1", "react-timezone-select": "^1.0.7", + "react-use-intercom": "1.4.0", "short-uuid": "^4.2.0", "stripe": "^8.168.0", "tsdav": "1.0.6", diff --git a/pages/event-types/index.tsx b/pages/event-types/index.tsx index a6547f5981..93157fa272 100644 --- a/pages/event-types/index.tsx +++ b/pages/event-types/index.tsx @@ -313,7 +313,7 @@ const EventTypesPage = (props: PageProps) => { )} {props.eventTypes && props.eventTypes.map((input) => ( - <> + {/* hide list heading when there is only one (current user) */} {(props.eventTypes.length !== 1 || input.teamId) && ( { profile={input.profile} readOnly={input.metadata?.readOnly} /> - + ))} {props.eventTypes.length === 0 && } diff --git a/yarn.lock b/yarn.lock index a3e7094ca4..5a6b67430b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6062,6 +6062,11 @@ react-transition-group@^4.3.0: loose-envify "^1.4.0" prop-types "^15.6.2" +react-use-intercom@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/react-use-intercom/-/react-use-intercom-1.4.0.tgz#796527728c131ebf132186385bf78f69dbcd84cc" + integrity sha512-HqPp7nRnftREE01i88w2kYWOV45zvJt0Of6jtHflIBa3eKl1bAs/izZUINGCJ0DOdgAdlbLweAvJlP4VTzsJjQ== + react-with-direction@^1.3.1: version "1.3.1" resolved "https://registry.npmjs.org/react-with-direction/-/react-with-direction-1.3.1.tgz"