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
parent
889b3f36ae
commit
9e7cb2c0b8
|
@ -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=
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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 />}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue