feat: add docs routing
This commit is contained in:
Generated
+1592
-3
File diff suppressed because it is too large
Load Diff
@@ -18,11 +18,14 @@
|
|||||||
"@react-three/fiber": "^9.6.0",
|
"@react-three/fiber": "^9.6.0",
|
||||||
"@react-three/postprocessing": "^3.0.4",
|
"@react-three/postprocessing": "^3.0.4",
|
||||||
"@react-three/rapier": "^2.2.0",
|
"@react-three/rapier": "^2.2.0",
|
||||||
|
"@tanstack/react-router": "^1.168.25",
|
||||||
"gsap": "^3.15.0",
|
"gsap": "^3.15.0",
|
||||||
"lil-gui": "^0.21.0",
|
"lil-gui": "^0.21.0",
|
||||||
"r3f-perf": "^7.2.3",
|
"r3f-perf": "^7.2.3",
|
||||||
"react": "^19.2.4",
|
"react": "^19.2.4",
|
||||||
"react-dom": "^19.2.4",
|
"react-dom": "^19.2.4",
|
||||||
|
"react-markdown": "^10.1.0",
|
||||||
|
"remark-gfm": "^4.0.1",
|
||||||
"three": "^0.183.2"
|
"three": "^0.183.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
+3
-18
@@ -1,23 +1,8 @@
|
|||||||
import { Suspense } from "react";
|
import { RouterProvider } from "@tanstack/react-router";
|
||||||
import { Canvas } from "@react-three/fiber";
|
import { router } from "@/router";
|
||||||
import { Crosshair } from "@/components/ui/Crosshair";
|
|
||||||
import { InteractPrompt } from "@/components/ui/InteractPrompt";
|
|
||||||
import { DebugPerf } from "@/utils/debug/DebugPerf";
|
|
||||||
import { World } from "@/world/World";
|
|
||||||
|
|
||||||
function App(): React.JSX.Element {
|
function App(): React.JSX.Element {
|
||||||
return (
|
return <RouterProvider router={router} />;
|
||||||
<>
|
|
||||||
<Canvas camera={{ position: [85, 60, 85], fov: 42 }} shadows>
|
|
||||||
<Suspense fallback={null}>
|
|
||||||
<World />
|
|
||||||
<DebugPerf />
|
|
||||||
</Suspense>
|
|
||||||
</Canvas>
|
|
||||||
<Crosshair />
|
|
||||||
<InteractPrompt />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|||||||
+162
@@ -27,6 +27,168 @@ canvas {
|
|||||||
display: block;
|
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 {
|
.crosshair {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|||||||
@@ -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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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 />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user