61 lines
2.2 KiB
TypeScript
61 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import ReactMarkdown from "react-markdown";
|
|
|
|
import { Button } from "@/components/ui/button";
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { Input } from "@/components/ui/input";
|
|
import type { WikiPageSummary } from "@/lib/types";
|
|
|
|
export function WikiView({
|
|
pages,
|
|
initialPageContent,
|
|
}: {
|
|
pages: WikiPageSummary[];
|
|
initialPageContent: { title: string; content: string } | null;
|
|
}) {
|
|
const [activeTitle, setActiveTitle] = useState(initialPageContent?.title || "Select a page");
|
|
const [activeContent, setActiveContent] = useState(initialPageContent?.content || "");
|
|
const [filter, setFilter] = useState("");
|
|
|
|
const filteredPages = pages.filter((page) =>
|
|
filter.length === 0 ? true : page.title.toLowerCase().includes(filter.toLowerCase()),
|
|
);
|
|
|
|
async function openPage(filename: string) {
|
|
const response = await fetch(`/api/wiki/${filename}`);
|
|
const page = await response.json();
|
|
setActiveTitle(page.metadata.title);
|
|
setActiveContent(page.content);
|
|
}
|
|
|
|
return (
|
|
<div className="grid gap-6 lg:grid-cols-[280px_minmax(0,1fr)]">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Wiki Pages</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-3">
|
|
<Input placeholder="Search wiki" value={filter} onChange={(event) => setFilter(event.target.value)} />
|
|
<div className="space-y-2">
|
|
{filteredPages.map((page) => (
|
|
<Button className="w-full justify-start" key={page.filename} variant="ghost" onClick={() => openPage(page.filename)}>
|
|
{page.title}
|
|
</Button>
|
|
))}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>{activeTitle}</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="prose prose-invert max-w-none prose-pre:rounded-xl prose-pre:border prose-pre:border-white/10 prose-pre:bg-slate-950/70">
|
|
{activeContent ? <ReactMarkdown>{activeContent}</ReactMarkdown> : <p className="text-slate-400">Select a wiki page to view it.</p>}
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|