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>
pull/773/head
Omar López 2021-09-24 14:02:03 -06:00 committed by GitHub
parent 889b3f36ae
commit 9e7cb2c0b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 80 additions and 5 deletions

View File

@ -51,3 +51,6 @@ PAYMENT_FEE_FIXED=10 # Take 10 additional cents commission
# Application Key for symmetric encryption and decryption # Application Key for symmetric encryption and decryption
# must be 32 bytes for AES256 encryption algorithm # must be 32 bytes for AES256 encryption algorithm
CALENDSO_ENCRYPTION_KEY= CALENDSO_ENCRYPTION_KEY=
# Intercom Config
NEXT_PUBLIC_INTERCOM_APP_ID=

View File

@ -17,6 +17,8 @@ import { useRouter } from "next/router";
import React, { Fragment, useEffect, useState } from "react"; import React, { Fragment, useEffect, useState } from "react";
import { Toaster } from "react-hot-toast"; import { Toaster } from "react-hot-toast";
import HelpMenuItemDynamic from "@ee/lib/intercom/HelpMenuItemDynamic";
import classNames from "@lib/classNames"; import classNames from "@lib/classNames";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry"; import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry";
@ -315,6 +317,7 @@ function UserDropdown({ small, bottom }: { small?: boolean; bottom?: boolean })
</a> </a>
)} )}
</Menu.Item> </Menu.Item>
<HelpMenuItemDynamic />
</div> </div>
<div className="py-1"> <div className="py-1">
<Menu.Item> <Menu.Item>

View File

@ -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 (
<Menu.Item>
{({ active }) => (
<button
onClick={() => {
boot();
show();
}}
className={classNames(
active ? "bg-gray-100 text-gray-900" : "text-neutral-700",
"w-full flex px-4 py-2 text-sm font-medium"
)}>
<ChatAltIcon
className={classNames(
"text-neutral-400 group-hover:text-neutral-500",
"mr-2 flex-shrink-0 h-5 w-5"
)}
aria-hidden="true"
/>
Help
</button>
)}
</Menu.Item>
);
};
export default HelpMenuItem;

View File

@ -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;

View File

@ -0,0 +1,8 @@
import { FC } from "react";
import { IntercomProvider } from "react-use-intercom";
const Provider: FC = ({ children }) => (
<IntercomProvider appId={process.env.NEXT_PUBLIC_INTERCOM_APP_ID!}>{children}</IntercomProvider>
);
export default Provider;

View File

@ -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;

View File

@ -3,6 +3,8 @@ import React from "react";
import { HydrateProps, QueryClient, QueryClientProvider } from "react-query"; import { HydrateProps, QueryClient, QueryClientProvider } from "react-query";
import { Hydrate } from "react-query/hydration"; import { Hydrate } from "react-query/hydration";
import DynamicIntercomProvider from "@ee/lib/intercom/providerDynamic";
import { Session } from "@lib/auth"; import { Session } from "@lib/auth";
import { createTelemetryClient, TelemetryProvider } from "@lib/telemetry"; import { createTelemetryClient, TelemetryProvider } from "@lib/telemetry";
@ -19,9 +21,11 @@ const AppProviders: React.FC<AppProviderProps> = ({ pageProps, children }) => {
return ( return (
<TelemetryProvider value={createTelemetryClient()}> <TelemetryProvider value={createTelemetryClient()}>
<QueryClientProvider client={queryClient}> <QueryClientProvider client={queryClient}>
<Hydrate state={pageProps.dehydratedState}> <DynamicIntercomProvider>
<Provider session={pageProps.session}>{children}</Provider> <Hydrate state={pageProps.dehydratedState}>
</Hydrate> <Provider session={pageProps.session}>{children}</Provider>
</Hydrate>
</DynamicIntercomProvider>
</QueryClientProvider> </QueryClientProvider>
</TelemetryProvider> </TelemetryProvider>
); );

View File

@ -70,6 +70,7 @@
"react-query": "^3.21.0", "react-query": "^3.21.0",
"react-select": "^4.3.1", "react-select": "^4.3.1",
"react-timezone-select": "^1.0.7", "react-timezone-select": "^1.0.7",
"react-use-intercom": "1.4.0",
"short-uuid": "^4.2.0", "short-uuid": "^4.2.0",
"stripe": "^8.168.0", "stripe": "^8.168.0",
"tsdav": "1.0.6", "tsdav": "1.0.6",

View File

@ -313,7 +313,7 @@ const EventTypesPage = (props: PageProps) => {
)} )}
{props.eventTypes && {props.eventTypes &&
props.eventTypes.map((input) => ( props.eventTypes.map((input) => (
<> <Fragment key={input.profile?.slug}>
{/* hide list heading when there is only one (current user) */} {/* hide list heading when there is only one (current user) */}
{(props.eventTypes.length !== 1 || input.teamId) && ( {(props.eventTypes.length !== 1 || input.teamId) && (
<EventTypeListHeading <EventTypeListHeading
@ -326,7 +326,7 @@ const EventTypesPage = (props: PageProps) => {
profile={input.profile} profile={input.profile}
readOnly={input.metadata?.readOnly} readOnly={input.metadata?.readOnly}
/> />
</> </Fragment>
))} ))}
{props.eventTypes.length === 0 && <CreateFirstEventTypeView />} {props.eventTypes.length === 0 && <CreateFirstEventTypeView />}

View File

@ -6062,6 +6062,11 @@ react-transition-group@^4.3.0:
loose-envify "^1.4.0" loose-envify "^1.4.0"
prop-types "^15.6.2" 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: react-with-direction@^1.3.1:
version "1.3.1" version "1.3.1"
resolved "https://registry.npmjs.org/react-with-direction/-/react-with-direction-1.3.1.tgz" resolved "https://registry.npmjs.org/react-with-direction/-/react-with-direction-1.3.1.tgz"