From c9c1c90b30e243563bb4f731da15b3fe657556d2 Mon Sep 17 00:00:00 2001 From: Armand Philippot 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 --- .../post-preview-meta/post-preview-meta.tsx | 254 +++++++++++++++++++++ 1 file changed, 254 insertions(+) create mode 100644 src/components/organisms/post-preview/post-preview-meta/post-preview-meta.tsx (limited to 'src/components/organisms/post-preview/post-preview-meta/post-preview-meta.tsx') diff --git a/src/components/organisms/post-preview/post-preview-meta/post-preview-meta.tsx b/src/components/organisms/post-preview/post-preview-meta/post-preview-meta.tsx new file mode 100644 index 0000000..5a342da --- /dev/null +++ b/src/components/organisms/post-preview/post-preview-meta/post-preview-meta.tsx @@ -0,0 +1,254 @@ +import type { FC, ReactNode } from 'react'; +import { useIntl } from 'react-intl'; +import type { PageLink } from '../../../../types'; +import { getReadingTimeFrom } from '../../../../utils/helpers'; +import { Link, Time, VisuallyHidden } from '../../../atoms'; +import { + CardMeta, + type MetaItemData, + type CardMetaProps, +} from '../../../molecules'; + +const a11y = (chunks: ReactNode) => {chunks}; + +export type PostPreviewMetaComment = { + /** + * The number of comments. + */ + count: number; + /** + * The post heading (used to generate an accessible label). + */ + postHeading: string; + /** + * An url to the comments section. + */ + url?: string; +}; + +export type PostPreviewMetaData = { + /** + * The author name. + */ + author?: string; + /** + * The number of comments on the post and eventually an url to read them. + */ + comments?: PostPreviewMetaComment; + /** + * The publication date of the post. + */ + publicationDate?: string; + /** + * The thematics attached to the post. + */ + thematics?: PageLink[]; + /** + * The topics attached to the post. + */ + topics?: PageLink[]; + /** + * The last modification date of the post. + */ + updateDate?: string; + /** + * The number of words in the post. + */ + wordsCount?: number; +}; + +const validMetaKeys = [ + 'author', + 'comments', + 'publicationDate', + 'thematics', + 'topics', + 'updateDate', + 'wordsCount', +] satisfies (keyof PostPreviewMetaData)[]; + +const isValidMetaKey = (key: string): key is keyof PostPreviewMetaData => + (validMetaKeys as string[]).includes(key); + +export type PostPreviewMetaProps = Omit & { + /** + * The post meta. + */ + meta: PostPreviewMetaData; +}; + +export const PostPreviewMeta: FC = ({ + meta, + ...props +}) => { + const intl = useIntl(); + + const getAuthor = (): MetaItemData | undefined => { + if (!meta.author) return undefined; + + return { + id: 'author', + label: intl.formatMessage({ + defaultMessage: 'Written by:', + description: 'PostPreviewMeta: author label', + id: '2U7ixo', + }), + value: meta.author, + }; + }; + + const getCommentsCount = (): MetaItemData | undefined => { + if (!meta.comments) return undefined; + + const commentsLabel = intl.formatMessage( + { + defaultMessage: + '{commentsCount, plural, =0 {No comments} one {# comment} other {# comments}} about {title}', + description: 'PostPreviewMeta: comments count', + id: 'NfAn9N', + }, + { + a11y, + commentsCount: meta.comments.count, + title: meta.comments.postHeading, + } + ); + + return { + id: 'comments', + label: intl.formatMessage({ + defaultMessage: 'Comments:', + description: 'PostPreviewMeta: comments label', + id: 'FCpPCm', + }), + value: meta.comments.url ? ( + {commentsLabel} + ) : ( + <>{commentsLabel} + ), + }; + }; + + const getPublicationDate = (): MetaItemData | undefined => { + if (!meta.publicationDate) return undefined; + + return { + id: 'publication-date', + label: intl.formatMessage({ + defaultMessage: 'Published on:', + description: 'PostPreviewMeta: publication date label', + id: '+6f4p1', + }), + value: