refactor: rename Node page to Nodes and reorganize network page sections

- Renamed NodePage component and directory to NodesPage/nodes for consistency
- Updated all navigation links from "Node" to "Nodes" across headers and footer
- Replaced anchor tags with React Router Link components for proper SPA navigation
- Reorganized NetworkPage component order and added NetworkPros section
- Converted NetworkUsecases from horizontal slider to responsive grid layout
- Added new use cases for adaptive mesh and compute fabric
- Update
This commit is contained in:
2025-11-14 17:01:29 +01:00
parent 3a656ef5e9
commit 326efc9fbd
20 changed files with 139 additions and 64 deletions

View File

@@ -11,7 +11,7 @@ const ComputePage = lazy(() => import('./pages/compute/ComputePage'));
const StoragePage = lazy(() => import('./pages/storage/StoragePage'));
const GpuPage = lazy(() => import('./pages/gpu/GpuPage'));
const PodsPage = lazy(() => import('./pages/pods/PodsPage'));
const NodePage = lazy(() => import('./pages/node/NodePage'));
const NodesPage = lazy(() => import('./pages/nodes/NodesPage'));
function App() {
return (
@@ -28,7 +28,7 @@ function App() {
<Route path="storage" element={<StoragePage />} />
<Route path="gpu" element={<GpuPage />} />
<Route path="pods" element={<PodsPage />} />
<Route path="nodes" element={<NodePage />} />
<Route path="nodes" element={<NodesPage />} />
</Route>
</Routes>
</Suspense>

View File

@@ -28,7 +28,7 @@ export function Footer() {
Agents
</Link>
<Link to="/nodes" className="text-sm text-gray-700 hover:text-cyan-500 transition-colors">
Node
Nodes
</Link>
</nav>
</div>

View File

@@ -46,7 +46,7 @@ export function Header() {
to="/nodes"
className="text-base/7 tracking-tight text-gray-700 hover:text-cyan-500 transition-colors"
>
Node
Nodes
</Link>
</div>
</div>
@@ -135,7 +135,7 @@ export function Header() {
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-gray-900 hover:bg-gray-50"
onClick={() => setMobileMenuOpen(false)}
>
Node
Nodes
</Link>
</div>
<div className="py-6">

View File

@@ -46,7 +46,7 @@ export function HeaderDark() {
to="/nodes"
className="text-base/7 tracking-tight text-gray-300 hover:text-cyan-400 transition-colors"
>
Node
Nodes
</Link>
</div>
</div>
@@ -135,7 +135,7 @@ export function HeaderDark() {
className="-mx-3 block rounded-lg px-3 py-2 text-base font-semibold leading-7 text-white hover:bg-gray-800"
onClick={() => setMobileMenuOpen(false)}
>
Node
Nodes
</Link>
</div>
<div className="py-6">

View File

@@ -1,3 +1,4 @@
import { Link } from 'react-router-dom';
import { Container } from '@/components/Container'
import { Button } from '@/components/Button'
import { H3, P } from '@/components/Texts'
@@ -63,9 +64,9 @@ export function CallToAction() {
Deploy in Cloud
</Button>
<a href="/nodes" className="text-cyan-400 hover:text-cyan-300 transition-colors">
<Link to="/nodes" className="text-cyan-400 hover:text-cyan-300 transition-colors">
Host a Node &rarr;
</a>
</Link>
</div>
</div>
</Container>

View File

@@ -1,6 +1,7 @@
"use client";
import { Container } from "@/components/Container";
import { Link } from 'react-router-dom';
import { Container } from '@/components/Container'
import { Button } from "@/components/Button";
export function CallToAction() {
@@ -42,9 +43,9 @@ Use the network to link environments, deploy workloads, or host nodes to strengt
Deploy in Cloud
</Button>
<a href="/nodes" className="text-cyan-400 hover:text-cyan-300 transition-colors">
<Link to="/nodes" className="text-cyan-400 hover:text-cyan-300 transition-colors">
Host a Node &rarr;
</a>
</Link>
</div>
</div>
</Container>

View File

@@ -6,6 +6,8 @@ import { SecondaryFeatures } from './SecondaryFeatures'
import { CallToAction } from './CallToAction'
import { NetworkCapabilities } from './NetworkCapabilities'
import { NetworkUsecases } from './NetworkUsecases'
import { NetworkPros } from './NetworkPros'
export default function NetworkPage() {
return (
@@ -19,7 +21,7 @@ export default function NetworkPage() {
</AnimatedSection>
<AnimatedSection>
<Features />
<SecondaryFeatures />
</AnimatedSection>
<AnimatedSection>
@@ -27,13 +29,18 @@ export default function NetworkPage() {
</AnimatedSection>
<AnimatedSection>
<NetworkUsecases />
<Features />
</AnimatedSection>
<AnimatedSection>
<SecondaryFeatures />
<NetworkPros />
</AnimatedSection>
<AnimatedSection>
<NetworkUsecases />
</AnimatedSection>
<AnimatedSection>
<CallToAction />
</AnimatedSection>

View File

@@ -0,0 +1,68 @@
import { Small } from '@/components/Texts'
const highlights = [
{
label: 'Network Advantage',
title: 'Fully peer-to-peer, no logins, no central cloud.',
description:
'Connectivity flows directly between users, nodes, and services without platform ownership.',
},
{
label: 'Identity',
title: 'One identity across all capabilities.',
description:
'A single cryptographic identity governs your network, storage, agents, and deployments.',
},
{
label: 'Scale',
title: 'Scales instantly from one POD to thousands.',
description:
'Deploy locally or expand globally — the mesh routes and balances itself automatically.',
},
{
label: 'Security',
title: 'Secure, quantum-safe, and edge-ready for the next decade.',
description:
'Next-gen encryption, multipath routing, and attested nodes protect workloads everywhere.',
},
]
export function NetworkPros() {
return (
<section className="relative w-full bg-[#121212] overflow-hidden">
{/* ✅ Top horizontal line with spacing */}
<div className="max-w-7xl bg-[#111111] mx-auto py-6 border border-t-0 border-b-0 border-gray-800"></div>
<div className="w-full border-t border-l border-r border-gray-800" />
<div className="bg-[#121212] w-full max-w-7xl mx-auto border border-t-0 border-b-0 border-gray-800">
<div className="grid lg:grid-cols-4">
{highlights.map((item) => (
<div
key={item.title}
className="group relative overflow-hidden border border-white/10 bg-white/4 p-8 backdrop-blur-sm transition hover:border-cyan-300/50 hover:bg-white/8"
>
<div className="absolute inset-0 bg-linear-to-br from-cyan-500/0 via-white/5 to-cyan-300/20 opacity-0 transition group-hover:opacity-100" />
<div className="relative">
<Small className="text-xs uppercase tracking-[0.16em] text-cyan-200">
{item.label}
</Small>
<h3 className="mt-4 text-lg font-semibold leading-tight text-white">
{item.title}
</h3>
<p className="mt-4 text-sm leading-relaxed text-gray-300">
{item.description}
</p>
</div>
</div>
))}
</div>
</div>
<div className="w-full border-b border-gray-800 bg-[#121212]" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-gray-800" />
</section>
)
}

View File

@@ -1,12 +1,12 @@
"use client";
import { useRef } from "react";
import { Eyebrow, SectionHeader, P } from "@/components/Texts";
import { IoArrowBackOutline, IoArrowForwardOutline } from "react-icons/io5";
import {
LockClosedIcon,
ArrowPathIcon,
GlobeAltIcon,
SignalIcon,
CpuChipIcon,
} from "@heroicons/react/24/solid";
const networkUseCases = [
@@ -27,46 +27,52 @@ const networkUseCases = [
{
title: "Service-to-Service Networking Across Environments",
description:
"Connect applications running across home labs, cloud regions, edge nodes, and data centers all on one address space.",
"Connect apps running across home labs, cloud regions, edge nodes, and datacenters all on one address space.",
ideal: "Ideal for: dev teams, distributed apps, container + K3s workloads",
icon: GlobeAltIcon,
},
{
title: "Resilient Connectivity Across Regions & Outages",
description:
"Connect systems across countries, datacenters, edge locations, and remote deployments — with routing that automatically heals around ISP failures, censorship, and regional outages.",
"Automatically routes around ISP failures, censorship, and regional outages using multipath encrypted relays.",
ideal:
"Ideal for: research networks, cross-border orgs, distributed compute, off-grid / rural deployments",
"Ideal for: cross-border orgs, distributed compute, remote/off-grid deployments",
icon: ArrowPathIcon,
},
{
title: "Adaptive Mesh for Mobile & Edge Movement",
description:
"Devices moving between networks, cities, or countries maintain continuous secure connectivity with no reconnection steps.",
ideal: "Ideal for: mobile agents, field teams, robotics, vehicles, IoT",
icon: SignalIcon,
},
{
title: "Compute Fabric Linking Nodes & Agents",
description:
"Agents, jobs, and tasks can interact across nodes without exposing private IPs or opening firewalls.",
ideal: "Ideal for: agent networks, edge AI workloads, distributed computation",
icon: CpuChipIcon,
},
];
export function NetworkUsecases() {
const sliderRef = useRef<HTMLUListElement>(null);
const scrollLeft = () =>
sliderRef.current?.scrollBy({ left: -400, behavior: "smooth" });
const scrollRight = () =>
sliderRef.current?.scrollBy({ left: 400, behavior: "smooth" });
return (
<section className="bg-white w-full max-w-8xl mx-auto">
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-slate-200" />
<div className="w-full border-t border-l border-r border-slate-200" />
<div className="relative mx-auto max-w-7xl border border-t-0 border-b-0 border-slate-200 bg-white overflow-hidden">
<ul
ref={sliderRef}
className="flex overflow-x-auto snap-x snap-mandatory scroll-smooth no-scrollbar"
>
<div className="mx-auto max-w-7xl border border-t-0 border-b-0 border-slate-200 bg-white">
{/* GRID 3 x 3 */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
{networkUseCases.map((item, idx) => (
<li
<div
key={idx}
className={`snap-start shrink-0 w-[85%] sm:w-[50%] lg:w-[33%] border border-slate-200 p-10 relative ${
item.isIntro ? "bg-gray-50/80" : "bg-white"
}`}
className={`
border border-slate-200 p-10 relative
${item.isIntro ? "bg-gray-50/80" : "bg-white"}
`}
>
{/* Intro Card */}
{item.isIntro ? (
<div className="flex flex-col justify-between h-full">
<div>
@@ -81,47 +87,39 @@ export function NetworkUsecases() {
{item.description}
</P>
</div>
<div className="flex items-center gap-x-4 mt-2">
<button
onClick={scrollLeft}
className="h-8 w-8 flex items-center justify-center border border-slate-300 rounded-md hover:border-cyan-500 transition-colors"
>
<IoArrowBackOutline className="text-gray-600" size={16} />
</button>
<button
onClick={scrollRight}
className="h-8 w-8 flex items-center justify-center border border-slate-300 rounded-md hover:border-cyan-500 transition-colors"
>
<IoArrowForwardOutline className="text-gray-600" size={16} />
</button>
</div>
</div>
) : (
<>
{/* Icon above title */}
{item.icon && (
{/* Icon */}
{item.icon && (
<div className="h-10 w-10 flex items-center justify-center rounded-xl bg-gray-100 mb-4">
<item.icon className="h-6 w-6 text-cyan-600" />
</div>
)}
<p className="text-lg font-semibold text-gray-900">
{/* Title */}
<p className="text-lg font-semibold text-gray-900">
{item.title}
</p>
<p className="mt-2 text-gray-600 leading-snug">
{/* Description */}
<p className="mt-2 text-gray-600 leading-snug">
{item.description}
</p>
<p className="mt-3 text-xs font-medium text-cyan-700">
{/* Ideal for */}
<p className="mt-3 text-xs font-medium text-cyan-700">
{item.ideal}
</p>
</>
)}
</li>
</div>
))}
</ul>
</div>
</div>
<div className="w-full border-b border-slate-200 bg-white" />
<div className="max-w-7xl mx-auto py-6 border border-t-0 border-b-0 border-slate-200" />
</section>
);
}

View File

@@ -197,12 +197,12 @@ export function SecondaryFeatures() {
<Container className="py-12 border border-t-0 border-b-0 border-gray-100">
<div className="mx-auto max-w-4xl sm:text-center">
<h2 className="text-base/7 font-semibold text-cyan-500">IN ACTIVE EVOLUTION</h2>
<h2 className="text-base/7 font-semibold text-cyan-500">FEATURES</h2>
<p className="text-3xl lg:text-4xl font-medium tracking-tight text-gray-900">
Expanding the Network Layer
Core Features
</p>
<p className="mt-6 text-lg text-gray-600">
The Mycelium Network is evolving to support richer data movement, identity, and application connectivity across the mesh. These enhancements deepen autonomy and improve real-world usability.
The Mycelium Network is evolving with new features to support richer data movement, identity, and application connectivity across the mesh.
</p>
</div>
<ul

View File

@@ -6,7 +6,7 @@ import { NodeProducts } from './NodeProducts';
import { NodeSpecs } from './NodeSpecs';
import { CallToAction } from './CallToAction';
const NodePage: React.FC = () => {
const NodesPage: React.FC = () => {
return (
<>
<NodeHero />
@@ -19,4 +19,4 @@ const NodePage: React.FC = () => {
);
};
export default NodePage;
export default NodesPage;