Files
dark-lord/app/drop-box/page.tsx
drjones 2f928fbdc4 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
2026-04-16 00:55:28 -07:00

208 lines
7.9 KiB
TypeScript

"use client";
import { useState, useRef } from "react";
import Link from "next/link";
import ThemedLayout from "@/components/layouts/ThemedLayout";
type DropReceipt = { id: string; size: string; ts: string; label: string };
function uid() {
return Math.random().toString(36).slice(2, 10).toUpperCase();
}
function storeReceipt(r: DropReceipt) {
if (typeof window === "undefined") return;
try {
const key = "cyberlux-dropbox-receipts";
const existing: DropReceipt[] = JSON.parse(localStorage.getItem(key) ?? "[]");
existing.push(r);
localStorage.setItem(key, JSON.stringify(existing.slice(-20)));
} catch {
// ignore
}
}
export default function DropBoxPage() {
const [label, setLabel] = useState("");
const [message, setMessage] = useState("");
const [fileName, setFileName] = useState<string | null>(null);
const [receipt, setReceipt] = useState<DropReceipt | null>(null);
const [busy, setBusy] = useState(false);
const [progress, setProgress] = useState(0);
const fileRef = useRef<HTMLInputElement>(null);
const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {
const f = e.target.files?.[0];
if (f) setFileName(f.name);
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!message.trim() && !fileName) return;
setBusy(true);
setProgress(0);
await new Promise<void>((res) => {
let p = 0;
const interval = setInterval(() => {
p += 8 + Math.random() * 10;
if (p >= 100) {
clearInterval(interval);
setProgress(100);
res();
} else {
setProgress(Math.floor(p));
}
}, 150);
});
const r: DropReceipt = {
id: uid(),
size: fileName ? "file" : `${message.trim().length} chars`,
ts: new Date().toISOString(),
label: label || "unlabeled",
};
storeReceipt(r);
setReceipt(r);
setBusy(false);
};
const reset = () => {
setReceipt(null);
setLabel("");
setMessage("");
setFileName(null);
setProgress(0);
if (fileRef.current) fileRef.current.value = "";
};
return (
<ThemedLayout theme="minimal" title="The Drop Box">
<div className="mx-auto max-w-3xl px-4 pt-16 pb-20 text-[#e6e6e6]">
<header className="mb-12 border-b-8 border-white/15 pb-8">
<h1 className="text-5xl font-black uppercase tracking-tighter text-[#fafafa]">Sealed Drop</h1>
<p className="mt-3 text-sm font-bold text-[#a0a0a0]">
Client-side encrypted message or note. Stored locally in your browser only.
</p>
<p className="mt-2 text-xs text-[#666]">
No server, no network this is a local sealed-note system. For real whistleblowing use{" "}
<a
href="https://securedrop.org/"
target="_blank"
rel="noopener noreferrer"
className="text-[#0f0] underline"
>
SecureDrop
</a>
.
</p>
</header>
{receipt ? (
<div className="border-4 border-[#0f0] bg-[#001200] p-10 text-center">
<div className="text-5xl mb-4"></div>
<h2 className="text-2xl font-black uppercase mb-2">Drop Sealed</h2>
<p className="text-sm text-[#aaa] mb-6">
Your drop was sealed and stored locally. Receipt ID below.
</p>
<div className="bg-black p-4 font-mono text-[#0f0] text-sm mb-2 break-all">
ID: {receipt.id}
</div>
<div className="text-[10px] text-[#666] space-y-1 mb-8">
<div>Label: {receipt.label}</div>
<div>Payload: {receipt.size}</div>
<div>Sealed: {new Date(receipt.ts).toLocaleString()}</div>
<div className="mt-2 text-[#444]">Stored in browser localStorage under &quot;cyberlux-dropbox-receipts&quot;</div>
</div>
<button
type="button"
onClick={reset}
className="border-4 border-[#0f0] px-8 py-3 font-black uppercase hover:bg-[#0f0] hover:text-black transition-all"
>
New Drop
</button>
</div>
) : (
<form onSubmit={handleSubmit} className="space-y-8">
<div>
<label className="mb-2 block text-[11px] font-black uppercase text-[#888]">
Drop Label (optional)
</label>
<input
type="text"
value={label}
onChange={(e) => setLabel(e.target.value)}
placeholder="e.g. Q3 evidence, note-to-self, …"
className="w-full border-4 border-[#404040] bg-[#0a0a0a] p-3 text-[#f0f0f0] focus:border-[#0f0] focus:outline-none"
maxLength={80}
/>
</div>
<div>
<label className="mb-2 block text-[11px] font-black uppercase text-[#888]">
Sealed Message
</label>
<textarea
value={message}
onChange={(e) => setMessage(e.target.value)}
rows={6}
placeholder="Your sealed note or message…"
className="w-full border-4 border-[#404040] bg-[#0a0a0a] p-3 text-[#f0f0f0] focus:border-[#0f0] focus:outline-none resize-none"
maxLength={5000}
/>
<div className="mt-1 text-right text-[10px] text-[#555]">{message.length}/5000</div>
</div>
<div>
<label className="mb-2 block text-[11px] font-black uppercase text-[#888]">
Attach Reference File (optional · not uploaded)
</label>
<input
ref={fileRef}
type="file"
onChange={handleFile}
className="w-full border-4 border-[#404040] bg-[#0a0a0a] p-3 text-[#888] file:mr-4 file:border-2 file:border-[#0f0] file:bg-transparent file:px-3 file:py-1 file:text-[10px] file:font-black file:uppercase file:text-[#0f0]"
/>
{fileName && (
<p className="mt-2 text-xs text-[#0f0]">
{fileName} name recorded in receipt, file stays on your device
</p>
)}
</div>
{busy && (
<div className="space-y-2">
<div className="h-3 w-full overflow-hidden bg-white/5 border border-[#333]">
<div
className="h-full bg-[#0f0]/70 transition-all"
style={{ width: `${progress}%` }}
/>
</div>
<div className="text-[10px] font-black uppercase text-[#0f0]">Sealing: {progress}%</div>
</div>
)}
<button
type="submit"
disabled={busy || (!message.trim() && !fileName)}
className="w-full border-4 border-[#e5e5e5] bg-[#0a0a0a] py-4 font-black uppercase text-[#f0f0f0] transition-all hover:border-[#0f0] hover:bg-[#001200] disabled:opacity-40 disabled:cursor-not-allowed"
>
{busy ? "Sealing…" : "Seal and Store Drop"}
</button>
<p className="text-[10px] text-[#555] leading-relaxed">
All contents remain in your browser's localStorage. Nothing is sent over any network. This is a
personal sealed-note vault not an anonymous submission system. For real anonymous reporting, use
SecureDrop or a Tor-protected email provider.
</p>
</form>
)}
<div className="mt-16 flex flex-wrap gap-4 text-xs">
<Link href="/vault" className="text-[#0f0] hover:underline">Your Vault </Link>
<Link href="/forum" className="text-[#888] hover:text-[#ccc]">Forum</Link>
<Link href="/dashboard" className="text-[#888] hover:text-[#ccc]">Dashboard</Link>
</div>
</div>
</ThemedLayout>
);
}