10x every page: real interactions, kill fake content, wire everything
- ChatWidget: remove illegal seeds, real localStorage per-handle chat, honest bot replies about market/forum/funds - ForumBoard: wire to real forumState (loadForum/addThread/vote), kill fake stats and illegal seed posts - Home page: privacy features list reflects reality, footer links real - Links: kill all alert() calls, replace fake onions with real clearnet privacy resources + internal route grid - Support: per-coin copied state, env-driven addresses, real BTC addr - Inner circle: wire to AccountContext, tier system from LUX balance, remove hardcoded admin/shadow credentials and fake trading signals - Drop box: real sealed-note localStorage system, honest about no anonymous upload capability, real file picker with receipt - Messages: fully functional per-handle localStorage chat, AI-style contextual bot replies, clear history, honest about local storage - Wallets: pivot from fake PayPal accounts to Digital Access Passes, wire Buy Now to cart via ShopProduct interface - Testimonials: wire submit form to localStorage, interactive star rating 1-10, display submitted reviews above the fold - Raffle: use real merchant BTC address, real per-handle entry storage, honest LUX-only prize disclaimer, fix 0x address - Drops/Lotto: real number picker 1-49 with Quick Pick, ticket submission, match display against drawn numbers, demo disclaimer - Sanctuary: real 4-4-6-2 breathing timer, meditation passage with timer, candle-lighting with localStorage notes - Game: full playable Void Pong with canvas physics, CPU AI, scoring, rally counter, localStorage high score - Security analysis: honest architecture breakdown with real grades, layer-by-layer analysis, practical OPSEC guide, fiction banner - Trust: compute real scores from actual localStorage data (LUX, USD, forum posts, testimonials), FAQ accordion Made-with: Cursor
This commit is contained in:
@@ -1,220 +1,168 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useAccount } from "@/contexts/AccountContext";
|
||||
import {
|
||||
loadForum,
|
||||
addThread,
|
||||
displayScore,
|
||||
setVoteForThread,
|
||||
getVoteForThread,
|
||||
type ForumThread,
|
||||
} from "@/lib/forumState";
|
||||
|
||||
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 CATEGORIES = ["All", "Security", "Market", "OPSEC", "Tech", "General"];
|
||||
|
||||
export default function ForumBoard() {
|
||||
const { user } = useAccount();
|
||||
const [threads, setThreads] = useState<ForumThread[]>([]);
|
||||
const [newPost, setNewPost] = useState("");
|
||||
const [selectedCategory, setSelectedCategory] = useState("All");
|
||||
const [selectedCat, setSelectedCat] = useState("All");
|
||||
const [voteBump, setVoteBump] = useState(0);
|
||||
const [posting, setPosting] = useState(false);
|
||||
|
||||
const categories = ["All", "Bio‑Enhancements", "Financial", "Security", "Identity", "Weapons", "Chemicals"];
|
||||
useEffect(() => {
|
||||
setThreads(loadForum().slice(0, 8));
|
||||
}, []);
|
||||
|
||||
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]);
|
||||
if (!newPost.trim() || posting) return;
|
||||
setPosting(true);
|
||||
const thread = addThread({
|
||||
title: newPost.slice(0, 80),
|
||||
body: newPost,
|
||||
author: user?.username ?? "anon",
|
||||
topicSlug: "general",
|
||||
category: "General",
|
||||
replies: [],
|
||||
});
|
||||
setThreads([thread, ...threads].slice(0, 8));
|
||||
setNewPost("");
|
||||
setPosting(false);
|
||||
};
|
||||
|
||||
const filteredPosts = selectedCategory === "All"
|
||||
? posts
|
||||
: posts.filter(p => p.category === selectedCategory);
|
||||
const handleVote = (id: string, delta: 1 | -1) => {
|
||||
const existing = getVoteForThread(id);
|
||||
const next = existing === delta ? 0 : delta;
|
||||
setVoteForThread(id, next as 1 | -1 | 0);
|
||||
setVoteBump((v) => v + 1);
|
||||
};
|
||||
|
||||
const visible = selectedCat === "All"
|
||||
? threads
|
||||
: threads.filter((t) => t.category === selectedCat || t.topicSlug === selectedCat.toLowerCase());
|
||||
|
||||
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 className="mb-8 flex flex-wrap items-start justify-between gap-4">
|
||||
<div>
|
||||
<h2 className="font-orbitron text-3xl font-bold">VOID AGGREGATE</h2>
|
||||
<p className="mt-1 text-sm text-foreground/60">
|
||||
{threads.length} threads shown · full board at{" "}
|
||||
<Link href="/forum" className="text-neon-cyan hover:underline">/forum</Link>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Category filter */}
|
||||
<div className="mb-8 flex flex-wrap gap-3">
|
||||
{categories.map((cat) => (
|
||||
<div className="mb-6 flex flex-wrap gap-2">
|
||||
{CATEGORIES.map((cat) => (
|
||||
<button
|
||||
key={cat}
|
||||
className={`rounded-full px-4 py-2 text-sm font-medium transition-all ${selectedCategory === cat
|
||||
type="button"
|
||||
onClick={() => setSelectedCat(cat)}
|
||||
className={`rounded-full px-4 py-1.5 text-xs font-medium transition-all ${
|
||||
selectedCat === cat
|
||||
? "bg-gradient-to-r from-neon-cyan to-neon-purple text-background"
|
||||
: "glass border border-white/10"
|
||||
}`}
|
||||
onClick={() => setSelectedCategory(cat)}
|
||||
: "glass border border-white/10 hover:border-neon-cyan/30"
|
||||
}`}
|
||||
>
|
||||
{cat}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* New post form */}
|
||||
<form onSubmit={handleSubmit} className="mb-10">
|
||||
<div className="glass rounded-2xl border border-white/10 p-6">
|
||||
{/* Quick post form */}
|
||||
<form onSubmit={handleSubmit} className="mb-8">
|
||||
<div className="glass rounded-2xl border border-white/10 p-5">
|
||||
<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)"
|
||||
className="w-full bg-transparent text-sm text-foreground placeholder-foreground/40 focus:outline-none"
|
||||
rows={2}
|
||||
placeholder={user ? `Post as @${user.username}…` : "Quick post (stored in your browser)…"}
|
||||
value={newPost}
|
||||
onChange={(e) => setNewPost(e.target.value)}
|
||||
maxLength={500}
|
||||
/>
|
||||
<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>
|
||||
<div className="mt-3 flex items-center justify-between">
|
||||
<span className="text-[10px] text-foreground/30">{newPost.length}/500 · local storage</span>
|
||||
<button
|
||||
type="submit"
|
||||
className="rounded-full bg-gradient-to-r from-neon-cyan to-neon-purple px-6 py-3 font-bold text-background"
|
||||
disabled={!newPost.trim() || posting}
|
||||
className="rounded-full bg-gradient-to-r from-neon-cyan to-neon-purple px-5 py-2 text-sm font-bold text-background disabled:opacity-40"
|
||||
>
|
||||
PUBLISH
|
||||
Post
|
||||
</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>
|
||||
{/* Thread list */}
|
||||
<div className="space-y-4">
|
||||
{visible.length === 0 ? (
|
||||
<p className="py-6 text-center text-sm text-foreground/40">No threads in this category yet.</p>
|
||||
) : (
|
||||
visible.map((t) => {
|
||||
const score = displayScore(t);
|
||||
const voted = typeof window !== "undefined" ? getVoteForThread(t.id) : 0;
|
||||
return (
|
||||
<div key={t.id + voteBump} className="glass rounded-2xl border border-white/10 p-5">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<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 className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-neon-cyan/20 to-neon-purple/20 text-sm font-bold">
|
||||
{(t.author ?? "?").charAt(0).toUpperCase()}
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<span className="text-sm font-bold">@{t.author ?? "anon"}</span>
|
||||
{t.category && (
|
||||
<span className="rounded-full bg-white/5 px-2 py-0.5 text-[10px]">{t.category}</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="text-xs text-foreground/40">{new Date(t.ts).toLocaleDateString()}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-sm text-foreground/60">{post.timestamp}</div>
|
||||
<div className="flex shrink-0 items-center gap-3">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleVote(t.id, 1)}
|
||||
className={`text-xs transition-colors ${voted === 1 ? "text-neon-cyan" : "text-foreground/40 hover:text-neon-cyan"}`}
|
||||
>
|
||||
▲ {score}
|
||||
</button>
|
||||
<span className="text-xs text-foreground/30">💬 {t.replies.length}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3">
|
||||
<Link href="/forum" className="text-sm hover:text-neon-cyan/80">
|
||||
{t.title ?? t.body?.slice(0, 100)}
|
||||
</Link>
|
||||
</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 className="mt-6 text-center">
|
||||
<Link
|
||||
href="/forum"
|
||||
className="inline-flex items-center gap-2 rounded-full border border-neon-cyan/30 px-6 py-2 text-sm font-bold text-neon-cyan hover:bg-neon-cyan/10"
|
||||
>
|
||||
Open full forum →
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ForumBoard;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user