knowledgebase overhaul
This commit is contained in:
169
src/pages/knowledgebase/[slug].astro
Normal file
169
src/pages/knowledgebase/[slug].astro
Normal file
@@ -0,0 +1,169 @@
|
||||
---
|
||||
import { getCollection } from 'astro:content';
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||
import { getToolsData } from '../../utils/dataService.js';
|
||||
|
||||
// Prerender these pages at build time
|
||||
export const prerender = true;
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const knowledgebaseEntries = await getCollection('knowledgebase');
|
||||
|
||||
console.log('Building static paths for:', knowledgebaseEntries.map(e => e.slug));
|
||||
|
||||
return knowledgebaseEntries.map((entry) => {
|
||||
return {
|
||||
params: { slug: entry.slug },
|
||||
props: { entry },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const { entry }: { entry: any } = Astro.props;
|
||||
|
||||
// Render the content
|
||||
const { Content } = await entry.render();
|
||||
|
||||
// Load tools data to get the tool details
|
||||
const data = await getToolsData();
|
||||
const tool = data.tools.find((t: any) => t.name === entry.data.tool_name);
|
||||
|
||||
if (!tool) {
|
||||
console.warn(`Tool not found for knowledgebase entry: ${entry.data.tool_name}`);
|
||||
return Astro.redirect('/knowledgebase');
|
||||
}
|
||||
|
||||
// Determine tool type for styling
|
||||
const isMethod = tool.type === 'method';
|
||||
const isConcept = tool.type === 'concept';
|
||||
const hasValidProjectUrl = tool.projectUrl !== undefined &&
|
||||
tool.projectUrl !== null &&
|
||||
tool.projectUrl !== "" &&
|
||||
tool.projectUrl.trim() !== "";
|
||||
---
|
||||
|
||||
<BaseLayout title={entry.data.title} description={entry.data.description}>
|
||||
<article style="max-width: 900px; margin: 0 auto;">
|
||||
<!-- Header -->
|
||||
<header style="margin-bottom: 2rem; padding: 2rem; background: linear-gradient(135deg, var(--color-bg-secondary) 0%, var(--color-bg-tertiary) 100%); border-radius: 1rem; border: 1px solid var(--color-border);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 1rem;">
|
||||
<div style="flex: 1;">
|
||||
<h1 style="margin: 0 0 0.5rem 0; color: var(--color-primary);">
|
||||
{tool.icon && <span style="margin-right: 0.75rem; font-size: 1.5rem;">{tool.icon}</span>}
|
||||
{entry.data.title}
|
||||
</h1>
|
||||
<p style="margin: 0; color: var(--color-text-secondary); font-size: 1.125rem;">
|
||||
{entry.data.description}
|
||||
</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; gap: 0.5rem; align-items: end;">
|
||||
<div style="display: flex; gap: 0.5rem; flex-wrap: wrap;">
|
||||
{isConcept && <span class="badge" style="background-color: var(--color-concept); color: white;">Konzept</span>}
|
||||
{isMethod && <span class="badge" style="background-color: var(--color-method); color: white;">Methode</span>}
|
||||
{!isMethod && !isConcept && <span class="badge" style="background-color: var(--color-primary); color: white;">Software</span>}
|
||||
{!isMethod && !isConcept && hasValidProjectUrl && <span class="badge badge-primary">CC24-Server</span>}
|
||||
{!isMethod && !isConcept && tool.license !== 'Proprietary' && <span class="badge badge-success">Open Source</span>}
|
||||
<span class="badge badge-error">📖</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Metadata -->
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid var(--color-border);">
|
||||
<div>
|
||||
<strong style="font-size: 0.875rem; color: var(--color-text-secondary);">Schwierigkeit</strong>
|
||||
<p style="margin: 0; font-size: 0.9375rem;">{entry.data.difficulty}</p>
|
||||
</div>
|
||||
<div>
|
||||
<strong style="font-size: 0.875rem; color: var(--color-text-secondary);">Letztes Update</strong>
|
||||
<p style="margin: 0; font-size: 0.9375rem;">{entry.data.last_updated.toLocaleDateString('de-DE')}</p>
|
||||
</div>
|
||||
<div>
|
||||
<strong style="font-size: 0.875rem; color: var(--color-text-secondary);">Autor</strong>
|
||||
<p style="margin: 0; font-size: 0.9375rem;">{entry.data.author}</p>
|
||||
</div>
|
||||
{entry.data.categories && entry.data.categories.length > 0 && (
|
||||
<div>
|
||||
<strong style="font-size: 0.875rem; color: var(--color-text-secondary);">Kategorien</strong>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 0.25rem; margin-top: 0.25rem;">
|
||||
{entry.data.categories.map((cat: string) => (
|
||||
<span class="tag" style="font-size: 0.75rem;">{cat}</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav style="margin-bottom: 2rem; position: relative; z-index: 50;">
|
||||
<a href="/knowledgebase" class="btn btn-secondary">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
|
||||
<polyline points="15,18 9,12 15,6"></polyline>
|
||||
</svg>
|
||||
Zurück zur Knowledgebase
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="card" style="padding: 2rem;">
|
||||
<div class="kb-content markdown-content" style="line-height: 1.7;">
|
||||
<Content />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tool Actions -->
|
||||
<div class="card" style="margin-top: 2rem; background-color: var(--color-bg-secondary);">
|
||||
<h3 style="margin: 0 0 1rem 0; color: var(--color-text);">Tool-Aktionen</h3>
|
||||
<div style="display: flex; gap: 1rem; flex-wrap: wrap;">
|
||||
{isConcept ? (
|
||||
<a href={tool.url} target="_blank" rel="noopener noreferrer" class="btn btn-primary" style="background-color: var(--color-concept); border-color: var(--color-concept);">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
|
||||
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
|
||||
<polyline points="15 3 21 3 21 9"/>
|
||||
<line x1="10" y1="14" x2="21" y2="3"/>
|
||||
</svg>
|
||||
Mehr erfahren
|
||||
</a>
|
||||
) : isMethod ? (
|
||||
<a href={tool.projectUrl || tool.url} target="_blank" rel="noopener noreferrer" class="btn btn-primary" style="background-color: var(--color-method); border-color: var(--color-method);">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
|
||||
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
|
||||
<polyline points="15 3 21 3 21 9"/>
|
||||
<line x1="10" y1="14" x2="21" y2="3"/>
|
||||
</svg>
|
||||
Zur Methode
|
||||
</a>
|
||||
) : (
|
||||
<>
|
||||
<a href={tool.url} target="_blank" rel="noopener noreferrer" class="btn btn-secondary">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
|
||||
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>
|
||||
<polyline points="15 3 21 3 21 9"/>
|
||||
<line x1="10" y1="14" x2="21" y2="3"/>
|
||||
</svg>
|
||||
Software-Homepage
|
||||
</a>
|
||||
{hasValidProjectUrl && (
|
||||
<a href={tool.projectUrl} target="_blank" rel="noopener noreferrer" class="btn btn-primary">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<path d="M12 16l4-4-4-4"/>
|
||||
<path d="M8 12h8"/>
|
||||
</svg>
|
||||
Zugreifen
|
||||
</a>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<a href="/" class="btn btn-secondary">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
|
||||
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>
|
||||
<polyline points="9,22 9,12 15,12 15,22"/>
|
||||
</svg>
|
||||
Zur Hauptseite
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</BaseLayout>
|
||||
Reference in New Issue
Block a user