guestbook test

This commit is contained in:
yequari 2025-06-26 20:22:41 -07:00
parent d96cc85a8b
commit 08e35c4cf6
2 changed files with 134 additions and 0 deletions

28
content/guestbook.html Normal file
View File

@ -0,0 +1,28 @@
---
title: "Guestbook"
date: 2025-06-26T20:17:07-07:00
---
<script type="module" src="/guestbook.js"></script>
<form action="https://beta.webweav.ing/websites/26wxzbrx/guestbook/comments/create/remote" method="post">
<div>
<label for="authorname">Name</label>
<input type="text" name="authorname" id="authorname" />
</div>
<div>
<label for="authoremail">Email (Optional) </label>
<input type="text" name="authoremail" id="authoremail" />
</div>
<div>
<label for="authorsite">Site Url (Optional) </label>
<input type="text" name="authorsite" id="authorsite" />
</div>
<div>
<label for="content">Comment</label>
<textarea name="content" id="content"></textarea>
</div>
<div>
<input type="submit" value="Submit" />
</div>
</form>
<comment-list src="https://beta.webweav.ing/websites/26wxzbrx/guestbook/comments"></comment-list>

106
static/guestbook.js Normal file
View File

@ -0,0 +1,106 @@
class CommentList extends HTMLElement {
static get observedAttributes() {
return ['src'];
}
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.comments = [];
this.loading = false;
this.error = null;
}
connectedCallback() {
if (this.hasAttribute('src')) {
this.fetchComments();
}
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'src' && oldValue !== newValue) {
this.fetchComments();
}
}
async fetchComments() {
const src = this.getAttribute('src');
if (!src) return;
this.loading = true;
this.error = null;
this.render();
try {
const response = await fetch(src);
if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
const data = await response.json();
this.comments = Array.isArray(data) ? data : [];
this.loading = false;
this.render();
} catch (err) {
this.error = err.message;
this.loading = false;
this.render();
}
}
formatDate(isoString) {
if (!isoString) return '';
const date = new Date(isoString);
return date.toLocaleString();
}
render() {
this.shadowRoot.innerHTML = `
<style>
.comment-list {
font-family: Arial, sans-serif;
border: 1px solid #ddd;
border-radius: 6px;
padding: 1em;
background: #fafafa;
}
.comment {
border-bottom: 1px solid #eee;
padding: 0.7em 0;
}
.comment:last-child {
border-bottom: none;
}
.author {
font-weight: bold;
margin-right: 1em;
}
.timestamp {
color: #888;
font-size: 0.85em;
}
.text {
margin: 0.2em 0 0 0;
}
.error {
color: red;
}
</style>
<div class="comment-list">
${this.loading
? `<div>Loading comments...</div>`
: this.error
? `<div class="error">Error: ${this.error}</div>`
: this.comments.length === 0
? `<div>No comments found.</div>`
: this.comments.map(comment => `
<div class="comment">
<span class="author">${comment.AuthorName || 'Unknown Author'}</span>
<span class="timestamp">${this.formatDate(comment.Created)}</span>
<div class="text">${comment.CommentText || ''}</div>
</div>
`).join('')
}
</div>
`;
}
}
customElements.define('comment-list', CommentList);