Files
InsanityLab-web/src/layouts/Admin.astro
T
Adriano 03510d3940 Area riservata: menu essenziale e veste grafica del sito
Il menu in alto si riduce alle voci che servono davvero — Articoli,
Contenuti, Utenti, Sito, Esci — con la voce corrente evidenziata; ognuna
resta visibile solo a chi ha il ruolo per aprirla, e in pagina di login la
barra mostra il solo marchio. "Nuovo" esce dal menu perché il pulsante per
creare un articolo è già in cima all'elenco Articoli.

Il pannello smette di essere un foglio di stile a sé: adotta i font e la
palette del sito, come Campus e Stress Index, con tabelle, pulsanti, campi
e pillole di stato riportati allo stesso linguaggio.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 16:28:35 +02:00

141 lines
6.0 KiB
Plaintext

---
// Layout dell'area riservata. Usa i token e i font del sito, come il Campus e Stress Index:
// il pannello non è più un foglio di stile a sé, così chi passa dal sito all'amministrazione
// resta nello stesso mondo visivo.
import '@fontsource/montserrat/400.css';
import '@fontsource/montserrat/500.css';
import '@fontsource/montserrat/600.css';
import '@fontsource/open-sans/400.css';
import '@fontsource/open-sans/600.css';
import '../styles/global.css';
interface Props { title: string }
const { title } = Astro.props;
const user = Astro.locals.user;
const path = Astro.url.pathname;
const isManager = user?.role === 'superuser' || user?.role === 'admin';
// Voci del menu: ognuna compare solo a chi può davvero aprirla.
const VOCI = [
{ href: '/admin', label: 'Articoli', visibile: true, exact: true },
{ href: '/admin/content', label: 'Contenuti', visibile: isManager },
{ href: '/admin/users', label: 'Utenti', visibile: user?.role === 'admin' },
];
const attiva = (v: { href: string; exact?: boolean }) =>
v.exact ? path === v.href : path.startsWith(v.href);
---
<!doctype html>
<html lang="it">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{title} — Admin InsanityLab</title>
<meta name="robots" content="noindex" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
</head>
<body class="ad">
<header class="abar">
<a class="abar__brand" href="/admin">
<span class="abar__eyebrow">InsanityLab</span>
Area riservata
</a>
{user && (
<nav class="abar__nav" aria-label="pannello">
{VOCI.filter((v) => v.visibile).map((v) => (
<a href={v.href} class:list={['abar__link', { 'is-active': attiva(v) }]}>{v.label}</a>
))}
<a class="abar__link" href="/" target="_blank" rel="noopener">Sito</a>
<a class="abar__link abar__link--out" href="/admin/logout">Esci</a>
</nav>
)}
{user && <p class="abar__user">{user.username}</p>}
</header>
<main class="awrap"><slot /></main>
<style is:global>
body.ad { background: var(--c-bg-alt); }
/* --- barra --- */
.abar {
display: flex; align-items: center; gap: 28px; flex-wrap: wrap;
background: var(--c-dark); color: #cfc6bd; padding: 16px 32px;
}
.abar__brand {
font-family: var(--font-heading); font-size: 1rem; font-weight: 600; letter-spacing: .12em;
text-transform: uppercase; color: #fff; text-decoration: none; line-height: 1.15;
}
.abar__eyebrow { display: block; font-size: .62rem; letter-spacing: .2em; color: var(--c-accent); }
.abar__nav { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; }
.abar__link {
font-family: var(--font-heading); font-size: .72rem; font-weight: 600; letter-spacing: .16em;
text-transform: uppercase; color: #b6ada3; text-decoration: none; padding: 4px 0;
border-bottom: 1px solid transparent;
}
.abar__link:hover { color: #fff; }
.abar__link.is-active { color: #fff; border-bottom-color: var(--c-accent); }
.abar__link--out { color: var(--c-accent); }
.abar__user {
margin: 0 0 0 auto; font-size: .74rem; letter-spacing: .12em; text-transform: uppercase; color: #8d8379;
}
/* --- contenuto --- */
.awrap { max-width: 1080px; margin: 40px auto 80px; padding: 0 24px; }
.awrap h1 {
font-size: clamp(1.6rem, 3vw, 2.1rem); text-transform: none; letter-spacing: .02em; margin-bottom: .6em;
}
.awrap h2 { font-size: 1.15rem; text-transform: none; letter-spacing: .02em; }
/* --- comandi --- */
.abtn {
display: inline-block; background: var(--c-dark); color: #fff; border: 1px solid var(--c-dark);
padding: 10px 20px; cursor: pointer; text-decoration: none; font-family: var(--font-heading);
font-size: .7rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
}
.abtn:hover { background: var(--c-dark-2); border-color: var(--c-dark-2); }
.abtn--danger { background: none; color: #a4544a; border-color: #ddcfc9; }
.abtn--danger:hover { background: #a4544a; border-color: #a4544a; color: #fff; }
.afield {
width: 100%; padding: 11px 13px; margin-bottom: 14px; border: 1px solid #ddd6cb;
box-sizing: border-box; font: inherit; font-size: .92rem; background: #fff; border-radius: 0;
}
.afield:focus { outline: 2px solid var(--c-accent); outline-offset: -2px; }
/* --- tabelle --- */
table { width: 100%; border-collapse: collapse; background: #fff; border: 1px solid #e4dfd7; }
th, td { text-align: left; padding: 12px 14px; border-bottom: 1px solid #efeae2; font-size: .9rem; }
th {
font-family: var(--font-heading); font-size: .68rem; font-weight: 600; letter-spacing: .14em;
text-transform: uppercase; color: var(--c-text-light); background: #faf8f5;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: #faf8f5; }
td a { color: var(--c-accent-dark); font-weight: 600; text-decoration: none; }
td a:hover { text-decoration: underline; }
.pill {
display: inline-block; font-family: var(--font-heading); font-size: .64rem; font-weight: 600;
letter-spacing: .1em; text-transform: uppercase; padding: 3px 10px;
background: rgba(111,143,106,.16); color: #5f7c5a;
}
.pill--draft { background: rgba(192,138,62,.18); color: #96682a; }
.aform { max-width: 380px; background: #fff; border: 1px solid #e4dfd7; padding: 26px 24px; }
.form-msg { font-size: .88rem; margin-top: 8px; }
.form-msg--ok { color: #5f7c5a; }
.form-msg--err { color: #a4544a; }
@media (max-width: 720px) {
.abar { padding: 14px 20px; gap: 14px; }
.abar__nav { gap: 16px; width: 100%; }
.abar__user { margin-left: 0; }
.awrap { margin-top: 26px; padding: 0 20px; }
}
</style>
</body>
</html>