diff --git a/static/gsApp/components/gsBanner.tsx b/static/gsApp/components/gsBanner.tsx index 3f522b0c57c11b..77172b6360cea6 100644 --- a/static/gsApp/components/gsBanner.tsx +++ b/static/gsApp/components/gsBanner.tsx @@ -1,4 +1,4 @@ -import React, {Component, Fragment} from 'react'; +import React, {Component, Fragment, useEffect} from 'react'; import {ThemeProvider, useTheme} from '@emotion/react'; import * as Sentry from '@sentry/react'; import Cookies from 'js-cookie'; @@ -25,6 +25,7 @@ import {ConfigStore} from 'sentry/stores/configStore'; import {GuideStore} from 'sentry/stores/guideStore'; import {DataCategory} from 'sentry/types/core'; import type {Organization} from 'sentry/types/organization'; +import {showIntercom} from 'sentry/utils/intercom'; import {isActiveSuperuser} from 'sentry/utils/isActiveSuperuser'; import {promptIsDismissed} from 'sentry/utils/promptIsDismissed'; import {useInvertedTheme} from 'sentry/utils/theme/useInvertedTheme'; @@ -96,10 +97,43 @@ function objectFromBilledCategories(callback: (c: BilledDataCategoryInfo) => any const ALERTS_OFF = objectFromBilledCategories(() => false); type SuspensionModalProps = ModalRenderProps & { + organization: Organization; subscription: Subscription; }; -function SuspensionModal({Header, Body, Footer, subscription}: SuspensionModalProps) { +function SuspensionModal({ + Header, + Body, + Footer, + organization, + subscription, +}: SuspensionModalProps) { + const hasIntercom = organization.features.includes('intercom-support'); + + useEffect(() => { + if (hasIntercom) { + trackGetsentryAnalytics('intercom_link.viewed', { + organization, + source: 'account-suspension', + }); + } + }, [hasIntercom, organization]); + + async function handleIntercomClick() { + trackGetsentryAnalytics('intercom_link.clicked', { + organization, + source: 'account-suspension', + }); + try { + await showIntercom(organization.slug); + } catch { + const supportEmail = ConfigStore.get('supportEmail'); + if (supportEmail) { + window.location.href = `mailto:${supportEmail}?subject=${window.encodeURIComponent('Account Suspension')}`; + } + } + } + return (
{'Action Required'}
@@ -120,13 +154,17 @@ function SuspensionModal({Header, Body, Footer, subscription}: SuspensionModalPr

); @@ -482,13 +520,19 @@ class GSBanner extends Component { } tryTriggerSuspendedModal() { - const {subscription} = this.props; + const {organization, subscription} = this.props; if (!subscription.isSuspended) { return; } - openModal(props => ); + openModal(props => ( + + )); } tryTriggerNoticeModal() { diff --git a/static/gsApp/views/amCheckout/index.tsx b/static/gsApp/views/amCheckout/index.tsx index e36040a928a288..501d6c2a415131 100644 --- a/static/gsApp/views/amCheckout/index.tsx +++ b/static/gsApp/views/amCheckout/index.tsx @@ -23,6 +23,7 @@ import {t, tct} from 'sentry/locale'; import {ConfigStore} from 'sentry/stores/configStore'; import type {DataCategory} from 'sentry/types/core'; import type {Organization} from 'sentry/types/organization'; +import {showIntercom} from 'sentry/utils/intercom'; import {normalizeUrl} from 'sentry/utils/url/normalizeUrl'; import type {ReactRouter3Navigate} from 'sentry/utils/useNavigate'; import {withApi} from 'sentry/utils/withApi'; @@ -564,6 +565,8 @@ function AMCheckout(props: Props) { loadStripe(ConfigStore.get('getsentry.stripePublishKey')!); }, []); + const hasIntercom = organization.features.includes('intercom-support'); + useEffect(() => { trackGetsentryAnalytics('am_checkout.viewed', { organization, @@ -573,6 +576,15 @@ function AMCheckout(props: Props) { Sentry.getReplay()?.start(); }, [organization, subscription]); + useEffect(() => { + if (hasIntercom) { + trackGetsentryAnalytics('intercom_link.viewed', { + organization, + source: 'checkout', + }); + } + }, [hasIntercom, organization]); + useEffect(() => { if (subscription.canSelfServe) { if (!hasFetchedBillingConfig.current) { @@ -750,7 +762,29 @@ function AMCheckout(props: Props) { help: ( ), - contact: hasZendesk() ? ( + contact: hasIntercom ? ( + + ) : hasZendesk() ? ( diff --git a/static/gsApp/views/subscriptionPage/planMigrationActive/index.tsx b/static/gsApp/views/subscriptionPage/planMigrationActive/index.tsx index 82aabd87abe1db..424527ed7f9883 100644 --- a/static/gsApp/views/subscriptionPage/planMigrationActive/index.tsx +++ b/static/gsApp/views/subscriptionPage/planMigrationActive/index.tsx @@ -1,15 +1,21 @@ +import {useEffect} from 'react'; import styled from '@emotion/styled'; import moment from 'moment-timezone'; +import {Button} from '@sentry/scraps/button'; import {ExternalLink} from '@sentry/scraps/link'; import {Panel} from 'sentry/components/panels/panel'; import {IconBusiness} from 'sentry/icons'; import {t, tct} from 'sentry/locale'; +import {ConfigStore} from 'sentry/stores/configStore'; +import {showIntercom} from 'sentry/utils/intercom'; +import {useOrganization} from 'sentry/utils/useOrganization'; import ZendeskLink from 'getsentry/components/zendeskLink'; import {ANNUAL} from 'getsentry/constants'; import {CohortId, type PlanMigration, type Subscription} from 'getsentry/types'; +import {trackGetsentryAnalytics} from 'getsentry/utils/trackGetsentryAnalytics'; import {PanelBodyWithTable} from 'getsentry/views/subscriptionPage/styles'; import {PlanMigrationTable} from './planMigrationTable'; @@ -39,10 +45,46 @@ function getMigrationDate(migration: PlanMigration, subscription: Subscription) } export function PlanMigrationActive({subscription, migration}: Props) { + const organization = useOrganization(); + const hasIntercom = organization.features.includes('intercom-support'); + const shouldRender = Boolean(migration?.cohort?.nextPlan); + + useEffect(() => { + if (shouldRender && hasIntercom) { + trackGetsentryAnalytics('intercom_link.viewed', { + organization, + source: 'billing', + }); + } + }, [shouldRender, hasIntercom, organization]); + if (!migration?.cohort?.nextPlan) { return null; } + async function handleIntercomClick() { + trackGetsentryAnalytics('intercom_link.clicked', { + organization, + source: 'billing', + }); + try { + await showIntercom(organization.slug); + } catch { + const supportEmail = ConfigStore.get('supportEmail'); + if (supportEmail) { + window.location.href = `mailto:${supportEmail}?subject=${window.encodeURIComponent('Legacy Plan Migration Question')}`; + } + } + } + + const supportLink = hasIntercom ? ( + + ) : ( + + ); + const isAM3Migration = migration.cohort.cohortId >= CohortId.EIGHTH; return ( @@ -90,17 +132,12 @@ export function PlanMigrationActive({subscription, migration}: Props) { {tct( - 'For more details please see our [faqLink:FAQ] or contact [zendeskLink:Support].', + 'For more details please see our [faqLink:FAQ] or contact [supportLink:Support].', { faqLink: ( ), - zendeskLink: ( - - ), + supportLink, } )} diff --git a/static/gsApp/views/subscriptionPage/trial/trialEnded.tsx b/static/gsApp/views/subscriptionPage/trial/trialEnded.tsx index 12fa3bd646a7d5..ee94a48e590178 100644 --- a/static/gsApp/views/subscriptionPage/trial/trialEnded.tsx +++ b/static/gsApp/views/subscriptionPage/trial/trialEnded.tsx @@ -1,23 +1,67 @@ +import {useEffect} from 'react'; + import {Alert} from '@sentry/scraps/alert'; +import {Button} from '@sentry/scraps/button'; import {tct} from 'sentry/locale'; +import {ConfigStore} from 'sentry/stores/configStore'; +import {showIntercom} from 'sentry/utils/intercom'; +import {useOrganization} from 'sentry/utils/useOrganization'; import ZendeskLink from 'getsentry/components/zendeskLink'; import type {Subscription} from 'getsentry/types'; +import {trackGetsentryAnalytics} from 'getsentry/utils/trackGetsentryAnalytics'; type Props = { subscription: Subscription; }; export function TrialEnded({subscription}: Props) { + const organization = useOrganization(); + const hasIntercom = organization.features.includes('intercom-support'); const canRequestTrial = subscription.canSelfServe && subscription.planDetails?.trialPlan; + const shouldRender = !( + subscription.isTrial || + subscription.canTrial || + !canRequestTrial + ); + + useEffect(() => { + if (shouldRender && hasIntercom) { + trackGetsentryAnalytics('intercom_link.viewed', { + organization, + source: 'trial', + }); + } + }, [shouldRender, hasIntercom, organization]); - if (subscription.isTrial || subscription.canTrial || !canRequestTrial) { + if (!shouldRender) { return null; } - const supportLink = ; + async function handleIntercomClick() { + trackGetsentryAnalytics('intercom_link.clicked', { + organization, + source: 'trial', + }); + try { + await showIntercom(organization.slug); + } catch { + const supportEmail = ConfigStore.get('supportEmail'); + if (supportEmail) { + window.location.href = `mailto:${supportEmail}?subject=${window.encodeURIComponent('Request Another Trial')}`; + } + } + } + + const supportLink = hasIntercom ? ( + + ) : ( + + ); return (