From 70b4f633a6fbedb58c8b9134ac64ede854d489de Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Mon, 20 Nov 2023 12:27:46 +0100 Subject: refactor(components): replace PageLayout template with Page * split pages in smaller components (it is both easier to maintain and more readable, we avoid the use of fragments in pages directory) * extract breadcrumbs from article tag (the navigation is not related to the page contents) * remove useReadingTime hook * remove layout options except `isHome` --- src/components/templates/page/page-comments.tsx | 178 ++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/components/templates/page/page-comments.tsx (limited to 'src/components/templates/page/page-comments.tsx') diff --git a/src/components/templates/page/page-comments.tsx b/src/components/templates/page/page-comments.tsx new file mode 100644 index 0000000..bc715e8 --- /dev/null +++ b/src/components/templates/page/page-comments.tsx @@ -0,0 +1,178 @@ +import { + type ForwardRefRenderFunction, + type HTMLAttributes, + forwardRef, + type ReactNode, + useCallback, +} from 'react'; +import { useIntl } from 'react-intl'; +import { sendComment } from '../../../services/graphql'; +import type { SendCommentInput } from '../../../types'; +import { Heading, Link } from '../../atoms'; +import { Card, CardBody } from '../../molecules'; +import { + type CommentData, + CommentsList, + type CommentsListProps, +} from '../../organisms/comments-list'; +import { CommentForm, type CommentFormSubmit } from '../../organisms/forms'; +import styles from './page.module.scss'; + +const link = (chunks: ReactNode) => ( + // eslint-disable-next-line react/jsx-no-literals + {chunks} +); + +export type PageCommentsProps = Omit< + HTMLAttributes, + 'children' | 'onSubmit' +> & + Pick & { + /** + * Should the comments form be removed from the page? + * + * @default false + */ + areCommentsClosed?: boolean; + /** + * The page comments. + */ + comments: CommentData[]; + /** + * The database page id. + */ + pageId: number; + }; + +const PageCommentsWithRef: ForwardRefRenderFunction< + HTMLDivElement, + PageCommentsProps +> = ( + { + areCommentsClosed = false, + className = '', + comments, + depth, + pageId, + ...props + }, + ref +) => { + const wrapperClass = `${styles.comments} ${className}`; + const commentsCount = + comments.length + + comments.reduce( + (accumulator, currentValue) => + accumulator + (currentValue.replies?.length ?? 0), + 0 + ); + const intl = useIntl(); + const commentsListTitle = intl.formatMessage( + { + defaultMessage: + '{commentsCount, plural, =0 {No comments} one {# comment} other {# comments}}', + description: 'PageComments: the section title of the comments list', + id: 'H4pKJP', + }, + { commentsCount } + ); + const commentFormSectionTitle = intl.formatMessage({ + defaultMessage: 'Leave a comment', + description: 'PageComments: the section title of the comment form', + id: 'Y7XdNp', + }); + const commentFormTitle = intl.formatMessage({ + defaultMessage: 'Comment form', + description: 'PageComments: an accessible name for the comment form', + id: 'o+wCJz', + }); + const noCommentsYet = intl.formatMessage( + { + defaultMessage: 'No comments yet. Be the first!', + id: 'w+BpPg', + description: 'PageComments: no comments text', + }, + { + link, + } + ); + + const saveComment: CommentFormSubmit = useCallback( + async (data) => { + const commentData: SendCommentInput = { + author: data.author, + authorEmail: data.email, + authorUrl: data.website ?? '', + clientMutationId: 'comment', + commentOn: pageId, + content: data.comment, + parent: data.parentId, + }; + const { comment, success } = await sendComment(commentData); + const successPrefix = intl.formatMessage({ + defaultMessage: 'Thanks, your comment was successfully sent.', + description: 'PageComments: comment form success message', + id: 'ZcFroC', + }); + const successMessage = comment?.approved + ? intl.formatMessage({ + defaultMessage: 'It has been approved.', + id: 'UgJwSU', + description: 'PageComments: comment approved.', + }) + : intl.formatMessage({ + defaultMessage: 'It is now awaiting moderation.', + id: '/EfcyW', + description: 'PageComments: comment awaiting moderation', + }); + + return { + messages: { + success: `${successPrefix} ${successMessage}`, + }, + validator: () => success, + }; + }, + [intl, pageId] + ); + + return ( +
+
+ + {commentsListTitle} + + {comments.length ? ( + + ) : ( + + {noCommentsYet} + + )} +
+ {areCommentsClosed ? null : ( +
+ + {commentFormSectionTitle} + + +
+ )} +
+ ); +}; + +export const PageComments = forwardRef(PageCommentsWithRef); -- cgit v1.2.3