feat(about): add Notable Questions, fix grammar, blockquote formatting

This commit is contained in:
2026-07-05 19:09:57 +02:00
parent d84c8b62e0
commit e3b9014c02
6 changed files with 182 additions and 52 deletions
+6 -7
View File
@@ -1,15 +1,14 @@
export default function About() {
import { type ReactElement } from "react";
import MdProcessor from "./MdProcessor";
import aboutMd from "../content/about.md?raw";
export default function About(): ReactElement {
return (
<>
<h1 className="text-center m-6 text-3xl font-bold text-ctp-mauve">
About
</h1>
<div className="flex justify-center mb-6">
<p className="text-ctp-text">
</p>
<p className="text-ctp-text"></p>
</div>
<MdProcessor content={aboutMd} />
</>
);
}
@@ -1,4 +1,10 @@
import { useEffect, useState, useMemo, type ReactElement } from "react";
import {
useEffect,
useState,
useMemo,
type ComponentPropsWithoutRef,
type ReactElement,
} from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import rehypeRaw from "rehype-raw";
@@ -56,44 +62,57 @@ const resolveImageSrc = (src: string, base: string | null): string => {
return `${base}/${clean}`;
};
const fetchREADME = async (repoUrl: string): Promise<string> => {
try {
const rawUrl = toRawUrl(repoUrl);
const response = await fetch(rawUrl);
if (!response.ok) {
throw new Error("Failed to fetch README");
}
return await response.text();
} catch (error) {
console.error(error);
return "Error fetching README. Make sure the URL points to a raw markdown file.";
}
};
interface ProjectsReadmeProps {
repoUrl: string;
interface MdProcessorProps {
content?: string;
repoUrl?: string;
}
export default function ProjectsReadme({
export default function MdProcessor({
content: directContent,
repoUrl,
}: ProjectsReadmeProps): ReactElement {
const [readmeContent, setReadmeContent] = useState<string>("");
const [isLoading, setIsLoading] = useState<boolean>(true);
}: MdProcessorProps): ReactElement {
const useRemote = !directContent && !!repoUrl;
const base = useMemo(() => getRepoRawBase(repoUrl), [repoUrl]);
const [fetchState, setFetchState] = useState<{
url: string;
content: string;
}>({ url: "", content: "" });
useEffect(() => {
if (!useRemote || !repoUrl) return;
const fetchREADME = async (url: string): Promise<string> => {
try {
const rawUrl = toRawUrl(url);
const response = await fetch(rawUrl);
if (!response.ok) {
throw new Error("Failed to fetch README");
}
return await response.text();
} catch (error) {
console.error(error);
return "Error fetching README. Make sure the URL points to a raw markdown file.";
}
};
fetchREADME(repoUrl).then((content) => {
setReadmeContent(content);
setIsLoading(false);
setFetchState({ url: repoUrl, content });
});
}, [repoUrl]);
}, [useRemote, repoUrl]);
const base = useMemo(() => {
if (directContent) return null;
return repoUrl ? getRepoRawBase(repoUrl) : null;
}, [directContent, repoUrl]);
const loading = useRemote && fetchState.url !== repoUrl;
const displayContent = directContent ?? fetchState.content;
return (
<div className="w-full max-w-4xl mx-auto p-4 md:p-8 bg-ctp-mantle rounded-xl shadow-sm border border-ctp-text">
{isLoading ? (
{loading ? (
<div className="flex flex-col gap-3 animate-pulse w-full">
<div className="h-4 bg-ctp-overlay0 rounded-full w-3/4"></div>
<div className="h-4 bg-ctp-overlay0 rounded-full w-3/4"></div>
@@ -109,7 +128,7 @@ export default function ProjectsReadme({
className,
children,
...props
}: React.ComponentPropsWithoutRef<"code">): ReactElement {
}: ComponentPropsWithoutRef<"code">): ReactElement {
const isBlock =
className ||
(typeof children === "string" &&
@@ -139,7 +158,7 @@ export default function ProjectsReadme({
pre({
children,
...props
}: React.ComponentPropsWithoutRef<"pre">): ReactElement {
}: ComponentPropsWithoutRef<"pre">): ReactElement {
return (
<pre
className="bg-ctp-mantle p-4 rounded-lg overflow-x-auto text-sm my-4"
@@ -152,7 +171,7 @@ export default function ProjectsReadme({
h1({
children,
}: React.ComponentPropsWithoutRef<"h1">): ReactElement {
}: ComponentPropsWithoutRef<"h1">): ReactElement {
return (
<h1 className="text-3xl font-bold text-ctp-mauve mt-8 mb-4 border-b pb-2 border-ctp-green">
{children}
@@ -162,7 +181,7 @@ export default function ProjectsReadme({
h2({
children,
}: React.ComponentPropsWithoutRef<"h2">): ReactElement {
}: ComponentPropsWithoutRef<"h2">): ReactElement {
return (
<h2 className="text-2xl font-bold text-ctp-lavender mt-8 mb-4 border-b pb-2 border-ctp-green">
{children}
@@ -172,7 +191,7 @@ export default function ProjectsReadme({
h3({
children,
}: React.ComponentPropsWithoutRef<"h3">): ReactElement {
}: ComponentPropsWithoutRef<"h3">): ReactElement {
return (
<h3 className="text-xl font-bold text-ctp-lavender mt-5 mb-3">
{children}
@@ -182,7 +201,7 @@ export default function ProjectsReadme({
p({
children,
}: React.ComponentPropsWithoutRef<"p">): ReactElement {
}: ComponentPropsWithoutRef<"p">): ReactElement {
return (
<p className="mb-4 text-ctp-text">
{children}
@@ -192,7 +211,7 @@ export default function ProjectsReadme({
ul({
children,
}: React.ComponentPropsWithoutRef<"ul">): ReactElement {
}: ComponentPropsWithoutRef<"ul">): ReactElement {
return (
<ul className="list-disc pl-6 mb-4">
{children}
@@ -202,7 +221,7 @@ export default function ProjectsReadme({
ol({
children,
}: React.ComponentPropsWithoutRef<"ol">): ReactElement {
}: ComponentPropsWithoutRef<"ol">): ReactElement {
return (
<ol className="list-decimal pl-6 mb-4">
{children}
@@ -212,14 +231,14 @@ export default function ProjectsReadme({
li({
children,
}: React.ComponentPropsWithoutRef<"li">): ReactElement {
}: ComponentPropsWithoutRef<"li">): ReactElement {
return <li className="mb-1">{children}</li>;
},
a({
children,
href,
}: React.ComponentPropsWithoutRef<"a">): ReactElement {
}: ComponentPropsWithoutRef<"a">): ReactElement {
return (
<a
href={href}
@@ -234,7 +253,7 @@ export default function ProjectsReadme({
blockquote({
children,
}: React.ComponentPropsWithoutRef<"blockquote">): ReactElement {
}: ComponentPropsWithoutRef<"blockquote">): ReactElement {
return (
<blockquote className="border-l-4 border-ctp-text pl-4 py-1 mb-4 bg-ctp-mantle rounded-r-lg">
{children}
@@ -242,10 +261,42 @@ export default function ProjectsReadme({
);
},
table({
children,
}: ComponentPropsWithoutRef<"table">): ReactElement {
return (
<div className="overflow-x-auto my-4">
<table className="w-full border-collapse border border-ctp-overlay0">
{children}
</table>
</div>
);
},
th({
children,
}: ComponentPropsWithoutRef<"th">): ReactElement {
return (
<th className="border border-ctp-overlay0 bg-ctp-surface0 px-4 py-2 text-left font-bold text-ctp-lavender">
{children}
</th>
);
},
td({
children,
}: ComponentPropsWithoutRef<"td">): ReactElement {
return (
<td className="border border-ctp-overlay0 px-4 py-2 text-ctp-text">
{children}
</td>
);
},
img({
src,
alt,
}: React.ComponentPropsWithoutRef<"img">): ReactElement {
}: ComponentPropsWithoutRef<"img">): ReactElement {
const resolved = resolveImageSrc(
src || "",
base,
@@ -262,7 +313,7 @@ export default function ProjectsReadme({
},
}}
>
{readmeContent}
{displayContent}
</ReactMarkdown>
</div>
)}
+6 -2
View File
@@ -1,10 +1,14 @@
export default function Systems() {
import { type ReactElement } from "react";
import MdProcessor from "./MdProcessor";
import systemsMd from "../content/systems.md?raw";
export default function Systems(): ReactElement {
return (
<>
<h1 className="text-center m-6 text-3xl font-bold text-ctp-mauve">
Systems
</h1>
<div></div>
<MdProcessor content={systemsMd} />
</>
);
}