Struttura: il sito esistente si sposta sotto apps/sito
Primo passo della separazione sito / piattaforme decisa da Adriano il 03/09: due applicazioni autosufficienti, senza workspace di root, cosi' che ognuna resti un progetto Astro completo ed estraibile. Qui non cambia niente del codice: solo la radice. I pattern del .gitignore che avevano una barra erano ancorati alla radice e dopo lo spostamento non avrebbero piu' coperto niente (data/*.db*, uploads/*): resi validi a qualunque profondita'. Suite: 45 file, 347 test verdi prima e dopo lo spostamento. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EndnceRA5WnA6rvA5iV9WL
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
---
|
||||
// Cestino degli articoli: qui si recupera ciò che è stato tolto dal sito, o lo si elimina
|
||||
// per sempre. Chi gestisce vede tutto, gli altri solo i propri articoli.
|
||||
import Admin from '../../layouts/Admin.astro';
|
||||
import { getDb } from '../../lib/db';
|
||||
import { listTrashed } from '../../lib/posts';
|
||||
import { listUsers } from '../../lib/auth';
|
||||
export const prerender = false;
|
||||
const user = Astro.locals.user!;
|
||||
const isManager = user.role === 'superuser' || user.role === 'admin';
|
||||
const posts = listTrashed(getDb(), isManager ? undefined : user.id);
|
||||
const nameById = new Map(listUsers(getDb()).map((u) => [u.id, u.username]));
|
||||
const fmt = new Intl.DateTimeFormat('it-IT', { dateStyle: 'short', timeStyle: 'short' });
|
||||
---
|
||||
<Admin title="Cestino">
|
||||
<h1>Cestino</h1>
|
||||
<p class="atoolbar"><a class="abtn abtn--ghost" href="/admin">← Torna agli articoli</a></p>
|
||||
|
||||
{posts.length === 0 ? (
|
||||
<p class="amuted">Il cestino è vuoto.</p>
|
||||
) : (
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Titolo</th><th>Categoria</th>{isManager && <th>Autore</th>}<th>Nel cestino dal</th><th class="uactions">Azioni</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{posts.map((p) => (
|
||||
<tr>
|
||||
<td>{p.title}</td>
|
||||
<td>{p.category}</td>
|
||||
{isManager && <td>{p.author_id ? (nameById.get(p.author_id) ?? 'Staff InsanityLab') : 'Staff InsanityLab'}</td>}
|
||||
<td>{p.deleted_at ? fmt.format(new Date(p.deleted_at.replace(' ', 'T') + 'Z')) : '—'}</td>
|
||||
<td class="uactions">
|
||||
<button class="aicon" data-restore={p.id} title="Ripristina" aria-label={`Ripristina ${p.title}`}>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 5V2L7 6l5 4V7a5 5 0 1 1-5 5H5a7 7 0 1 0 7-7Z"/></svg>
|
||||
</button>
|
||||
<button class="aicon aicon--danger" data-purge={p.id} title="Elimina definitivamente" aria-label={`Elimina definitivamente ${p.title}`}>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M9 3h6l1 2h4v2H4V5h4l1-2Zm-3 6h12l-1 11a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2L6 9Z"/></svg>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
<p class="form-msg" id="row-msg"></p>
|
||||
</Admin>
|
||||
|
||||
<script>
|
||||
const rowMsg = document.getElementById('row-msg')!;
|
||||
const errore = async (res: Response) => {
|
||||
rowMsg.className = 'form-msg form-msg--err';
|
||||
rowMsg.textContent = (await res.json()).error ?? 'Operazione non riuscita.';
|
||||
};
|
||||
|
||||
document.querySelectorAll<HTMLButtonElement>('[data-restore]').forEach((b) =>
|
||||
b.addEventListener('click', async () => {
|
||||
const res = await fetch(`/api/admin/posts/${b.dataset.restore}`, { method: 'POST' });
|
||||
if (res.ok) location.reload();
|
||||
else errore(res);
|
||||
}));
|
||||
|
||||
document.querySelectorAll<HTMLButtonElement>('[data-purge]').forEach((b) =>
|
||||
b.addEventListener('click', async () => {
|
||||
if (!confirm('Eliminare definitivamente questo articolo? Il contenuto sarà perso.')) return;
|
||||
const res = await fetch(`/api/admin/posts/${b.dataset.purge}?definitivo=1`, { method: 'DELETE' });
|
||||
if (res.ok) location.reload();
|
||||
else errore(res);
|
||||
}));
|
||||
</script>
|
||||
Reference in New Issue
Block a user