diff options
Diffstat (limited to 'src/components/MetaItems')
| -rw-r--r-- | src/components/MetaItems/Author/Author.tsx | 20 | ||||
| -rw-r--r-- | src/components/MetaItems/CommentsCount/CommentsCount.tsx | 41 | ||||
| -rw-r--r-- | src/components/MetaItems/Dates/Dates.tsx | 56 | ||||
| -rw-r--r-- | src/components/MetaItems/MetaItem/MetaItem.module.scss | 18 | ||||
| -rw-r--r-- | src/components/MetaItems/MetaItem/MetaItem.tsx | 36 | ||||
| -rw-r--r-- | src/components/MetaItems/PostsCount/PostsCount.tsx | 27 | ||||
| -rw-r--r-- | src/components/MetaItems/ReadingTime/ReadingTime.tsx | 55 | ||||
| -rw-r--r-- | src/components/MetaItems/Thematics/Thematics.tsx | 42 | ||||
| -rw-r--r-- | src/components/MetaItems/Topics/Topics.tsx | 36 | ||||
| -rw-r--r-- | src/components/MetaItems/Website/Website.tsx | 20 | ||||
| -rw-r--r-- | src/components/MetaItems/index.tsx | 21 |
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, +}; |
