From d8862ba8ecae526aa3f367a769f6df0ea5eacbaf Mon Sep 17 00:00:00 2001 From: AdrianoDev Date: Fri, 31 Jul 2026 17:16:39 +0200 Subject: [PATCH] Blog: numero di articoli accanto a ogni tematica I filtri non dicevano dove ci fosse materiale: si sceglieva una categoria per scoprirla vuota. Ora ognuna porta il proprio conteggio, cestino e bozze esclusi, e il numero si aggiorna insieme ai filtri quando si cambia tematica senza ricaricare. Co-Authored-By: Claude Opus 5 (1M context) --- src/lib/posts.ts | 8 ++++++++ src/pages/blog/index.astro | 15 ++++++++++++--- tests/posts-cestino.test.ts | 9 +++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/lib/posts.ts b/src/lib/posts.ts index 199df79..35d83f0 100644 --- a/src/lib/posts.ts +++ b/src/lib/posts.ts @@ -69,6 +69,14 @@ export function listPublished( return { items, total }; } +/** Quanti articoli pubblicati ha ogni categoria, cestino escluso. */ +export function countPublishedByCategory(db: Database.Database): Record { + const righe = db.prepare( + 'SELECT category, COUNT(*) AS n FROM posts WHERE draft = 0 AND deleted_at IS NULL GROUP BY category' + ).all() as { category: string; n: number }[]; + return Object.fromEntries(righe.map((r) => [r.category, r.n])); +} + export function listAllPosts(db: Database.Database): Post[] { return db.prepare('SELECT * FROM posts WHERE deleted_at IS NULL ORDER BY updated_at DESC').all() as Post[]; } diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro index f655ef1..36e7ab5 100644 --- a/src/pages/blog/index.astro +++ b/src/pages/blog/index.astro @@ -2,7 +2,7 @@ import Base from '../../layouts/Base.astro'; import PageHero from '../../components/PageHero.astro'; import { getDb } from '../../lib/db'; -import { listPublished } from '../../lib/posts'; +import { listPublished, countPublishedByCategory } from '../../lib/posts'; import { CATEGORIES } from '../../lib/blog-const'; export const prerender = false; @@ -15,6 +15,9 @@ const { items, total } = listPublished(getDb(), { page, perPage: PER_PAGE, }); const pages = Math.max(1, Math.ceil(total / PER_PAGE)); +// Conteggi per categoria: mostrati accanto ai filtri, così si vede subito dove c'è materiale. +const perCategoria = countPublishedByCategory(getDb()); +const totalePubblicati = Object.values(perCategoria).reduce((n, v) => n + v, 0); const fmt = (d: string | null) => d ? new Intl.DateTimeFormat('it-IT', { dateStyle: 'long' }).format(new Date(d)) : ''; const linkFor = (cat?: string, p = 1) => { const q = new URLSearchParams(); @@ -33,9 +36,13 @@ const linkFor = (cat?: string, p = 1) => {

Edugo è lo spazio di InsanityLab dedicato alla conoscenza: articoli, guide e approfondimenti su allenamento, nutrizione e salute per capire il corpo e migliorare il proprio benessere. Perché la conoscenza è il primo passo del cambiamento.

@@ -122,6 +129,8 @@ const linkFor = (cat?: string, p = 1) => { .bfilters { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-bottom: 50px; } .bfilters__item { font-family: var(--font-heading); font-size: .7rem; letter-spacing: .16em; text-transform: uppercase; text-decoration: none; color: var(--c-text); padding: 10px 16px; } .bfilters__item.is-active { background: var(--c-accent); color: #fff; } + .bfilters__n { color: var(--c-text-light); } + .bfilters__item.is-active .bfilters__n { color: rgba(255,255,255,.75); } .bfilters__item { transition: background .2s ease, color .2s ease; } #blog-results { transition: opacity .25s ease; } #blog-results.is-loading { opacity: .35; } diff --git a/tests/posts-cestino.test.ts b/tests/posts-cestino.test.ts index ae5b91b..f08c3f7 100644 --- a/tests/posts-cestino.test.ts +++ b/tests/posts-cestino.test.ts @@ -4,6 +4,7 @@ import { createDb } from '../src/lib/db'; import { createPost, trashPost, restorePost, deletePost, getPostById, listAllPosts, listByAuthor, listTrashed, listPublished, listRecent, listArchiveMonths, getPublishedBySlug, + countPublishedByCategory, } from '../src/lib/posts'; let db: Database.Database; @@ -60,6 +61,14 @@ describe('cestino', () => { expect(getPublishedBySlug(db, 'uno')).toBeDefined(); }); + it('i conteggi per categoria escludono cestino e bozze', () => { + expect(countPublishedByCategory(db)).toEqual({ training: 2 }); + trashPost(db, id); + expect(countPublishedByCategory(db)).toEqual({ training: 1 }); + restorePost(db, id); + expect(countPublishedByCategory(db)).toEqual({ training: 2 }); + }); + it('la cancellazione definitiva rimuove davvero la riga', () => { trashPost(db, id); deletePost(db, id);