aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/organisms/layout/summary.tsx
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-11-06 18:08:04 +0100
committerArmand Philippot <git@armandphilippot.com>2023-11-11 18:15:27 +0100
commitc9c1c90b30e243563bb4f731da15b3fe657556d2 (patch)
tree8263c176b4096e2893b9d9319bfa7edb01fce188 /src/components/organisms/layout/summary.tsx
parent2771de88f40a5f4ed7480bd8614532dda72deeda (diff)
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
Diffstat (limited to 'src/components/organisms/layout/summary.tsx')
-rw-r--r--src/components/organisms/layout/summary.tsx235
1 files changed, 0 insertions, 235 deletions
diff --git a/src/components/organisms/layout/summary.tsx b/src/components/organisms/layout/summary.tsx
deleted file mode 100644
index 0c95f90..0000000
--- a/src/components/organisms/layout/summary.tsx
+++ /dev/null
@@ -1,235 +0,0 @@
-import NextImage, { type ImageProps as NextImageProps } from 'next/image';
-import type { FC, ReactNode } from 'react';
-import { useIntl } from 'react-intl';
-import type { Article, Meta as MetaType } from '../../../types';
-import { useReadingTime } from '../../../utils/hooks';
-import { ButtonLink, type HeadingLevel, Icon, Link, Time } from '../../atoms';
-import {
- Card,
- CardActions,
- CardBody,
- CardCover,
- CardFooter,
- CardHeader,
- CardMeta,
- CardTitle,
- type MetaItemData,
-} from '../../molecules';
-import styles from './summary.module.scss';
-
-export type Cover = Pick<NextImageProps, 'alt' | 'src' | 'width' | 'height'>;
-
-export type SummaryMeta = Pick<
- MetaType<'article'>,
- | 'author'
- | 'commentsCount'
- | 'cover'
- | 'dates'
- | 'thematics'
- | 'topics'
- | 'wordsCount'
->;
-
-export type SummaryProps = Pick<Article, 'intro' | 'title'> & {
- /**
- * The post metadata.
- */
- meta: SummaryMeta;
- /**
- * The heading level (hn).
- */
- titleLevel?: HeadingLevel;
- /**
- * The post url.
- */
- url: string;
-};
-
-/**
- * Summary component
- *
- * Render a page summary.
- */
-export const Summary: FC<SummaryProps> = ({
- intro,
- meta,
- title,
- titleLevel = 2,
- url,
-}) => {
- const intl = useIntl();
- const figureLabel = intl.formatMessage(
- {
- defaultMessage: '{title} cover',
- description: 'Summary: figure (cover) accessible name',
- id: 'RNVe1W',
- },
- { title }
- );
- const readMore = intl.formatMessage(
- {
- defaultMessage: 'Read more<a11y> about {title}</a11y>',
- description: 'Summary: read more link',
- id: 'Zpgv+f',
- },
- {
- title,
- a11y: (chunks: ReactNode) => (
- // eslint-disable-next-line react/jsx-no-literals -- SR class allowed
- <span className="screen-reader-text">{chunks}</span>
- ),
- }
- );
- const readingTime = useReadingTime(meta.wordsCount, true);
-
- const getMetaItems = (): MetaItemData[] => {
- const summaryMeta: MetaItemData[] = [
- {
- id: 'publication-date',
- label: intl.formatMessage({
- defaultMessage: 'Published on:',
- description: 'Summary: publication date label',
- id: 'TvQ2Ee',
- }),
- value: <Time date={meta.dates.publication} />,
- },
- ];
-
- if (meta.dates.update && meta.dates.update !== meta.dates.publication)
- summaryMeta.push({
- id: 'update-date',
- label: intl.formatMessage({
- defaultMessage: 'Updated on:',
- description: 'Summary: update date label',
- id: 'f0Z/Po',
- }),
- value: <Time date={meta.dates.update} />,
- });
-
- summaryMeta.push({
- id: 'reading-time',
- label: intl.formatMessage({
- defaultMessage: 'Reading time:',
- description: 'Summary: reading time label',
- id: 'tyzdql',
- }),
- value: readingTime,
- });
-
- if (meta.author)
- summaryMeta.push({
- id: 'author',
- label: intl.formatMessage({
- defaultMessage: 'Written by:',
- description: 'Summary: author label',
- id: 'r/6HOI',
- }),
- value: meta.author.name,
- });
-
- if (meta.thematics)
- summaryMeta.push({
- id: 'thematics',
- label: intl.formatMessage({
- defaultMessage: 'Thematics:',
- description: 'Summary: thematics label',
- id: 'bk0WOp',
- }),
- value: meta.thematics.map((thematic) => {
- return {
- id: `thematic-${thematic.id}`,
- value: <Link href={thematic.url}>{thematic.name}</Link>,
- };
- }),
- });
-
- if (meta.topics)
- summaryMeta.push({
- id: 'topics',
- label: intl.formatMessage({
- defaultMessage: 'Topics:',
- description: 'Summary: topics label',
- id: 'yIZ+AC',
- }),
- value: meta.topics.map((topic) => {
- return {
- id: `topic-${topic.id}`,
- value: <Link href={topic.url}>{topic.name}</Link>,
- };
- }),
- });
-
- if (meta.commentsCount !== undefined) {
- const commentsCount = intl.formatMessage(
- {
- defaultMessage:
- '{commentsCount, plural, =0 {No comments} one {# comment} other {# comments}}<a11y> about {title}</a11y>',
- description: 'Summary: comments count',
- id: 'ye/vlA',
- },
- {
- a11y: (chunks: ReactNode) => (
- <span className="screen-reader-text">{chunks}</span>
- ),
- commentsCount: meta.commentsCount,
- title,
- }
- );
- summaryMeta.push({
- id: 'comments-count',
- label: intl.formatMessage({
- defaultMessage: 'Comments:',
- description: 'Summary: comments label',
- id: 'bfPp0g',
- }),
- value: (
- <Link href={`${url}#comments`}>{commentsCount as JSX.Element}</Link>
- ),
- });
- }
-
- return summaryMeta;
- };
-
- return (
- <Card
- className={styles.wrapper}
- cover={
- meta.cover ? (
- <CardCover aria-label={figureLabel} hasBorders>
- <NextImage {...meta.cover} />
- </CardCover>
- ) : undefined
- }
- meta={<CardMeta items={getMetaItems()} />}
- >
- <CardHeader>
- <CardTitle className={styles.title} level={titleLevel}>
- <Link href={url}>{title}</Link>
- </CardTitle>
- </CardHeader>
- <CardBody>
- <div
- className={styles.intro}
- // eslint-disable-next-line react/no-danger
- dangerouslySetInnerHTML={{ __html: intro }}
- />
- </CardBody>
- <CardFooter>
- <CardActions>
- <ButtonLink to={url}>
- {readMore}
- <Icon
- aria-hidden={true}
- className={styles.icon}
- // eslint-disable-next-line react/jsx-no-literals -- Direction allowed
- orientation="right"
- // eslint-disable-next-line react/jsx-no-literals -- Shape allowed
- shape="arrow"
- />
- </ButtonLink>
- </CardActions>
- </CardFooter>
- </Card>
- );
-};