aboutsummaryrefslogtreecommitdiff
path: root/src/components/BlogComments.jsx
diff options
context:
space:
mode:
authorAndrew Lee <alee14498@protonmail.com>2024-06-28 20:31:02 -0400
committerAndrew Lee <alee14498@protonmail.com>2024-06-28 20:31:02 -0400
commit64cd7fc83d43a0ad7db1b51214291736bd245b44 (patch)
treeda8f9e47d50583932e144fa6b21585d5dd70bd21 /src/components/BlogComments.jsx
parent8edeebb44d9b3636268d95c30d462593d9a074d8 (diff)
downloadpersonal-website-64cd7fc83d43a0ad7db1b51214291736bd245b44.tar.gz
personal-website-64cd7fc83d43a0ad7db1b51214291736bd245b44.tar.bz2
personal-website-64cd7fc83d43a0ad7db1b51214291736bd245b44.zip
Guestbook overhaul; Comments; New post; Updated packages
Diffstat (limited to 'src/components/BlogComments.jsx')
-rw-r--r--src/components/BlogComments.jsx89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/components/BlogComments.jsx b/src/components/BlogComments.jsx
new file mode 100644
index 0000000..183fb94
--- /dev/null
+++ b/src/components/BlogComments.jsx
@@ -0,0 +1,89 @@
+import { Component } from 'preact';
+import { formatDate } from "../util";
+import sanitizeHtml from 'sanitize-html';
+import BlogCommentsForm from "./BlogCommentsForm.jsx";
+
+class BlogComments extends Component {
+ state = {
+ message: null,
+ error: null,
+ page: 1,
+ };
+
+ fetchMessages = async (page) => {
+ try {
+ const response = await fetch(`${import.meta.env.PUBLIC_API_URL}/comments/${this.props.slug}?page=${page}`);
+
+ if (!response.ok) {
+ const errorData = await response.json();
+ this.setState({ error: errorData.message });
+ console.error('Failed to fetch data:', errorData.message);
+ return;
+ }
+
+ const { messages, totalPages } = await response.json();
+
+ this.setState({
+ message: messages,
+ totalPages: totalPages,
+ error: null // clear any previous error
+ });
+
+ } catch (error) {
+ this.setState({ error: `${error.message}` });
+ console.error('Failed to fetch data:', error);
+ }
+ }
+
+ refresh = async () => {
+ await this.fetchMessages(this.state.page);
+ }
+
+ async componentDidMount() {
+ await this.fetchMessages(this.state.page);
+ }
+
+ handleNext = async () => {
+ const nextPage = this.state.page + 1;
+ if (nextPage > this.state.totalPages) {
+ return;
+ }
+ this.setState({ page: nextPage });
+ await this.fetchMessages(nextPage);
+ }
+
+ handlePrevious = async () => {
+ const previousPage = this.state.page - 1;
+ this.setState({ page: previousPage });
+ await this.fetchMessages(previousPage);
+ }
+
+ render() {
+ const { message, error, page, totalPages } = this.state;
+
+ return (
+ <div>
+ <BlogCommentsForm onMessageSent={this.refresh} slug={this.props.slug} />
+ {error ? (
+ <p>{error}</p>
+ ) : message ? (
+ <div>
+ {message.map((g) => (
+ <article className="card">
+ <h1>{g.author}</h1>
+ <div dangerouslySetInnerHTML={{__html: sanitizeHtml(g.comment)}}/>
+ <small>{formatDate(g.created_at)}</small>
+ </article>
+ ))}
+ {page > 1 && <button class="button margin" onClick={this.handlePrevious}>Previous</button>}
+ {page < totalPages && <button class="button margin" onClick={this.handleNext}>Next</button>}
+ </div>
+ ) : (
+ <p>Loading comments...</p>
+ )}
+ </div>
+ );
+ }
+}
+
+export default BlogComments;