Longevity: nessuna pagina senza uscita (#10)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-26 13:48:42 +00:00
4 changed files with 50 additions and 2 deletions
@@ -14,6 +14,7 @@ import '@fontsource/open-sans/400.css';
import '@fontsource/open-sans/600.css'; import '@fontsource/open-sans/600.css';
import '../styles/global.css'; import '../styles/global.css';
import '../styles/longevity.css'; import '../styles/longevity.css';
import { codicePerUtenteLoggato } from '../lib/longevity/anagrafica';
interface Props { interface Props {
title: string; title: string;
@@ -25,6 +26,13 @@ interface Props {
const { title, crumbs = [], variante = 'referto' } = Astro.props; const { title, crumbs = [], variante = 'referto' } = Astro.props;
const path = Astro.url.pathname; const path = Astro.url.pathname;
// Nessuna pagina di Longevity deve lasciare l'utente senza un'uscita (#10): il gestionale
// mostra "Il mio referto" solo a chi ha davvero un fascicolo, e il referto porta sempre
// un link fuori dalla piattaforma (più uno al gestionale, per lo staff).
const user = Astro.locals.user;
const staff = user?.role === 'admin' || user?.role === 'trainer';
const haFascicolo = user ? codicePerUtenteLoggato(user.id) !== null : false;
// Le voci della barra laterale del gestionale: nasce con due pagine, non le sette di // Le voci della barra laterale del gestionale: nasce con due pagine, non le sette di
// Stress Index — un elenco più lungo arriverà con gli sviluppi futuri (#3, #7, #8). // Stress Index — un elenco più lungo arriverà con gli sviluppi futuri (#3, #7, #8).
const NAV_GESTIONALE = [ const NAV_GESTIONALE = [
@@ -58,7 +66,9 @@ const NAV_GESTIONALE = [
{item.label} {item.label}
</a> </a>
))} ))}
{haFascicolo && (
<a class="lg-nav__link lg-nav__link--referto" href="/longevity/io">Il mio referto</a> <a class="lg-nav__link lg-nav__link--referto" href="/longevity/io">Il mio referto</a>
)}
</nav> </nav>
</aside> </aside>
<div class="lg-body"> <div class="lg-body">
@@ -78,6 +88,10 @@ const NAV_GESTIONALE = [
<strong>Longevity</strong> <strong>Longevity</strong>
{crumbs.map((c) => <span> / {c}</span>)} {crumbs.map((c) => <span> / {c}</span>)}
</p> </p>
<p class="lg-top__links">
{staff && <a class="lg-top__link" href="/longevity/gestionale">← Gestionale</a>}
<a class="lg-top__link" href="/piattaforme">Piattaforme</a>
</p>
</header> </header>
<main class="lg-main"><slot /></main> <main class="lg-main"><slot /></main>
</div> </div>
+11 -1
View File
@@ -22,7 +22,17 @@ const referto = sessioneId !== null ? refertoDi(db, sessioneId) : null;
<Longevity title="Il tuo referto" crumbs={['Il tuo referto']}> <Longevity title="Il tuo referto" crumbs={['Il tuo referto']}>
{!codice && ( {!codice && (
<div class="lg-card"> <div class="lg-card">
<p>Nessun fascicolo è ancora collegato al tuo account. Contatta lo staff InsanityLab.</p> {user.role === 'admin' || user.role === 'trainer' ? (
<p>
Il tuo account è da staff: non ha un fascicolo personale.
<a href="/longevity/gestionale">Torna al gestionale</a>.
</p>
) : (
<p>
Nessun fascicolo è ancora collegato al tuo account. Contatta lo staff InsanityLab.
<a href="/piattaforme">Torna alle piattaforme</a>.
</p>
)}
</div> </div>
)} )}
+11
View File
@@ -43,6 +43,11 @@
top: 0; top: 0;
z-index: 10; z-index: 10;
background: var(--lg-surface); background: var(--lg-surface);
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 6px 20px;
} }
.lg-top p { margin: 0; } .lg-top p { margin: 0; }
.lg-top__crumbs { .lg-top__crumbs {
@@ -50,6 +55,12 @@
text-transform: uppercase; color: var(--c-text-light); text-transform: uppercase; color: var(--c-text-light);
} }
.lg-top__crumbs strong { color: var(--c-heading); font-weight: 600; } .lg-top__crumbs strong { color: var(--c-heading); font-weight: 600; }
.lg-top__links { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.lg-top__link {
font-family: var(--font-heading); font-size: .74rem; font-weight: 600; letter-spacing: .1em;
text-transform: uppercase; color: var(--c-text-light); text-decoration: none;
}
.lg-top__link:hover { color: var(--c-heading); }
.lg-main { flex: 1; padding: 34px 32px 70px; } .lg-main { flex: 1; padding: 34px 32px 70px; }
@@ -13,6 +13,19 @@ describe('il guscio della piattaforma', () => {
expect(l).toMatch(/noindex/); // area riservata: mai indicizzata expect(l).toMatch(/noindex/); // area riservata: mai indicizzata
}); });
it('nessuna pagina Longevity e senza uscita (#10): il referto porta sempre a Piattaforme, e a Gestionale per lo staff', () => {
const l = leggi('src/layouts/Longevity.astro');
expect(l).toMatch(/href=["']\/piattaforme["']/);
expect(l).toMatch(/href=["']\/longevity\/gestionale["']/);
// "Il mio referto" nel gestionale va mostrato solo a chi ha davvero un fascicolo.
expect(l).toMatch(/haFascicolo &&/);
});
it('io.astro offre un uscita al gestionale per chi non ha un fascicolo (staff)', () => {
const src = leggi('src/pages/longevity/io.astro');
expect(src).toMatch(/href=["']\/longevity\/gestionale["']/);
});
it('il foglio di stile e globale e prefissato, non scoped', () => { it('il foglio di stile e globale e prefissato, non scoped', () => {
expect(existsSync(join(process.cwd(), 'src/styles/longevity.css'))).toBe(true); expect(existsSync(join(process.cwd(), 'src/styles/longevity.css'))).toBe(true);
const css = leggi('src/styles/longevity.css'); const css = leggi('src/styles/longevity.css');