feat: add docs routing

This commit is contained in:
2026-04-27 15:32:39 +02:00
parent 8abc69ebc3
commit 7fd39f58d8
7 changed files with 1881 additions and 21 deletions
+1592 -3
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -18,11 +18,14 @@
"@react-three/fiber": "^9.6.0",
"@react-three/postprocessing": "^3.0.4",
"@react-three/rapier": "^2.2.0",
"@tanstack/react-router": "^1.168.25",
"gsap": "^3.15.0",
"lil-gui": "^0.21.0",
"r3f-perf": "^7.2.3",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-markdown": "^10.1.0",
"remark-gfm": "^4.0.1",
"three": "^0.183.2"
},
"devDependencies": {
+3 -18
View File
@@ -1,23 +1,8 @@
import { Suspense } from "react";
import { Canvas } from "@react-three/fiber";
import { Crosshair } from "@/components/ui/Crosshair";
import { InteractPrompt } from "@/components/ui/InteractPrompt";
import { DebugPerf } from "@/utils/debug/DebugPerf";
import { World } from "@/world/World";
import { RouterProvider } from "@tanstack/react-router";
import { router } from "@/router";
function App(): React.JSX.Element {
return (
<>
<Canvas camera={{ position: [85, 60, 85], fov: 42 }} shadows>
<Suspense fallback={null}>
<World />
<DebugPerf />
</Suspense>
</Canvas>
<Crosshair />
<InteractPrompt />
</>
);
return <RouterProvider router={router} />;
}
export default App;
+162
View File
@@ -27,6 +27,168 @@ canvas {
display: block;
}
.docs-page {
display: grid;
grid-template-columns: minmax(220px, 280px) minmax(0, 1fr);
width: 100vw;
height: 100vh;
overflow: hidden;
background:
radial-gradient(
circle at top left,
rgba(77, 146, 217, 0.18),
transparent 34rem
),
#071019;
color: rgba(255, 255, 255, 0.88);
}
.docs-sidebar {
padding: 32px 24px;
border-right: 1px solid rgba(255, 255, 255, 0.12);
background: rgba(4, 7, 13, 0.72);
overflow-y: auto;
}
.docs-sidebar h1 {
margin: 24px 0 18px;
font-size: 26px;
line-height: 1.1;
}
.docs-sidebar nav {
display: grid;
gap: 10px;
}
.docs-sidebar a,
.docs-back-link {
color: rgba(255, 255, 255, 0.78);
text-decoration: none;
}
.docs-sidebar nav a {
padding: 10px 12px;
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 10px;
background: rgba(255, 255, 255, 0.04);
}
.docs-sidebar a:hover,
.docs-sidebar a:focus-visible {
color: white;
border-color: rgba(255, 255, 255, 0.24);
}
.docs-back-link {
display: inline-flex;
font-size: 14px;
}
.docs-content {
overflow-y: auto;
scroll-behavior: smooth;
padding: 48px clamp(20px, 5vw, 72px);
}
.docs-section {
max-width: 980px;
margin: 0 auto 48px;
padding: clamp(24px, 4vw, 44px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 24px;
background: rgba(255, 255, 255, 0.055);
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.26);
}
.docs-section h1,
.docs-section h2,
.docs-section h3 {
color: white;
line-height: 1.15;
}
.docs-section h1 {
margin-top: 0;
font-size: clamp(32px, 5vw, 56px);
}
.docs-section h2 {
margin-top: 34px;
font-size: clamp(24px, 3vw, 34px);
}
.docs-section h3 {
margin-top: 26px;
font-size: 20px;
}
.docs-section p,
.docs-section li {
line-height: 1.75;
}
.docs-section a {
color: #8bd3ff;
}
.docs-section code {
border-radius: 6px;
padding: 2px 6px;
background: rgba(255, 255, 255, 0.12);
color: #d7f2ff;
}
.docs-section pre {
overflow-x: auto;
padding: 18px;
border-radius: 16px;
background: rgba(0, 0, 0, 0.34);
}
.docs-section pre code {
padding: 0;
background: transparent;
}
.docs-section table {
display: block;
width: 100%;
overflow-x: auto;
border-collapse: collapse;
}
.docs-section th,
.docs-section td {
padding: 10px 12px;
border: 1px solid rgba(255, 255, 255, 0.16);
text-align: left;
}
.docs-section blockquote {
margin-left: 0;
padding-left: 18px;
border-left: 3px solid rgba(139, 211, 255, 0.72);
color: rgba(255, 255, 255, 0.72);
}
@media (max-width: 760px) {
.docs-page {
display: block;
overflow-y: auto;
}
.docs-sidebar {
border-right: 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
.docs-content {
overflow: visible;
padding: 24px 16px;
}
}
.crosshair {
position: fixed;
top: 50%;
+66
View File
@@ -0,0 +1,66 @@
import { Link } from "@tanstack/react-router";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import readme from "../../README.md?raw";
import architecture from "../../docs/technical/architecture.md?raw";
import targetArchitecture from "../../docs/technical/target-architecture.md?raw";
import features from "../../docs/user/features.md?raw";
interface DocSection {
id: string;
title: string;
content: string;
}
const docSections: DocSection[] = [
{
id: "readme",
title: "README",
content: readme,
},
{
id: "architecture",
title: "Architecture actuelle",
content: architecture,
},
{
id: "target-architecture",
title: "Architecture cible",
content: targetArchitecture,
},
{
id: "features",
title: "Fonctionnalites",
content: features,
},
];
export function DocsPage(): React.JSX.Element {
return (
<main className="docs-page">
<aside className="docs-sidebar" aria-label="Documentation">
<Link className="docs-back-link" to="/">
Retour a l'experience 3D
</Link>
<h1>Documentation</h1>
<nav>
{docSections.map((section) => (
<a key={section.id} href={`#${section.id}`}>
{section.title}
</a>
))}
</nav>
</aside>
<div className="docs-content">
{docSections.map((section) => (
<article key={section.id} id={section.id} className="docs-section">
<ReactMarkdown remarkPlugins={[remarkGfm]}>
{section.content}
</ReactMarkdown>
</article>
))}
</div>
</main>
);
}
+21
View File
@@ -0,0 +1,21 @@
import { Suspense } from "react";
import { Canvas } from "@react-three/fiber";
import { Crosshair } from "@/components/ui/Crosshair";
import { InteractPrompt } from "@/components/ui/InteractPrompt";
import { DebugPerf } from "@/utils/debug/DebugPerf";
import { World } from "@/world/World";
export function HomePage(): React.JSX.Element {
return (
<>
<Canvas camera={{ position: [85, 60, 85], fov: 42 }} shadows>
<Suspense fallback={null}>
<World />
<DebugPerf />
</Suspense>
</Canvas>
<Crosshair />
<InteractPrompt />
</>
);
}
+34
View File
@@ -0,0 +1,34 @@
import {
Outlet,
createRootRoute,
createRoute,
createRouter,
} from "@tanstack/react-router";
import { DocsPage } from "@/pages/DocsPage";
import { HomePage } from "@/pages/HomePage";
const rootRoute = createRootRoute({
component: Outlet,
});
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/",
component: HomePage,
});
const docsRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/docs",
component: DocsPage,
});
const routeTree = rootRoute.addChildren([indexRoute, docsRoute]);
export const router = createRouter({ routeTree });
declare module "@tanstack/react-router" {
interface Register {
router: typeof router;
}
}