mirror of
https://github.com/DefectingCat/DefectingCat.github.io
synced 2025-07-16 01:01:38 +00:00
add slug page
This commit is contained in:
74
app/p/[slug]/page.tsx
Normal file
74
app/p/[slug]/page.tsx
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import rehypePrism from '@mapbox/rehype-prism';
|
||||||
|
import components from 'components/mdx/components';
|
||||||
|
import PostCommnetLine from 'components/post/post-commnet-line';
|
||||||
|
import PostToc from 'components/post/post-toc';
|
||||||
|
import data from 'content/mdx-data';
|
||||||
|
import { readSinglePost } from 'lib/posts';
|
||||||
|
import { SingleToc, generateToc } from 'lib/utils';
|
||||||
|
import { MDXRemote, compileMDX } from 'next-mdx-remote/rsc';
|
||||||
|
import { serialize } from 'next-mdx-remote/serialize';
|
||||||
|
import { notFound } from 'next/navigation';
|
||||||
|
import { Suspense, lazy } from 'react';
|
||||||
|
import rehypeSlug from 'rehype-slug';
|
||||||
|
import remarkGfm from 'remark-gfm';
|
||||||
|
|
||||||
|
const PostComment = lazy(() => import('components/post/post-comment'));
|
||||||
|
|
||||||
|
const Page = async ({
|
||||||
|
params,
|
||||||
|
}: {
|
||||||
|
params: {
|
||||||
|
slug: string;
|
||||||
|
};
|
||||||
|
}) => {
|
||||||
|
const slug = params.slug;
|
||||||
|
if (!slug) notFound();
|
||||||
|
|
||||||
|
const post = await readSinglePost(slug);
|
||||||
|
const toc = generateToc(post);
|
||||||
|
// const { ref, inView } = useInView();
|
||||||
|
|
||||||
|
const calcLength = (prev: number, cur: SingleToc) => {
|
||||||
|
const childLen = cur.children.length;
|
||||||
|
return childLen ? prev + childLen + 1 : prev + 1;
|
||||||
|
};
|
||||||
|
const tocLength = toc.reduce(calcLength, 0);
|
||||||
|
const mdxSource = await compileMDX({
|
||||||
|
source: post,
|
||||||
|
options: {
|
||||||
|
parseFrontmatter: true,
|
||||||
|
mdxOptions: {
|
||||||
|
remarkPlugins: [remarkGfm],
|
||||||
|
rehypePlugins: [
|
||||||
|
[rehypePrism, { alias: { vue: 'xml' }, ignoreMissing: true }],
|
||||||
|
rehypeSlug,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
scope: data,
|
||||||
|
},
|
||||||
|
// components: components as {},
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<main id="article" className="relative max-w-4xl px-4 mx-auto my-10">
|
||||||
|
{/* @ts-expect-error Async Server Component */}
|
||||||
|
<h1>{mdxSource.frontmatter?.title}</h1>
|
||||||
|
{/* @ts-expect-error Async Server Component */}
|
||||||
|
<time>{mdxSource.frontmatter?.date}</time>
|
||||||
|
<PostToc toc={toc} tocLength={tocLength} />
|
||||||
|
|
||||||
|
<article id="post-content">
|
||||||
|
{mdxSource.content}
|
||||||
|
|
||||||
|
<PostCommnetLine />
|
||||||
|
<div className="mt-4">
|
||||||
|
<PostComment />
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Page;
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import CopyButton from 'components/post/copy-button';
|
import CopyButton from 'components/post/copy-button';
|
||||||
import useCopyToClipboard from 'lib/hooks/use-copy-to-clipboard';
|
import useCopyToClipboard from 'lib/hooks/use-copy-to-clipboard';
|
||||||
@ -42,4 +44,4 @@ const Pre = ({ ...rest }: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(Pre);
|
export default memo(Pre);
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import Giscus from '@giscus/react';
|
import Giscus from '@giscus/react';
|
||||||
import { useTheme } from 'next-themes';
|
import { useTheme } from 'next-themes';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
@ -24,4 +26,4 @@ const PostComment = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(PostComment);
|
export default memo(PostComment);
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { useTheme } from 'next-themes';
|
import { useTheme } from 'next-themes';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
@ -29,4 +31,4 @@ const PostCommnetLine = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(PostCommnetLine);
|
export default memo(PostCommnetLine);
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import Anchor from 'components/mdx/anchor';
|
import Anchor from 'components/mdx/anchor';
|
||||||
import { SingleToc } from 'lib/utils';
|
import { SingleToc } from 'lib/utils';
|
||||||
@ -77,4 +79,4 @@ const PostToc = ({ toc, tocLength }: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(PostToc);
|
export default memo(PostToc);
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import useInView from 'lib/hooks/use-in-view';
|
import useInView from 'lib/hooks/use-in-view';
|
||||||
import { useTheme } from 'next-themes';
|
import { useTheme } from 'next-themes';
|
||||||
@ -64,4 +66,4 @@ const RUACodeSandbox = ({ url }: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(RUACodeSandbox);
|
export default memo(RUACodeSandbox);
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import useInView from 'lib/hooks/use-in-view';
|
import useInView from 'lib/hooks/use-in-view';
|
||||||
import { useTheme } from 'next-themes';
|
import { useTheme } from 'next-themes';
|
||||||
@ -80,4 +82,4 @@ const RUACodepen = ({ defaultTab, url }: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(RUACodepen);
|
export default memo(RUACodepen);
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { Sandpack, SandpackProps } from '@codesandbox/sandpack-react';
|
import { Sandpack, SandpackProps } from '@codesandbox/sandpack-react';
|
||||||
import { useTheme } from 'next-themes';
|
import { useTheme } from 'next-themes';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
@ -20,4 +22,4 @@ const RUASandpack = ({ ...rest }: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(RUASandpack);
|
export default memo(RUASandpack);
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { memo, useState } from 'react';
|
import React, { memo, useState } from 'react';
|
||||||
import { ItemProps } from './tab-item';
|
import { ItemProps } from './tab-item';
|
||||||
@ -56,4 +58,4 @@ const Tab = ({ defaultValue, children }: Props) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default memo(Tab);
|
export default memo(Tab);
|
Reference in New Issue
Block a user