diff --git a/src/layouts/Admin.astro b/src/layouts/Admin.astro index 0cb4bd0..e61622f 100644 --- a/src/layouts/Admin.astro +++ b/src/layouts/Admin.astro @@ -22,13 +22,17 @@ const user = Astro.locals.user; th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid #eee; font-size: .92rem; } .pill { font-size: .75rem; padding: 2px 10px; border-radius: 10px; background: #e5decf; } .pill--draft { background: #f3d9a4; } + .form-msg { font-size: .9rem; margin-top: 8px; } + .form-msg--ok { color: #3c7a3c; } + .form-msg--err { color: #b03030; }
InsanityLab · Admin - {user && <>{`Ciao, ${user.username}`} Articoli Nuovo Esci Vedi sito ↗} + {user && user.role === 'editor' && <>{`Ciao, ${user.username}`} Contenuti Esci} + {user && user.role !== 'editor' && <>{`Ciao, ${user.username}`} Articoli Contenuti Nuovo Esci Vedi sito ↗}
diff --git a/src/pages/admin/content.astro b/src/pages/admin/content.astro new file mode 100644 index 0000000..2779967 --- /dev/null +++ b/src/pages/admin/content.astro @@ -0,0 +1,242 @@ +--- +import Admin from '../../layouts/Admin.astro'; +import { getDb } from '../../lib/db'; +import { seedByTag } from '../../data/content-seed'; +import { STYLE_GROUPS } from '../../lib/style-presets'; +export const prerender = false; + +// Mappa esplicita prefisso tag → gruppo del pannello (spec §7). +const GROUP_BY_PREFIX: Record = { + home: 'Home', + about: 'About', team: 'About', method: 'About', + program: 'Programmi', programs: 'Programmi', pricing: 'Programmi', + training: 'Training', + contact: 'Contatti', form: 'Contatti', + global: 'Globali', header: 'Globali', footer: 'Globali', + agenda: 'Globali', partner: 'Globali', notfound: 'Globali', +}; +const GROUP_ORDER = ['Home', 'About', 'Programmi', 'Training', 'Contatti', 'Globali', 'Altro']; + +interface Row { tag: string; type: string; value: string; styles: string; updated_at: string; updated_by: string | null } +const rows = getDb().prepare( + 'SELECT tag, type, value, styles, updated_at, updated_by FROM content_blocks ORDER BY tag' +).all() as Row[]; + +interface Item extends Row { parsedStyles: Record; styleOptions: readonly string[] } +const groups = new Map(GROUP_ORDER.map((g) => [g, []])); +for (const r of rows) { + let parsedStyles: Record = {}; + try { parsedStyles = JSON.parse(r.styles); } catch { /* styles corrotto: si ignora */ } + if (typeof parsedStyles !== 'object' || parsedStyles === null) parsedStyles = {}; + const group = GROUP_BY_PREFIX[r.tag.split('.')[0]] ?? 'Altro'; + groups.get(group)!.push({ ...r, parsedStyles, styleOptions: seedByTag.get(r.tag)?.styleOptions ?? [] }); +} + +const fmt = new Intl.DateTimeFormat('it-IT', { dateStyle: 'short', timeStyle: 'short' }); +const snippet = (v: string) => (v.length > 60 ? `${v.slice(0, 60)}…` : v); +const isLong = (v: string) => v.length > 80 || v.includes('\n'); +const imgLabel = (v: string) => (v ? '(immagine personalizzata)' : '(immagine originale)'); +const allStyles = STYLE_GROUPS as Record; +--- + +
+

Contenuti

+ Vedi sito con tag ↗ +
+ + +
+ {GROUP_ORDER.map((g) => { + const items = groups.get(g)!; + return items.length > 0 && ( +
+ {g} {items.length} + {items.map((it) => ( +
+ + {it.tag} + {it.type === 'image' ? imgLabel(it.value) : snippet(it.value)} + +
+ {it.type === 'image' ? ( + <> +

+ {it.value + ? {it.tag} + : Nessun override: il sito usa l'immagine originale.} +

+

+ + + +

+ + ) : ( + <> + {isLong(it.value) + ? + : } + {it.styleOptions.length > 0 && ( +

+ {it.styleOptions.map((sg) => ( + + ))} +

+ )} +

+ + )} + + {it.updated_by && ( +

Aggiornato {fmt.format(new Date(it.updated_at.replace(' ', 'T') + 'Z'))} da {it.updated_by}

+ )} +
+
+ ))} +
+ ); + })} +
+ +
+ + + +