68 lines
2.2 KiB
TypeScript
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;
|