deuxième aventure
This commit is contained in:
152
src/pages/codex/[...slug].astro
Normal file
152
src/pages/codex/[...slug].astro
Normal file
@@ -0,0 +1,152 @@
|
||||
---
|
||||
import { getCollection, type CollectionEntry } from "astro:content";
|
||||
import GameLayout from "../../layouts/GameLayout.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const codexEntries = await getCollection("codex");
|
||||
return codexEntries.map((entry) => ({
|
||||
params: { slug: entry.slug },
|
||||
}));
|
||||
}
|
||||
|
||||
const { slug } = Astro.params;
|
||||
const codexEntries = await getCollection("codex");
|
||||
|
||||
const entry = codexEntries.find((entry) => entry.slug === slug);
|
||||
|
||||
if (!entry) {
|
||||
return Astro.redirect("/404");
|
||||
}
|
||||
|
||||
const { Content } = await entry.render();
|
||||
---
|
||||
|
||||
<GameLayout title={entry.data.title}>
|
||||
<main class="codex-entry-container">
|
||||
<article class="parchment-card">
|
||||
<div class="header">
|
||||
<h1>{entry.data.title}</h1>
|
||||
<h2>{entry.data.subtitle}</h2>
|
||||
<p class="publish-date">
|
||||
Savoir acquis le : {
|
||||
entry.data.publishDate.toLocaleDateString("fr-FR", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
})
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="transmutation-table">
|
||||
<div class="table-row header">
|
||||
<div class="col-title">Ancien Monde (2D)</div>
|
||||
<div class="col-title">Mécanique</div>
|
||||
<div class="col-title">Monde de Demain (3D)</div>
|
||||
</div>
|
||||
<div class="table-row">
|
||||
<div>{entry.data.concept2D}</div>
|
||||
<div>{entry.data.mecanique}</div>
|
||||
<div>{entry.data.vision3D}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{entry.data.tags && (
|
||||
<div class="tags-container">
|
||||
{entry.data.tags.map((tag) => (
|
||||
<a href={`/codex/tags/${tag.toLowerCase()}`} class="tag">{tag}</a>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div class="prose">
|
||||
<Content />
|
||||
</div>
|
||||
|
||||
<a href="/codex" class="back-link"> ← Retourner au Codex </a>
|
||||
</article>
|
||||
</main>
|
||||
</GameLayout>
|
||||
|
||||
<style>
|
||||
.codex-entry-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
|
||||
.parchment-card {
|
||||
background: linear-gradient(145deg, #fefbf3, #f8f1e4);
|
||||
border: 2px solid #dcd0b9;
|
||||
border-radius: 15px;
|
||||
padding: 2rem 3rem;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.header {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.header h1 {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.header h2 {
|
||||
font-family: "EB Garamond", serif;
|
||||
font-style: italic;
|
||||
font-size: 1.4rem;
|
||||
color: #4a4130;
|
||||
margin-top: 0;
|
||||
}
|
||||
/* On retire l'ornement pour le h2 de la carte */
|
||||
.header h2::after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
.publish-date {
|
||||
font-style: italic;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.transmutation-table {
|
||||
margin: 2rem 0;
|
||||
font-size: 0.9rem;
|
||||
background-color: rgba(253, 246, 232, 0.5);
|
||||
border: 1px solid #dcd0b9;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1.5fr 1.5fr;
|
||||
gap: 1rem;
|
||||
padding: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
.table-row.header {
|
||||
background-color: rgba(220, 208, 185, 0.4);
|
||||
}
|
||||
|
||||
.table-row:not(.header) {
|
||||
border-top: 1px solid #dcd0b9;
|
||||
}
|
||||
|
||||
.col-title {
|
||||
font-family: "Cinzel", serif;
|
||||
font-weight: bold;
|
||||
color: #4a4130;
|
||||
}
|
||||
|
||||
.back-link {
|
||||
display: inline-block;
|
||||
margin-top: 3rem;
|
||||
font-family: "Cinzel", serif;
|
||||
color: #b8860b;
|
||||
text-decoration: none;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.back-link:hover {
|
||||
transform: translateX(-5px);
|
||||
}
|
||||
</style>
|
||||
28
src/pages/codex/index.astro
Normal file
28
src/pages/codex/index.astro
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import GameLayout from "../../layouts/GameLayout.astro";
|
||||
import ContentSearch from "../../components/ContentSearch.astro";
|
||||
|
||||
// 1. Récupérer toutes les entrées du codex
|
||||
const codexEntries = await getCollection("codex");
|
||||
|
||||
// 2. Trier les entrées par date de publication
|
||||
const sortedEntries = codexEntries.sort(
|
||||
(a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf()
|
||||
);
|
||||
|
||||
// 3. Extraire tous les domaines uniques pour les catégories
|
||||
const allDomains = [...new Set(codexEntries.map(entry => entry.data.domain))];
|
||||
---
|
||||
|
||||
<GameLayout title="Codex de la Substance">
|
||||
<h1>Le Codex de la Substance</h1>
|
||||
<p style="text-align: center; margin-bottom: 3rem;">
|
||||
Le laboratoire où le pèlerin dissèque les mécanismes du réel (le code)
|
||||
pour insuffler le "souffle de vie" (Hebel) à ses créations.
|
||||
</p>
|
||||
|
||||
<!-- On passe les entrées, les domaines (en tant que tags) et le chemin de base au composant de recherche -->
|
||||
<ContentSearch posts={sortedEntries} tags={allDomains} basePath="codex" />
|
||||
|
||||
</GameLayout>
|
||||
38
src/pages/codex/tag/[tag].astro
Normal file
38
src/pages/codex/tag/[tag].astro
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import GameLayout from "../../../layouts/GameLayout.astro";
|
||||
import CodexCard from "../../../components/ui/CodexCard.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const allCodexEntries = await getCollection("codex");
|
||||
const allTags = allCodexEntries.flatMap((entry) => entry.data.tags);
|
||||
const uniqueTags = [...new Set(allTags)];
|
||||
|
||||
return uniqueTags.map((tag) => {
|
||||
return {
|
||||
params: { tag: tag.toLowerCase() },
|
||||
props: { tag },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const { tag } = Astro.props;
|
||||
|
||||
const allCodexEntries = await getCollection("codex");
|
||||
|
||||
const filteredEntries = allCodexEntries.filter((entry) =>
|
||||
entry.data.tags.map(t => t.toLowerCase()).includes(Astro.params.tag)
|
||||
);
|
||||
---
|
||||
|
||||
<GameLayout title={`Domaine : ${tag}`}>
|
||||
<main class="codex-container">
|
||||
<h1>Domaine : {tag}</h1>
|
||||
<p>
|
||||
Liste de tous les savoirs et mécaniques liés au domaine "{tag}".
|
||||
</p>
|
||||
<div class="card-grid">
|
||||
{filteredEntries.map((entry) => <CodexCard entry={entry} />)}
|
||||
</div>
|
||||
</main>
|
||||
</GameLayout>
|
||||
Reference in New Issue
Block a user