66 lines
1.8 KiB
TypeScript
66 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { TTCMD, TTCMDRenderer } from "@/components/ttcmd";
|
|
import { extractFrontMatter } from "@/lib/tcmd";
|
|
import { FC, use, useCallback, useEffect, useState } from "react";
|
|
|
|
export const HelpClient: FC<{ body: Promise<string>; title: string }> = ({
|
|
body: bodyPromise,
|
|
title,
|
|
}) => {
|
|
const body = use(bodyPromise);
|
|
const [toc, setToc] = useState<Token[]>();
|
|
const escapeTOC = useCallback((t: Token[]) => {
|
|
setToc(t);
|
|
return true;
|
|
}, []);
|
|
|
|
const [frontMatter, setFrontMatter] = useState<FrontMatter>({});
|
|
const [cleanBody, setBody] = useState<string>("");
|
|
|
|
useEffect(() => {
|
|
if (!body) return;
|
|
|
|
const [frontmatter, clean] = extractFrontMatter(body);
|
|
setFrontMatter(frontmatter);
|
|
setBody(clean);
|
|
}, [body]);
|
|
|
|
return (
|
|
<>
|
|
<section className="heading">
|
|
<h2 className="strapline">Help</h2>
|
|
<h1>{frontMatter.title || decodeURIComponent(title)}</h1>
|
|
<div className="text-white/50">
|
|
{!!frontMatter.date && (
|
|
<div className="text-white/50">
|
|
Published: {frontMatter.date}
|
|
{!!frontMatter.updated && (
|
|
<span className="text-white/50">
|
|
, Last updated: {frontMatter.updated}
|
|
</span>
|
|
)}
|
|
</div>
|
|
)}
|
|
{!!frontMatter.author && (
|
|
<div className="italic text-white/50">By: {frontMatter.author}</div>
|
|
)}
|
|
</div>
|
|
</section>
|
|
<section className="grid grid-cols-3 gap-x-8 gap-y-6 my-6">
|
|
<div className="col-span-2">
|
|
<TTCMD
|
|
body={cleanBody}
|
|
escapeTOC={escapeTOC}
|
|
/>
|
|
</div>
|
|
{toc && (
|
|
<div className="sticky top-6 h-min">
|
|
<TTCMDRenderer tokens={toc} />
|
|
</div>
|
|
)}
|
|
</section>
|
|
</>
|
|
);
|
|
};
|