Files
dashboard/components/shared/MarkdownWithToc.tsx
T
Alberto-Audrix 32a36cceff
CI / lint-and-test (push) Canceled after 0s
first commit
2026-07-28 08:55:05 +07:00

68 lines
2.2 KiB
TypeScript

import React from 'react';
import { useMarkdown } from '../../hooks/useMarkdown.ts';
interface MarkdownWithTocProps {
fileUrl: string;
}
const MarkdownWithToc: React.FC<MarkdownWithTocProps> = ({ fileUrl }) => {
const { markdownHtml, toc, isLoading, error } = useMarkdown(fileUrl);
const renderLayout = () => {
if (isLoading) {
return (
<div className="text-center col-span-full py-20">
<i className="fa-solid fa-spinner fa-spin text-4xl text-gray-400"></i>
<p className="mt-2 text-gray-600">Loading Document...</p>
</div>
);
}
if (error) {
return (
<div className="text-center text-red-500 col-span-full py-20">
<i className="fa-solid fa-exclamation-triangle text-4xl"></i>
<p className="mt-2 font-semibold">Could not load document</p>
<p className="text-sm">{error}</p>
</div>
);
}
return (
<>
<aside className="w-full lg:w-1/4 mb-8 lg:mb-0">
<div className="sticky top-24 self-start bg-white p-4 rounded-lg shadow-md border border-gray-200">
<h3 className="font-bold text-lg mb-3">Daftar Isi</h3>
{toc.length > 0 ? (
<ul className="space-y-2">
{toc.map((item) => (
<li key={item.id} style={{ marginLeft: `${(item.level - 1) * 1}rem` }}>
<a
href={`#${item.id}`}
className="text-gray-600 hover:text-red-600 text-sm hover:underline transition-colors"
>
{item.text}
</a>
</li>
))}
</ul>
) : (
<p className="text-sm text-gray-500">Tidak ada daftar isi.</p>
)}
</div>
</aside>
<main className="w-full lg:w-3/4 bg-white p-6 sm:p-8 md:p-12 rounded-lg shadow-lg">
<div className="prose max-w-none" dangerouslySetInnerHTML={{ __html: markdownHtml }} />
</main>
</>
);
};
return (
<div className="container mx-auto px-4 sm:px-6 lg:px-8 pb-8">
<div className="flex flex-col lg:flex-row lg:space-x-8">{renderLayout()}</div>
</div>
);
};
export default MarkdownWithToc;