Skip to content

Commit

Permalink
feat: always show intercom on desktop by default (hidden on mobile) (#…
Browse files Browse the repository at this point in the history
…14423)

* feat: always show intercom on desktop by default (hidden on mobile)

* Revert "feat: always show intercom on desktop by default (hidden on mobile)"

This reverts commit d14a7b0.

* feat: always show intercom on desktop by default (hidden on mobile)

* fix: type error

* refactor

* saved showIntercom in localstorage instead of DB

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
  • Loading branch information
SomayChauhan and PeerRich committed Apr 11, 2024
1 parent 0c67f49 commit f010279
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 64 deletions.
10 changes: 0 additions & 10 deletions apps/web/modules/event-types/views/event-types-listing-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { memo, useEffect, useState } from "react";
import { z } from "zod";

import { useOrgBranding } from "@calcom/features/ee/organizations/context/provider";
import useIntercom from "@calcom/features/ee/support/lib/intercom/useIntercom";
import { EventTypeEmbedButton, EventTypeEmbedDialog } from "@calcom/features/embed/EventTypeEmbed";
import { EventTypeDescription } from "@calcom/features/eventtypes/components";
import CreateEventTypeDialog from "@calcom/features/eventtypes/components/CreateEventTypeDialog";
Expand Down Expand Up @@ -950,8 +949,6 @@ const EventTypesPage: React.FC & {
getLayout?: AppProps["Component"]["getLayout"];
} = () => {
const { t } = useLocale();
const searchParams = useCompatSearchParams();
const { open } = useIntercom();
const { data: user } = useMeQuery();
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [showProfileBanner, setShowProfileBanner] = useState(false);
Expand All @@ -966,13 +963,6 @@ const EventTypesPage: React.FC & {
staleTime: 1 * 60 * 60 * 1000,
});

useEffect(() => {
if (searchParams?.get("openIntercom") === "true") {
open();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
setShowProfileBanner(
!!orgBranding && !document.cookie.includes("calcom-profile-banner=1") && !user?.completedOnboarding
Expand Down
2 changes: 2 additions & 0 deletions apps/web/public/static/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -2403,5 +2403,7 @@
"unreviewed": "Unreviewed",
"rating_url_info":"The URL for Rating Feedback Form",
"no_show_url_info":"The URL for No Show Feedback",
"no_support_needed":"No Support Needed?",
"hide_support":"Hide Support",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
}
2 changes: 0 additions & 2 deletions packages/features/ee/support/components/ContactMenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { Icon, UpgradeTeamsBadge } from "@calcom/ui";

import FreshChatMenuItem from "../lib/freshchat/FreshChatMenuItem";
import HelpscoutMenuItem from "../lib/helpscout/HelpscoutMenuItem";
import IntercomMenuItem from "../lib/intercom/IntercomMenuItem";
import ZendeskMenuItem from "../lib/zendesk/ZendeskMenuItem";

interface ContactMenuItem {
Expand All @@ -20,7 +19,6 @@ export default function ContactMenuItem(props: ContactMenuItem) {
<>
{hasPaidPlan ? (
<>
<IntercomMenuItem onHelpItemSelect={onHelpItemSelect} />
<ZendeskMenuItem onHelpItemSelect={onHelpItemSelect} />
<HelpscoutMenuItem onHelpItemSelect={onHelpItemSelect} />
<FreshChatMenuItem onHelpItemSelect={onHelpItemSelect} />
Expand Down
85 changes: 60 additions & 25 deletions packages/features/ee/support/components/HelpMenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { useState } from "react";
import { useChat } from "react-live-chat-loader";

import classNames from "@calcom/lib/classNames";
import { JOIN_DISCORD } from "@calcom/lib/constants";
import { useHasPaidPlan } from "@calcom/lib/hooks/useHasPaidPlan";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { localStorage } from "@calcom/lib/webstorage";
import { trpc } from "@calcom/trpc/react";
import { Button, showToast, TextArea } from "@calcom/ui";
import { Icon } from "@calcom/ui";
Expand All @@ -20,13 +19,21 @@ interface HelpMenuItemProps {

export default function HelpMenuItem({ onHelpItemSelect }: HelpMenuItemProps) {
const [rating, setRating] = useState<null | string>(null);
const { open } = useIntercom();
const [showIntercom, setShowIntercom] = useState<boolean>(
localStorage.getItem("showIntercom") === "false" ? false : true
);
const { open, shutdown } = useIntercom();
const [comment, setComment] = useState("");
const [disableSubmit, setDisableSubmit] = useState(true);
const [active, setActive] = useState(false);
const [, loadChat] = useChat();
const { t } = useLocale();

const toggleIntercom = (value: boolean) => {
setShowIntercom(value);
localStorage.setItem("showIntercom", String(value));
};

const { setActive: setFreshChat } = useFreshChat();

const mutation = trpc.viewer.submitFeedback.useMutation({
Expand All @@ -46,8 +53,6 @@ export default function HelpMenuItem({ onHelpItemSelect }: HelpMenuItemProps) {
mutation.mutate({ rating: rating, comment: comment });
};

const { hasPaidPlan } = useHasPaidPlan();

return (
<div className="bg-default border-default w-full rounded-md">
<div className="w-full py-5">
Expand All @@ -71,7 +76,6 @@ export default function HelpMenuItem({ onHelpItemSelect }: HelpMenuItemProps) {
<ContactMenuItem onHelpItemSelect={onHelpItemSelect} />
</div>
</div>

<hr className="border-muted" />
<div className="w-full p-5">
<p className="text-subtle mb-1">{t("feedback").toUpperCase()}</p>
Expand Down Expand Up @@ -188,33 +192,64 @@ export default function HelpMenuItem({ onHelpItemSelect }: HelpMenuItemProps) {
</div>
)}
</div>
<div className="text-subtle bg-muted w-full p-5">
<p className="">{t("specific_issue")}</p>
{hasPaidPlan ? (
<button
className="hover:text-emphasis text-defualt font-medium underline"
onClick={async () => {
setActive(true);
{/* visible on desktop */}
<div className="text-subtle bg-muted hidden w-full flex-col p-5 md:block">
<p className="">{showIntercom ? t("no_support_needed") : t("specific_issue")}</p>
<button
className="hover:text-emphasis text-defualt font-medium underline"
onClick={async () => {
setActive(true);
if (showIntercom) {
if (isFreshChatEnabled) {
setFreshChat(false);
} else if (isInterComEnabled) {
shutdown();
}
toggleIntercom(false);
} else {
if (isFreshChatEnabled) {
setFreshChat(true);
} else if (isInterComEnabled) {
await open();
} else {
loadChat({ open: true });
}
toggleIntercom(true);
}
onHelpItemSelect();
}}>
{showIntercom ? t("hide_support") : t("contact_support")}
</button>
<span> {t("or").toLowerCase()} </span>
<a
onClick={() => onHelpItemSelect()}
className="hover:text-emphasis text-defualt font-medium underline"
href="https://cal.com/docs"
target="_blank"
rel="noreferrer">
{t("browse_our_docs")}
</a>
.
</div>
{/* visible on mobile */}
<div className="text-subtle bg-muted w-full p-5 md:hidden">
<p className="">{t("specific_issue")}</p>
<button
className="hover:text-emphasis text-defualt font-medium underline"
onClick={async () => {
setActive(true);
if (isFreshChatEnabled) {
setFreshChat(true);
} else if (isInterComEnabled) {
await open();
} else {
loadChat({ open: true });
}

onHelpItemSelect();
}}>
{t("contact_support")}
</button>
) : (
<a
href={JOIN_DISCORD}
target="_blank"
className="hover:text-emphasis text-defualt font-medium underline">
{t("community_support")}
</a>
)}
onHelpItemSelect();
}}>
{t("contact_support")}
</button>
<span> {t("or").toLowerCase()} </span>
<a
onClick={() => onHelpItemSelect()}
Expand Down
26 changes: 0 additions & 26 deletions packages/features/ee/support/lib/intercom/IntercomMenuItem.tsx

This file was deleted.

34 changes: 33 additions & 1 deletion packages/features/ee/support/lib/intercom/useIntercom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const useIntercomHook = isInterComEnabled
return {
boot: noop,
show: noop,
shutdown: noop,
};
};

Expand All @@ -26,6 +27,37 @@ export const useIntercom = () => {
const { hasPaidPlan } = useHasPaidPlan();
const { hasTeamPlan } = useHasTeamPlan();

const boot = async () => {
let userHash;

const req = await fetch(`/api/intercom-hash`);
const res = await req.json();
if (res?.hash) {
userHash = res.hash;
}

hookData.boot({
...(data && data?.name && { name: data.name }),
...(data && data?.email && { email: data.email }),
...(data && data?.id && { userId: data.id }),
createdAt: String(dayjs(data?.createdDate).unix()),
...(userHash && { userHash }),
customAttributes: {
//keys should be snake cased
user_name: data?.username,
link: `${WEBSITE_URL}/${data?.username}`,
admin_link: `${WEBAPP_URL}/settings/admin/users/${data?.id}/edit`,
identity_provider: data?.identityProvider,
timezone: data?.timeZone,
locale: data?.locale,
has_paid_plan: hasPaidPlan,
has_team_plan: hasTeamPlan,
metadata: data?.metadata,
is_logged_in: !!data,
},
});
};

const open = async () => {
let userHash;

Expand Down Expand Up @@ -57,7 +89,7 @@ export const useIntercom = () => {
});
hookData.show();
};
return { ...hookData, open };
return { ...hookData, open, boot };
};

export default useIntercom;
11 changes: 11 additions & 0 deletions packages/features/shell/Shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
} from "@calcom/features/ee/organizations/components/OrgUpgradeBanner";
import { getOrgFullOrigin } from "@calcom/features/ee/organizations/lib/orgDomains";
import HelpMenuItem from "@calcom/features/ee/support/components/HelpMenuItem";
import useIntercom from "@calcom/features/ee/support/lib/intercom/useIntercom";
import { TeamsUpgradeBanner, type TeamsUpgradeBannerProps } from "@calcom/features/ee/teams/components";
import { useFlagMap } from "@calcom/features/flags/context/provider";
import { KBarContent, KBarRoot, KBarTrigger } from "@calcom/features/kbar/Kbar";
Expand Down Expand Up @@ -52,8 +53,10 @@ import { useFormbricks } from "@calcom/lib/formbricks-client";
import getBrandColours from "@calcom/lib/getBrandColours";
import { useBookerUrl } from "@calcom/lib/hooks/useBookerUrl";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import useMediaQuery from "@calcom/lib/hooks/useMediaQuery";
import useTheme from "@calcom/lib/hooks/useTheme";
import { isKeyInObject } from "@calcom/lib/isKeyInObject";
import { localStorage } from "@calcom/lib/webstorage";
import type { User } from "@calcom/prisma/client";
import { trpc } from "@calcom/trpc/react";
import useEmailVerifyCheck from "@calcom/trpc/react/hooks/useEmailVerifyCheck";
Expand Down Expand Up @@ -213,8 +216,16 @@ const useBanners = () => {
const Layout = (props: LayoutProps) => {
const banners = useBanners();

const showIntercom = localStorage.getItem("showIntercom");
const isMobile = useMediaQuery("(max-width: 768px)");
const { boot } = useIntercom();
const pageTitle = typeof props.heading === "string" && !props.title ? props.heading : props.title;

useEffect(() => {
if (showIntercom === "false" || isMobile) return;
boot();
}, [showIntercom, isMobile]);

const bannersHeight = useMemo(() => {
const activeBanners =
banners &&
Expand Down

0 comments on commit f010279

Please sign in to comment.