Skip to content

Commit

Permalink
chore: Add newsletter to bottom banner
Browse files Browse the repository at this point in the history
  • Loading branch information
kaloster committed Sep 24, 2024
1 parent 5ecc076 commit f470fdb
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
["<meta charset=\"utf-8\">","<meta name=\"description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta name=\"next-head-count\" content=\"17\">","<meta name=\"theme-color\" content=\"#000000\">","<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">","<meta property=\"og:creator\" content=\"@cziscience\">","<meta property=\"og:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"og:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"og:site\" content=\"@cziscience\">","<meta property=\"og:site_name\" content=\"Cellxgene Data Portal\">","<meta property=\"og:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"og:type\" content=\"website\">","<meta property=\"og:url\" content=\"https://cellxgene.cziscience.com/\">","<meta property=\"title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"twitter:card\" content=\"summary\">","<meta property=\"twitter:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"twitter:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"twitter:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">"]
["<meta charset=\"utf-8\">","<meta id=\"newsletter-signup-meta\" name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\">","<meta name=\"description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta name=\"next-head-count\" content=\"17\">","<meta name=\"theme-color\" content=\"#000000\">","<meta property=\"og:creator\" content=\"@cziscience\">","<meta property=\"og:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"og:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"og:site\" content=\"@cziscience\">","<meta property=\"og:site_name\" content=\"Cellxgene Data Portal\">","<meta property=\"og:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"og:type\" content=\"website\">","<meta property=\"og:url\" content=\"https://cellxgene.cziscience.com/\">","<meta property=\"title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"twitter:card\" content=\"summary\">","<meta property=\"twitter:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"twitter:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"twitter:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">"]
Original file line number Diff line number Diff line change
@@ -1 +1 @@
["<meta charset=\"utf-8\">","<meta name=\"description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta name=\"next-head-count\" content=\"17\">","<meta name=\"theme-color\" content=\"#000000\">","<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">","<meta property=\"og:creator\" content=\"@cziscience\">","<meta property=\"og:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"og:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"og:site\" content=\"@cziscience\">","<meta property=\"og:site_name\" content=\"Cellxgene Data Portal\">","<meta property=\"og:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"og:type\" content=\"website\">","<meta property=\"og:url\" content=\"https://cellxgene.cziscience.com/\">","<meta property=\"title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"twitter:card\" content=\"summary\">","<meta property=\"twitter:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"twitter:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"twitter:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">"]
["<meta charset=\"utf-8\">","<meta id=\"newsletter-signup-meta\" name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\">","<meta name=\"description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta name=\"next-head-count\" content=\"17\">","<meta name=\"theme-color\" content=\"#000000\">","<meta property=\"og:creator\" content=\"@cziscience\">","<meta property=\"og:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"og:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"og:site\" content=\"@cziscience\">","<meta property=\"og:site_name\" content=\"Cellxgene Data Portal\">","<meta property=\"og:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"og:type\" content=\"website\">","<meta property=\"og:url\" content=\"https://cellxgene.cziscience.com/\">","<meta property=\"title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"twitter:card\" content=\"summary\">","<meta property=\"twitter:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"twitter:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"twitter:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">"]
Original file line number Diff line number Diff line change
@@ -1 +1 @@
["<meta charset=\"utf-8\">","<meta name=\"description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta name=\"next-head-count\" content=\"17\">","<meta name=\"theme-color\" content=\"#000000\">","<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1\">","<meta property=\"og:creator\" content=\"@cziscience\">","<meta property=\"og:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"og:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"og:site\" content=\"@cziscience\">","<meta property=\"og:site_name\" content=\"Cellxgene Data Portal\">","<meta property=\"og:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"og:type\" content=\"website\">","<meta property=\"og:url\" content=\"https://cellxgene.cziscience.com/\">","<meta property=\"title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"twitter:card\" content=\"summary\">","<meta property=\"twitter:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"twitter:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"twitter:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">"]
["<meta charset=\"utf-8\">","<meta id=\"newsletter-signup-meta\" name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\">","<meta name=\"description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta name=\"next-head-count\" content=\"17\">","<meta name=\"theme-color\" content=\"#000000\">","<meta property=\"og:creator\" content=\"@cziscience\">","<meta property=\"og:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"og:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"og:site\" content=\"@cziscience\">","<meta property=\"og:site_name\" content=\"Cellxgene Data Portal\">","<meta property=\"og:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"og:type\" content=\"website\">","<meta property=\"og:url\" content=\"https://cellxgene.cziscience.com/\">","<meta property=\"title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">","<meta property=\"twitter:card\" content=\"summary\">","<meta property=\"twitter:description\" content=\"Explore single-cell transcriptomics data in CellGuide, a comprehensive resource that empowers researchers with deep insights into the intricacies of cell types\">","<meta property=\"twitter:image\" content=\"https://cellxgene.cziscience.com/open-graph.jpg\">","<meta property=\"twitter:title\" content=\"CellGuide Cell Types and Cell Tissues - CZ CELLxGENE\">"]
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import {

export const useConnect = ({
id,
isHubSpotReady,
email,
setError,
}: {
id?: string;
isHubSpotReady: boolean;
email: string;
setError: (error: string) => void;
}) => {
Expand Down Expand Up @@ -83,6 +85,7 @@ export const useConnect = ({
* handles the submission success flow and email validation failure flow
*/
useEffect(() => {
if (!isHubSpotReady) return;
const observer = new MutationObserver((mutations) => {
for (const mutation of mutations) {
for (let i = 0; i < mutation.addedNodes.length; i++) {
Expand All @@ -104,6 +107,14 @@ export const useConnect = ({

const form = document.querySelector(formContainerQueryId);

hbspt.forms.create({
region: "na1",
portalId: "7272273",
formId: "eb65b811-0451-414d-8304-7b9b6f468ce5",
target: formContainerQueryId,
formInstanceId: id,
});

if (form) {
observer.observe(form, {
childList: true,
Expand All @@ -114,7 +125,7 @@ export const useConnect = ({
return () => {
observer.disconnect();
};
}, [formContainerQueryId, id, setError]);
}, [formContainerQueryId, id, setError, isHubSpotReady]);

return {
isSubmitted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {

export default function BottomBannerModalContent({
id = "newsletter-banner",
isHubSpotReady = false,
setEmail,
setError,
emailValidationError,
Expand All @@ -33,7 +34,7 @@ export default function BottomBannerModalContent({
submitButtonEnabledOnce,
setSubmitButtonEnabledOnce,
emailRef,
} = useConnect({ id, setError, email });
} = useConnect({ id, isHubSpotReady, setError, email });

return (
<StyledNewsletterSignupModal data-testid="newsletter-modal-content">
Expand Down
21 changes: 19 additions & 2 deletions frontend/src/components/BottomBanner/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,28 @@ import {
import { track } from "src/common/analytics";
import { EVENTS } from "src/common/analytics/events";

export const useConnect = ({ asFooter }: { asFooter?: boolean }) => {
export const useConnect = ({
isHubSpotReadyProp,
asFooter,
}: {
isHubSpotReadyProp: boolean;
asFooter?: boolean;
}) => {
const [bottomBannerLastClosedTime, setBottomBannerLastClosedTime] =
useLocalStorage<number>(BOTTOM_BANNER_LAST_CLOSED_TIME_KEY, 0);

const [newsletterModalIsOpen, setNewsletterModalIsOpen] = useState(false);
const [isHubSpotReady, setIsHubSpotReady] = useState(false);
const [email, setEmail] = useState("");
const [emailValidationError, setError] = useState("");
const [isDirectLink, setIsDirectLink] = useState(false);

useEffect(() => {
if (!isHubSpotReadyProp) return;

setIsHubSpotReady(true);
}, [isHubSpotReady, isHubSpotReadyProp]);

/**
* useEffect
* Reads a query parameter from the URL to auto open the newsletter signup modal
Expand All @@ -24,6 +37,8 @@ export const useConnect = ({ asFooter }: { asFooter?: boolean }) => {
* isDirectLink is tracked in setter function or else we get window not defined error
*/
useEffect(() => {
if (!isHubSpotReady) return;

if (!asFooter && window) {
const openModalParam = new URLSearchParams(window.location.search).get(
"newsletter_signup"
Expand All @@ -39,7 +54,7 @@ export const useConnect = ({ asFooter }: { asFooter?: boolean }) => {
});
}
}
}, [asFooter, isDirectLink]);
}, [asFooter, isDirectLink, isHubSpotReady]);

/**
* showBanner
Expand Down Expand Up @@ -78,9 +93,11 @@ export const useConnect = ({ asFooter }: { asFooter?: boolean }) => {
return {
setBottomBannerLastClosedTime,
newsletterModalIsOpen,
setIsHubSpotReady,
isDirectLink,
toggleNewsletterSignupModal,
showBanner,
isHubSpotReady,
email,
setEmail,
emailValidationError,
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/components/BottomBanner/constants.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
export const FORM_CONTAINER_ID = "form-container";
export const FORM_CONTAINER_ID = "hubspot-form-container";
export const FORM_CONTAINER_ID_QUERY = `#${FORM_CONTAINER_ID}`;

export const BOTTOM_BANNER_EXPIRATION_TIME_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
export const BOTTOM_BANNER_LAST_CLOSED_TIME_KEY = "bottomBannerLastClosedTime";
export const BOTTOM_BANNER_SURVEY_LINK_TEXT = "quick survey.";
export const BOTTOM_BANNER_SURVEY_TEXT = "Send us feedback with this";

//(smcanny) 07/24 - Newsletter constants not currently in use
// leaving it here incase a new newsletter modal is established
export const NEWSLETTER_SIGNUP_TITLE = "Join Our Newsletter";
export const NEWSLETTER_SIGNUP_MESSAGE = "Thanks for subscribing!";
export const NEWSLETTER_SIGNUP_SUCCESS_MESSAGE =
Expand All @@ -22,3 +20,4 @@ export const FAILED_EMAIL_VALIDATION_STRING =
"Please provide a valid email address.";
export const HIDDEN_NEWSLETTER_SUCCESS_MESSAGE =
"Thank you for joining our newsletter.";
export const HUBSPOT_URL = "https://js.hsforms.net/forms/v2.js";
37 changes: 34 additions & 3 deletions frontend/src/components/BottomBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import Script from "next/script";
import { memo } from "react";
import {
BOTTOM_BANNER_ID,
NewsletterModal,
StyledBanner,
StyledBottomBannerWrapper,
StyledLink,
HeaderContainer,
HiddenHubSpotForm,
FooterContentWrapper,
StyledCloseButtonIcon,
HeaderContainer,
} from "./style";
import CellxgeneLogoSvg from "src/common/images/CellxGene.svg";
import Head from "next/head";
import { EXCLUDE_IN_SCREENSHOT_CLASS_NAME } from "src/views/WheresMyGeneV2/components/GeneSearchBar/components/SaveExport";
import { noop } from "src/common/constants/utils";
import BottomBannerModalContent from "./components/ModalContent";
import { useConnect } from "./connect";
import {
FORM_CONTAINER_ID,
HUBSPOT_URL,
BOTTOM_BANNER_SURVEY_LINK_TEXT,
BOTTOM_BANNER_SURVEY_TEXT,
NEWSLETTER_SIGNUP_BANNER_SUBSCRIBE_BUTTON_TEXT,
Expand All @@ -23,29 +29,50 @@ import { Props } from "./types";

export default memo(function BottomBanner({
hasSurveyLink = true,
hasNewsletterSignup = false,
hasNewsletterSignup = true,
asFooter = false,
customSurveyLinkPrefix,
analyticsHandler,
surveyLink,
id = "newsletter-banner",
isHubSpotReady: isHubSpotReadyProp = false,
onHubSpotReady = noop,
}: Props): JSX.Element | null {
const {
setBottomBannerLastClosedTime,
setEmail,
setError,
setIsHubSpotReady,
toggleNewsletterSignupModal,
newsletterModalIsOpen,
isDirectLink,
showBanner,
isHubSpotReady,
email,
emailValidationError,
} = useConnect({ asFooter });
} = useConnect({ isHubSpotReadyProp, asFooter });

if (!showBanner) return null;

return (
<>
<Head>
{!asFooter && (
<meta
id="newsletter-signup-meta"
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1"
/>
)}
</Head>
<Script
onReady={() => {
setIsHubSpotReady(true);
onHubSpotReady();
}}
type="text/javascript"
src={HUBSPOT_URL}
/>
<StyledBottomBannerWrapper
asFooter={asFooter}
id={BOTTOM_BANNER_ID}
Expand All @@ -58,9 +85,12 @@ export default memo(function BottomBanner({
onClose={() => setBottomBannerLastClosedTime(Date.now())}
data-id={id}
>
{/* Hidden form for submitting the data to HubSpot */}
<HiddenHubSpotForm id={FORM_CONTAINER_ID} />
{asFooter ? (
<FooterContentWrapper>
<BottomBannerModalContent
isHubSpotReady={isHubSpotReady}
setError={setError}
setEmail={setEmail}
email={email}
Expand Down Expand Up @@ -115,6 +145,7 @@ export default memo(function BottomBanner({
/>
</HeaderContainer>
<BottomBannerModalContent
isHubSpotReady={isHubSpotReady}
setError={setError}
setEmail={setEmail}
email={email}
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/components/BottomBanner/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { SKINNY_MODE_BREAKPOINT_WIDTH } from "src/views/CellGuide/components/Cel

export const BOTTOM_BANNER_ID = "bottom-banner";

export const HiddenHubSpotForm = styled.div`
display: none;
`;

export const StyledBanner = styled(Banner)`
${fontBodyS}
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/components/BottomBanner/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,16 @@ export interface Props {
* we need to give each banner a unique id to differentiate them.
*/
id?: string;
/**
* (thuang): This is needed for homepage, because we have two instances of BottomBanner
* and the HubSpot script is only loaded once, so only the first instance of BottomBanner
* gets the onReady callback.
*/
isHubSpotReady?: boolean;
/**
* (thuang): The first instance of BottomBanner in the UI needs to call onHubSpotReady(),
* so the second BottomBanner knows when HubSpot is ready via `isHubSpotReady` prop.
*/
onHubSpotReady?: () => void;
emailValidationError?: string;
}
1 change: 1 addition & 0 deletions frontend/src/components/LandingFooter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { EVENTS } from "src/common/analytics/events";
import { ROUTES } from "src/common/constants/routes";
import Wordmark from "src/common/images/cellxgene-discover-wordmark.svg";
import CZILogo from "src/components/common/staticPages/czi-logo-white.png";

import styles from "./index.module.scss";

const LandingFooter = (): JSX.Element => {
Expand Down

0 comments on commit f470fdb

Please sign in to comment.