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/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
@@ -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
@@ -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%;
|
||||
|
||||
@@ -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