Restructure into pnpm monorepo with game shell, docs, and SpacetimeDB backend
- Restructure flat static prototype into pnpm workspace monorepo - apps/game: playable shell with R3F 3D scene, HUD, SpacetimeDB connection - apps/docs: design docs and prototypes - apps/site: landing page - packages/ui: shared Button and Panel primitives - services/spacetimedb: backend module (9 tables, 11 reducers) - Archive legacy static files to archive/legacy-static/ - Game loop: connect, undock, target, approach, dock, mine, sell - Add pnpm-workspace.yaml, tsconfig.base.json, spacetime.json
This commit is contained in:
11
apps/docs/src/components/NotFound.tsx
Normal file
11
apps/docs/src/components/NotFound.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export function NotFound() {
|
||||
return (
|
||||
<div className="mx-auto max-w-content">
|
||||
<h1>Page Not Found</h1>
|
||||
<p className="text-fg-dim">The requested route does not exist.</p>
|
||||
<Link className="inline-flex items-center gap-2 rounded-lg border border-accent bg-accent px-4 py-2 text-[0.8rem] font-semibold text-bg transition-all duration-150 hover:bg-accent-hover" to="/docs">Back to documentation</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
68
apps/docs/src/components/Sidebar.tsx
Normal file
68
apps/docs/src/components/Sidebar.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import { NavLink } from "react-router-dom";
|
||||
import { navSections } from "../data/nav";
|
||||
|
||||
type SidebarProps = {
|
||||
collapsed: boolean;
|
||||
};
|
||||
|
||||
export function Sidebar({ collapsed }: SidebarProps) {
|
||||
return (
|
||||
<aside
|
||||
className={[
|
||||
"z-10 flex h-screen flex-col overflow-hidden border-r border-border bg-surface transition-[width,min-width] duration-[250ms] max-md:h-auto max-md:max-h-[142px] max-md:w-full max-md:min-w-0 max-md:flex-shrink-0 max-md:border-r-0 max-md:border-b",
|
||||
collapsed ? "w-sidebar-collapsed min-w-sidebar-collapsed max-md:w-full" : "w-sidebar min-w-sidebar",
|
||||
].join(" ")}
|
||||
>
|
||||
<div
|
||||
className={[
|
||||
"flex min-h-topbar items-center gap-3 border-b border-border px-5 py-4 max-md:min-h-[38px] max-md:justify-start max-md:px-4 max-md:py-2",
|
||||
collapsed ? "justify-center px-4" : "",
|
||||
].join(" ")}
|
||||
>
|
||||
<div
|
||||
className={[
|
||||
"overflow-hidden whitespace-nowrap font-mono text-[0.8rem] font-bold uppercase tracking-[0.05em] text-accent max-md:text-[0.72rem]",
|
||||
collapsed ? "text-0 max-md:text-[0.72rem]" : "",
|
||||
].join(" ")}
|
||||
>
|
||||
GDD<span className="text-cyan">::</span>DOCS
|
||||
</div>
|
||||
</div>
|
||||
<nav
|
||||
className={[
|
||||
"flex-1 overflow-y-auto px-3 py-3 max-md:flex max-md:gap-2 max-md:overflow-x-auto max-md:overflow-y-hidden max-md:px-3 max-md:pb-3 max-md:pt-2",
|
||||
collapsed ? "px-2 py-2" : "",
|
||||
].join(" ")}
|
||||
>
|
||||
{navSections.map((section) => (
|
||||
<div key={section.title} className="max-md:flex max-md:flex-none max-md:gap-2">
|
||||
<div
|
||||
className={[
|
||||
"overflow-hidden whitespace-nowrap px-3 pb-2 pt-4 font-mono text-[0.65rem] uppercase tracking-[0.1em] text-muted max-md:hidden",
|
||||
collapsed ? "h-2 p-2 text-0" : "",
|
||||
].join(" ")}
|
||||
>
|
||||
{section.title}
|
||||
</div>
|
||||
{section.items.map((item) => (
|
||||
<NavLink
|
||||
key={item.path}
|
||||
className={({ isActive }) =>
|
||||
[
|
||||
"mb-0.5 flex select-none items-center gap-3 overflow-hidden whitespace-nowrap rounded-lg px-3 py-2 text-[0.85rem] text-fg-dim no-underline transition-all duration-150 hover:bg-surface-raised hover:text-fg-bright max-md:mb-0 max-md:justify-start",
|
||||
collapsed ? "justify-center p-3 max-md:px-3 max-md:py-2" : "",
|
||||
isActive ? "border border-accent/25 bg-accent/8 text-accent" : "",
|
||||
].join(" ")
|
||||
}
|
||||
to={item.path}
|
||||
>
|
||||
<span className="min-w-5 text-center text-base">{item.icon}</span>
|
||||
<span className={collapsed ? "hidden max-md:inline" : ""}>{item.label}</span>
|
||||
</NavLink>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</nav>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
37
apps/docs/src/components/TopBar.tsx
Normal file
37
apps/docs/src/components/TopBar.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
import { pageTitles } from "../data/nav";
|
||||
|
||||
type TopBarProps = {
|
||||
collapsed: boolean;
|
||||
onToggle: () => void;
|
||||
};
|
||||
|
||||
export function TopBar({ collapsed, onToggle }: TopBarProps) {
|
||||
const location = useLocation();
|
||||
const meta = pageTitles.get(location.pathname);
|
||||
const section = meta?.section?.includes("Demo") || meta?.section?.includes("Prototype") ? "Demos" : "Docs";
|
||||
const title = meta?.title ?? "Overview";
|
||||
|
||||
return (
|
||||
<div className="flex h-topbar min-h-topbar min-w-0 items-center gap-4 border-b border-border bg-surface px-5 text-[0.8rem] max-md:gap-2 max-md:px-3">
|
||||
<button
|
||||
className="flex cursor-pointer items-center rounded border border-border bg-transparent px-2 py-1 text-base text-muted transition-all duration-150 hover:border-border-light hover:text-fg"
|
||||
onClick={onToggle}
|
||||
>
|
||||
{collapsed ? "→" : "←"}
|
||||
</button>
|
||||
<div className="flex min-w-0 items-center gap-2 overflow-hidden whitespace-nowrap font-mono text-[0.75rem] text-muted max-md:flex-1">
|
||||
<Link className="text-inherit no-underline" to="/">VOID::NAV</Link>
|
||||
<span className="text-border-light">/</span>
|
||||
<span>{section}</span>
|
||||
<span className="text-border-light">/</span>
|
||||
<span className="overflow-hidden text-ellipsis text-fg-bright">{title}</span>
|
||||
</div>
|
||||
<div className="ml-auto flex items-center gap-4 whitespace-nowrap font-mono text-[0.7rem] text-muted max-md:hidden">
|
||||
<span><span className="mr-1 inline-block size-1.5 rounded-full bg-green shadow-[0_0_6px_var(--color-green)]" /> Connected</span>
|
||||
<span className="text-accent">●</span>
|
||||
<span>Prototype v0.1.0</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user