"use client"; import { useEffect, useState } from "react"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import rehypeSlug from "rehype-slug"; import { FileText } from "lucide-react"; import { api } from "@/lib/api-client"; // Rendert SPEZIFIKATION.md (via /api/spec) als lesbares Dokument. Das Styling läuft über // die Klasse .md-doc in globals.css und folgt damit dem gewählten Farbschema. export function SpecView({ anchor }: { anchor?: string | null }) { const [markdown, setMarkdown] = useState(null); const [error, setError] = useState(null); useEffect(() => { api .get<{ markdown: string }>("/api/spec") .then((data) => setMarkdown(data.markdown)) .catch((e) => setError(e instanceof Error ? e.message : "Laden fehlgeschlagen.")); }, []); // Sprungmarke aus einem Rechenweg: erst nach dem Rendern des Markdowns existiert die // Überschrift mit der von rehype-slug erzeugten id. useEffect(() => { if (!anchor || markdown === null) return; const el = document.getElementById(anchor); if (el) el.scrollIntoView({ behavior: "smooth", block: "start" }); }, [anchor, markdown]); if (error) return

{error}

; if (markdown === null) return

Lädt…

; return (

Spezifikation

(
{children}
), }} > {markdown}
); }