1
0
mirror of https://github.com/Llewellynvdm/conky.git synced 2024-11-17 02:25:09 +00:00
conky/web/pages/documents/[slug].tsx
2024-02-22 18:56:09 -05:00

110 lines
2.8 KiB
TypeScript

import {
getNextDocumentBySlug,
getDocumentBySlug,
getPreviousDocumentBySlug,
documentFilePaths,
} from '../../utils/mdx-utils'
import Layout from '../../components/Layout'
import SEO from '../../components/SEO'
import { GetStaticProps } from 'next'
import { getSearchIndex, SearchIndex } from '../../utils/search'
import Link from 'next/link'
import { unified } from 'unified'
import rehypeReact from 'rehype-react'
import * as prod from 'react/jsx-runtime'
import rehypeParse from 'rehype-parse'
import { createElement, Fragment, useEffect, useState } from 'react'
// @ts-expect-error: the react types are missing.
const production = { Fragment: prod.Fragment, jsx: prod.jsx, jsxs: prod.jsxs }
interface FrontMatter {
title: string
description: string
}
interface DocumentPageProps {
source: string
frontMatter: FrontMatter
searchIndex: SearchIndex
}
export default function DocumentPage({
source,
frontMatter,
searchIndex,
}: DocumentPageProps) {
const [children, setChildren] = useState(createElement(Fragment))
useEffect(
function () {
;(async function () {
const file = await unified()
.use(rehypeParse, { fragment: true })
// @ts-expect-error: the react types are missing.
.use(rehypeReact, { ...production, components: { a: Link } })
.process(source)
setChildren(file.result)
})()
},
[source]
)
return (
<Layout searchIndex={searchIndex}>
<SEO
title={`${frontMatter.title}`}
description={frontMatter.description}
/>
<article className="px-6 md:px-0">
<header>
<h1 className="text-3xl md:text-5xl dark:text-white mb-12">
{frontMatter.title}
</h1>
{frontMatter.description && (
<p className="text-xl mb-4">{frontMatter.description}</p>
)}
</header>
<main>
<article className="prose dark:prose-invert">{children}</article>
</main>
</article>
</Layout>
)
}
export const getStaticProps: GetStaticProps = async ({ params }) => {
if (params) {
const { source, data } = await getDocumentBySlug(params.slug as string)
const prevDocument = getPreviousDocumentBySlug(params.slug as string)
const nextDocument = getNextDocumentBySlug(params.slug as string)
const searchIndex = getSearchIndex()
return {
props: {
searchIndex,
source,
frontMatter: data,
prevDocument,
nextDocument,
},
}
}
return { props: {} }
}
export const getStaticPaths = async () => {
const paths = documentFilePaths
// Remove file extensions for page paths
.map((path) => path.replace(/\.mdx?$/, ''))
// Map the path into the static paths object required by Next.js
.map((slug) => ({ params: { slug } }))
return {
paths,
fallback: false,
}
}