summaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-04-29 12:13:34 +0200
committerArmand Philippot <git@armandphilippot.com>2022-04-29 18:30:05 +0200
commit7e16f500cb7bc0cfd8bafbf6bb1555704f771231 (patch)
treebfc2b4a475cb06a787e2c4bdf284165644e82952 /src/utils
parent5324664e87bedfaa01ba62c0c847ef5b861e69b3 (diff)
chore: remove old pages, components, helpers and types
Since I'm using new components, I will also rewrite the GraphQL queries so it is easier to start from scratch.
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/helpers/format.ts332
-rw-r--r--src/utils/helpers/i18n.ts2
-rw-r--r--src/utils/helpers/prism.ts34
-rw-r--r--src/utils/helpers/projects.ts86
-rw-r--r--src/utils/helpers/sort.ts21
-rw-r--r--src/utils/hooks/useGithubApi.tsx23
-rw-r--r--src/utils/hooks/useHeadingsTree.tsx104
-rw-r--r--src/utils/providers/ackee.tsx3
-rw-r--r--src/utils/providers/prism-theme.tsx2
9 files changed, 5 insertions, 602 deletions
diff --git a/src/utils/helpers/format.ts b/src/utils/helpers/format.ts
deleted file mode 100644
index 47a7b57..0000000
--- a/src/utils/helpers/format.ts
+++ /dev/null
@@ -1,332 +0,0 @@
-import { ParamsIds, ParamsSlug, Slug } from '@ts/types/app';
-import {
- Article,
- ArticlePreview,
- RawArticle,
- RawArticlePreview,
-} from '@ts/types/articles';
-import { Comment, RawComment } from '@ts/types/comments';
-import {
- RawTopic,
- RawTopicPreview,
- RawThematic,
- Topic,
- TopicPreview,
- Thematic,
-} from '@ts/types/taxonomies';
-import { settings } from '@utils/config';
-
-/**
- * Format a post preview from RawArticlePreview to ArticlePreview type.
- * @param rawPost - A post preview coming from WP GraphQL.
- * @returns A formatted post preview.
- */
-export const getFormattedPostPreview = (rawPost: RawArticlePreview) => {
- const {
- acfPosts,
- commentCount,
- contentParts,
- date,
- featuredImage,
- id,
- info,
- modified,
- slug,
- title,
- } = rawPost;
-
- const dates = {
- publication: date,
- update: modified,
- };
-
- const topics = acfPosts.postsInTopic ? acfPosts.postsInTopic : [];
- const thematics = acfPosts.postsInThematic ? acfPosts.postsInThematic : [];
-
- const formattedPost: ArticlePreview = {
- commentCount,
- dates,
- featuredImage: featuredImage ? featuredImage.node : null,
- id,
- info,
- intro: contentParts.beforeMore,
- slug,
- topics,
- thematics,
- title,
- };
-
- return formattedPost;
-};
-
-/**
- * Format an array of posts list from RawArticlePreview to ArticlePreview type.
- * @param rawPosts - A posts list coming from WP GraphQL.
- * @returns A formatted posts list.
- */
-export const getFormattedPostsList = (
- rawPosts: RawArticlePreview[]
-): ArticlePreview[] => {
- return rawPosts
- .filter((post) => Object.getOwnPropertyNames(post).length > 0)
- .map((post) => {
- return getFormattedPostPreview(post);
- });
-};
-
-/**
- * Format a topic from RawTopic to Topic type.
- * @param rawTopic - A topic coming from WP GraphQL.
- * @returns A formatted topic.
- */
-export const getFormattedTopic = (rawTopic: RawTopic): Topic => {
- const {
- acfTopics,
- contentParts,
- databaseId,
- date,
- featuredImage,
- id,
- info,
- modified,
- seo,
- title,
- } = rawTopic;
-
- const dates = {
- publication: date,
- update: modified,
- };
-
- const posts = getFormattedPostsList(acfTopics.postsInTopic);
-
- const formattedTopic: Topic = {
- content: contentParts.afterMore,
- databaseId,
- dates,
- featuredImage: featuredImage ? featuredImage.node : null,
- id,
- info,
- intro: contentParts.beforeMore,
- officialWebsite: acfTopics.officialWebsite,
- posts,
- seo,
- title,
- };
-
- return formattedTopic;
-};
-
-/**
- * Format a thematic from RawThematic to Thematic type.
- * @param rawThematic - A thematic coming from wP GraphQL.
- * @returns A formatted thematic.
- */
-export const getFormattedThematic = (rawThematic: RawThematic): Thematic => {
- const {
- acfThematics,
- contentParts,
- databaseId,
- date,
- id,
- info,
- modified,
- seo,
- title,
- } = rawThematic;
-
- const dates = {
- publication: date,
- update: modified,
- };
-
- const posts = getFormattedPostsList(acfThematics.postsInThematic);
-
- const formattedThematic: Thematic = {
- content: contentParts.afterMore,
- databaseId,
- dates,
- id,
- info,
- intro: contentParts.beforeMore,
- posts,
- seo,
- title,
- };
-
- return formattedThematic;
-};
-
-/**
- * Format a comments list from RawComment to Comment type.
- * @param rawComments - A comments list coming from WP GraphQL.
- * @returns A formatted comments list.
- */
-export const getFormattedComments = (rawComments: RawComment[]): Comment[] => {
- const formattedComments: Comment[] = rawComments.map((comment) => {
- const formattedComment: Comment = {
- ...comment,
- author: comment.author.node,
- replies: [],
- };
-
- return formattedComment;
- });
-
- return formattedComments;
-};
-
-/**
- * Create a comments tree with replies.
- * @param comments - A flatten comments list.
- * @returns An array of comments with replies.
- */
-export const buildCommentsTree = (comments: Comment[]) => {
- type CommentsHashTable = {
- [key: string]: Comment;
- };
-
- const hashTable: CommentsHashTable = Object.create(null);
- const commentsTree: Comment[] = [];
-
- comments.forEach(
- (comment) => (hashTable[comment.databaseId] = { ...comment, replies: [] })
- );
-
- comments.forEach((comment) => {
- if (!comment.parentDatabaseId) {
- commentsTree.push(hashTable[comment.databaseId]);
- } else {
- hashTable[comment.parentDatabaseId].replies.push(
- hashTable[comment.databaseId]
- );
- }
- });
-
- return commentsTree;
-};
-
-export const getFormattedTopicsPreview = (
- topics: RawTopicPreview[]
-): TopicPreview[] => {
- const formattedTopics: TopicPreview[] = topics.map((topic) => {
- return {
- ...topic,
- featuredImage: topic.featuredImage ? topic.featuredImage.node : null,
- };
- });
-
- return formattedTopics;
-};
-
-/**
- * Format an article from RawArticle to Article type.
- * @param rawPost - An article coming from WP GraphQL.
- * @returns A formatted article.
- */
-export const getFormattedPost = (rawPost: RawArticle): Article => {
- const {
- acfPosts,
- author,
- commentCount,
- contentParts,
- databaseId,
- date,
- featuredImage,
- id,
- info,
- modified,
- seo,
- title,
- } = rawPost;
-
- const dates = {
- publication: date,
- update: modified,
- };
-
- const topics = acfPosts.postsInTopic
- ? getFormattedTopicsPreview(acfPosts.postsInTopic)
- : [];
-
- const formattedPost: Article = {
- author: author.node,
- commentCount,
- content: contentParts.afterMore,
- databaseId,
- dates,
- featuredImage: featuredImage ? featuredImage.node : null,
- id,
- info,
- intro: contentParts.beforeMore,
- seo,
- topics,
- thematics: acfPosts.postsInThematic ? acfPosts.postsInThematic : [],
- title,
- };
-
- return formattedPost;
-};
-
-/**
- * Converts a date to a string by using the specified locale.
- * @param {string} date - The date.
- * @param {string} [locale] - A locale.
- * @returns {string} The formatted date to locale date string.
- */
-export const getFormattedDate = (
- date: string,
- locale: string = settings.locales.defaultLocale
-): string => {
- const dateOptions: Intl.DateTimeFormatOptions = {
- day: 'numeric',
- month: 'long',
- year: 'numeric',
- };
-
- return new Date(date).toLocaleDateString(locale, dateOptions);
-};
-
-/**
- * Converts a date to a time string by using the specified locale.
- * @param {string} date - The date.
- * @param {string} [locale] - A locale.
- * @returns {string} The formatted time to locale date string.
- */
-export const getFormattedTime = (
- date: string,
- locale: string = settings.locales.defaultLocale
-): string => {
- const time = new Date(date).toLocaleTimeString(locale, {
- hour: 'numeric',
- minute: 'numeric',
- });
-
- return locale === 'fr' ? time.replace(':', 'h') : time;
-};
-
-/**
- * Convert an array of slugs to an array of params with slug.
- * @param {Slug} array - An array of object with slug.
- * @returns {ParamsSlug} An array of params with slug.
- */
-export const getFormattedPaths = (array: Slug[]): ParamsSlug[] => {
- return array.map((object) => {
- return { params: { slug: object.slug } };
- });
-};
-
-/**
- * Convert a number of pages to an array of params with ids.
- * @param {number} totalPages - The total pages.
- * @returns {ParamsIds} An array of params with ids.
- */
-export const getFormattedPageNumbers = (totalPages: number): ParamsIds[] => {
- const paths = [];
-
- for (let i = 1; i <= totalPages; i++) {
- paths.push({ params: { id: `${i}` } });
- }
-
- return paths;
-};
diff --git a/src/utils/helpers/i18n.ts b/src/utils/helpers/i18n.ts
index c4734ad..5d19c8c 100644
--- a/src/utils/helpers/i18n.ts
+++ b/src/utils/helpers/i18n.ts
@@ -3,7 +3,7 @@ import { settings } from '@utils/config';
import { readFile } from 'fs/promises';
import path from 'path';
-type Messages = { [key: string]: string };
+export type Messages = { [key: string]: string };
export const defaultLocale = settings.locales.defaultLocale;
diff --git a/src/utils/helpers/prism.ts b/src/utils/helpers/prism.ts
deleted file mode 100644
index a5f5787..0000000
--- a/src/utils/helpers/prism.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Check if the current block has a defined language.
- * @param classList - A list of class.
- * @returns {boolean} - True if a class starts with "language-".
- */
-const isLanguageBlock = (classList: DOMTokenList) => {
- const classes = Array.from(classList);
- return classes.some((className) => /language-.*/.test(className));
-};
-
-/**
- * Add automatically some classes and attributes for PrismJs.
- *
- * These classes and attributes are needed by Prism or to customize comments.
- */
-export const addPrismClasses = () => {
- const preTags = document.getElementsByTagName('pre');
-
- Array.from(preTags).forEach((preTag) => {
- if (!isLanguageBlock(preTag.classList)) return;
-
- preTag.classList.add('match-braces');
-
- if (preTag.classList.contains('filter-output')) {
- preTag.setAttribute('data-filter-output', '#output#');
- }
-
- if (preTag.classList.contains('language-bash')) {
- preTag.classList.add('command-line');
- } else if (!preTag.classList.contains('language-diff')) {
- preTag.classList.add('line-numbers');
- }
- });
-};
diff --git a/src/utils/helpers/projects.ts b/src/utils/helpers/projects.ts
deleted file mode 100644
index 1612dae..0000000
--- a/src/utils/helpers/projects.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { Project, ProjectMeta } from '@ts/types/app';
-import { readdirSync } from 'fs';
-import path from 'path';
-
-/**
- * Retrieve project's data by id.
- * @param {string} id - The filename without extension.
- * @returns {Promise<Project>} - The project data.
- */
-export const getProjectData = async (id: string): Promise<Project> => {
- try {
- const {
- intro,
- meta,
- seo,
- tagline,
- }: {
- intro: string;
- meta: ProjectMeta & { title: string };
- seo: { title: string; description: string };
- tagline?: string;
- } = await import(`../../content/projects/${id}.mdx`);
-
- const { title, ...onlyMeta } = meta;
-
- return {
- id,
- intro: intro || '',
- meta: onlyMeta || {},
- slug: id,
- title,
- seo: seo || {},
- tagline: tagline || '',
- };
- } catch (err) {
- console.error(err);
- throw err;
- }
-};
-
-/**
- * Retrieve the projects data from filenames.
- * @param {string[]} filenames - An array of filenames.
- * @returns {Promise<Project[]>} An array of projects with meta.
- */
-const getProjectsWithMeta = async (filenames: string[]): Promise<Project[]> => {
- return Promise.all(
- filenames.map(async (filename) => {
- return getProjectData(filename);
- })
- );
-};
-
-/**
- * Method to sort an array of projects by publication date.
- * @param {Project} a - A single project.
- * @param {Project} b - A single project.
- * @returns The result used by Array.sort() method: 1 || -1 || 0.
- */
-const sortProjectByPublicationDate = (a: Project, b: Project) => {
- if (a.meta.publishedOn < b.meta.publishedOn) return 1;
- if (a.meta.publishedOn > b.meta.publishedOn) return -1;
- return 0;
-};
-
-/**
- * Retrieve all the projects filename.
- * @returns {string[]} An array of filenames.
- */
-export const getAllProjectsFilename = (): string[] => {
- const projectsDirectory = path.join(process.cwd(), 'src/content/projects');
- const filenames = readdirSync(projectsDirectory);
-
- return filenames.map((filename) => filename.replace(/\.mdx$/, ''));
-};
-
-/**
- * Retrieve all projects in content folder sorted by publication date.
- * @returns {Promise<Project[]>} An array of projects.
- */
-export const getSortedProjects = async (): Promise<Project[]> => {
- const filenames = getAllProjectsFilename();
- const projects = await getProjectsWithMeta(filenames);
-
- return [...projects].sort(sortProjectByPublicationDate);
-};
diff --git a/src/utils/helpers/sort.ts b/src/utils/helpers/sort.ts
deleted file mode 100644
index c1ee35d..0000000
--- a/src/utils/helpers/sort.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { ArticlePreview } from '@ts/types/articles';
-import { PostsList } from '@ts/types/blog';
-
-type YearCollection = {
- [key: string]: ArticlePreview[];
-};
-
-export const sortPostsByYear = (data: PostsList[]) => {
- const yearCollection: YearCollection = {};
-
- data.forEach((page) => {
- page.posts.forEach((post) => {
- const postYear = new Date(post.dates.publication)
- .getFullYear()
- .toString();
- yearCollection[postYear] = [...(yearCollection[postYear] || []), post];
- });
- });
-
- return yearCollection;
-};
diff --git a/src/utils/hooks/useGithubApi.tsx b/src/utils/hooks/useGithubApi.tsx
deleted file mode 100644
index 4b0b3b2..0000000
--- a/src/utils/hooks/useGithubApi.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import { RepoData } from '@ts/types/repos';
-import useSWR, { Fetcher } from 'swr';
-
-const fetcher: Fetcher<RepoData, string> = (...args) =>
- fetch(...args).then((res) => res.json());
-
-/**
- * Retrieve data from Github API.
- * @param repo The repo name. Format: "User/project-slug".
- * @returns {object} The data and two booleans to determine if is loading/error.
- */
-const useGithubApi = (repo: string) => {
- const apiUrl = repo ? `https://api.github.com/repos/${repo}` : null;
- const { data, error } = useSWR<RepoData>(apiUrl, fetcher);
-
- return {
- data,
- isLoading: !error && !data,
- isError: error,
- };
-};
-
-export default useGithubApi;
diff --git a/src/utils/hooks/useHeadingsTree.tsx b/src/utils/hooks/useHeadingsTree.tsx
deleted file mode 100644
index f2be406..0000000
--- a/src/utils/hooks/useHeadingsTree.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-import { Heading } from '@ts/types/app';
-import { slugify } from '@utils/helpers/slugify';
-import { useRouter } from 'next/router';
-import { useCallback, useEffect, useMemo, useState } from 'react';
-
-const useHeadingsTree = (wrapper: string) => {
- const router = useRouter();
- const depths = useMemo(() => ['h2', 'h3', 'h4', 'h5', 'h6'], []);
- const [allHeadings, setAllHeadings] =
- useState<NodeListOf<HTMLHeadingElement>>();
-
- useEffect(() => {
- const query = depths
- .map((depth) => `${wrapper} > *:not(aside, #comments) ${depth}`)
- .join(', ');
- const result: NodeListOf<HTMLHeadingElement> =
- document.querySelectorAll(query);
- setAllHeadings(result);
- }, [depths, wrapper, router.asPath]);
-
- const [headingsTree, setHeadingsTree] = useState<Heading[]>([]);
-
- const getElementDepth = useCallback(
- (el: HTMLHeadingElement) => {
- return depths.findIndex((depth) => depth === el.localName);
- },
- [depths]
- );
-
- const formatHeadings = useCallback(
- (headings: NodeListOf<HTMLHeadingElement>): Heading[] => {
- const formattedHeadings: Heading[] = [];
-
- Array.from(headings).forEach((heading) => {
- const title: string = heading.textContent!;
- const id = slugify(title);
- const depth = getElementDepth(heading);
- const children: Heading[] = [];
-
- heading.id = id;
-
- formattedHeadings.push({
- depth,
- id,
- children,
- title,
- });
- });
-
- return formattedHeadings;
- },
- [getElementDepth]
- );
-
- const buildSubTree = useCallback(
- (parent: Heading, currentHeading: Heading): void => {
- if (parent.depth === currentHeading.depth - 1) {
- parent.children.push(currentHeading);
- } else {
- const lastItem = parent.children[parent.children.length - 1];
- buildSubTree(lastItem, currentHeading);
- }
- },
- []
- );
-
- const buildTree = useCallback(
- (headings: Heading[]): Heading[] => {
- const tree: Heading[] = [];
-
- headings.forEach((heading) => {
- if (heading.depth === 0) {
- tree.push(heading);
- } else {
- const lastItem = tree[tree.length - 1];
- buildSubTree(lastItem, heading);
- }
- });
-
- return tree;
- },
- [buildSubTree]
- );
-
- const getHeadingsList = useCallback(
- (headings: NodeListOf<HTMLHeadingElement>): Heading[] => {
- const formattedHeadings = formatHeadings(headings);
-
- return buildTree(formattedHeadings);
- },
- [formatHeadings, buildTree]
- );
-
- useEffect(() => {
- if (allHeadings) {
- const headingsList = getHeadingsList(allHeadings);
- setHeadingsTree(headingsList);
- }
- }, [allHeadings, getHeadingsList]);
-
- return headingsTree;
-};
-
-export default useHeadingsTree;
diff --git a/src/utils/providers/ackee.tsx b/src/utils/providers/ackee.tsx
index c103668..0cb0166 100644
--- a/src/utils/providers/ackee.tsx
+++ b/src/utils/providers/ackee.tsx
@@ -1,5 +1,5 @@
import { useRouter } from 'next/router';
-import { createContext, FC, useContext, useState } from 'react';
+import { createContext, FC, ReactNode, useContext, useState } from 'react';
import useAckee from 'use-ackee';
export type AckeeProps = {
@@ -10,6 +10,7 @@ export type AckeeProps = {
};
export type AckeeProviderProps = {
+ children: ReactNode;
domain: string;
siteId: string;
ignoreLocalhost?: boolean;
diff --git a/src/utils/providers/prism-theme.tsx b/src/utils/providers/prism-theme.tsx
index 2ed8454..62bcf56 100644
--- a/src/utils/providers/prism-theme.tsx
+++ b/src/utils/providers/prism-theme.tsx
@@ -2,6 +2,7 @@ import { LocalStorage } from '@services/local-storage';
import {
createContext,
FC,
+ ReactNode,
useCallback,
useContext,
useEffect,
@@ -22,6 +23,7 @@ export type UsePrismThemeProps = {
export type PrismThemeProviderProps = {
attribute?: string;
+ children: ReactNode;
storageKey?: string;
themes?: PrismTheme[];
};