Add support for multiple ads

pull/3882/head
Kamran Ahmed 2 years ago
parent 504ee8cf5e
commit 9b73d60c5d
  1. 51
      src/components/PageSponsor.tsx
  2. 57
      src/components/Sponsor/Sponsor.astro
  3. 22
      src/components/Sponsor/sponsor.js
  4. 11
      src/layouts/BaseLayout.astro
  5. 1
      src/pages/[roadmapId]/index.astro
  6. 1
      src/pages/best-practices/[bestPracticeId]/index.astro

@ -1,37 +1,58 @@
import { useStore } from '@nanostores/preact'; import { useStore } from '@nanostores/preact';
import { useEffect, useState } from 'preact/hooks'; import { useEffect, useState } from 'preact/hooks';
import CloseIcon from '../icons/close.svg'; import CloseIcon from '../icons/close.svg';
import { httpGet } from '../lib/http';
import { sponsorHidden } from '../stores/page'; import { sponsorHidden } from '../stores/page';
export type PageSponsorType = { export type PageSponsorType = {
url: string;
title: string;
imageUrl: string;
description: string;
company: string; company: string;
page: string; description: string;
imageUrl: string;
pageUrl: string;
title: string;
url: string;
};
type V1GetSponsorResponse = {
href?: string;
sponsor?: PageSponsorType;
}; };
type PageSponsorProps = { type PageSponsorProps = {
sponsors?: PageSponsorType[]; gaPageIdentifier?: string;
}; };
export function PageSponsor(props: PageSponsorProps) { export function PageSponsor(props: PageSponsorProps) {
const { sponsors = [] } = props; const { gaPageIdentifier } = props;
const $isSponsorHidden = useStore(sponsorHidden); const $isSponsorHidden = useStore(sponsorHidden);
const [sponsor, setSponsor] = useState<PageSponsorType>(); const [sponsor, setSponsor] = useState<PageSponsorType>();
if (sponsors.length === 0) { const loadSponsor = async () => {
return null; const { response, error } = await httpGet<V1GetSponsorResponse>(
`${import.meta.env.PUBLIC_API_URL}/v1-get-sponsor`,
{
href: window.location.pathname,
} }
);
function loadSponsor() { if (error) {
console.log('loadSponsor'); console.error(error);
return;
}
const sponsorIndex = Math.floor(Math.random() * sponsors.length); if (!response?.sponsor) {
setSponsor(sponsors[sponsorIndex]); return;
} }
setSponsor(response.sponsor);
window.fireEvent({
category: 'SponsorImpression',
action: `${response.sponsor?.company} Impression`,
label: `${gaPageIdentifier} / ${response.sponsor?.company} Link`,
});
};
// We load the sponsor after 1second of the page load // We load the sponsor after 1second of the page load
useEffect(() => { useEffect(() => {
const timer = window.setTimeout(loadSponsor, 500); const timer = window.setTimeout(loadSponsor, 500);
@ -42,7 +63,7 @@ export function PageSponsor(props: PageSponsorProps) {
return null; return null;
} }
const { url, title, imageUrl, description, company, page } = sponsor; const { url, title, imageUrl, description, company, pageUrl } = sponsor;
return ( return (
<a <a
@ -54,7 +75,7 @@ export function PageSponsor(props: PageSponsorProps) {
window.fireEvent({ window.fireEvent({
category: 'SponsorClick', category: 'SponsorClick',
action: `${company} Redirect`, action: `${company} Redirect`,
label: `${page} / ${company} Link`, label: `${gaPageIdentifier} / ${company} Link`,
}); });
}} }}
> >

@ -1,57 +0,0 @@
---
import type { GAEventType } from '../Analytics/analytics';
import Icon from '../AstroIcon.astro';
export type SponsorType = {
url: string;
title: string;
imageUrl: string;
description: string;
event: GAEventType;
};
export interface Props {
sponsor: SponsorType;
}
const {
sponsor: { title, url, description, imageUrl, event },
} = Astro.props;
---
<script src='./sponsor.js'></script>
<a
href={url}
id='sponsor-ad'
target='_blank'
rel='noopener sponsored nofollow'
ga-category={event?.category}
ga-action={event?.action}
ga-label={event?.label}
class='fixed bottom-[15px] right-[15px] outline-transparent z-50 bg-white max-w-[350px] shadow-lg outline-0 hidden'
>
<button
class='absolute top-1.5 right-1.5 text-gray-300 hover:text-gray-800'
aria-label='Close'
close-sponsor
>
<Icon icon='close' class='h-4' />
</button>
<img src={imageUrl} class='h-[150px] lg:h-[169px]' alt='Sponsor Banner' />
<span class='text-sm flex flex-col justify-between'>
<span class='p-[10px]'>
<span class='font-semibold mb-0.5 block'>{title}</span>
<span class='text-gray-500 block'>{description}</span>
</span>
<span class='sponsor-footer'>Partner Content</span>
</span>
</a>
<script>
document.querySelector('[close-sponsor]')?.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
document.getElementById('sponsor-ad')?.classList.add('hidden');
});
</script>

@ -1,22 +0,0 @@
import { sponsorHidden } from '../../stores/page';
function showHideSponsor(shouldHide) {
const ad = document.querySelector('#sponsor-ad');
if (!ad) {
return;
}
if (shouldHide) {
ad.classList.add('hidden');
ad.classList.remove('flex');
} else {
ad.classList.remove('hidden');
ad.classList.add('flex');
}
}
sponsorHidden.listen(showHideSponsor);
window.setTimeout(() => {
showHideSponsor(false);
}, 500);

@ -11,6 +11,8 @@ import '../styles/global.css';
export interface Props { export interface Props {
title: string; title: string;
// This isn't used anywhere except for the sponsor event labels
briefTitle?: string;
redirectUrl?: string; redirectUrl?: string;
description?: string; description?: string;
keywords?: string[]; keywords?: string[];
@ -23,6 +25,7 @@ export interface Props {
const { const {
title = siteConfig.title, title = siteConfig.title,
briefTitle,
description = siteConfig.description, description = siteConfig.description,
keywords = siteConfig.keywords, keywords = siteConfig.keywords,
noIndex = false, noIndex = false,
@ -41,6 +44,12 @@ const canonicalUrl = givenCanonical || currentPageAbsoluteUrl;
const commitUrl = `https://github.com/kamranahmedse/developer-roadmap/commit/${ const commitUrl = `https://github.com/kamranahmedse/developer-roadmap/commit/${
import.meta.env.GITHUB_SHA import.meta.env.GITHUB_SHA
}`; }`;
// e.g. frontend:react or best-practices:frontend-performance
const gaPageIdentifier = Astro.url.pathname
.replace(/^\//, '')
.replace(/\/$/, '')
.replace(/\//g, ':');
--- ---
<!DOCTYPE html> <!DOCTYPE html>
@ -140,7 +149,7 @@ const commitUrl = `https://github.com/kamranahmedse/developer-roadmap/commit/${
<Analytics /> <Analytics />
<Authenticator /> <Authenticator />
<PageProgress client:idle /> <PageProgress client:idle />
<PageSponsor sponsors={sponsors || []} client:idle /> <PageSponsor gaPageIdentifier={briefTitle || gaPageIdentifier} client:idle />
<slot name='after-footer' /> <slot name='after-footer' />
</body> </body>

@ -61,6 +61,7 @@ const contentContributionLink = `https://github.com/kamranahmedse/developer-road
<BaseLayout <BaseLayout
permalink={`/${roadmapId}`} permalink={`/${roadmapId}`}
title={roadmapData?.seo?.title} title={roadmapData?.seo?.title}
briefTitle={roadmapData?.briefTitle}
description={roadmapData.seo.description} description={roadmapData.seo.description}
keywords={roadmapData.seo.keywords} keywords={roadmapData.seo.keywords}
sponsors={roadmapData.sponsors} sponsors={roadmapData.sponsors}

@ -53,6 +53,7 @@ const contentContributionLink = `https://github.com/kamranahmedse/developer-road
<BaseLayout <BaseLayout
permalink={`/best-practices/${bestPracticeId}`} permalink={`/best-practices/${bestPracticeId}`}
title={bestPracticeData?.seo?.title} title={bestPracticeData?.seo?.title}
briefTitle={bestPracticeData?.briefTitle}
description={bestPracticeData.seo.description} description={bestPracticeData.seo.description}
keywords={bestPracticeData.seo.keywords} keywords={bestPracticeData.seo.keywords}
sponsors={bestPracticeData.sponsors} sponsors={bestPracticeData.sponsors}

Loading…
Cancel
Save