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
220 lines
7.9 KiB
TypeScript
220 lines
7.9 KiB
TypeScript
"use client";
|
||
|
||
import Link from "next/link";
|
||
import { useState } from "react";
|
||
|
||
const ForumBoard = () => {
|
||
const [posts, setPosts] = useState([
|
||
{
|
||
id: 1,
|
||
user: "GhostInTheShell",
|
||
avatar: "👻",
|
||
timestamp: "2 hours ago",
|
||
content: "Has anyone tested the new neural stimulant? Need reports on side‑effects.",
|
||
upvotes: 42,
|
||
replies: 12,
|
||
category: "Bio‑Enhancements",
|
||
},
|
||
{
|
||
id: 2,
|
||
user: "ZeroCool",
|
||
avatar: "🕵️",
|
||
timestamp: "5 hours ago",
|
||
content: "Quantum counterfeit notes batch #8 passes all validation tests. Available for bulk orders.",
|
||
upvotes: 89,
|
||
replies: 24,
|
||
category: "Financial",
|
||
},
|
||
{
|
||
id: 3,
|
||
user: "CypherPunk",
|
||
avatar: "🔐",
|
||
timestamp: "1 day ago",
|
||
content: "New darknet router vulnerability discovered. Patch your firmware immediately.",
|
||
upvotes: 156,
|
||
replies: 47,
|
||
category: "Security",
|
||
},
|
||
{
|
||
id: 4,
|
||
user: "Ethereal",
|
||
avatar: "🌌",
|
||
timestamp: "2 days ago",
|
||
content: "Looking for reliable identity pack vendor with EU passports. DM with reputation score.",
|
||
upvotes: 33,
|
||
replies: 8,
|
||
category: "Identity",
|
||
},
|
||
]);
|
||
|
||
const [newPost, setNewPost] = useState("");
|
||
const [selectedCategory, setSelectedCategory] = useState("All");
|
||
|
||
const categories = ["All", "Bio‑Enhancements", "Financial", "Security", "Identity", "Weapons", "Chemicals"];
|
||
|
||
const handleSubmit = (e: React.FormEvent) => {
|
||
e.preventDefault();
|
||
if (!newPost.trim()) return;
|
||
const newPostObj = {
|
||
id: posts.length + 1,
|
||
user: "Anonymous",
|
||
avatar: "🕶️",
|
||
timestamp: "Just now",
|
||
content: newPost,
|
||
upvotes: 0,
|
||
replies: 0,
|
||
category: "Uncategorized",
|
||
};
|
||
setPosts([newPostObj, ...posts]);
|
||
setNewPost("");
|
||
};
|
||
|
||
const filteredPosts = selectedCategory === "All"
|
||
? posts
|
||
: posts.filter(p => p.category === selectedCategory);
|
||
|
||
return (
|
||
<div className="glass rounded-3xl border border-white/10 p-8">
|
||
<div className="mb-10">
|
||
<h2 className="font-orbitron text-4xl font-bold">DARKNET FORUM</h2>
|
||
<p className="mt-2 text-foreground/70">Encrypted, anonymous discussions. No logs, no traces.</p>
|
||
</div>
|
||
|
||
{/* Category filter */}
|
||
<div className="mb-8 flex flex-wrap gap-3">
|
||
{categories.map((cat) => (
|
||
<button
|
||
key={cat}
|
||
className={`rounded-full px-4 py-2 text-sm font-medium transition-all ${selectedCategory === cat
|
||
? "bg-gradient-to-r from-neon-cyan to-neon-purple text-background"
|
||
: "glass border border-white/10"
|
||
}`}
|
||
onClick={() => setSelectedCategory(cat)}
|
||
>
|
||
{cat}
|
||
</button>
|
||
))}
|
||
</div>
|
||
|
||
{/* New post form */}
|
||
<form onSubmit={handleSubmit} className="mb-10">
|
||
<div className="glass rounded-2xl border border-white/10 p-6">
|
||
<textarea
|
||
className="w-full bg-transparent text-foreground placeholder-foreground/50 focus:outline-none"
|
||
rows={3}
|
||
placeholder="Type your encrypted message... (all posts are ephemeral)"
|
||
value={newPost}
|
||
onChange={(e) => setNewPost(e.target.value)}
|
||
/>
|
||
<div className="mt-4 flex items-center justify-between">
|
||
<div className="flex gap-4">
|
||
<button
|
||
type="button"
|
||
className="flex items-center gap-2 rounded-full bg-white/5 px-4 py-2 text-sm"
|
||
>
|
||
<span>🔒</span> Encrypt
|
||
</button>
|
||
<button
|
||
type="button"
|
||
className="flex items-center gap-2 rounded-full bg-white/5 px-4 py-2 text-sm"
|
||
>
|
||
<span>🕵️</span> Post Anonymously
|
||
</button>
|
||
</div>
|
||
<button
|
||
type="submit"
|
||
className="rounded-full bg-gradient-to-r from-neon-cyan to-neon-purple px-6 py-3 font-bold text-background"
|
||
>
|
||
PUBLISH
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
|
||
{/* Posts list */}
|
||
<div className="space-y-6">
|
||
{filteredPosts.map((post) => (
|
||
<div key={post.id} className="glass rounded-2xl border border-white/10 p-6">
|
||
<div className="flex items-start justify-between">
|
||
<div className="flex items-center gap-4">
|
||
<div className="flex h-12 w-12 items-center justify-center rounded-full bg-gradient-to-br from-neon-cyan to-neon-purple text-2xl">
|
||
{post.avatar}
|
||
</div>
|
||
<div>
|
||
<div className="flex items-center gap-3">
|
||
<span className="font-bold">{post.user}</span>
|
||
<span className="rounded-full bg-white/5 px-3 py-1 text-xs">{post.category}</span>
|
||
</div>
|
||
<div className="text-sm text-foreground/60">{post.timestamp}</div>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-center gap-4">
|
||
<button className="flex items-center gap-2 text-sm text-foreground/60 hover:text-neon-cyan">
|
||
<span>⬆</span> {post.upvotes}
|
||
</button>
|
||
<button className="flex items-center gap-2 text-sm text-foreground/60 hover:text-neon-cyan">
|
||
<span>💬</span> {post.replies}
|
||
</button>
|
||
<button className="rounded-full bg-white/5 p-2 hover:bg-white/10">
|
||
<span>🔗</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div className="mt-6">
|
||
<p>{post.content}</p>
|
||
</div>
|
||
<div className="mt-6 flex items-center gap-6 border-t border-white/10 pt-6">
|
||
<button className="flex items-center gap-2 text-sm">
|
||
<span>⬆</span> Upvote
|
||
</button>
|
||
<button className="flex items-center gap-2 text-sm">
|
||
<span>⬇</span> Downvote
|
||
</button>
|
||
<button className="flex items-center gap-2 text-sm">
|
||
<span>💬</span> Reply
|
||
</button>
|
||
<button className="flex items-center gap-2 text-sm">
|
||
<span>🔐</span> Encrypt Reply
|
||
</button>
|
||
<button className="flex items-center gap-2 text-sm">
|
||
<span>🚀</span> Boost
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
{/* Forum stats */}
|
||
<div className="mt-10 grid grid-cols-2 gap-6 md:grid-cols-4">
|
||
<div className="glass rounded-2xl border border-white/10 p-6 text-center">
|
||
<div className="text-3xl font-bold text-neon-cyan">2.4k</div>
|
||
<div className="text-sm text-foreground/60">Active Users</div>
|
||
</div>
|
||
<div className="glass rounded-2xl border border-white/10 p-6 text-center">
|
||
<div className="text-3xl font-bold text-neon-purple">18.5k</div>
|
||
<div className="text-sm text-foreground/60">Total Posts</div>
|
||
</div>
|
||
<div className="glass rounded-2xl border border-white/10 p-6 text-center">
|
||
<div className="text-3xl font-bold text-neon-pink">94%</div>
|
||
<div className="text-sm text-foreground/60">Encrypted</div>
|
||
</div>
|
||
<div className="glass rounded-2xl border border-white/10 p-6 text-center">
|
||
<div className="text-3xl font-bold text-neon-green">0</div>
|
||
<div className="text-sm text-foreground/60">Data Leaks</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="mt-8 text-center text-xs text-foreground/40">
|
||
<p>
|
||
Preview board — for threads that persist in your browser, open the{" "}
|
||
<Link href="/forum" className="text-neon-cyan hover:underline">
|
||
full forum
|
||
</Link>{" "}
|
||
(dedicated .onion maps here too).
|
||
</p>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default ForumBoard; |