diff options
Diffstat (limited to 'src/components/organisms/layout/comments-list.tsx')
| -rw-r--r-- | src/components/organisms/layout/comments-list.tsx | 88 |
1 files changed, 74 insertions, 14 deletions
diff --git a/src/components/organisms/layout/comments-list.tsx b/src/components/organisms/layout/comments-list.tsx index 2d43583..385aea9 100644 --- a/src/components/organisms/layout/comments-list.tsx +++ b/src/components/organisms/layout/comments-list.tsx @@ -1,12 +1,20 @@ -import type { FC } from 'react'; +import { useState, type FC, useCallback } from 'react'; +import { useIntl } from 'react-intl'; import type { SingleComment } from '../../../types'; -import { List, ListItem } from '../../atoms'; -import { UserComment, type UserCommentProps } from './comment'; +import { Heading, List, ListItem } from '../../atoms'; +import { + ApprovedComment, + type CommentReplyHandler, + PendingComment, + ReplyCommentForm, + type ReplyCommentFormProps, +} from '../comment'; +import styles from './comments-list.module.scss'; // eslint-disable-next-line @typescript-eslint/no-magic-numbers export type CommentsListDepth = 0 | 1 | 2 | 3 | 4; -export type CommentsListProps = Pick<UserCommentProps, 'onSubmit'> & { +export type CommentsListProps = Pick<ReplyCommentFormProps, 'onSubmit'> & { /** * An array of comments. */ @@ -27,6 +35,21 @@ export const CommentsList: FC<CommentsListProps> = ({ depth, onSubmit, }) => { + const [replyingTo, setReplyingTo] = useState<number | null>(null); + const intl = useIntl(); + const replyFormHeading = intl.formatMessage({ + defaultMessage: 'Leave a reply', + description: 'CommentsList: comment form title', + id: 'w8uLLF', + }); + + const handleReplyFormVisibility: CommentReplyHandler = useCallback((id) => { + setReplyingTo((prevId) => { + if (prevId === id) return null; + return id; + }); + }, []); + /** * Get each comment wrapped in a list item. * @@ -39,16 +62,53 @@ export const CommentsList: FC<CommentsListProps> = ({ ): JSX.Element[] => { const isLastLevel = startLevel === depth; - return commentsList.map(({ replies, ...comment }) => ( - <ListItem key={comment.id}> - <UserComment canReply={!isLastLevel} onSubmit={onSubmit} {...comment} /> - {replies.length && !isLastLevel ? ( - <List hideMarker isOrdered spacing="sm"> - {getItems(replies, startLevel + 1)} - </List> - ) : null} - </ListItem> - )); + return commentsList.map( + ({ approved, meta, replies, parentId, ...comment }) => { + const replyBtnLabel = + replyingTo === comment.id + ? intl.formatMessage({ + defaultMessage: 'Cancel reply', + description: 'CommentsList: cancel reply button', + id: 'uZj4QI', + }) + : intl.formatMessage({ + defaultMessage: 'Reply', + description: 'CommentsList: reply button', + id: 'Qa9twM', + }); + + return ( + <ListItem key={comment.id}> + {approved ? ( + <> + <ApprovedComment + {...comment} + author={meta.author} + onReply={handleReplyFormVisibility} + publicationDate={meta.date} + replyBtn={replyBtnLabel} + /> + {replyingTo === comment.id ? ( + <ReplyCommentForm + className={styles.reply} + heading={<Heading level={2}>{replyFormHeading}</Heading>} + onSubmit={onSubmit} + commentId={comment.id} + /> + ) : null} + </> + ) : ( + <PendingComment /> + )} + {replies.length && !isLastLevel ? ( + <List hideMarker isOrdered spacing="sm"> + {getItems(replies, startLevel + 1)} + </List> + ) : null} + </ListItem> + ); + } + ); }; return ( |
