feat: add guestbook admin page
This commit is contained in:
parent
79c7aff48b
commit
892afc2161
2 changed files with 4705 additions and 329 deletions
4961
apps/blog/package-lock.json
generated
4961
apps/blog/package-lock.json
generated
File diff suppressed because it is too large
Load diff
73
apps/blog/src/pages/admin.astro
Normal file
73
apps/blog/src/pages/admin.astro
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
export const prerender = false;
|
||||
|
||||
import { getSession } from 'auth-astro/server';
|
||||
import { getPendingEntries, type GuestbookEntry } from '../lib/db';
|
||||
import { isAdmin } from '../lib/auth';
|
||||
import '../styles/global.css';
|
||||
|
||||
const session = await getSession(Astro.request);
|
||||
|
||||
if (!session) {
|
||||
return Astro.redirect('/api/auth/signin');
|
||||
}
|
||||
|
||||
if (!isAdmin(session.user?.id)) {
|
||||
return new Response('Forbidden', { status: 403 });
|
||||
}
|
||||
|
||||
let entries: GuestbookEntry[] = [];
|
||||
try {
|
||||
entries = await getPendingEntries();
|
||||
} catch {
|
||||
// handle error
|
||||
}
|
||||
|
||||
function formatDate(date: Date): string {
|
||||
const d = String(date.getDate()).padStart(2, '0');
|
||||
const m = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const y = String(date.getFullYear()).slice(-2);
|
||||
return `${d}/${m}/${y}`;
|
||||
}
|
||||
---
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><meta charset="UTF-8"><title>admin - guestbook</title></head>
|
||||
<body>
|
||||
<h1>guestbook admin</h1>
|
||||
<p>logged in as {session.user?.name} <a href="/api/auth/signout">sign out</a></p>
|
||||
|
||||
{entries.length === 0 ? (
|
||||
<p class="muted">no pending entries</p>
|
||||
) : (
|
||||
<ul id="entries">
|
||||
{entries.map(e => (
|
||||
<li data-id={e.id}>
|
||||
<span class="muted">{formatDate(e.createdAt)}</span>
|
||||
<strong>{e.name}</strong>
|
||||
{e.url && <a href={e.url}>{e.url}</a>}
|
||||
<p>{e.message}</p>
|
||||
<button class="approve">approve</button>
|
||||
<button class="reject">reject</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
|
||||
<script>
|
||||
document.querySelectorAll('#entries li').forEach(li => {
|
||||
const id = li.getAttribute('data-id');
|
||||
|
||||
li.querySelector('.approve')?.addEventListener('click', async () => {
|
||||
const res = await fetch(`/api/guestbook/${id}`, { method: 'PATCH' });
|
||||
if (res.ok) li.remove();
|
||||
});
|
||||
|
||||
li.querySelector('.reject')?.addEventListener('click', async () => {
|
||||
const res = await fetch(`/api/guestbook/${id}`, { method: 'DELETE' });
|
||||
if (res.ok) li.remove();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue