Articoli: cestino con ripristino, e azioni a icona come in Utenti

Eliminare un articolo non lasciava nulla di recuperabile: ora la riga
finisce nel cestino (colonna deleted_at, aggiunta anche ai database già
esistenti) e sparisce da sito e pannello, ma resta ripristinabile dalla
nuova pagina /admin/cestino, dove sta anche la cancellazione definitiva.
L'API la accetta solo su articoli già cestinati, così il contenuto non si
perde per un clic distratto.

Ogni lettura pubblica — elenco, recenti, archivio per mese, pagina del
singolo articolo — filtra il cestino, e chi non gestisce vede nel cestino
soltanto i propri articoli.

Le azioni di riga diventano icone (matita e cestino) come nell'elenco
utenti, con etichetta accessibile che nomina l'articolo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-31 16:47:27 +02:00
parent 59d6246c77
commit 6a97a98325
7 changed files with 232 additions and 17 deletions
+24 -3
View File
@@ -1,6 +1,6 @@
import type { APIRoute } from 'astro';
import { getDb } from '../../../../lib/db';
import { getPostById, updatePost, deletePost, canModifyPost } from '../../../../lib/posts';
import { getPostById, updatePost, deletePost, trashPost, restorePost, canModifyPost } from '../../../../lib/posts';
import { parsePostBody } from '../../../../lib/post-body';
export const prerender = false;
@@ -25,11 +25,32 @@ export const PUT: APIRoute = async ({ params, request, locals }) => {
}
};
export const DELETE: APIRoute = ({ params, locals }) => {
/**
* Sposta l'articolo nel cestino. Con `?definitivo=1` lo cancella davvero: è la sola via per
* perdere il contenuto, e vale solo per ciò che è già nel cestino.
*/
export const DELETE: APIRoute = ({ params, locals, url }) => {
const id = Number(params.id);
const existing = getPostById(getDb(), id);
if (!existing) return json(404, { error: 'Articolo non trovato.' });
if (!canModifyPost(locals.user!.role, locals.user!.id, existing)) return json(403, { error: 'Non puoi eliminare questo articolo.' });
deletePost(getDb(), id);
if (url.searchParams.get('definitivo') === '1') {
if (!existing.deleted_at) return json(400, { error: 'Sposta prima l\'articolo nel cestino.' });
deletePost(getDb(), id);
return json(200, { ok: true, definitivo: true });
}
trashPost(getDb(), id);
return json(200, { ok: true });
};
/** Riporta l'articolo fuori dal cestino, nello stato in cui era (bozza o pubblicato). */
export const POST: APIRoute = ({ params, locals }) => {
const id = Number(params.id);
const existing = getPostById(getDb(), id);
if (!existing) return json(404, { error: 'Articolo non trovato.' });
if (!canModifyPost(locals.user!.role, locals.user!.id, existing)) return json(403, { error: 'Non puoi ripristinare questo articolo.' });
restorePost(getDb(), id);
return json(200, { ok: true });
};