Skip to content

Commit 3bcc802

Browse files
author
tkokhing
committed
major upgrade pages to Next-mdx-remote@6, add Mermaid rendering, enhance navi-bar
1 parent 9d0e181 commit 3bcc802

13 files changed

Lines changed: 3117 additions & 1498 deletions

File tree

package-lock.json

Lines changed: 2878 additions & 1455 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@
2727
"gray-matter": "^4.0.3",
2828
"jsonwebtoken": "^9.0.2",
2929
"lodash": "^4.17.21",
30+
"mermaid": "^11.13.0",
3031
"moment": "^2.30.1",
3132
"morgan": "^1.10.0",
32-
"next": "^15.3.2",
33-
"next-mdx-remote": "^5.0.0",
33+
"next": "^15.5.14",
34+
"next-mdx-remote": "^6.0.0",
3435
"path-to-regexp": "^8.2.0",
3536
"qs": "^6.14.0",
36-
"react": "^19.1.0",
37-
"react-dom": "^19.1.0",
37+
"react": "^19",
38+
"react-dom": "^19",
3839
"react-icons": "^5.4.0",
3940
"rehype-autolink-headings": "^7.1.0",
4041
"rehype-pretty-code": "^0.14.1",
@@ -50,8 +51,8 @@
5051
"devDependencies": {
5152
"@tailwindcss/typography": "^0.5.16",
5253
"@types/node": "^20.14.8",
53-
"@types/react": "^18.3.3",
54-
"@types/react-dom": "^18.3.0",
54+
"@types/react": "^19",
55+
"@types/react-dom": "^19",
5556
"autoprefixer": "^10.4.19",
5657
"postcss": "^8.4.38",
5758
"tailwindcss": "^3.4.4",

src/app/_components/main_frame/dismissible-box.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ export default function DismissibleBox({ children }: { children: React.ReactNode
88
if (!visible) return null;
99

1010
return (
11-
<div className="relative border border-gray-300 rounded-md p-4 bg-gray-200 hover:bg-slate-400 text-slate-800">
11+
<div className="my-5 relative border border-gray-300 rounded-md p-4 bg-teal-100 hover:bg-slate-400 dark:bg-gray-200 hover:dark:bg-slate-400 text-slate-800">
1212
<button
1313
onClick={() => setVisible(false)}
14-
className="absolute top-2 right-2 text-gray-500 hover:text-red-600 text-sm font-bold"
14+
className="absolute top-2 right-2 text-red-600 hover:text-white text-sm font-bold"
1515
aria-label="Close"
1616
>
1717

src/app/_components/main_frame/navi-bar.tsx

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
import { useEffect } from "react";
44
import { usePathname } from "next/navigation";
5-
import { Disclosure, DisclosureButton, DisclosurePanel, Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
6-
import { Bars3Icon, BellIcon, XMarkIcon } from "@heroicons/react/24/outline";
5+
import { Disclosure, DisclosureButton, DisclosurePanel } from "@headlessui/react";
6+
import { Bars3Icon, XMarkIcon } from "@heroicons/react/24/outline";
77
import { ProfileLogoSVG, HomeWithTextIcon, BlogWithTextIcon, TopicWithTextIcon, HeptagoningWithTextIcon, ResearchWithTextIcon } from "@/app/_components/main_frame/icons_svg";
88
import { useNavigation } from "@/app/_components/main_frame/navigation-context";
99
import { TKOKHING_LOGO_SVG_URL } from "@/lib/share/constants";
@@ -69,7 +69,7 @@ export default function Navigationbar() {
6969
return (
7070
<div className="min-h-full">
7171
<Disclosure as="nav" className="mt-3 mb-16 md:mb-12">
72-
<div className="container mx-auto px-5 sm:px-6 lg:px-8 ">
72+
<div className="container mx-auto px-5 sm:px-6 lg:px-8 relative">
7373
<div className="flex h-16 items-center justify-between">
7474
<div className="flex items-center">
7575
<div className="shrink-0 flex size-28">
@@ -115,25 +115,46 @@ export default function Navigationbar() {
115115
</div>
116116
</div>
117117
<DisclosurePanel className="md:hidden">
118-
<div className="border-t border-gray-700 pb-3 pt-4 items-center flex flex-row justify-around">
119-
<ThemeSwitcher />
120-
<FontSizeDropdown />
121-
</div>
122-
<div className="space-y-1 px-2 pb-3 pt-2 sm:px-3">
123-
{navigation.map((item) => (
124-
<DisclosureButton
125-
key={item.name}
126-
as="a"
127-
href={item.href}
128-
aria-current={selected === item.name ? 'page' : undefined}
129-
className={classNames(
130-
selected === item.name ? 'bg-gray-700 dark:bg-gray-600' : 'text-sky-800 hover:bg-gray-500',
131-
'block rounded-md px-3 py-2'
132-
)}
133-
>
134-
<item.icon aria-hidden="true" />
135-
</DisclosureButton>
136-
))}
118+
{/* blur out backdrop */}
119+
<div className="fixed inset-0 z-40 bg-black/40 backdrop-blur-sm" />
120+
{/* Drawer panel */}
121+
<div className="absolute origin-top-right right-5 sm:right-6 lg:right-8 z-50 h-full w-[80%] max-w-sm">
122+
{/* separate shading which cannot be absolute, resizing will failed*/}
123+
<div className="bg-white dark:bg-zinc-900 border-1 border-gray-300 dark:border-zinc-700 shadow-2xl transition-transform duration-300">
124+
{/* Top Controls */}
125+
<div className="flex items-center justify-between p-4 border-b border-gray-300 dark:border-zinc-700">
126+
<span className="font-semibold">Menu</span>
127+
<DisclosureButton
128+
className="group relative inline-flex items-center justify-center rounded-md bg-gray-800 p-2 text-gray-400 hover:bg-gray-700 hover:text-tkokhing-blue hover:dark:text-tkokhing-dark focus:outline-none focus:ring-2 focus:ring-white focus:ring-offset-2 focus:ring-offset-gray-800"
129+
aria-label="Open Main Menu"
130+
>
131+
<span className="absolute -inset-0.5" />
132+
<XMarkIcon aria-hidden="true" className="size-6 group-data-[open]:block" />
133+
</DisclosureButton>
134+
</div>
135+
{/* Settings */}
136+
<div className="flex justify-around py-4 border-b border-gray-200 dark:border-zinc-700">
137+
<ThemeSwitcher />
138+
<FontSizeDropdown />
139+
</div>
140+
{/* Navigation */}
141+
<div className="space-y-2 px-4 py-4">
142+
{navigation.map((item) => (
143+
<DisclosureButton
144+
key={item.name}
145+
as="a"
146+
href={item.href}
147+
aria-current={selected === item.name ? 'page' : undefined}
148+
className={classNames(
149+
selected === item.name ? 'bg-gray-700 dark:bg-gray-600' : 'text-sky-800 hover:bg-gray-500',
150+
'block rounded-md px-3 py-2'
151+
)}
152+
>
153+
<item.icon aria-hidden="true" />
154+
</DisclosureButton>
155+
))}
156+
</div>
157+
</div>
137158
</div>
138159
</DisclosurePanel>
139160
</Disclosure>

src/app/_components/main_frame/subpage-header.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ const SubpageHeader = () => {
4343
};
4444

4545
return (
46-
<div className="sticky top-0 z-30 bg-transparent">
46+
<div className="sticky top-0 z-30 bg-inherit/40 dark:bg-transparent/40 backdrop-blur-md">
4747
<Container>
48-
<h2 className="uppercase text-adaptive_fs_sm md:text-adaptive_fs_xs font-light tracking-tight md:tracking-tighter leading-tight py-1 flex items-center">
48+
<h2 className="uppercase text-adaptive_fs_sm md:text-adaptive_fs_xs text-tkokhing-blue dark:text-tkokhing-dark font-light tracking-tight md:tracking-tighter leading-tight py-1 flex items-center">
4949
<div className="truncate">{generateBreadcrumbs()}</div>
5050
</h2>
5151
<div className="h-1 bg-sky-500 transition-all" style={{ width: `${scroll}%` }} />

src/app/_components/post_gen/post-list-concise.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ type Props = {
1111
};
1212

1313
export function PostListConcise ({ dir, chosen_subPath }: Props) {
14+
if (typeof dir !== 'string'|| !dir.trim()) {
15+
throw new TypeError(`post_folder must be a non-empty string, got: ${dir}`);}
1416
const allPosts = getAllPosts(dir);
1517

1618
const filteredPosts = allPosts.filter(
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// render-mermaid.tsx
2+
"use client";
3+
4+
import mermaid from "mermaid";
5+
import { useEffect, useRef } from "react";
6+
7+
let mermaidInitialized = false;
8+
9+
export default function Mermaid({ chart }: { chart: string }) {
10+
const ref = useRef<HTMLDivElement>(null);
11+
12+
useEffect(() => {
13+
if (!mermaidInitialized) {
14+
mermaid.initialize({
15+
startOnLoad: false,
16+
theme: "default",
17+
securityLevel: "loose",
18+
});
19+
mermaidInitialized = true;
20+
}
21+
22+
const renderChart = async () => {
23+
if (!ref.current) return;
24+
25+
const id = "mermaid-" + Math.random().toString(36).slice(2);
26+
27+
const { svg } = await mermaid.render(id, chart);
28+
29+
// Inject white background rectangle into SVG
30+
const svgWithBg = svg.replace(
31+
"<svg",
32+
`<svg style="background:white"`
33+
);
34+
35+
ref.current.innerHTML = svgWithBg;
36+
};
37+
38+
renderChart();
39+
}, [chart]);
40+
41+
return (
42+
<div className="not-prose flex-auto justify-center my-8 mx-5">
43+
<div ref={ref} className="max-w-full overflow-x-auto" />
44+
</div>
45+
);
46+
}

src/app/blog/posts/[slug]/page.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { FrontierLeadinData } from "@/lib/_data_exporter/data_securingdigitalfro
1212
import { ToggleFrame } from "@/app/_components/preference/toggle-frame";
1313
import { ToggleAllFrame } from "@/app/_components/preference/toggle-frame-display";
1414
import { PostListConcise } from "@/app/_components/post_gen/post-list-concise";
15+
import Mermaid from "@/app/_components/post_gen/render-mermaid";
16+
import Diagram from "@/lib/_data_exporter/diagrams/diagrams_exporter";
1517

1618
const MDX_FOLDER = "_blog_post/_blogs";
1719

@@ -28,6 +30,8 @@ export default async function Post(props: Params) {
2830
FrontierLeadinData,
2931
ToggleFrame,
3032
PostListConcise,
33+
Mermaid,
34+
Diagram,
3135
};
3236
const post = getPostBySlug(params.slug, MDX_FOLDER);
3337
if (!post || post.subPath != 'blog/posts') return notFound();

src/app/blog/posts/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
import { PostListConcise } from "@/app/_components/post_gen/post-list-concise";
33

44
export default function BlogPostListPage() {
5-
return <PostListConcise dir={"_blog_post/_blogs"} chosen_subPath={"blog/posts"}/>
5+
return <PostListConcise dir="_blog_post/_blogs" chosen_subPath="blog/posts"/>
66
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { PostListConcise } from "@/app/_components/post_gen/post-list-concise";
22

33
export default function KillChainIndexPage() {
4-
return <PostListConcise dir={"_heptagoning/_kill-chain"} chosen_subPath={"heptagoning/kill-chain"}/>
4+
return <PostListConcise dir="_heptagoning/_kill-chain" chosen_subPath="heptagoning/kill-chain"/>
55
}

0 commit comments

Comments
 (0)