148 lines
8.0 KiB
TypeScript
148 lines
8.0 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import Navbar from "@/components/Navbar";
|
|
import Link from "next/link";
|
|
|
|
const DOCUMENTS = [
|
|
{ id: "d1", title: "Tor Circuit Selection — Deep Technical Analysis", category: "Network", pages: 24, access: "free", views: 1842, updated: "2025-03" },
|
|
{ id: "d2", title: "Opsec Field Manual v4.1", category: "OPSEC", pages: 88, access: "void:10", views: 3210, updated: "2025-01" },
|
|
{ id: "d3", title: "PGP Web of Trust — Trust Models Compared", category: "Crypto", pages: 32, access: "free", views: 956, updated: "2024-11" },
|
|
{ id: "d4", title: "Darknet Exit Scam Patterns — Attribution Study", category: "Intel", pages: 56, access: "void:20", views: 2107, updated: "2025-04" },
|
|
{ id: "d5", title: "Bitcoin Privacy: Complete Transaction Graph Analysis", category: "Crypto", pages: 44, access: "void:15", views: 1654, updated: "2025-02" },
|
|
{ id: "d6", title: "Hidden Service Hardening — Production Checklist", category: "Network", pages: 18, access: "free", views: 4321, updated: "2025-04" },
|
|
{ id: "d7", title: "Law Enforcement Network Forensics — Countermeasures", category: "Counter-Intel", pages: 72, access: "void:35", views: 876, updated: "2024-10" },
|
|
{ id: "d8", title: "Monero Ring Signature Privacy Analysis", category: "Crypto", pages: 28, access: "void:12", views: 1123, updated: "2025-01" },
|
|
];
|
|
|
|
const CATS = ["All", "OPSEC", "Crypto", "Network", "Intel", "Counter-Intel"];
|
|
const CAT_ICONS: Record<string, string> = { OPSEC: "🛡️", Crypto: "🔐", Network: "🌐", Intel: "🔍", "Counter-Intel": "🕵️" };
|
|
|
|
export default function CodexPage() {
|
|
const [cat, setCat] = useState("All");
|
|
const [search, setSearch] = useState("");
|
|
|
|
const filtered = DOCUMENTS.filter((d) => {
|
|
const matchCat = cat === "All" || d.category === cat;
|
|
const matchSearch = !search || d.title.toLowerCase().includes(search.toLowerCase());
|
|
return matchCat && matchSearch;
|
|
});
|
|
|
|
return (
|
|
<>
|
|
<Navbar />
|
|
<main className="min-h-screen bg-[#0a0a0a] pt-24 pb-20">
|
|
{/* Header */}
|
|
<section className="container mx-auto max-w-6xl px-4 mb-12">
|
|
<p className="mb-2 font-mono text-[10px] uppercase tracking-[0.35em] text-neon-purple/70">the codex · encrypted document archive</p>
|
|
<div className="flex flex-col gap-4 md:flex-row md:items-end md:justify-between">
|
|
<div>
|
|
<h1 className="font-orbitron text-4xl font-bold md:text-5xl">THE <span className="text-neon-purple">CODEX</span></h1>
|
|
<p className="mt-3 max-w-xl text-foreground/60">
|
|
Curated archive of technical documents, research, and operational guides. Free entries and VOID-gated deep files.
|
|
</p>
|
|
</div>
|
|
<div className="flex gap-3">
|
|
<Link href="/sign-in" className="rounded-lg border border-neon-purple/40 bg-neon-purple/10 px-4 py-2 text-sm font-bold text-neon-purple hover:bg-neon-purple/20">
|
|
Submit document →
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Stats */}
|
|
<section className="container mx-auto max-w-6xl px-4 mb-8">
|
|
<div className="flex flex-wrap gap-6 text-sm">
|
|
{[
|
|
{ label: "Documents", value: DOCUMENTS.length },
|
|
{ label: "Free access", value: DOCUMENTS.filter((d) => d.access === "free").length },
|
|
{ label: "Total pages", value: DOCUMENTS.reduce((a, d) => a + d.pages, 0).toLocaleString() },
|
|
{ label: "Total reads", value: DOCUMENTS.reduce((a, d) => a + d.views, 0).toLocaleString() },
|
|
].map((s) => (
|
|
<div key={s.label} className="rounded-xl border border-zinc-800 bg-black/40 px-5 py-3">
|
|
<p className="font-bold text-foreground text-lg">{s.value}</p>
|
|
<p className="text-xs text-foreground/40">{s.label}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</section>
|
|
|
|
{/* Filters */}
|
|
<section className="container mx-auto max-w-6xl px-4 mb-6">
|
|
<div className="flex flex-wrap items-center gap-3">
|
|
<input
|
|
className="rounded-lg border border-zinc-700 bg-zinc-900 px-4 py-2 text-sm text-foreground placeholder-foreground/30 w-64 focus:border-neon-purple/40 outline-none"
|
|
placeholder="Search documents…"
|
|
value={search}
|
|
onChange={(e) => setSearch(e.target.value)}
|
|
/>
|
|
{CATS.map((c) => (
|
|
<button
|
|
key={c}
|
|
onClick={() => setCat(c)}
|
|
className={`rounded-full px-3 py-1.5 text-xs font-semibold border transition ${cat === c ? "border-neon-purple/50 bg-neon-purple/20 text-neon-purple" : "border-zinc-700 bg-zinc-900 text-foreground/60 hover:border-zinc-500"}`}
|
|
>
|
|
{c in CAT_ICONS ? `${CAT_ICONS[c]} ` : ""}{c}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</section>
|
|
|
|
{/* Document list */}
|
|
<section className="container mx-auto max-w-6xl px-4">
|
|
<div className="space-y-2">
|
|
{filtered.map((doc) => {
|
|
const isFree = doc.access === "free";
|
|
const cost = isFree ? null : parseInt(doc.access.split(":")[1] ?? "0");
|
|
return (
|
|
<div
|
|
key={doc.id}
|
|
className="flex flex-col gap-3 rounded-xl border border-zinc-700/40 bg-black/40 p-5 hover:border-zinc-500 transition sm:flex-row sm:items-center"
|
|
>
|
|
<div className="flex-1 min-w-0">
|
|
<div className="flex flex-wrap items-center gap-2 mb-1.5">
|
|
<span className="rounded-full border border-zinc-600 bg-zinc-800 px-2 py-0.5 text-[9px] uppercase tracking-wider text-zinc-400">
|
|
{CAT_ICONS[doc.category] ?? ""} {doc.category}
|
|
</span>
|
|
{isFree ? (
|
|
<span className="rounded-full border border-neon-green/30 bg-neon-green/10 px-2 py-0.5 text-[9px] font-bold text-neon-green">FREE</span>
|
|
) : (
|
|
<span className="rounded-full border border-neon-purple/30 bg-neon-purple/10 px-2 py-0.5 text-[9px] font-bold text-neon-purple">✦ {cost} VOID</span>
|
|
)}
|
|
<span className="text-[10px] text-foreground/30">{doc.pages}p · updated {doc.updated}</span>
|
|
</div>
|
|
<p className="font-semibold text-sm text-foreground">{doc.title}</p>
|
|
<p className="text-xs text-foreground/35 mt-0.5">{doc.views.toLocaleString()} reads</p>
|
|
</div>
|
|
<div className="shrink-0">
|
|
{isFree ? (
|
|
<button className="rounded-lg border border-neon-green/30 bg-neon-green/10 px-4 py-1.5 text-xs font-bold text-neon-green hover:bg-neon-green/20 transition">
|
|
Read →
|
|
</button>
|
|
) : (
|
|
<Link href="/tools" className="rounded-lg border border-neon-purple/30 bg-neon-purple/10 px-4 py-1.5 text-xs font-bold text-neon-purple hover:bg-neon-purple/20 transition">
|
|
Unlock with VOID →
|
|
</Link>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</section>
|
|
|
|
{/* CTA */}
|
|
<section className="container mx-auto max-w-2xl px-4 mt-16 text-center">
|
|
<div className="rounded-2xl border border-neon-purple/20 bg-neon-purple/5 p-8">
|
|
<h2 className="font-orbitron text-xl font-bold mb-3">Contribute to the Codex</h2>
|
|
<p className="text-sm text-foreground/60 mb-5">Submit original research and technical documents. Earn VOID credits for approved submissions.</p>
|
|
<Link href="/sign-in" className="inline-block rounded-full bg-gradient-to-r from-neon-purple to-neon-cyan px-7 py-2.5 text-sm font-bold text-background hover:opacity-90">
|
|
Submit Document →
|
|
</Link>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
</>
|
|
);
|
|
}
|