summaryrefslogtreecommitdiffstats
path: root/src/components/MetaItems
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-03-01 22:05:08 +0100
committerArmand Philippot <git@armandphilippot.com>2022-03-01 22:05:08 +0100
commit8bd9784acdee6871ad70e86d0d7120299bf76969 (patch)
tree9b81e0cd3ff881b2cbeb81f9f96b52b510d67646 /src/components/MetaItems
parent21c228600a7a69cfea3b7d8af6838bcfda1d7399 (diff)
refactor: split posts meta into smaller components
Diffstat (limited to 'src/components/MetaItems')
-rw-r--r--src/components/MetaItems/Author/Author.tsx20
-rw-r--r--src/components/MetaItems/CommentsCount/CommentsCount.tsx41
-rw-r--r--src/components/MetaItems/Dates/Dates.tsx56
-rw-r--r--src/components/MetaItems/MetaItem/MetaItem.module.scss18
-rw-r--r--src/components/MetaItems/MetaItem/MetaItem.tsx36
-rw-r--r--src/components/MetaItems/PostsCount/PostsCount.tsx27
-rw-r--r--src/components/MetaItems/ReadingTime/ReadingTime.tsx55
-rw-r--r--src/components/MetaItems/Thematics/Thematics.tsx42
-rw-r--r--src/components/MetaItems/Topics/Topics.tsx36
-rw-r--r--src/components/MetaItems/Website/Website.tsx20
-rw-r--r--src/components/MetaItems/index.tsx21
11 files changed, 372 insertions, 0 deletions
diff --git a/src/components/MetaItems/Author/Author.tsx b/src/components/MetaItems/Author/Author.tsx
new file mode 100644
index 0000000..c3d78c2
--- /dev/null
+++ b/src/components/MetaItems/Author/Author.tsx
@@ -0,0 +1,20 @@
+import { MetaKind } from '@ts/types/app';
+import { useIntl } from 'react-intl';
+import { MetaItem } from '..';
+
+const Author = ({ name, kind }: { name: string; kind: MetaKind }) => {
+ const intl = useIntl();
+
+ return (
+ <MetaItem
+ title={intl.formatMessage({
+ defaultMessage: 'Written by:',
+ description: 'Author: article author meta label',
+ })}
+ value={name}
+ kind={kind}
+ />
+ );
+};
+
+export default Author;
diff --git a/src/components/MetaItems/CommentsCount/CommentsCount.tsx b/src/components/MetaItems/CommentsCount/CommentsCount.tsx
new file mode 100644
index 0000000..bd1990d
--- /dev/null
+++ b/src/components/MetaItems/CommentsCount/CommentsCount.tsx
@@ -0,0 +1,41 @@
+import { MetaKind } from '@ts/types/app';
+import { useRouter } from 'next/router';
+import { useIntl } from 'react-intl';
+import { MetaItem } from '..';
+
+const CommentsCount = ({ total, kind }: { total: number; kind: MetaKind }) => {
+ const intl = useIntl();
+ const { asPath } = useRouter();
+
+ const isArticle = () => asPath.includes('/article/');
+
+ const getCommentsCount = () => {
+ return intl.formatMessage(
+ {
+ defaultMessage:
+ '{total, plural, =0 {No comments} one {# comment} other {# comments}}',
+ description: 'CommentsCount: comment count value',
+ },
+ { total }
+ );
+ };
+
+ return (
+ <MetaItem
+ title={intl.formatMessage({
+ defaultMessage: 'Comments:',
+ description: 'CommentsCount: comment count meta label',
+ })}
+ value={
+ isArticle() ? (
+ <a href="#comments">{getCommentsCount()}</a>
+ ) : (
+ getCommentsCount()
+ )
+ }
+ kind={kind}
+ />
+ );
+};
+
+export default CommentsCount;
diff --git a/src/components/MetaItems/Dates/Dates.tsx b/src/components/MetaItems/Dates/Dates.tsx
new file mode 100644
index 0000000..04dff3a
--- /dev/null
+++ b/src/components/MetaItems/Dates/Dates.tsx
@@ -0,0 +1,56 @@
+import { MetaKind } from '@ts/types/app';
+import { settings } from '@utils/config';
+import { getFormattedDate } from '@utils/helpers/format';
+import { useRouter } from 'next/router';
+import { useIntl } from 'react-intl';
+import { MetaItem } from '..';
+
+const Dates = ({
+ publication,
+ update,
+ kind,
+}: {
+ publication: string;
+ update: string;
+ kind: MetaKind;
+}) => {
+ const intl = useIntl();
+ const { locale } = useRouter();
+ const validLocale = locale ? locale : settings.locales.defaultLocale;
+
+ const publicationDate = getFormattedDate(publication, validLocale);
+ const updateDate = getFormattedDate(update, validLocale);
+
+ return (
+ <>
+ <MetaItem
+ title={intl.formatMessage({
+ defaultMessage: 'Published on:',
+ description: 'Dates: publication date meta label',
+ })}
+ values={[
+ <time key={publication} dateTime={publication}>
+ {publicationDate}
+ </time>,
+ ]}
+ kind={kind}
+ />
+ {publicationDate !== updateDate && (
+ <MetaItem
+ title={intl.formatMessage({
+ defaultMessage: 'Updated on:',
+ description: 'Dates: update date meta label',
+ })}
+ values={[
+ <time key={update} dateTime={update}>
+ {updateDate}
+ </time>,
+ ]}
+ kind={kind}
+ />
+ )}
+ </>
+ );
+};
+
+export default Dates;
diff --git a/src/components/MetaItems/MetaItem/MetaItem.module.scss b/src/components/MetaItems/MetaItem/MetaItem.module.scss
new file mode 100644
index 0000000..0b159ca
--- /dev/null
+++ b/src/components/MetaItems/MetaItem/MetaItem.module.scss
@@ -0,0 +1,18 @@
+.wrapper--article {
+ display: flex;
+ flex-flow: row wrap;
+}
+
+.title--article {
+ margin-right: var(--spacing-2xs);
+ color: var(--color-fg-light);
+}
+
+.body--article {
+ &:not(:first-of-type) {
+ &::before {
+ content: "/";
+ margin: 0 var(--spacing-2xs);
+ }
+ }
+}
diff --git a/src/components/MetaItems/MetaItem/MetaItem.tsx b/src/components/MetaItems/MetaItem/MetaItem.tsx
new file mode 100644
index 0000000..5c51283
--- /dev/null
+++ b/src/components/MetaItems/MetaItem/MetaItem.tsx
@@ -0,0 +1,36 @@
+import { MetaKind } from '@ts/types/app';
+import { ReactElement } from 'react';
+import styles from './MetaItem.module.scss';
+
+const MetaItem = ({
+ title,
+ value,
+ values,
+ info,
+ kind = 'list',
+}: {
+ title: string;
+ value?: ReactElement | string;
+ values?: ReactElement[] | string[];
+ info?: string;
+ kind: MetaKind;
+}) => {
+ return (
+ <div className={styles[`wrapper--${kind}`]}>
+ <dt className={styles[`title--${kind}`]}>{title}</dt>
+ {value && (
+ <dd className={styles[`body--${kind}`]} title={info}>
+ {value}
+ </dd>
+ )}
+ {values &&
+ values.map((currentValue, index) => (
+ <dd key={index} className={styles[`body--${kind}`]} title={info}>
+ {currentValue}
+ </dd>
+ ))}
+ </div>
+ );
+};
+
+export default MetaItem;
diff --git a/src/components/MetaItems/PostsCount/PostsCount.tsx b/src/components/MetaItems/PostsCount/PostsCount.tsx
new file mode 100644
index 0000000..9fb1784
--- /dev/null
+++ b/src/components/MetaItems/PostsCount/PostsCount.tsx
@@ -0,0 +1,27 @@
+import { MetaKind } from '@ts/types/app';
+import { useIntl } from 'react-intl';
+import { MetaItem } from '..';
+
+const PostsCount = ({ total, kind }: { total: number; kind: MetaKind }) => {
+ const intl = useIntl();
+
+ return (
+ <MetaItem
+ title={intl.formatMessage({
+ defaultMessage: 'Total:',
+ description: 'PostCount: total found articles meta label',
+ })}
+ value={intl.formatMessage(
+ {
+ defaultMessage:
+ '{total, plural, =0 {No articles} one {# article} other {# articles}}',
+ description: 'PostCount: total found articles',
+ },
+ { total }
+ )}
+ kind={kind}
+ />
+ );
+};
+
+export default PostsCount;
diff --git a/src/components/MetaItems/ReadingTime/ReadingTime.tsx b/src/components/MetaItems/ReadingTime/ReadingTime.tsx
new file mode 100644
index 0000000..94215b3
--- /dev/null
+++ b/src/components/MetaItems/ReadingTime/ReadingTime.tsx
@@ -0,0 +1,55 @@
+import { MetaKind } from '@ts/types/app';
+import { useRouter } from 'next/router';
+import { useIntl } from 'react-intl';
+import { MetaItem } from '..';
+
+const ReadingTime = ({
+ time,
+ words,
+ kind,
+}: {
+ time: number;
+ words: number;
+ kind: MetaKind;
+}) => {
+ const intl = useIntl();
+ const { locale } = useRouter();
+
+ const getEstimation = () => {
+ if (time < 0) {
+ return intl.formatMessage({
+ defaultMessage: 'less than 1 minute',
+ description: 'ReadingTime: Reading time value',
+ });
+ }
+
+ return intl.formatMessage(
+ {
+ defaultMessage:
+ '{time, plural, =0 {# minutes} one {# minute} other {# minutes}}',
+ description: 'ReadingTime: reading time value',
+ },
+ { time }
+ );
+ };
+
+ return (
+ <MetaItem
+ title={intl.formatMessage({
+ defaultMessage: 'Reading time:',
+ description: 'ReadingTime: reading time meta label',
+ })}
+ value={getEstimation()}
+ info={intl.formatMessage(
+ {
+ defaultMessage: `Approximately {number} words`,
+ description: 'ReadingTime: number of words',
+ },
+ { number: words.toLocaleString(locale) }
+ )}
+ kind={kind}
+ />
+ );
+};
+
+export default ReadingTime;
diff --git a/src/components/MetaItems/Thematics/Thematics.tsx b/src/components/MetaItems/Thematics/Thematics.tsx
new file mode 100644
index 0000000..a127715
--- /dev/null
+++ b/src/components/MetaItems/Thematics/Thematics.tsx
@@ -0,0 +1,42 @@
+import { MetaKind } from '@ts/types/app';
+import { ThematicPreview } from '@ts/types/taxonomies';
+import Link from 'next/link';
+import { useIntl } from 'react-intl';
+import { MetaItem } from '..';
+
+const Thematics = ({
+ list,
+ kind,
+}: {
+ list: ThematicPreview[];
+ kind: MetaKind;
+}) => {
+ const intl = useIntl();
+
+ const getThematics = () => {
+ return list.map((thematic) => {
+ return (
+ <Link key={thematic.databaseId} href={`/thematique/${thematic.slug}`}>
+ <a>{thematic.title}</a>
+ </Link>
+ );
+ });
+ };
+
+ return (
+ <MetaItem
+ title={intl.formatMessage(
+ {
+ defaultMessage:
+ '{thematicsCount, plural, =0 {Thematics:} one {Thematic:} other {Thematics:}}',
+ description: 'Thematics: thematics list meta label',
+ },
+ { thematicsCount: list.length }
+ )}
+ values={getThematics()}
+ kind={kind}
+ />
+ );
+};
+
+export default Thematics;
diff --git a/src/components/MetaItems/Topics/Topics.tsx b/src/components/MetaItems/Topics/Topics.tsx
new file mode 100644
index 0000000..4f2dc1f
--- /dev/null
+++ b/src/components/MetaItems/Topics/Topics.tsx
@@ -0,0 +1,36 @@
+import { MetaKind } from '@ts/types/app';
+import { TopicPreview } from '@ts/types/taxonomies';
+import Link from 'next/link';
+import { useIntl } from 'react-intl';
+import { MetaItem } from '..';
+
+const Topics = ({ list, kind }: { list: TopicPreview[]; kind: MetaKind }) => {
+ const intl = useIntl();
+
+ const getTopics = () => {
+ return list.map((topic) => {
+ return (
+ <Link key={topic.databaseId} href={`/sujet/${topic.slug}`}>
+ <a>{topic.title}</a>
+ </Link>
+ );
+ });
+ };
+
+ return (
+ <MetaItem
+ title={intl.formatMessage(
+ {
+ defaultMessage:
+ '{topicsCount, plural, =0 {Topics:} one {Topic:} other {Topics:}}',
+ description: 'Topics: topics list meta label',
+ },
+ { topicsCount: list.length }
+ )}
+ values={getTopics()}
+ kind={kind}
+ />
+ );
+};
+
+export default Topics;
diff --git a/src/components/MetaItems/Website/Website.tsx b/src/components/MetaItems/Website/Website.tsx
new file mode 100644
index 0000000..bcf3fc8
--- /dev/null
+++ b/src/components/MetaItems/Website/Website.tsx
@@ -0,0 +1,20 @@
+import { MetaKind } from '@ts/types/app';
+import { useIntl } from 'react-intl';
+import { MetaItem } from '..';
+
+const Website = ({ url, kind }: { url: string; kind: MetaKind }) => {
+ const intl = useIntl();
+
+ return (
+ <MetaItem
+ title={intl.formatMessage({
+ defaultMessage: 'Website:',
+ description: 'Website: website meta label',
+ })}
+ value={<a href={url}>{url}</a>}
+ kind={kind}
+ />
+ );
+};
+
+export default Website;
diff --git a/src/components/MetaItems/index.tsx b/src/components/MetaItems/index.tsx
new file mode 100644
index 0000000..e90d5a6
--- /dev/null
+++ b/src/components/MetaItems/index.tsx
@@ -0,0 +1,21 @@
+import Author from './Author/Author';
+import CommentsCount from './CommentsCount/CommentsCount';
+import Dates from './Dates/Dates';
+import MetaItem from './MetaItem/MetaItem';
+import PostsCount from './PostsCount/PostsCount';
+import ReadingTime from './ReadingTime/ReadingTime';
+import Thematics from './Thematics/Thematics';
+import Topics from './Topics/Topics';
+import Website from './Website/Website';
+
+export {
+ Author,
+ CommentsCount,
+ Dates,
+ MetaItem,
+ PostsCount,
+ ReadingTime,
+ Thematics,
+ Topics,
+ Website,
+};