add post fix
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { BlogPost } from '../types.js'
|
||||
import { putRecord } from '../lib/auth.js'
|
||||
|
||||
function formatDate(dateStr: string): string {
|
||||
const date = new Date(dateStr)
|
||||
@@ -38,17 +39,77 @@ export function mountPostList(container: HTMLElement, posts: BlogPost[]): void {
|
||||
container.innerHTML = `<ul class="post-list">${html}</ul>`
|
||||
}
|
||||
|
||||
export function mountPostDetail(container: HTMLElement, post: BlogPost, handle: string): void {
|
||||
export function mountPostDetail(container: HTMLElement, post: BlogPost, handle: string, collection: string, canEdit: boolean = false): void {
|
||||
const rkey = post.uri.split('/').pop() || ''
|
||||
const jsonUrl = `?mode=browser&handle=${handle}&collection=${encodeURIComponent(collection)}&rkey=${rkey}`
|
||||
|
||||
const editBtn = canEdit ? `<button class="edit-btn" id="edit-btn">edit</button>` : ''
|
||||
|
||||
container.innerHTML = `
|
||||
<article class="post-detail">
|
||||
<header class="post-header">
|
||||
<h1 class="post-title">${escapeHtml(post.title)}</h1>
|
||||
<h1 class="post-title" id="post-title">${escapeHtml(post.title)}</h1>
|
||||
<div class="post-meta">
|
||||
<time class="post-date">${formatDate(post.createdAt)}</time>
|
||||
<a href="${jsonUrl}" class="json-btn">json</a>
|
||||
${editBtn}
|
||||
</div>
|
||||
</header>
|
||||
<div class="post-content">${escapeHtml(post.content)}</div>
|
||||
<footer class="post-footer">
|
||||
<a href="?handle=${handle}" class="back-link">← Back to posts</a>
|
||||
</footer>
|
||||
<div class="post-content" id="post-content">${escapeHtml(post.content)}</div>
|
||||
</article>
|
||||
|
||||
<div class="edit-form-container" id="edit-form-container" style="display: none;">
|
||||
<h3>Edit Post</h3>
|
||||
<form class="edit-form" id="edit-form">
|
||||
<input type="text" id="edit-title" class="edit-form-title" value="${escapeHtml(post.title)}" placeholder="Title" required>
|
||||
<textarea id="edit-content" class="edit-form-body" placeholder="Content" required>${escapeHtml(post.content)}</textarea>
|
||||
<div class="edit-form-footer">
|
||||
<button type="button" id="edit-cancel" class="edit-cancel-btn">Cancel</button>
|
||||
<button type="submit" id="edit-submit" class="edit-submit-btn">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`
|
||||
|
||||
if (canEdit) {
|
||||
const editBtnEl = document.getElementById('edit-btn')
|
||||
const editFormContainer = document.getElementById('edit-form-container')
|
||||
const editForm = document.getElementById('edit-form') as HTMLFormElement
|
||||
const editCancel = document.getElementById('edit-cancel')
|
||||
const postArticle = container.querySelector('.post-detail') as HTMLElement
|
||||
|
||||
editBtnEl?.addEventListener('click', () => {
|
||||
postArticle.style.display = 'none'
|
||||
editFormContainer!.style.display = 'block'
|
||||
})
|
||||
|
||||
editCancel?.addEventListener('click', () => {
|
||||
postArticle.style.display = 'block'
|
||||
editFormContainer!.style.display = 'none'
|
||||
})
|
||||
|
||||
editForm?.addEventListener('submit', async (e) => {
|
||||
e.preventDefault()
|
||||
const title = (document.getElementById('edit-title') as HTMLInputElement).value
|
||||
const content = (document.getElementById('edit-content') as HTMLTextAreaElement).value
|
||||
const submitBtn = document.getElementById('edit-submit') as HTMLButtonElement
|
||||
|
||||
try {
|
||||
submitBtn.disabled = true
|
||||
submitBtn.textContent = 'Saving...'
|
||||
|
||||
await putRecord(collection, rkey, {
|
||||
title,
|
||||
content,
|
||||
createdAt: post.createdAt,
|
||||
})
|
||||
|
||||
window.location.reload()
|
||||
} catch (err) {
|
||||
alert('Save failed: ' + err)
|
||||
submitBtn.disabled = false
|
||||
submitBtn.textContent = 'Save'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,3 +161,27 @@ export async function deleteRecord(collection: string, rkey: string): Promise<bo
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
export async function putRecord(
|
||||
collection: string,
|
||||
rkey: string,
|
||||
record: Record<string, unknown>
|
||||
): Promise<{ uri: string; cid: string } | null> {
|
||||
if (!agent) return null
|
||||
|
||||
try {
|
||||
const result = await agent.com.atproto.repo.putRecord({
|
||||
repo: agent.assertDid,
|
||||
collection,
|
||||
rkey,
|
||||
record: {
|
||||
$type: collection,
|
||||
...record,
|
||||
},
|
||||
})
|
||||
return { uri: result.data.uri, cid: result.data.cid }
|
||||
} catch (err) {
|
||||
console.error('Put record error:', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,8 @@ async function init(): Promise<void> {
|
||||
if (rkey) {
|
||||
const post = await getRecord(profile.did, config.collection, rkey)
|
||||
if (post) {
|
||||
mountPostDetail(contentEl, post, handle)
|
||||
const canEdit = isLoggedIn && authSession?.did === profile.did
|
||||
mountPostDetail(contentEl, post, handle, config.collection, canEdit)
|
||||
} else {
|
||||
contentEl.innerHTML = '<p>Post not found</p>'
|
||||
}
|
||||
|
||||
@@ -288,6 +288,97 @@ body {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.edit-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4px 8px;
|
||||
background: #28a745;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.edit-btn:hover {
|
||||
background: #218838;
|
||||
}
|
||||
|
||||
/* Edit Form */
|
||||
.edit-form-container {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.edit-form-container h3 {
|
||||
font-size: 18px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.edit-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.edit-form-title {
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.edit-form-body {
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
resize: vertical;
|
||||
min-height: 200px;
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.edit-form-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.edit-cancel-btn {
|
||||
padding: 10px 24px;
|
||||
background: #6c757d;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.edit-cancel-btn:hover {
|
||||
background: #5a6268;
|
||||
}
|
||||
|
||||
.edit-submit-btn {
|
||||
padding: 10px 24px;
|
||||
background: #28a745;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.edit-submit-btn:hover {
|
||||
background: #218838;
|
||||
}
|
||||
|
||||
.edit-submit-btn:disabled {
|
||||
background: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.post-content {
|
||||
font-size: 16px;
|
||||
line-height: 1.8;
|
||||
@@ -549,6 +640,12 @@ body {
|
||||
background: #333;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
.edit-form-title,
|
||||
.edit-form-body {
|
||||
background: #1a1a1a;
|
||||
border-color: #333;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
.tab:hover {
|
||||
background: #333;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user