aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/organisms/layout/comments-list.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/organisms/layout/comments-list.tsx')
-rw-r--r--src/components/organisms/layout/comments-list.tsx88
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 (