summaryrefslogtreecommitdiffstats
path: root/src/components/CommentForm
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/CommentForm')
-rw-r--r--src/components/CommentForm/CommentForm.tsx150
1 files changed, 98 insertions, 52 deletions
diff --git a/src/components/CommentForm/CommentForm.tsx b/src/components/CommentForm/CommentForm.tsx
index 0ea3276..762bb75 100644
--- a/src/components/CommentForm/CommentForm.tsx
+++ b/src/components/CommentForm/CommentForm.tsx
@@ -1,68 +1,107 @@
import { ButtonSubmit } from '@components/Buttons';
import { Form, FormItem, Input, TextArea } from '@components/Form';
import Notice from '@components/Notice/Notice';
+import Spinner from '@components/Spinner/Spinner';
import { createComment } from '@services/graphql/mutations';
+import { NoticeType } from '@ts/types/app';
import { ForwardedRef, forwardRef, useState } from 'react';
import { useIntl } from 'react-intl';
import styles from './CommentForm.module.scss';
const CommentForm = (
- {
- articleId,
- parentId = 0,
- isReply = false,
- }: {
- articleId: number;
- parentId?: number;
- isReply?: boolean;
- },
+ { articleId, parentId = 0 }: { articleId: number; parentId?: number },
ref: ForwardedRef<HTMLInputElement>
) => {
const intl = useIntl();
- const [name, setName] = useState('');
- const [email, setEmail] = useState('');
- const [website, setWebsite] = useState('');
- const [message, setMessage] = useState('');
- const [isSuccess, setIsSuccess] = useState(false);
- const [isApproved, setIsApproved] = useState(false);
+ const [name, setName] = useState<string>('');
+ const [email, setEmail] = useState<string>('');
+ const [website, setWebsite] = useState<string>('');
+ const [comment, setComment] = useState<string>('');
+ const [isSubmitting, setIsSubmitting] = useState<boolean>(false);
+ const [notice, setNotice] = useState<string>();
+ const [noticeType, setNoticeType] = useState<NoticeType>('success');
const resetForm = () => {
setName('');
setEmail('');
setWebsite('');
- setMessage('');
+ setComment('');
+ setIsSubmitting(false);
};
- const submitHandler = async (e: SubmitEvent) => {
- e.preventDefault();
+ const isEmptyString = (value: string): boolean => value.trim() === '';
+ const areRequiredFieldsSet = (): boolean =>
+ !isEmptyString(name) && !isEmptyString(email) && !isEmptyString(comment);
- if (name && email && message && articleId) {
- const data = {
- author: name,
- authorEmail: email,
- authorUrl: website,
- content: message,
- parent: parentId,
- commentOn: articleId,
- mutationId: 'createComment',
- };
- const createdComment = await createComment(data);
+ const sendComment = async () => {
+ const data = {
+ author: name,
+ authorEmail: email,
+ authorUrl: website,
+ content: comment,
+ parent: parentId,
+ commentOn: articleId,
+ mutationId: 'createComment',
+ };
- if (createdComment.success) setIsSuccess(true);
- if (isSuccess) {
- resetForm();
- if (createdComment.comment?.approved) setIsApproved(true);
+ const createdComment = await createComment(data);
- setTimeout(() => {
- setIsSuccess(false);
- setIsApproved(false);
- }, 8000);
+ if (createdComment.success) {
+ resetForm();
+ setNoticeType('success');
+ if (createdComment.comment?.approved) {
+ setNotice(
+ intl.formatMessage({
+ defaultMessage: 'Thanks for your comment!',
+ description: 'CommentForm: success notice',
+ })
+ );
+ } else {
+ setNotice(
+ intl.formatMessage({
+ defaultMessage:
+ 'Thanks for your comment! It is now awaiting moderation.',
+ description: 'CommentForm: success notice but awaiting moderation',
+ })
+ );
}
+
+ setTimeout(() => {
+ setNotice(undefined);
+ }, 10000);
+ } else {
+ setNoticeType('error');
+ setNotice(
+ intl.formatMessage({
+ defaultMessage:
+ 'An unexpected error happened. Comment cannot be submitted.',
+ description: 'CommentForm: error notice',
+ })
+ );
+ }
+ };
+
+ const submitHandler = async (e: SubmitEvent) => {
+ e.preventDefault();
+ setNotice(undefined);
+ setIsSubmitting(true);
+
+ if (areRequiredFieldsSet()) {
+ sendComment();
} else {
- setIsSuccess(false);
+ setIsSubmitting(false);
+ setNoticeType('warning');
+ setNotice(
+ intl.formatMessage({
+ defaultMessage:
+ 'Some required fields are empty. Comment cannot be submitted.',
+ description: 'CommentForm: missing required fields',
+ })
+ );
}
};
+ const isReply = parentId !== 0;
const wrapperClasses = `${styles.wrapper} ${
isReply ? styles['wrapper--reply'] : ''
}`;
@@ -72,7 +111,7 @@ const CommentForm = (
<h2 className={styles.title}>
{intl.formatMessage({
defaultMessage: 'Leave a comment',
- description: 'CommentForm: form title',
+ description: 'CommentForm: Form title',
})}
</h2>
<Form
@@ -97,6 +136,7 @@ const CommentForm = (
<Input
id="commenter-email"
name="commenter-email"
+ type="email"
label={intl.formatMessage({
defaultMessage: 'Email',
description: 'CommentForm: Email field label',
@@ -120,18 +160,24 @@ const CommentForm = (
</FormItem>
<FormItem>
<TextArea
- id="commenter-message"
- name="commenter-message"
+ id="commenter-comment"
+ name="commenter-comment"
label={intl.formatMessage({
defaultMessage: 'Comment',
description: 'CommentForm: Comment field label',
})}
- value={message}
- setValue={setMessage}
+ value={comment}
+ setValue={setComment}
required={true}
/>
</FormItem>
<FormItem>
+ <noscript>
+ {intl.formatMessage({
+ defaultMessage: 'Javascript is required to post a comment.',
+ description: 'CommentForm: noscript tag',
+ })}
+ </noscript>
<ButtonSubmit>
{intl.formatMessage({
defaultMessage: 'Send',
@@ -139,16 +185,16 @@ const CommentForm = (
})}
</ButtonSubmit>
</FormItem>
- {isSuccess && !isApproved && (
- <Notice type="success">
- {intl.formatMessage({
- defaultMessage:
- 'Thanks for your comment! It is now awaiting moderation.',
- description: 'CommentForm: Comment sent success message',
- })}
- </Notice>
- )}
</Form>
+ {isSubmitting && (
+ <Spinner
+ message={intl.formatMessage({
+ defaultMessage: 'Submitting...',
+ description: 'CommentForm: submitting message',
+ })}
+ />
+ )}
+ {notice && <Notice type={noticeType}>{notice}</Notice>}
</div>
);
};