import {
type ForwardRefRenderFunction,
type HTMLAttributes,
forwardRef,
type ReactNode,
useCallback,
} from 'react';
import { useIntl } from 'react-intl';
import {
createComment,
type CreateCommentInput,
} from '../../../services/graphql';
import { COMMENTS_SECTION_ID } from '../../../utils/constants';
import { Heading, Link, Section } 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' | 'id' | '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: CreateCommentInput = {
author: data.author,
authorEmail: data.email,
authorUrl: data.website ?? '',
clientMutationId: 'comment',
commentOn: pageId,
content: data.comment,
parent: data.parentId,
};
const { comment, success } = await createComment(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 (
);
};
export const PageComments = forwardRef(PageCommentsWithRef);