|
| 1 | +import PropTypes from 'prop-types' |
| 2 | +import React, {useState} from 'react' |
| 3 | +import * as Yup from 'yup' |
| 4 | +import Form from '@/components/molecules/Form' |
| 5 | +import Text from '@/components/atoms/Inputs/Text' |
| 6 | +import postComment from '@/api/frontend/wp/comments/postComment' |
| 7 | + |
| 8 | +/** |
| 9 | + * Render an individual comment component. |
| 10 | + * |
| 11 | + * @author WebDevStudios |
| 12 | + * @param {object} props The component attributes as props. |
| 13 | + * @param {Array} props.comment The comment to display. |
| 14 | + * @return {Element} The Comment component. |
| 15 | + */ |
| 16 | +function SingleComment({comment}) { |
| 17 | + if (!comment) { |
| 18 | + return '' |
| 19 | + } |
| 20 | + const {content, date, author} = comment |
| 21 | + const {name, url} = author.node |
| 22 | + let nameElement = <span>{name}</span> |
| 23 | + if (url) { |
| 24 | + nameElement = ( |
| 25 | + <a href={url} rel="nofollow noreferrer" target="_blank"> |
| 26 | + {name} |
| 27 | + </a> |
| 28 | + ) |
| 29 | + } |
| 30 | + return ( |
| 31 | + <> |
| 32 | + <h4> |
| 33 | + {nameElement} |
| 34 | + {` at ${date}`} |
| 35 | + </h4> |
| 36 | + <div |
| 37 | + dangerouslySetInnerHTML={{ |
| 38 | + __html: content |
| 39 | + }} |
| 40 | + /> |
| 41 | + <hr /> |
| 42 | + </> |
| 43 | + ) |
| 44 | +} |
| 45 | + |
| 46 | +SingleComment.propTypes = { |
| 47 | + comment: PropTypes.object.isRequired |
| 48 | +} |
| 49 | + |
| 50 | +SingleComment.defaultProps = { |
| 51 | + comment: {} |
| 52 | +} |
| 53 | + |
| 54 | +/** |
| 55 | + * Render the Comments component. |
| 56 | + * |
| 57 | + * @author WebDevStudios |
| 58 | + * @param {object} props The component attributes as props. |
| 59 | + * @param {Array} props.comments The array of comments to display. |
| 60 | + * @param {number} props.postId The database ID of the post. |
| 61 | + * @return {Element} The Comments component. |
| 62 | + */ |
| 63 | +export default function Comments({comments, postId}) { |
| 64 | + const [message, setMessage] = useState('') |
| 65 | + const [postedComment, setPostedComment] = useState(false) |
| 66 | + |
| 67 | + return ( |
| 68 | + <> |
| 69 | + <h3>Comments</h3> |
| 70 | + { |
| 71 | + // If there are comments, loop over and display. |
| 72 | + !!comments?.length && |
| 73 | + comments.map((comment, index) => ( |
| 74 | + <SingleComment comment={comment.node} key={index} /> |
| 75 | + )) |
| 76 | + } |
| 77 | + |
| 78 | + {!!postedComment && ( |
| 79 | + <SingleComment comment={postedComment} key="posted-comment" /> |
| 80 | + )} |
| 81 | + |
| 82 | + <Form |
| 83 | + className="comment-form" |
| 84 | + id="comment-form" |
| 85 | + title="Add a comment" |
| 86 | + validationSchema={Yup.object().shape({ |
| 87 | + author: Yup.string().required('This field is required.'), |
| 88 | + authorEmail: Yup.string().required('This field is required.') |
| 89 | + })} |
| 90 | + onSubmit={async (values, {setSubmitting}) => { |
| 91 | + const {author, authorEmail, authorUrl, content} = values |
| 92 | + const response = await postComment( |
| 93 | + author, |
| 94 | + authorEmail, |
| 95 | + authorUrl, |
| 96 | + postId, |
| 97 | + content |
| 98 | + ) |
| 99 | + if (response.error) { |
| 100 | + setMessage(response.errorMessage) |
| 101 | + setSubmitting(false) |
| 102 | + return |
| 103 | + } |
| 104 | + |
| 105 | + // alert(JSON.stringify(response)) |
| 106 | + if (response.success && !response.comment) { |
| 107 | + setMessage( |
| 108 | + 'Your comment was sent and will appear after moderation.' |
| 109 | + ) |
| 110 | + } |
| 111 | + |
| 112 | + if (response.comment) { |
| 113 | + setPostedComment(response.comment) |
| 114 | + } |
| 115 | + setSubmitting(false) |
| 116 | + }} |
| 117 | + > |
| 118 | + {!!message && <div>{message}</div>} |
| 119 | + <Text id="author" label="Author" isRequired type="text" /> |
| 120 | + <Text id="authorEmail" label="Email" isRequired type="email" /> |
| 121 | + <Text id="authorUrl" label="Website" type="url" /> |
| 122 | + <Text id="content" label="Comment" isRequired type="text" /> |
| 123 | + </Form> |
| 124 | + </> |
| 125 | + ) |
| 126 | +} |
| 127 | + |
| 128 | +Comments.propTypes = { |
| 129 | + comments: PropTypes.array.isRequired, |
| 130 | + postId: PropTypes.number.isRequired |
| 131 | +} |
| 132 | + |
| 133 | +Comments.defaultProps = { |
| 134 | + comments: [], |
| 135 | + postId: 0 |
| 136 | +} |
0 commit comments