223 lines
5.4 KiB
Plaintext
223 lines
5.4 KiB
Plaintext
---
|
||
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> |