From c9c1c90b30e243563bb4f731da15b3fe657556d2 Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Mon, 6 Nov 2023 18:08:04 +0100
Subject: refactor(components): replace Summary component with PostPreview

* rename component to PostPreview because Summary is an HTML element
and it could lead to confusion
* replace `title` and `titleLevel` with `heading` and `headingLvl`
because `title` is a native attribute
* rename `intro` prop to `excerpt`
* extract `cover` from `meta` prop
* rewrite meta type
* extract meta logic into a new component
---
 src/utils/helpers/pages.tsx | 124 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 124 insertions(+)
 create mode 100644 src/utils/helpers/pages.tsx

(limited to 'src/utils/helpers/pages.tsx')

diff --git a/src/utils/helpers/pages.tsx b/src/utils/helpers/pages.tsx
new file mode 100644
index 0000000..556b4fb
--- /dev/null
+++ b/src/utils/helpers/pages.tsx
@@ -0,0 +1,124 @@
+import NextImage from 'next/image';
+import type { LinksListItems, PostData } from '../../components';
+import { getArticleFromRawData } from '../../services/graphql';
+import type {
+  Article,
+  EdgesResponse,
+  PageLink,
+  RawArticle,
+  RawThematicPreview,
+  RawTopicPreview,
+} from '../../types';
+import { ROUTES } from '../constants';
+import { getImageFromRawData } from './images';
+
+/**
+ * Convert raw data to a Link object.
+ *
+ * @param data - An object.
+ * @param {number} data.databaseId - The data id.
+ * @param {number} [data.logo] - The data logo.
+ * @param {string} data.slug - The data slug.
+ * @param {string} data.title - The data name.
+ * @returns {PageLink} The link data (id, slug and title).
+ */
+export const getPageLinkFromRawData = (
+  data: RawThematicPreview | RawTopicPreview,
+  kind: 'thematic' | 'topic'
+): PageLink => {
+  const { databaseId, featuredImage, slug, title } = data;
+  const baseUrl = `${
+    kind === 'thematic' ? ROUTES.THEMATICS.INDEX : ROUTES.TOPICS
+  }/`;
+
+  return {
+    id: databaseId,
+    logo: featuredImage ? getImageFromRawData(featuredImage.node) : undefined,
+    name: title,
+    url: `${baseUrl}${slug}`,
+  };
+};
+
+/**
+ * Method to sort PageLink objects by name.
+ *
+ * @param {PageLink} a - A PageLink object.
+ * @param {PageLink} b - Another PageLink object.
+ * @returns {1 | -1 | 0}
+ */
+export const sortPageLinksByName = (a: PageLink, b: PageLink) => {
+  const nameA = a.name.toUpperCase();
+  const nameB = b.name.toUpperCase();
+
+  if (nameA < nameB) return -1;
+  if (nameA > nameB) return 1;
+  return 0;
+};
+
+/**
+ * Convert page link data to an array of links items.
+ *
+ * @param {PageLink[]} links - An array of page links.
+ * @returns {LinksListItem[]} An array of links items.
+ */
+export const getLinksListItems = (links: PageLink[]): LinksListItems[] =>
+  links.map((link) => {
+    return {
+      name: link.name,
+      url: link.url,
+    };
+  });
+
+/**
+ * Retrieve the posts list with the article URL.
+ *
+ * @param {Article[]} posts - An array of articles.
+ * @returns {PostData[]} An array of posts with full article URL.
+ */
+export const getPostsWithUrl = (posts: Article[]): PostData[] =>
+  posts.map(({ intro, meta, slug, title, ...post }) => {
+    return {
+      ...post,
+      cover: meta.cover ? <NextImage {...meta.cover} /> : undefined,
+      excerpt: intro,
+      heading: title,
+      meta: {
+        publicationDate: meta.dates.publication,
+        updateDate: meta.dates.update,
+        wordsCount: meta.wordsCount,
+        author: meta.author?.name,
+        thematics: meta.thematics,
+        topics: meta.topics,
+        comments:
+          meta.commentsCount === undefined
+            ? undefined
+            : {
+                count: meta.commentsCount,
+                postHeading: title,
+                url: `${ROUTES.ARTICLE}/${slug}#comments`,
+              },
+      },
+      url: `${ROUTES.ARTICLE}/${slug}`,
+    };
+  });
+
+/**
+ * Retrieve the posts list from raw data.
+ *
+ * @param {EdgesResponse<RawArticle>[]} rawData - The raw data.
+ * @returns {PostData[]} An array of posts.
+ */
+export const getPostsList = (
+  rawData: EdgesResponse<RawArticle>[]
+): PostData[] => {
+  const articlesList: RawArticle[] = [];
+  rawData.forEach((articleData) => {
+    articleData.edges.forEach((edge) => {
+      articlesList.push(edge.node);
+    });
+  });
+
+  return getPostsWithUrl(
+    articlesList.map((article) => getArticleFromRawData(article))
+  );
+};
-- 
cgit v1.2.3

