Skip to content

Commit 8e700a2

Browse files
committed
Separate mdx, improve mdx styling.
1 parent e5c4961 commit 8e700a2

40 files changed

+331
-450
lines changed

app/docs/[...slug]/page.tsx

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,19 @@ import fs from "fs/promises";
22
import path from "path";
33

44
import matter from "gray-matter";
5-
import type { MDXComponents } from "mdx/types";
65
import type { Metadata } from "next";
76
import Link from "next/link";
87
import { notFound } from "next/navigation";
98
import { MDXRemote } from "next-mdx-remote/rsc";
109
import { Suspense, cache } from "react";
1110

11+
import { components, mdxOptions } from "@/components/mdx/mdx-components";
1212
import { DocsHeader } from "@/components/page/docs/content/DocsHeader";
1313
import { EditOnGitHub } from "@/components/page/docs/content/EditOnGitHub";
1414
import { ErrorBoundary } from "@/components/page/docs/content/ErrorBoundary";
1515
import { ReadingTime } from "@/components/page/docs/content/ReadingTime";
1616
import { ShortLink } from "@/components/page/docs/content/ShortLink";
1717
import { docsStructure } from "@/components/page/docs/sidebar-structure";
18-
import { components, mdxOptions } from "@/lib/mdx";
19-
20-
export const dynamic = "force-static";
21-
export const revalidate = 5;
2218

2319
interface DocMeta {
2420
title: string;
@@ -95,9 +91,9 @@ interface Props {
9591
}>;
9692
}
9793

98-
export async function generateMetadata(props: Props): Promise<Metadata> {
99-
const params = await props.params;
100-
const doc = await getDocBySlug(params.slug);
94+
export async function generateMetadata({ params }: Props): Promise<Metadata> {
95+
const resolvedParams = await params;
96+
const doc = await getDocBySlug(resolvedParams.slug);
10197
if (!doc) {
10298
return {
10399
title: "Documentation Not Found",
@@ -142,14 +138,12 @@ export async function generateStaticParams() {
142138
}));
143139
}
144140

145-
export default async function DocPage(props: Props) {
146-
const params = await props.params;
147-
const doc = await getDocBySlug(params.slug);
148-
if (!doc) {
149-
notFound();
150-
}
141+
export default async function DocPage({ params }: Props) {
142+
const resolvedParams = await params;
143+
const doc = await getDocBySlug(resolvedParams.slug);
144+
if (!doc) notFound();
151145

152-
const currentPath = "/docs/" + params.slug.join("/");
146+
const currentPath = "/docs/" + resolvedParams.slug.join("/");
153147
const { prev, next } = getDocNavigation(currentPath);
154148

155149
const category = docsStructure.find((item) => currentPath.startsWith(item.path))?.title;
@@ -165,7 +159,7 @@ export default async function DocPage(props: Props) {
165159
<>
166160
<ReadingTime content={doc.content} />
167161
<ShortLink path={currentPath} />
168-
<EditOnGitHub filePath={params.slug.join("/")} />
162+
<EditOnGitHub filePath={resolvedParams.slug.join("/")} />
169163
</>
170164
}
171165
/>
@@ -176,7 +170,7 @@ export default async function DocPage(props: Props) {
176170
<Suspense fallback={<LoadingFallback />}>
177171
<MDXRemote
178172
source={doc.content}
179-
components={components as MDXComponents}
173+
components={components}
180174
options={{ mdxOptions }}
181175
/>
182176
</Suspense>

app/docs/components.tsx

Lines changed: 0 additions & 14 deletions
This file was deleted.

app/docs/layout.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import { Metadata } from "next";
22
import { Poppins } from "next/font/google";
3-
import React from "react";
43

5-
import DocCopyEnhancer from "@/components/page/docs/code/DocCopyEnhancer";
64
import SidebarWrapper from "@/components/page/docs/sidebar/SidebarWrapper";
75
import Navbar from "@/components/page/header/Navbar";
86

97
const poppins = Poppins({
10-
weight: ["500"],
8+
weight: "500",
119
subsets: ["latin"],
1210
display: "swap",
1311
preload: true,
@@ -46,16 +44,12 @@ export default function DocsLayout({ children }: { children: React.ReactNode })
4644
<div className="mx-auto min-h-[calc(100vh-7rem)] max-w-screen-xl px-4 py-12 pt-36">
4745
<div className="flex flex-col gap-8 lg:flex-row">
4846
<SidebarWrapper />
49-
50-
<div className="flex min-w-0 flex-1 flex-col items-stretch">
47+
<main className="flex min-w-0 flex-1 flex-col items-stretch">
5148
<div className="w-full" style={{ minHeight: "60vh" }}>
52-
<DocCopyEnhancer />
5349
{children}
5450
</div>
55-
<div id="docs-navigation-buttons" className="mt-12 flex w-full justify-between">
56-
{/* Przyciski Next/Previous będą renderowane w page.tsx */}
57-
</div>
58-
</div>
51+
{/* Możesz tutaj dodać globalne elementy np. nawigację */}
52+
</main>
5953
</div>
6054
</div>
6155
</div>

app/docs/page.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
import { redirect } from "next/navigation";
2+
import { docsStructure } from "@/components/page/docs/sidebar-structure";
23

3-
export const dynamic = "force-static";
4-
export const revalidate = 5;
4+
function flattenDocs(structure: typeof docsStructure) {
5+
return structure.flatMap(item =>
6+
item.children?.length
7+
? item.children
8+
: [{ title: item.title, path: item.path }]
9+
);
10+
}
511

612
export default function DocsPage() {
7-
redirect("/docs/eternalcore/introduction");
13+
const flatDocs = flattenDocs(docsStructure);
14+
const firstDoc = flatDocs[0];
15+
if (!firstDoc) {
16+
return null;
17+
}
18+
redirect(firstDoc.path);
819
}

app/layout.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import { Analytics } from "@/components/Analytics";
88
import "./prism-languages";
99
import { CookieConsentModal } from "@/components/CookieConsentModal";
1010
import { CookiePreferencesMenu } from "@/components/CookiePreferencesMenu";
11-
import DocCopyEnhancer from "@/components/page/docs/code/DocCopyEnhancer";
12-
import Footer from "@/components/page/footer/Footer";
11+
import Footer from "@/components/footer/Footer";
1312
import Navbar from "@/components/page/header/Navbar";
1413
import { SpeedInsights } from "@/components/SpeedInsights";
1514
import { generateOgImageUrl } from "@/lib/og-utils";
@@ -131,7 +130,6 @@ export default function RootLayout({
131130
</main>
132131

133132
<Footer />
134-
<DocCopyEnhancer />
135133
<CookieConsentModal />
136134
<CookiePreferencesMenu />
137135
<Analytics />

app/projects/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Metadata } from "next";
22

33
import { generateOgImageMetadata } from "@/components/OgImage";
44
import Hero from "@/components/page/header/Hero";
5-
import Project from "@/components/page/projects/Projects";
5+
import Project from "@/components/projects/Projects";
66

77
export const dynamic = "force-dynamic";
88
export const fetchCache = "force-cache";

app/team/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Metadata } from "next";
22

33
import { generateOgImageMetadata } from "@/components/OgImage";
44
import Hero from "@/components/page/header/Hero";
5-
import Team from "@/components/page/team/Team";
5+
import Team from "@/components/team/Team";
66

77
export const metadata: Metadata = {
88
title: "EternalCode.pl | Team",

components/blog/BlogPostContent.tsx

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

33
import { MDXRemote } from "next-mdx-remote/rsc";
44

5-
import { components } from "@/lib/mdx";
5+
import { components } from "@/components/mdx/mdx-components";
66

77
interface BlogPostContentProps {
88
content: string;
@@ -16,4 +16,4 @@ export default function BlogPostContent({ content }: BlogPostContentProps) {
1616
<MDXRemote source={content} components={components} />
1717
</div>
1818
);
19-
}
19+
}

components/page/footer/Footer.tsx renamed to components/footer/Footer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export default function Footer() {
121121
<div className="mx-auto max-w-screen-xl px-4 py-8">
122122
<div className="md:flex md:justify-between">
123123
<div className="mb-6 flex flex-col items-center md:mb-0 md:items-start">
124-
<Link href="/" className="flex items-center" aria-label="Go to homepage">
124+
<Link href="/public" className="flex items-center" aria-label="Go to homepage">
125125
<Image
126126
className="mr-3 h-8 w-auto text-white dark:invert"
127127
alt="EternalCode Logo"

components/mdx/CodeBlock.tsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
"use client";
2+
3+
import { Copy, Check } from "lucide-react";
4+
import { memo, ReactNode, useState, useRef } from "react";
5+
6+
interface CodeBlockProps {
7+
children: ReactNode;
8+
language?: string;
9+
className?: string;
10+
}
11+
12+
export const CodeBlock = memo(({ children, language, className }: CodeBlockProps) => {
13+
const [copied, setCopied] = useState(false);
14+
const preRef = useRef<HTMLPreElement>(null);
15+
16+
const copyToClipboard = async () => {
17+
if (!preRef.current) return;
18+
try {
19+
const codeElement = preRef.current.querySelector('code');
20+
const textToCopy = codeElement ? codeElement.textContent : preRef.current.innerText;
21+
await navigator.clipboard.writeText(textToCopy || "");
22+
setCopied(true);
23+
setTimeout(() => setCopied(false), 1200);
24+
} catch {
25+
// silently ignore
26+
}
27+
};
28+
29+
return (
30+
<pre
31+
ref={preRef}
32+
role="region"
33+
aria-label={language ? `Code block in ${language}` : "Code block"}
34+
className={`relative my-4 overflow-x-auto rounded-lg border border-neutral-700 bg-gray-900 p-4 font-mono text-sm text-neutral-200 ${className ?? ""}`}
35+
>
36+
<button
37+
type="button"
38+
onClick={copyToClipboard}
39+
aria-label="Copy code to clipboard"
40+
className="absolute right-4 top-3 z-10 flex items-center gap-1 rounded-md border border-gray-700 bg-gray-800 px-3 py-1 text-xs font-medium text-gray-300 opacity-70 transition hover:bg-gray-900 hover:text-white hover:opacity-100"
41+
>
42+
{copied ? <Check className="h-4 w-4 text-green-500" /> : <Copy className="h-4 w-4" />}
43+
<span>{copied ? "Copied!" : "Copy"}</span>
44+
</button>
45+
46+
{typeof children === "string" ? <code className="whitespace-pre">{children}</code> : children}
47+
</pre>
48+
);
49+
});
50+
51+
CodeBlock.displayName = "CodeBlock";

0 commit comments

Comments
 (0)