'use client'; export const runtime = 'edge'; // Mira Wiki 單篇頁 // SDD: polaris/mira/.agents/specs/mira-app/design.md §5.2 + §3.5.7 // 對應 task: 7C.2 // 路由:/mira/wiki/[pageName] // 顯示單一 wiki block + 它的 children(wiki-paragraph) import { useEffect, useState, use } from 'react'; import Link from 'next/link'; import { MarkdownView } from '../../_shared/markdown'; import '../../mira.css'; const KBDB_BASE = 'https://kbdb.finally.click'; const API_BASE = process.env.NEXT_PUBLIC_API_BASE ?? 'https://cypher.arcrun.dev'; type Block = { id: string; page_name: string; content: string; type: string; parent_id: string | null; tags_json: string | null; created_at: number; updated_at: number; }; export default function WikiPagePage({ params, }: { params: Promise<{ pageName: string }>; }) { const { pageName } = use(params); const decodedName = decodeURIComponent(pageName); const [block, setBlock] = useState(null); const [siblings, setSiblings] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; async function load() { try { const meRes = await fetch(`${API_BASE}/me`, { credentials: 'include' }); if (!meRes.ok) throw new Error('未登入'); const me = (await meRes.json()) as { api_key: string }; const headers = { Authorization: `Bearer ${me.api_key}` }; const res = await fetch( `${KBDB_BASE}/blocks?page_name=${encodeURIComponent(decodedName)}&limit=1`, { headers }, ); if (!res.ok) throw new Error(`KBDB ${res.status}`); const data = await res.json(); const found: Block | undefined = data.blocks?.[0]; if (cancelled) return; if (!found) { setError(`找不到 wiki page:${decodedName}`); return; } setBlock(found); // 若這是個 child block,撈 parent 下其他 siblings 給導航用 if (found.parent_id) { // KBDB 沒 children endpoint,用 page_name 找不到 siblings;先略過 setSiblings([]); } } catch (e: any) { if (!cancelled) setError(e?.message ?? 'load failed'); } finally { if (!cancelled) setLoading(false); } } load(); return () => { cancelled = true; }; }, [decodedName]); const tags = parseTags(block?.tags_json); const subtype = tags .find((t) => t.startsWith('subtype:')) ?.replace('subtype:', ''); return (
← Wiki 索引

{decodedName}

{subtype && (
subtype: {subtype}
)}
{loading &&
載入中⋯
} {error && (
{error}
)} {block && !loading && !error && ( <>
{/* 7C.3 contribution log placeholder(此頁是 schema/index/log infra 而非 wiki-page,先不顯示) */} )}
); } function parseTags(tags_json: string | null | undefined): string[] { if (!tags_json) return []; try { return JSON.parse(tags_json) as string[]; } catch { return []; } }