Skip to content

Commit

Permalink
feat: add cover to article
Browse files Browse the repository at this point in the history
  • Loading branch information
fpasquet committed Jan 30, 2024
1 parent d0bd314 commit 4af2d1e
Show file tree
Hide file tree
Showing 14 changed files with 47 additions and 211 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ ALGOLIA_INDEX=blog_eleven_v2_dev
ALGOLIA_API_INDEXING_KEY=ec44181a2193f585175620ba8239dfb0

VITE_IS_DEBUG=true
VITE_HOST_URL=http://localhost:5173
VITE_ALGOLIA_APP_ID=5IGTHBX5JS
VITE_ALGOLIA_INDEX=blog_eleven_v2_dev
VITE_ALGOLIA_API_KEY=0ff075bf3ef8942ec3c6481f9aa05ae5
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ jobs:
NODE_ENV: production
BASE_URL: ${{ env.BASE_URL }}
VITE_IS_DEBUG: ${{ env.IS_DEBUG }}
VITE_HOST_URL: ${{ env.ENV_URL }}
VITE_ALGOLIA_APP_ID: ${{ env.ALGOLIA_APP_ID }}
VITE_ALGOLIA_API_KEY: ${{ env.ALGOLIA_API_SEARCH_KEY }}
VITE_ALGOLIA_INDEX: ${{ env.ALGOLIA_INDEX }}
Expand Down
21 changes: 4 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"node": ">= 20.0"
},
"dependencies": {
"@eleven-labs/design-system": "^0.24.0",
"@eleven-labs/design-system": "^0.27.0",
"@remix-run/router": "^1.7.2",
"algoliasearch": "^4.19.1",
"classnames": "^2.3.2",
Expand Down
Binary file added src/assets/imgs/cover-article.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getEnv } from '@/helpers/getEnvHelper';

export const IS_SSR = import.meta.env.SSR;
export const IS_PRERENDER = import.meta.env.MODE === 'prerender';
export const HOST_URL = getEnv<string>('VITE_HOST_URL') || 'https://blog.eleven-labs.com';
export const BASE_URL = getEnv<string>('BASE_URL') || '/';

export const IS_DEBUG = getEnv<string>('VITE_IS_DEBUG') === 'true';
Expand Down
2 changes: 0 additions & 2 deletions src/containers/AuthorPageContainer/useAuthorPageContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { useLoaderData, useParams } from 'react-router-dom';
import { blogUrl } from '@/config/website';
import { DEFAULT_LANGUAGE, PATHS } from '@/constants';
import { PostCardListContainer, PostCardListContainerProps } from '@/containers/PostCardListContainer';
import { getPathFile } from '@/helpers/assetHelper';
import { generatePath } from '@/helpers/routerHelper';
import { useNewsletterCard } from '@/hooks/useNewsletterCard';
import { useTitle } from '@/hooks/useTitle';
Expand Down Expand Up @@ -65,7 +64,6 @@ export const useAuthorPageContainer = (): AuthorPageProps | undefined => {
}),
content: <div dangerouslySetInnerHTML={{ __html: author.content }} />,
},
emptyAvatarImageUrl: getPathFile('/imgs/astronaut.png'),
title: t('pages.author.post_list_title'),
postCardList: (
<PostCardListContainer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ export const useCategoryPageContainer = (): CategoryPageProps => {
? {
title: <TransWithHtml i18nKey={`pages.category.${categoryName}.expertise.title`} onlyLineBreak />,
description: <TransWithHtml i18nKey={`pages.category.${categoryName}.expertise.description`} />,
expertiseLink: {
label: t(`pages.category.${categoryName}.expertise.link_label`),
href: t(`pages.category.${categoryName}.expertise.link_url`),
},
expertiseLink: !['agile'].includes(categoryName as string)
? {
label: t(`pages.category.${categoryName}.expertise.link_label`),
href: t(`pages.category.${categoryName}.expertise.link_url`),
}
: undefined,
}
: undefined,
title: <TransWithHtml i18nKey={`pages.category.${categoryName}.post_list_title`} onlyLineBreak />,
Expand Down
22 changes: 12 additions & 10 deletions src/containers/HomePageContainer/useHomePageContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,18 @@ export const useHomePageContainer = (): HomePageProps => {
href: generatePath(PATHS.CATEGORY, { categoryName: 'all', lang: i18n.language }),
},
},
lastTutorialsBlock: {
title: <TransWithHtml i18nKey="pages.home.last-tutorials-block.title" onlyLineBreak />,
description: <TransWithHtml i18nKey="pages.home.last-tutorials-block.description" />,
tutorialLabel: t('common.tutorial-tag'),
posts: lastTutorialsForCardList,
linkSeeMore: {
label: t('pages.home.last-tutorials-block.link-see-more'),
href: generatePath(PATHS.CATEGORY, { categoryName: ContentTypeEnum.TUTORIAL, lang: i18n.language }),
},
},
lastTutorialsBlock: lastTutorialsForCardList.length
? {
title: <TransWithHtml i18nKey="pages.home.last-tutorials-block.title" onlyLineBreak />,
description: <TransWithHtml i18nKey="pages.home.last-tutorials-block.description" />,
tutorialLabel: t('common.tutorial-tag'),
posts: lastTutorialsForCardList,
linkSeeMore: {
label: t('pages.home.last-tutorials-block.link-see-more'),
href: generatePath(PATHS.CATEGORY, { categoryName: ContentTypeEnum.TUTORIAL, lang: i18n.language }),
},
}
: undefined,
newsletterCard,
};
};
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { LayoutTemplateProps } from '@eleven-labs/design-system';
import { useHead, useLink, useMeta, useScript } from 'hoofd';
import React, { useEffect } from 'react';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { matchPath, useLoaderData, useLocation } from 'react-router-dom';

import { themeColor } from '@/config/website';
import { GOOGLE_SITE_VERIFICATION } from '@/constants';
import { PATHS } from '@/constants';
import { getPathFile } from '@/helpers/assetHelper';
import { getClickEventElements, handleClickEventListener } from '@/helpers/dataLayerHelper';
import { getUrl } from '@/helpers/getUrlHelper';
import { LayoutTemplateData } from '@/types';

import { HeaderContainer } from './HeaderContainer';
Expand Down Expand Up @@ -40,7 +40,7 @@ export const useLayoutTemplateContainer = (): Omit<LayoutTemplateProps, 'childre
});
useMeta({ property: 'og:locale', content: i18n.language });
useMeta({ property: 'og:site_name', content: 'Blog Eleven Labs' });
useMeta({ property: 'og:url', content: location.pathname + location.search });
useMeta({ property: 'og:url', content: getUrl(`${location.pathname}${location.search}`) });
useScript({
type: 'application/ld+json',
text: JSON.stringify({
Expand All @@ -54,7 +54,7 @@ export const useLayoutTemplateContainer = (): Omit<LayoutTemplateProps, 'childre
'@type': 'SearchAction',
target: {
'@type': 'EntryPoint',
urlTemplate: 'https://blog.eleven-labs.com/fr/search/?search={search_term_string}',
urlTemplate: `https://blog.eleven-labs.com/${i18n.language}/search/?search={search_term_string}`,
},
'query-input': 'required name=search_term_string',
},
Expand All @@ -67,22 +67,6 @@ export const useLayoutTemplateContainer = (): Omit<LayoutTemplateProps, 'childre
useLink({ rel: 'apple-touch-icon', sizes: '152x152', href: getPathFile('/imgs/icons/apple-icon-152x152.png') });
useLink({ rel: 'apple-touch-icon', sizes: '180x180', href: getPathFile('/imgs/icons/apple-icon-180x180.png') });

useEffect(() => {
window.scrollTo(0, 0);

const clickEventElements = getClickEventElements();

clickEventElements.forEach((element) => {
element.addEventListener('click', handleClickEventListener);
});

return () => {
clickEventElements.forEach((element) => {
element.removeEventListener('click', handleClickEventListener);
});
};
}, [location]);

return {
header: (
<>
Expand Down
154 changes: 0 additions & 154 deletions src/helpers/dataLayerHelper.ts
Original file line number Diff line number Diff line change
@@ -1,166 +1,12 @@
import { camelCase } from '@/helpers/stringHelper';

interface DataLayerEvent {
event: string;
}

interface DatalayerInternalLinkClickEvent extends DataLayerEvent {
event: 'internal_link_click';
link_type: 'home' | 'post' | 'author' | 'relatedPost' | 'category' | 'back';
link_url: string;
}

interface DatalayerShareLinkClickEvent extends DataLayerEvent {
event: 'share_link_click';
share_type: 'twitter' | 'facebook' | 'linkedIn' | 'reddit';
share_url: string;
}

interface DatalayerNewsletterLinkClickEvent extends DataLayerEvent {
event: 'newsletter_link_click';
}

interface DatalayerRSSLinkClickEvent extends DataLayerEvent {
event: 'rss_link_click';
}

interface DatalayerSocialLinkClickEvent extends DataLayerEvent {
event: 'social_link_click';
social_type: 'facebook' | 'twitter' | 'linkedin' | 'welcometothejungle';
}

interface DatalayerWebsiteLinkClickEvent extends DataLayerEvent {
event: 'website_link_click';
}

interface DatalayerLoadMoreButtonClickEvent extends DataLayerEvent {
event: 'load_more_button_click';
}

interface DatalayerCopyLinkButtonClickEvent extends DataLayerEvent {
event: 'copy_link_button_click';
link_url: string;
}

interface DatalayerContentSearchEvent extends DataLayerEvent {
event: 'content_search';
content_search_term: string;
}

export type DataLayerClickEventAvailable =
| DatalayerInternalLinkClickEvent
| DatalayerShareLinkClickEvent
| DatalayerNewsletterLinkClickEvent
| DatalayerRSSLinkClickEvent
| DatalayerSocialLinkClickEvent
| DatalayerWebsiteLinkClickEvent
| DatalayerLoadMoreButtonClickEvent
| DatalayerCopyLinkButtonClickEvent;

export type DataLayerEventAvailable = DataLayerClickEventAvailable | DatalayerContentSearchEvent;

interface ClickEventType {
eventName: DataLayerClickEventAvailable['event'];
dataAttribute: string;
dataAttributeValue?: string;
}

const clickEvents: ClickEventType[] = [
{
eventName: 'internal_link_click',
dataAttribute: 'internal-link',
},
{
eventName: 'share_link_click',
dataAttribute: 'share-link',
},
{
eventName: 'newsletter_link_click',
dataAttribute: 'newsletter-link',
},
{
eventName: 'rss_link_click',
dataAttribute: 'rss-link',
},
{
eventName: 'social_link_click',
dataAttribute: 'social-link',
},
{
eventName: 'website_link_click',
dataAttribute: 'website-link',
},
{
eventName: 'load_more_button_click',
dataAttribute: 'button',
dataAttributeValue: 'loadMore',
},
{
eventName: 'copy_link_button_click',
dataAttribute: 'button',
dataAttributeValue: 'copyLink',
},
];

export const getClickEventElements = (): HTMLElement[] =>
clickEvents.reduce<HTMLElement[]>(
(elements, clickEvent) => [
...elements,
...document.querySelectorAll<HTMLElement>(`[data-${clickEvent.dataAttribute}]`).values(),
],
[] as HTMLElement[]
);

export const handleClickEventListener = (event: MouseEvent): void => {
const target = event.currentTarget as HTMLElement;
const clickEvent = clickEvents.find((clickEvent) => {
const attributeValue = target.dataset?.[camelCase(clickEvent.dataAttribute)];
return clickEvent.dataAttributeValue ? attributeValue === clickEvent.dataAttributeValue : attributeValue;
});
if (!clickEvent) {
return;
}

let dataLayerEvent: DataLayerEventAvailable;
switch (clickEvent.eventName) {
case 'internal_link_click':
dataLayerEvent = {
event: clickEvent.eventName,
link_type: target.dataset[camelCase(clickEvent.dataAttribute)] as DatalayerInternalLinkClickEvent['link_type'],
link_url: target.getAttribute('href') as string,
};
break;
case 'share_link_click':
dataLayerEvent = {
event: clickEvent.eventName,
share_type: target.dataset['sharing'] as DatalayerShareLinkClickEvent['share_type'],
share_url: window.location.pathname,
};
break;
case 'social_link_click':
dataLayerEvent = {
event: clickEvent.eventName,
social_type: target.dataset[
camelCase(clickEvent.dataAttribute)
] as DatalayerSocialLinkClickEvent['social_type'],
};
break;
case 'copy_link_button_click':
dataLayerEvent = {
event: clickEvent.eventName,
link_url: window.location.pathname,
};
break;
default:
dataLayerEvent = {
event: clickEvent.eventName,
};
break;
}

window.dataLayer.push(dataLayerEvent);
};

export const trackContentSearchEvent = (term: string): void => {
const dataLayerEvent: DatalayerContentSearchEvent = {
event: 'content_search',
Expand Down
3 changes: 3 additions & 0 deletions src/helpers/getUrlHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { BASE_URL, HOST_URL } from '@/constants';

export const getUrl = (path: string): string => `${HOST_URL}${BASE_URL}${path}`;

0 comments on commit 4af2d1e

Please sign in to comment.