Replace remote with local repo
This commit is contained in:
147
app/codex/page.tsx
Normal file
147
app/codex/page.tsx
Normal file
@@ -0,0 +1,147 @@
|
||||
"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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user