From cb6a54e54f2f013e06049b20388ca78e26201e16 Mon Sep 17 00:00:00 2001
From: Armand Philippot <git@armandphilippot.com>
Date: Fri, 22 Apr 2022 17:27:01 +0200
Subject: chore: add a CommentsList component

---
 src/components/organisms/layout/comments-list.tsx | 65 +++++++++++++++++++++++
 1 file changed, 65 insertions(+)
 create mode 100644 src/components/organisms/layout/comments-list.tsx

(limited to 'src/components/organisms/layout/comments-list.tsx')

diff --git a/src/components/organisms/layout/comments-list.tsx b/src/components/organisms/layout/comments-list.tsx
new file mode 100644
index 0000000..03f508e
--- /dev/null
+++ b/src/components/organisms/layout/comments-list.tsx
@@ -0,0 +1,65 @@
+import SingleComment, {
+  type CommentProps,
+} from '@components/organisms/layout/comment';
+import { FC } from 'react';
+import styles from './comments-list.module.scss';
+
+export type Comment = Omit<CommentProps, 'canReply' | 'saveComment'> & {
+  child?: Comment[];
+};
+
+export type CommentsListProps = {
+  /**
+   * An array of comments.
+   */
+  comments: Comment[];
+  /**
+   * The maximum depth. Use `0` to not display nested comments.
+   */
+  depth: 0 | 1 | 2 | 3 | 4;
+  /**
+   * A callback function to save comment form data.
+   */
+  saveComment: CommentProps['saveComment'];
+};
+
+/**
+ * CommentsList component
+ *
+ * Render a comments list.
+ */
+const CommentsList: FC<CommentsListProps> = ({
+  comments,
+  depth,
+  saveComment,
+}) => {
+  /**
+   * Get each comment wrapped in a list item.
+   *
+   * @param {Comment[]} commentsList - An array of comments.
+   * @returns {JSX.Element[]} The list items.
+   */
+  const getItems = (
+    commentsList: Comment[],
+    startLevel: number
+  ): JSX.Element[] => {
+    const isLastLevel = startLevel === depth;
+
+    return commentsList.map(({ child, ...comment }) => (
+      <li key={comment.id} className={styles.item}>
+        <SingleComment
+          saveComment={saveComment}
+          canReply={!isLastLevel}
+          {...comment}
+        />
+        {child && !isLastLevel && (
+          <ol className={styles.list}>{getItems(child, startLevel + 1)}</ol>
+        )}
+      </li>
+    ));
+  };
+
+  return <ol className={styles.list}>{getItems(comments, 0)}</ol>;
+};
+
+export default CommentsList;
-- 
cgit v1.2.3

