feat(glossaire): enrich entries and refine glossary navigation
This commit is contained in:
223
src/pages/glossaire/index-complet.astro
Normal file
223
src/pages/glossaire/index-complet.astro
Normal file
@@ -0,0 +1,223 @@
|
||||
---
|
||||
import SiteLayout from "../../layouts/SiteLayout.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
const entries = await getCollection("glossaire");
|
||||
|
||||
const slugOf = (entry) => String(entry.id).replace(/\.(md|mdx)$/i, "");
|
||||
const hrefOf = (entry) => `/glossaire/${slugOf(entry)}/`;
|
||||
|
||||
const collator = new Intl.Collator("fr", { sensitivity: "base", numeric: true });
|
||||
|
||||
const kindLabels = {
|
||||
concept: "Concept",
|
||||
diagnostic: "Diagnostic",
|
||||
topologie: "Topologie",
|
||||
verbe: "Verbe",
|
||||
paradigme: "Paradigme",
|
||||
doctrine: "Doctrine",
|
||||
};
|
||||
|
||||
const domainLabels = {
|
||||
transversal: "Transversal",
|
||||
theorie: "Théorie",
|
||||
"cas-ia": "Cas IA",
|
||||
};
|
||||
|
||||
const levelLabels = {
|
||||
fondamental: "Fondamental",
|
||||
intermediaire: "Intermédiaire",
|
||||
avance: "Avancé",
|
||||
};
|
||||
|
||||
const sorted = [...entries].sort((a, b) => collator.compare(a.data.term, b.data.term));
|
||||
|
||||
function groupByInitial(list) {
|
||||
const map = new Map();
|
||||
|
||||
for (const entry of list) {
|
||||
const letter = (entry.data.term || "").trim().charAt(0).toUpperCase() || "#";
|
||||
if (!map.has(letter)) map.set(letter, []);
|
||||
map.get(letter).push(entry);
|
||||
}
|
||||
|
||||
return [...map.entries()].sort((a, b) => collator.compare(a[0], b[0]));
|
||||
}
|
||||
|
||||
const groupedAlpha = groupByInitial(sorted);
|
||||
---
|
||||
|
||||
<SiteLayout title="Index complet du glossaire">
|
||||
<section class="glossary-index-page">
|
||||
<header class="glossary-index-page__hero">
|
||||
<p class="glossary-index-page__kicker">Référentiel terminologique</p>
|
||||
<h1>Index complet du glossaire</h1>
|
||||
<p class="glossary-index-page__intro">
|
||||
Cette page rassemble l’ensemble des entrées du glossaire dans un ordre alphabétique intégral.
|
||||
Elle complète l’accueil conceptuel du glossaire par une navigation plus encyclopédique.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="glossary-index-page__topbar">
|
||||
<a class="glossary-index-page__back" href="/glossaire/">← Retour à l’accueil du glossaire</a>
|
||||
|
||||
<nav class="glossary-index-page__letters" aria-label="Lettres de l’index">
|
||||
{groupedAlpha.map(([letter]) => (
|
||||
<a href={`#letter-${letter}`}>{letter}</a>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<div class="glossary-index-page__groups">
|
||||
{groupedAlpha.map(([letter, items]) => (
|
||||
<section class="glossary-index-page__group" id={`letter-${letter}`}>
|
||||
<h2>{letter}</h2>
|
||||
<ul class="glossary-index-page__list">
|
||||
{items.map((entry) => (
|
||||
<li class="glossary-index-page__item">
|
||||
<a class="glossary-index-page__term" href={hrefOf(entry)}>
|
||||
{entry.data.term}
|
||||
</a>
|
||||
<p class="glossary-index-page__def">{entry.data.definitionShort}</p>
|
||||
<p class="glossary-index-page__meta">
|
||||
<span>{kindLabels[entry.data.kind] ?? entry.data.kind}</span>
|
||||
<span>{domainLabels[entry.data.domain] ?? entry.data.domain}</span>
|
||||
<span>{levelLabels[entry.data.level] ?? entry.data.level}</span>
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
</SiteLayout>
|
||||
|
||||
<style>
|
||||
.glossary-index-page{
|
||||
padding: 8px 0 32px;
|
||||
}
|
||||
|
||||
.glossary-index-page__hero{
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
|
||||
.glossary-index-page__kicker{
|
||||
margin: 0 0 8px;
|
||||
font-size: 12px;
|
||||
letter-spacing: .08em;
|
||||
text-transform: uppercase;
|
||||
opacity: .72;
|
||||
}
|
||||
|
||||
.glossary-index-page__hero h1{
|
||||
margin: 0 0 12px;
|
||||
font-size: clamp(2.2rem, 4vw, 3rem);
|
||||
line-height: 1.05;
|
||||
letter-spacing: -.03em;
|
||||
}
|
||||
|
||||
.glossary-index-page__intro{
|
||||
max-width: 76ch;
|
||||
margin: 0;
|
||||
opacity: .92;
|
||||
}
|
||||
|
||||
.glossary-index-page__topbar{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
margin: 22px 0 28px;
|
||||
}
|
||||
|
||||
.glossary-index-page__back{
|
||||
display: inline-flex;
|
||||
width: fit-content;
|
||||
align-items: center;
|
||||
border: 1px solid rgba(127,127,127,0.28);
|
||||
border-radius: 999px;
|
||||
padding: 7px 14px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.glossary-index-page__letters{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.glossary-index-page__letters a{
|
||||
min-width: 34px;
|
||||
text-align: center;
|
||||
border: 1px solid rgba(127,127,127,0.24);
|
||||
border-radius: 10px;
|
||||
padding: 5px 8px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.glossary-index-page__groups{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 28px;
|
||||
}
|
||||
|
||||
.glossary-index-page__group{
|
||||
scroll-margin-top: calc(var(--sticky-offset) + 20px);
|
||||
}
|
||||
|
||||
.glossary-index-page__group h2{
|
||||
margin: 0 0 14px;
|
||||
font-size: clamp(1.6rem, 2vw, 2rem);
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.glossary-index-page__list{
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.glossary-index-page__item{
|
||||
border: 1px solid rgba(127,127,127,0.20);
|
||||
border-radius: 16px;
|
||||
padding: 14px 16px;
|
||||
background: rgba(127,127,127,0.04);
|
||||
}
|
||||
|
||||
.glossary-index-page__term{
|
||||
display: inline-block;
|
||||
font-weight: 800;
|
||||
font-size: 1.04rem;
|
||||
text-decoration: none;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.glossary-index-page__def{
|
||||
margin: 0 0 8px;
|
||||
line-height: 1.5;
|
||||
opacity: .94;
|
||||
}
|
||||
|
||||
.glossary-index-page__meta{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
opacity: .78;
|
||||
}
|
||||
|
||||
.glossary-index-page__meta span{
|
||||
border: 1px solid rgba(127,127,127,0.20);
|
||||
border-radius: 999px;
|
||||
padding: 2px 8px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark){
|
||||
.glossary-index-page__item{
|
||||
background: rgba(255,255,255,0.04);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user