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,86 +1,226 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import Link from "next/link";
|
||||
import ThemedLayout from "@/components/layouts/ThemedLayout";
|
||||
import { useAccount } from "@/contexts/AccountContext";
|
||||
import { useWallet } from "@/contexts/WalletContext";
|
||||
|
||||
export default function MembershipPage() {
|
||||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||||
const [user, setUser] = useState("");
|
||||
const [pass, setPass] = useState("");
|
||||
const MEMBERSHIP_TIERS = [
|
||||
{ name: "Associate", minLux: 0, description: "Access to the channel digest and ring updates." },
|
||||
{ name: "Operative", minLux: 500, description: "Priority listing visibility and vault drop previews." },
|
||||
{ name: "Handler", minLux: 2000, description: "Early market access, barter priority lane, vendor fast-track." },
|
||||
{ name: "Principal", minLux: 8000, description: "All tiers plus operator-level forum ring keys and direct relay contact." },
|
||||
];
|
||||
|
||||
const handleLogin = (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (user === "admin" && pass === "shadow") {
|
||||
setIsLoggedIn(true);
|
||||
} else {
|
||||
alert("Invalid credentials. Access denied.");
|
||||
}
|
||||
};
|
||||
function getTier(lux: number) {
|
||||
let result = MEMBERSHIP_TIERS[0]!;
|
||||
for (const t of MEMBERSHIP_TIERS) {
|
||||
if (lux >= t.minLux) result = t;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const panel = "border-[10px] border-[#e5e5e5] bg-[#161616] p-12 shadow-[20px_20px_0_rgba(0,0,0,0.8)] text-[#f0f0f0]";
|
||||
const DIGEST = [
|
||||
{ tag: "MARKET", text: "New entropy dongle batch listed — vendor @relay_op, verified PGP.", href: "/market" },
|
||||
{ tag: "FORUM", text: "Thread on OPSEC hygiene for multi-site handles is trending in Ring IV.", href: "/forum" },
|
||||
{ tag: "DROPS", text: "Next scheduled drop in ~18h. Add /drops to your watchlist.", href: "/drops" },
|
||||
{ tag: "EXCHANGE", text: "WTB listing for XMR-to-credit bridge services posted 4h ago.", href: "/exchange" },
|
||||
{ tag: "VAULT", text: "Your receipts and earned keys live in the Vault — check after checkout.", href: "/vault" },
|
||||
];
|
||||
|
||||
export default function InnerCirclePage() {
|
||||
const { user, hydrated } = useAccount();
|
||||
const { luxCredits } = useWallet();
|
||||
const tier = getTier(luxCredits);
|
||||
const [tab, setTab] = useState<"digest" | "tiers" | "guide">("digest");
|
||||
|
||||
if (!hydrated) {
|
||||
return (
|
||||
<ThemedLayout theme="brutalist" title="The Inner Circle">
|
||||
<div className="mx-auto max-w-md pt-20 text-center font-mono text-sm text-foreground/50">
|
||||
Loading…
|
||||
</div>
|
||||
</ThemedLayout>
|
||||
);
|
||||
}
|
||||
|
||||
if (!user) {
|
||||
return (
|
||||
<ThemedLayout theme="brutalist" title="The Inner Circle">
|
||||
<div className="mx-auto max-w-md pt-20">
|
||||
<div className="border-[8px] border-[#e5e5e5] bg-[#161616] p-12 shadow-[16px_16px_0_rgba(0,0,0,0.8)] text-[#f0f0f0]">
|
||||
<h2 className="mb-4 text-4xl font-black uppercase italic">Members Only</h2>
|
||||
<p className="mb-8 text-sm text-[#aaa]">
|
||||
The Inner Circle is gated by your CyberLux handle. Sign in and earn LUX credits through purchases and
|
||||
forum activity to unlock higher tiers.
|
||||
</p>
|
||||
<div className="space-y-4">
|
||||
<Link
|
||||
href="/sign-in?next=/inner-circle"
|
||||
className="block w-full bg-[#f0f0f0] py-4 text-center font-black uppercase text-black transition-colors hover:bg-[#7cfc9a]"
|
||||
>
|
||||
Sign In
|
||||
</Link>
|
||||
<Link
|
||||
href="/sign-up?next=/inner-circle"
|
||||
className="block w-full border-4 border-[#e5e5e5] py-4 text-center font-black uppercase hover:border-[#7cfc9a]"
|
||||
>
|
||||
Create Handle
|
||||
</Link>
|
||||
</div>
|
||||
<div className="mt-10 border-t border-white/10 pt-6">
|
||||
<p className="text-[10px] uppercase text-[#666]">Tier access based on LUX balance — no paid gate</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ThemedLayout>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemedLayout theme="brutalist" title="The Inner Circle">
|
||||
<div className="mx-auto max-w-md pt-20">
|
||||
{!isLoggedIn ? (
|
||||
<div className={panel}>
|
||||
<h2 className="mb-8 text-4xl font-black uppercase italic text-[#fafafa]">Members Only</h2>
|
||||
<p className="mb-8 text-xs font-bold text-[#b0b0b0]">
|
||||
Access to the premium signal requires an active subscription. Pay 0.01 BTC to{" "}
|
||||
<span className="bg-[#262626] px-1 text-[#7cfc9a]">0x594f1Cf2A72b3f785fcB6ABdFa73B6D76FcC22b8</span> to
|
||||
receive your key.
|
||||
</p>
|
||||
<form onSubmit={handleLogin} className="space-y-6">
|
||||
<div className="mx-auto max-w-3xl pt-12 pb-20 px-4">
|
||||
<div className="border-[8px] border-[#e5e5e5] bg-[#161616] shadow-[16px_16px_0_rgba(0,0,0,0.8)] text-[#f0f0f0]">
|
||||
{/* Header */}
|
||||
<div className="border-b-4 border-[#e5e5e5] bg-[#111] px-8 py-6">
|
||||
<div className="flex flex-wrap items-center justify-between gap-4">
|
||||
<div>
|
||||
<label className="mb-2 block text-xs font-black uppercase text-[#a0a0a0]">Username</label>
|
||||
<input
|
||||
type="text"
|
||||
value={user}
|
||||
onChange={(e) => setUser(e.target.value)}
|
||||
className="w-full border-4 border-[#404040] bg-[#0a0a0a] p-3 font-bold text-[#f0f0f0] focus:border-[#7cfc9a] focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="mb-2 block text-xs font-black uppercase text-[#a0a0a0]">Access Key</label>
|
||||
<input
|
||||
type="password"
|
||||
value={pass}
|
||||
onChange={(e) => setPass(e.target.value)}
|
||||
className="w-full border-4 border-[#404040] bg-[#0a0a0a] p-3 font-bold text-[#f0f0f0] focus:border-[#7cfc9a] focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
<button className="w-full bg-[#f0f0f0] py-4 font-black uppercase text-black transition-colors hover:bg-[#7cfc9a]">
|
||||
Enter the Circle
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
) : (
|
||||
<div className={panel}>
|
||||
<h2 className="mb-8 text-4xl font-black uppercase text-[#fafafa]">Welcome, Initiate</h2>
|
||||
<div className="space-y-6">
|
||||
<div className="border-4 border-[#854d0e] bg-[#1c1410] p-4">
|
||||
<h3 className="font-black uppercase text-[#fbbf24]">Today's Signal</h3>
|
||||
<p className="mt-2 text-sm text-[#d6cbb8]">Buy $BTC at 64,200. Target 68,000. Stop loss 63,500.</p>
|
||||
</div>
|
||||
<div className="border-4 border-[#14532d] bg-[#0f1612] p-4">
|
||||
<h3 className="font-black uppercase text-[#4ade80]">Private Leak</h3>
|
||||
<p className="mt-2 text-sm text-[#d6cbb8]">
|
||||
New database from "GlobalCorp" available in the vault.
|
||||
<h2 className="text-3xl font-black uppercase italic">Welcome, @{user.username}</h2>
|
||||
<p className="mt-1 text-sm text-[#aaa]">
|
||||
Tier:{" "}
|
||||
<span className="font-black text-[#7cfc9a]">{tier.name}</span>
|
||||
{" · "}
|
||||
<span className="text-[#7cfc9a]">{luxCredits.toLocaleString()} LUX</span>
|
||||
</p>
|
||||
</div>
|
||||
<button onClick={() => setIsLoggedIn(false)} className="text-xs font-black uppercase text-[#a0a0a0] underline">
|
||||
Logout
|
||||
</button>
|
||||
<div className="text-right text-[10px] uppercase text-[#666]">
|
||||
<div className="text-2xl font-black text-[#7cfc9a]">{tier.name}</div>
|
||||
<div>{tier.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-12 flex items-center justify-center gap-4 opacity-60">
|
||||
<div className="flex h-12 w-12 items-center justify-center border-4 border-[#e5e5e5] font-black text-[#fafafa]">E</div>
|
||||
<div className="text-[10px] font-black uppercase leading-tight text-[#888]">
|
||||
Escrow Assured
|
||||
<br />
|
||||
by ShadowGuard™
|
||||
{/* Tier progress */}
|
||||
<div className="border-b-4 border-[#3a3a3a] px-8 py-4">
|
||||
<div className="flex gap-2">
|
||||
{MEMBERSHIP_TIERS.map((t, i) => {
|
||||
const reached = luxCredits >= t.minLux;
|
||||
const active = t.name === tier.name;
|
||||
return (
|
||||
<div
|
||||
key={t.name}
|
||||
className={`flex-1 border-2 py-2 text-center text-[10px] font-black uppercase transition-colors ${
|
||||
active
|
||||
? "border-[#7cfc9a] bg-[#7cfc9a]/15 text-[#7cfc9a]"
|
||||
: reached
|
||||
? "border-[#666] text-[#aaa]"
|
||||
: "border-[#333] text-[#555]"
|
||||
}`}
|
||||
>
|
||||
<div>{t.name}</div>
|
||||
<div className="font-normal">{t.minLux.toLocaleString()} LUX</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Tabs */}
|
||||
<div className="flex border-b-4 border-[#3a3a3a]">
|
||||
{(["digest", "tiers", "guide"] as const).map((t) => (
|
||||
<button
|
||||
key={t}
|
||||
type="button"
|
||||
onClick={() => setTab(t)}
|
||||
className={`flex-1 py-3 text-[11px] font-black uppercase transition-colors ${
|
||||
tab === t ? "bg-[#7cfc9a]/15 text-[#7cfc9a]" : "text-[#888] hover:text-[#ccc]"
|
||||
}`}
|
||||
>
|
||||
{t === "digest" ? "Signal Digest" : t === "tiers" ? "Tier Benefits" : "Operations Guide"}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="p-8">
|
||||
{tab === "digest" && (
|
||||
<div className="space-y-4">
|
||||
<p className="text-[11px] uppercase text-[#666]">Current hub signals · real-time activity</p>
|
||||
{DIGEST.map((d) => (
|
||||
<Link
|
||||
key={d.tag}
|
||||
href={d.href}
|
||||
className="flex items-start gap-4 border-2 border-[#333] bg-[#0d0d0d] p-4 transition-all hover:border-[#7cfc9a]/40"
|
||||
>
|
||||
<span className="mt-0.5 shrink-0 rounded bg-[#7cfc9a]/15 px-2 py-0.5 text-[10px] font-black uppercase text-[#7cfc9a]">
|
||||
{d.tag}
|
||||
</span>
|
||||
<p className="text-sm text-[#ddd]">{d.text}</p>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{tab === "tiers" && (
|
||||
<div className="space-y-4">
|
||||
<p className="text-[11px] uppercase text-[#666]">Earn LUX via purchases and activity</p>
|
||||
{MEMBERSHIP_TIERS.map((t) => {
|
||||
const reached = luxCredits >= t.minLux;
|
||||
return (
|
||||
<div
|
||||
key={t.name}
|
||||
className={`border-2 p-6 ${reached ? "border-[#7cfc9a]/40 bg-[#0f1a0f]" : "border-[#333] bg-[#0d0d0d] opacity-60"}`}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="text-xl font-black">{t.name}</div>
|
||||
<div className="text-sm font-bold text-[#7cfc9a]">{t.minLux.toLocaleString()} LUX</div>
|
||||
</div>
|
||||
<p className="mt-2 text-sm text-[#aaa]">{t.description}</p>
|
||||
{!reached && (
|
||||
<p className="mt-2 text-xs text-[#666]">
|
||||
Need {(t.minLux - luxCredits).toLocaleString()} more LUX
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{tab === "guide" && (
|
||||
<div className="space-y-6 text-sm text-[#ccc]">
|
||||
<p className="text-[11px] uppercase text-[#666]">Operational guidelines</p>
|
||||
<div>
|
||||
<h4 className="mb-2 font-black uppercase text-[#f0f0f0]">Earning LUX</h4>
|
||||
<p className="text-[#aaa] leading-relaxed">
|
||||
LUX credits are earned on every purchase at checkout. Spend at the Mixer (coin-blending theatre),
|
||||
or hold to maintain tier status. LUX is stored per-handle in your browser — export your account
|
||||
bundle to carry it across devices.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="mb-2 font-black uppercase text-[#f0f0f0]">Adding Funds</h4>
|
||||
<p className="text-[#aaa] leading-relaxed">
|
||||
Fund your account via Bitcoin at{" "}
|
||||
<Link href="/account/add-funds" className="text-[#7cfc9a] underline">
|
||||
/account/add-funds
|
||||
</Link>
|
||||
. After one confirmation, paste the txid — USD credit is applied to your handle at current spot.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="mb-2 font-black uppercase text-[#f0f0f0]">OPSEC basics</h4>
|
||||
<p className="text-[#aaa] leading-relaxed">
|
||||
Use Tor Browser on .onion deployments. Export your account bundle from{" "}
|
||||
<Link href="/dashboard" className="text-[#7cfc9a] underline">
|
||||
/dashboard
|
||||
</Link>{" "}
|
||||
before clearing site data. Verify mirror PGP each session — phishing clones exist.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user