OpenGuestbook/guestbook.js

100 lines
2.9 KiB
JavaScript
Raw Normal View History

2026-03-29 14:17:57 -05:00
(function() {
const API_URL = '<your-url>';
const form = document.getElementById('gb-form');
const list = document.getElementById('gb-entries');
const status = document.getElementById('gb-status');
function escapeHtml(text) {
if (!text) return "";
return text
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
async function loadComments() {
try {
const res = await fetch(API_URL);
if (!res.ok) throw new Error("Failed to load");
const data = await res.json();
if (data.length === 0) {
list.innerHTML = "<p>No entries yet. Be the first!</p>";
return;
}
list.innerHTML = data.map(c => {
let nameDisplay = escapeHtml(c.name);
if (c.website) {
const safeUrl = c.website.replace(/["<>;]/g, "");
nameDisplay = `${escapeHtml(c.name)} (<a href="${safeUrl}" target="_blank" style="">${safeUrl}</a>)`;
}
return `
<div style="margin-bottom: 20px;">
<div class="title-bar grey">
<div style="font-size:15px;" class="title-bar-text">
<span>${nameDisplay}</span>
</div>
<div>
<span style="font-size:15px;" class="title-bar-text">${c.date}</span>
</div>
</div>
<div class="window main-left gbComments" style="padding: 10px;">
${escapeHtml(c.message)}
</div>
</div>
`;
}).join('');
} catch (err) {
console.error(err);
list.innerHTML = "<p style='color: red;'>Error loading guestbook.</p>";
}
}
form.onsubmit = async (e) => {
e.preventDefault();
const btn = form.querySelector('button');
const nameInput = document.getElementById('gb-name');
const msgInput = document.getElementById('gb-msg');
const siteInput = document.getElementById('gb-site');
if (btn.disabled) return;
btn.disabled = true;
btn.innerText = "Sending...";
status.innerText = "";
try {
const res = await fetch(API_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: nameInput.value,
message: msgInput.value,
website: siteInput.value
})
});
const data = await res.json();
if (!res.ok) {
alert(data.error || "Error posting comment");
} else {
form.reset();
loadComments();
}
} catch (err) {
alert("Network error.");
} finally {
btn.disabled = false;
btn.innerText = "Post Comment";
}
};
loadComments();
})();