Inital commit of Astro Website

This commit is contained in:
2026-03-21 14:37:03 +01:00
commit bea1f0741d
60 changed files with 10838 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
---
import { getCollection, render } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
import BookNavigation from '../../components/BookNavigation.astro';
import "katex/dist/katex.min.css";
import "rehype-callouts/theme/obsidian";
import "../../styles/md-custom.css";
export async function getStaticPaths() {
const pages = await getCollection('book');
pages.sort((a, b) => a.id.localeCompare(b.id));
return pages.map((page, index) => {
return {
params: { slug: page.id },
props: {
page,
prevPage: index > 0 ? pages[index - 1] : null,
nextPage: index < pages.length - 1 ? pages[index + 1] : null,
allPages: pages
}
};
});
}
const { page, prevPage, nextPage, allPages } = Astro.props;
const { Content } = await render(page);
const chapters = allPages.reduce((acc, p) => {
const [chapter] = p.id.split('/');
if (!acc[chapter]) acc[chapter] = [];
acc[chapter].push(p);
return acc;
}, {} as Record<string, typeof allPages>);
---
<BaseLayout title={page.data.title} theme="book">
<div class="glass-container content prose">
<h1>{page.data.title}</h1>
<Content />
</div>
<BookNavigation
prevUrl={prevPage ? `/book/${prevPage.id}` : undefined}
prevTitle={prevPage?.data.title}
nextUrl={nextPage ? `/book/${nextPage.id}` : undefined}
nextTitle={nextPage?.data.title}
>
<div slot="toc" class="mini-toc">
{Object.entries(chapters).map(([chapter, items]) => (
<div class="mini-chapter">
<h4>{chapter.replace(/-/g, ' ').toUpperCase()}</h4>
<ul>
{items.map(item => (
<li>
<a
href={`/book/${item.id}`}
class={item.id === page.id ? 'active' : ''}
>
{item.data.title}
</a>
</li>
))}
</ul>
</div>
))}
</div>
</BookNavigation>
</BaseLayout>
<style>
.content {
line-height: 1.8;
padding: 2rem 3rem;
}
.mini-toc {
text-align: left;
}
.mini-chapter {
margin-bottom: 1rem;
}
.mini-chapter h4 {
margin: 0 0 0.5rem 0;
font-size: 0.9rem;
opacity: 0.7;
color: var(--text-main);
}
.mini-chapter ul {
list-style: none;
padding: 0;
margin: 0;
}
.mini-chapter li {
margin-bottom: 0.25rem;
}
.mini-chapter a {
display: block;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
font-size: 0.95rem;
color: var(--text-muted);
text-decoration: none;
}
.mini-chapter a:hover {
background: rgba(var(--accent-base), 0.1);
color: rgb(var(--accent-base));
}
.mini-chapter a.active {
background: rgba(var(--accent-base), 0.2);
color: rgb(var(--accent-base));
font-weight: 600;
}
</style>

View File

@@ -0,0 +1,44 @@
---
import { getCollection } from 'astro:content';
import BaseLayout from '../../layouts/BaseLayout.astro';
const pages = await getCollection('book');
pages.sort((a, b) => a.data.part - b.data.part);
const chapters = pages.reduce((acc, page) => {
const chapter = page.data.chapter["id"];
if (!acc[chapter]) acc[chapter] = [];
acc[chapter].push(page);
return acc;
}, {} as Record<string, typeof pages>);
---
<BaseLayout title="Das Buch" theme="book" description="Ein fortlaufendes Werk über Software, Design und Architektur von c0ntroller.de.">
<div class="glass-container header">
<h1>Das Buch</h1>
<p>Ein fortlaufendes Werk über Software, Design und Architektur.</p>
</div>
<div class="glass-container toc">
<h2>Inhaltsverzeichnis</h2>
{Object.entries(chapters).map(([chapter, items]) => (
<div class="chapter">
<h3>{chapter.replace(/-/g, ' ').toUpperCase()}</h3>
<ul class="page-list">
{items.map(item => (
<li><a href={`/book/${item.id}`}>{item.data.title}</a></li>
))}
</ul>
</div>
))}
</div>
</BaseLayout>
<style>
.header { margin-bottom: 2rem; }
.toc { padding: 2rem; }
.chapter { margin-bottom: 1.5rem; }
.chapter h3 { margin-top: 0; margin-bottom: 0.5rem; font-size: 1.1rem; opacity: 0.8; }
.page-list { list-style: none; padding-left: 0; margin: 0; }
.page-list li { margin-bottom: 0.5rem; }
.page-list a { display: block; padding: 0.5rem; border-radius: 0.25rem; transition: background 0.2s; }
.page-list a:hover { background: rgba(59, 130, 246, 0.1); }
</style>