fixing gitignore
This commit is contained in:
197
assets/scripts/comments.js
Normal file
197
assets/scripts/comments.js
Normal file
@@ -0,0 +1,197 @@
|
||||
let pageSlug = null;
|
||||
|
||||
/* -----------------------------
|
||||
* DOM builders
|
||||
* ----------------------------- */
|
||||
|
||||
|
||||
function showReplyForm(container, parentId) {
|
||||
if (container.querySelector(".reply-form")) return;
|
||||
|
||||
const form = document.createElement("form");
|
||||
form.className = "reply-form";
|
||||
|
||||
form.innerHTML = `
|
||||
<input type="text" name="author" placeholder="Your name (optional)">
|
||||
<textarea name="content" required placeholder="Write a reply..."></textarea>
|
||||
<button type="submit">Post reply</button>
|
||||
`;
|
||||
|
||||
form.addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
|
||||
const author = form.author.value.trim();
|
||||
const content = form.content.value.trim();
|
||||
if (!content) return;
|
||||
|
||||
const ok = await postComment(author, content, parentId);
|
||||
if (ok) loadComments();
|
||||
else alert("Failed to post reply");
|
||||
});
|
||||
|
||||
container.appendChild(form);
|
||||
}
|
||||
|
||||
function createComment(comment) {
|
||||
const wrapper = document.createElement("div");
|
||||
wrapper.className = "comment";
|
||||
wrapper.dataset.id = comment.id;
|
||||
|
||||
const author = document.createElement("strong");
|
||||
author.textContent = comment.author || "Anonymous";
|
||||
|
||||
const body = document.createElement("p");
|
||||
body.textContent = comment.content;
|
||||
|
||||
const time = document.createElement("time");
|
||||
time.className = "comment-date";
|
||||
time.dateTime = comment.created_at;
|
||||
time.textContent = new Date(comment.created_at).toLocaleString();
|
||||
|
||||
const replyBtn = document.createElement("button");
|
||||
replyBtn.className = "comment-reply";
|
||||
replyBtn.textContent = "Reply";
|
||||
replyBtn.onclick = () =>
|
||||
showReplyForm(wrapper, Number(comment.id));
|
||||
|
||||
wrapper.append(author, body, time, replyBtn);
|
||||
|
||||
if (comment.children?.length) {
|
||||
const replies = document.createElement("div");
|
||||
replies.className = "comment-children";
|
||||
|
||||
comment.children.forEach(child => {
|
||||
replies.appendChild(createComment(child));
|
||||
});
|
||||
|
||||
wrapper.appendChild(replies);
|
||||
}
|
||||
console.log("PARENT_ID RECEIVED:", comment.parent_id)
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function buildCommentTree(comments) {
|
||||
const byId = {};
|
||||
const roots = [];
|
||||
|
||||
comments.forEach(c => {
|
||||
c.children = [];
|
||||
byId[c.id] = c;
|
||||
});
|
||||
|
||||
comments.forEach(c => {
|
||||
if (c.parent_id) {
|
||||
const parent = byId[c.parent_id];
|
||||
if (parent) parent.children.push(c);
|
||||
} else {
|
||||
roots.push(c);
|
||||
}
|
||||
});
|
||||
|
||||
return roots;
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------
|
||||
* Rendering
|
||||
* ----------------------------- */
|
||||
|
||||
function renderComments(comments) {
|
||||
const list = document.getElementById("comments-list");
|
||||
list.innerHTML = "";
|
||||
|
||||
if (!comments.length) {
|
||||
const empty = document.createElement("p");
|
||||
empty.className = "comments-empty";
|
||||
empty.textContent = "No comments yet.";
|
||||
list.appendChild(empty);
|
||||
return;
|
||||
}
|
||||
|
||||
const tree = buildCommentTree(comments);
|
||||
tree.forEach(c => list.appendChild(createComment(c)));
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------
|
||||
* API
|
||||
* ----------------------------- */
|
||||
|
||||
async function fetchComments() {
|
||||
const res = await fetch(`/api/comments/${pageSlug}`);
|
||||
if (!res.ok) {
|
||||
console.error("Failed to fetch comments");
|
||||
return [];
|
||||
}
|
||||
return await res.json();
|
||||
}
|
||||
|
||||
async function postComment(author, content, parentId = null) {
|
||||
const res = await fetch("/api/comments", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
page_slug: pageSlug,
|
||||
author: author || null,
|
||||
content,
|
||||
parent_id: parentId
|
||||
})
|
||||
});
|
||||
|
||||
return res.ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* -----------------------------
|
||||
* Form handling
|
||||
* ----------------------------- */
|
||||
|
||||
function wireCommentForm() {
|
||||
const form = document.getElementById("comment-form");
|
||||
|
||||
form.addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
|
||||
const authorInput = form.querySelector("input[name='author']");
|
||||
const textarea = form.querySelector("textarea[name='content']");
|
||||
|
||||
const author = authorInput.value.trim();
|
||||
const content = textarea.value.trim();
|
||||
|
||||
if (!content) return;
|
||||
|
||||
const ok = await postComment(author, content);
|
||||
if (ok) {
|
||||
textarea.value = "";
|
||||
loadComments(); // same pattern as your Kanban board
|
||||
} else {
|
||||
alert("Failed to post comment");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------
|
||||
* Entry point
|
||||
* ----------------------------- */
|
||||
|
||||
async function loadComments() {
|
||||
const comments = await fetchComments();
|
||||
renderComments(comments);
|
||||
}
|
||||
|
||||
function initComments() {
|
||||
const section = document.getElementById("comments");
|
||||
if (!section) return;
|
||||
|
||||
pageSlug = section.dataset.slug;
|
||||
|
||||
wireCommentForm();
|
||||
loadComments();
|
||||
}
|
||||
|
||||
initComments();
|
||||
Reference in New Issue
Block a user