Add persistent onion key backup and restore, improve startup resilience, and flesh out the major site verticals with richer navigation, search coverage, and operator documentation. Made-with: Cursor
113 lines
3.7 KiB
TypeScript
113 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import React, { useEffect, useState } from "react";
|
|
import Link from "next/link";
|
|
|
|
export type ThemeName =
|
|
| "dark"
|
|
| "retro"
|
|
| "minimal"
|
|
| "hacker"
|
|
| "mystic"
|
|
| "brutalist"
|
|
| "terminal"
|
|
| "zine"
|
|
| "editorial"
|
|
| "institutional"
|
|
| "nature";
|
|
|
|
interface ThemedLayoutProps {
|
|
children: React.ReactNode;
|
|
theme: ThemeName;
|
|
/** Legacy prop; use siteTitle if you prefer */
|
|
title?: string;
|
|
siteTitle?: string;
|
|
siteSubtitle?: string;
|
|
}
|
|
|
|
export default function ThemedLayout({
|
|
children,
|
|
theme,
|
|
title,
|
|
siteTitle,
|
|
siteSubtitle,
|
|
}: ThemedLayoutProps) {
|
|
const heading = siteTitle ?? title ?? "CyberLux";
|
|
const [nodeTag, setNodeTag] = useState<number | null>(null);
|
|
|
|
useEffect(() => {
|
|
setNodeTag(Math.floor(Math.random() * 99999));
|
|
}, []);
|
|
|
|
const themes: Record<ThemeName, string> = {
|
|
dark: "bg-black text-white font-sans",
|
|
retro: "bg-[#222] text-[#0f0] font-mono border-4 border-double border-[#0f0]",
|
|
minimal: "bg-[#0d0d0d] text-[#e6e6e6] font-serif border border-white/10",
|
|
hacker: "bg-[#050505] text-[#00ff41] font-mono",
|
|
mystic: "bg-[#1a0f1a] text-[#d4af37] font-serif italic",
|
|
brutalist: "bg-[#111] text-[#f5f5f5] font-black uppercase border-[10px] border-[#f5f5f5]",
|
|
terminal: "bg-[#000080] text-white font-mono",
|
|
zine: "bg-[#1a1a1a] text-[#ff3366] font-sans border-y-8 border-[#ffff00]",
|
|
editorial:
|
|
"bg-[#121018] text-[#e8e4dc] font-serif border-x-[12px] border-double border-[#6b5c3d]/60",
|
|
institutional:
|
|
"bg-[#0c1e3d] text-[#e8eef7] font-sans border-t-4 border-[#c5a022]",
|
|
nature: "bg-[#0d1f14] text-[#c8e6c9] font-serif border-b-8 border-[#2e7d32]",
|
|
};
|
|
|
|
return (
|
|
<div className={`min-h-screen p-8 ${themes[theme]}`}>
|
|
<nav className="mb-12 flex flex-col gap-1 border-b pb-4 opacity-50 transition-opacity hover:opacity-100 md:flex-row md:items-center md:justify-between">
|
|
<div>
|
|
<div className="text-xl font-bold tracking-widest uppercase">{heading}</div>
|
|
{siteSubtitle ? (
|
|
<div className="mt-1 text-[10px] font-normal uppercase tracking-wider opacity-80">
|
|
{siteSubtitle}
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
<div className="flex flex-wrap gap-4 text-xs uppercase md:gap-6">
|
|
<Link href="/" className="hover:underline">
|
|
Hub
|
|
</Link>
|
|
<Link href="/market" className="hover:underline">
|
|
Market
|
|
</Link>
|
|
<Link href="/forum" className="hover:underline">
|
|
Forum
|
|
</Link>
|
|
<Link href="/exchange" className="hover:underline">
|
|
Exchange
|
|
</Link>
|
|
<Link href="/barter" className="hover:underline">
|
|
Barter
|
|
</Link>
|
|
<Link href="/search" className="hover:underline">
|
|
Crawler
|
|
</Link>
|
|
<Link href="/hidden-wiki" className="hover:underline">
|
|
Wiki
|
|
</Link>
|
|
<Link href="/darknet-atlas" className="hover:underline">
|
|
Atlas
|
|
</Link>
|
|
<Link href="/syndicate" className="hover:underline">
|
|
Syndicate
|
|
</Link>
|
|
<Link href="/vault" className="hover:underline">
|
|
Vault
|
|
</Link>
|
|
<Link href="/webring" className="hover:underline">
|
|
Webring
|
|
</Link>
|
|
</div>
|
|
</nav>
|
|
<main className="mx-auto max-w-4xl">{children}</main>
|
|
<footer className="mt-20 border-t border-current pt-8 text-center text-[10px] uppercase tracking-[0.3em] opacity-30">
|
|
<div className="mb-4 font-bold text-red-500"></div>
|
|
Node {nodeTag ?? "—"} // Shadow Network // {new Date().getFullYear()}
|
|
</footer>
|
|
</div>
|
|
);
|
|
}
|