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
101 lines
3.0 KiB
TypeScript
101 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import {
|
|
CYBERLUX_ENTRY_COOKIE,
|
|
parseCyberluxEntry,
|
|
type CyberluxEntry,
|
|
} from "@/lib/cyberluxEntry";
|
|
|
|
function readEntryFromCookie(): CyberluxEntry {
|
|
if (typeof document === "undefined") return "hub";
|
|
const raw = `; ${document.cookie}`;
|
|
const part = raw.split(`; ${CYBERLUX_ENTRY_COOKIE}=`);
|
|
if (part.length !== 2) return "hub";
|
|
const v = part.pop()?.split(";").shift();
|
|
return parseCyberluxEntry(v);
|
|
}
|
|
|
|
type Skin = { bar: string; label: string };
|
|
|
|
const DEFAULT_SKIN: Skin = {
|
|
bar: "border-zinc-600/40 bg-black/90 text-zinc-500",
|
|
label: "CYBERLUX NODE · Tor v3 · onion endpoint",
|
|
};
|
|
|
|
const SKINS: Partial<Record<CyberluxEntry, Skin>> = {
|
|
hub: {
|
|
bar: "border-cyan-500/25 bg-black/85 text-zinc-400",
|
|
label: "CYBERLUX · primary storefront · Tor v3 · connection verified",
|
|
},
|
|
forum: {
|
|
bar: "border-[#ff7a18]/40 bg-[#0c0500]/95 text-[#ffc9a3]/70",
|
|
label: "VOID AGGREGATE · forum relay · onion authenticated",
|
|
},
|
|
exchange: {
|
|
bar: "border-amber-900/50 bg-[#0f0d0a]/95 text-[#c4b5a0]",
|
|
label: "EXCHANGE MIRROR · classifieds host · encrypted circuit",
|
|
},
|
|
wiki: {
|
|
bar: "border-[#3d5a80]/45 bg-[#0a0e14]/95 text-[#94a8c4]",
|
|
label: "WIKI LAYER · directory mirror · read-only overlay",
|
|
},
|
|
market: {
|
|
bar: "border-emerald-900/50 bg-[#040806]/95 text-[#9ca89a]",
|
|
label: "MARKET NODE · vendor shelf · onion storefront",
|
|
},
|
|
barter: {
|
|
bar: "border-rose-900/45 bg-[#0c0608]/95 text-[#d4a8b0]",
|
|
label: "BARTER PIT · swap relay · Tor v3",
|
|
},
|
|
chatter: {
|
|
bar: "border-violet-900/50 bg-[#08060c]/95 text-[#b8a9d4]",
|
|
label: "CHATTER ARCHIVE · hub threads · public relay",
|
|
},
|
|
search: {
|
|
bar: "border-slate-600/50 bg-[#06080a]/95 text-[#a8b4c4]",
|
|
label: "SEARCH INDEX · catalog probe · encrypted circuit",
|
|
},
|
|
syndicate: {
|
|
bar: "border-yellow-900/40 bg-[#0c0a06]/95 text-[#c9b896]",
|
|
label: "SYNDICATE MAP · network atlas · node federation",
|
|
},
|
|
w: {
|
|
bar: "border-fuchsia-900/40 bg-[#0a060c]/95 text-[#d8b8e8]",
|
|
label: "SHADOW NODES · /w/[slug] · syndicate landing on /",
|
|
},
|
|
};
|
|
|
|
function skinFor(entry: CyberluxEntry): Skin {
|
|
return (
|
|
SKINS[entry] ?? {
|
|
...DEFAULT_SKIN,
|
|
label: `${entry.replace(/-/g, " ").toUpperCase()} · Tor v3 · onion relay`,
|
|
}
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Bottom strip keyed off proxy cookie (set from `X-Cyberlux-Node` behind nginx).
|
|
* One Tor service = one visual personality for the disclosure line.
|
|
*/
|
|
export default function OnionDisclosureBar() {
|
|
const [entry, setEntry] = useState<CyberluxEntry>("hub");
|
|
|
|
useEffect(() => {
|
|
setEntry(readEntryFromCookie());
|
|
}, []);
|
|
|
|
const skin = skinFor(entry);
|
|
|
|
return (
|
|
<div
|
|
className={`pointer-events-none fixed bottom-0 left-0 right-0 z-[10000] border-t-2 py-1.5 text-center font-mono text-[10px] uppercase tracking-[0.2em] backdrop-blur-sm ${skin.bar}`}
|
|
role="status"
|
|
aria-label="Entry host"
|
|
>
|
|
{skin.label}
|
|
</div>
|
|
);
|
|
}
|