simplify knowledgebase articles

This commit is contained in:
overcuriousity
2025-07-26 13:20:01 +02:00
parent a9c15eb9c6
commit 4cc28bceb7
14 changed files with 1092 additions and 846 deletions

View File

@@ -26,20 +26,35 @@ 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');
// UPGRADED: Handle optional tool association
const primaryTool = entry.data.tool_name
? data.tools.find((t: any) => t.name === entry.data.tool_name)
: null;
// UPGRADED: Handle multiple related tools
const relatedTools = entry.data.related_tools
? entry.data.related_tools.map((toolName: string) =>
data.tools.find((t: any) => t.name === toolName)
).filter(Boolean)
: [];
// UPGRADED: Use primary tool or first related tool for styling, fallback to generic
const displayTool = primaryTool || relatedTools[0];
// UPGRADED: Don't redirect - show article even without tool association
if (!displayTool && !entry.data.tool_name && relatedTools.length === 0) {
console.log(`Standalone knowledgebase article: ${entry.slug}`);
}
// 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() !== "";
// Determine styling based on tool type or fallback to generic
const isMethod = displayTool?.type === 'method';
const isConcept = displayTool?.type === 'concept';
const isStandalone = !displayTool;
const hasValidProjectUrl = displayTool && displayTool.projectUrl !== undefined &&
displayTool.projectUrl !== null &&
displayTool.projectUrl !== "" &&
displayTool.projectUrl.trim() !== "";
---
<BaseLayout title={entry.data.title} description={entry.data.description}>
@@ -49,7 +64,7 @@ const hasValidProjectUrl = tool.projectUrl !== undefined &&
<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>}
{displayTool?.icon && <span style="margin-right: 0.75rem; font-size: 1.5rem;">{displayTool.icon}</span>}
{entry.data.title}
</h1>
<p style="margin: 0; color: var(--color-text-secondary); font-size: 1.125rem;">
@@ -58,32 +73,59 @@ const hasValidProjectUrl = tool.projectUrl !== undefined &&
</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>}
<!-- UPGRADED: Conditional badges based on tool type or standalone -->
{isStandalone ? (
<span class="badge" style="background-color: var(--color-accent); color: white;">Artikel</span>
) : (
<>
{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 && !isStandalone && <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 && !isStandalone && displayTool?.license !== 'Proprietary' && <span class="badge badge-success">Open Source</span>}
</>
)}
<span class="badge badge-error">📖</span>
</div>
</div>
</div>
<!-- Metadata -->
<!-- UPGRADED: Flexible metadata section -->
<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>
<!-- Difficulty (always shown if present) -->
{entry.data.difficulty && (
<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>
)}
<!-- Last Updated (always shown) -->
<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>
<!-- Author (always shown) -->
<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>
<!-- UPGRADED: Show article type -->
<div>
<strong style="font-size: 0.875rem; color: var(--color-text-secondary);">Typ</strong>
<p style="margin: 0; font-size: 0.9375rem;">
{isStandalone ? 'Allgemeiner Artikel' :
isConcept ? 'Konzept-Artikel' :
isMethod ? 'Methoden-Artikel' :
'Software-Artikel'}
</p>
</div>
<!-- UPGRADED: Categories (if present) -->
{entry.data.categories && entry.data.categories.length > 0 && (
<div>
<div style="grid-column: 1 / -1;">
<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) => (
@@ -105,57 +147,107 @@ const hasValidProjectUrl = tool.projectUrl !== undefined &&
</a>
</nav>
<!-- Content -->
<div class="card" style="padding: 2rem;">
<div class="kb-content markdown-content" style="line-height: 1.7;">
<Content />
<!-- Content -->
<div class="card" style="padding: 2rem;">
<div class="kb-content markdown-content" style="line-height: 1.7;">
<Content />
</div>
</div>
</div>
<!-- Tool Actions -->
<!-- UPGRADED: Flexible Tool Actions Section -->
<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>
<h3 style="margin: 0 0 1rem 0; color: var(--color-text);">
{isStandalone ? 'Verwandte Aktionen' : '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);">
{isStandalone ? (
<!-- UPGRADED: Standalone article actions -->
<a href="/knowledgebase" 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;">
<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"/>
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
<line x1="16" y1="13" x2="8" y2="13"/>
<line x1="16" y1="17" x2="8" y2="17"/>
<polyline points="10 9 9 9 8 9"/>
</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
Weitere Artikel
</a>
) : (
<!-- UPGRADED: Tool-specific actions (existing logic) -->
<>
<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">
{isConcept ? (
<a href={displayTool.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;">
<circle cx="12" cy="12" r="10"/>
<path d="M12 16l4-4-4-4"/>
<path d="M8 12h8"/>
<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>
Zugreifen
Mehr erfahren
</a>
) : isMethod ? (
<a href={displayTool.projectUrl || displayTool.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={displayTool.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={displayTool.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>
)}
</>
)}
</>
)}
<!-- UPGRADED: Show related tools if present -->
{relatedTools.length > 0 && relatedTools.length > (primaryTool ? 1 : 0) && (
<div style="margin-left: auto;">
<details style="position: relative;">
<summary class="btn btn-secondary" style="cursor: pointer; list-style: none;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
<path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
<circle cx="8.5" cy="7" r="4"/>
<line x1="20" y1="8" x2="20" y2="14"/>
<line x1="23" y1="11" x2="17" y2="11"/>
</svg>
Verwandte Tools ({relatedTools.length})
</summary>
<div style="position: absolute; top: 100%; left: 0; background: var(--color-bg); border: 1px solid var(--color-border); border-radius: 0.5rem; padding: 1rem; min-width: 200px; z-index: 100; box-shadow: var(--shadow-lg);">
{relatedTools.map((tool: any) => (
<a href={tool.projectUrl || tool.url} target="_blank" rel="noopener noreferrer"
style="display: block; padding: 0.5rem; border-radius: 0.25rem; text-decoration: none; color: var(--color-text); margin-bottom: 0.25rem;"
onmouseover="this.style.backgroundColor='var(--color-bg-secondary)'"
onmouseout="this.style.backgroundColor='transparent'">
{tool.icon && <span style="margin-right: 0.5rem;">{tool.icon}</span>}
{tool.name}
</a>
))}
</div>
</details>
</div>
)}
<!-- Always show return to main page -->
<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"/>
@@ -166,4 +258,4 @@ const hasValidProjectUrl = tool.projectUrl !== undefined &&
</div>
</div>
</article>
</BaseLayout>
</BaseLayout>