Capture the current CyberLux UI, commerce, messaging, and Tor ops updates so local main can be pushed to the remote. Made-with: Cursor
77 lines
2.0 KiB
TypeScript
77 lines
2.0 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect, useCallback } from "react";
|
|
import SecretLayer from "@/components/SecretLayer";
|
|
import DDoSProtection from "@/components/DDoSProtection";
|
|
import OnionDisclosureBar from "@/components/OnionDisclosureBar";
|
|
import HubChatterPublicStrip from "@/components/HubChatterPublicStrip";
|
|
import AppProviders from "@/components/AppProviders";
|
|
import DarkWebLaunchFooter from "@/components/DarkWebLaunchFooter";
|
|
|
|
const DDOS_KEY = "ddos_verified";
|
|
|
|
function readDdosVerified(): boolean {
|
|
if (typeof window === "undefined") return false;
|
|
try {
|
|
if (sessionStorage.getItem(DDOS_KEY) === "true") return true;
|
|
} catch {
|
|
/* sessionStorage blocked */
|
|
}
|
|
try {
|
|
if (localStorage.getItem(DDOS_KEY) === "true") return true;
|
|
} catch {
|
|
/* localStorage blocked */
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function persistDdosVerified(): void {
|
|
try {
|
|
sessionStorage.setItem(DDOS_KEY, "true");
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
try {
|
|
localStorage.setItem(DDOS_KEY, "true");
|
|
} catch {
|
|
/* ignore */
|
|
}
|
|
}
|
|
|
|
export default function RootLayoutClient({ children }: { children: React.ReactNode }) {
|
|
/** Always start true for matching server/client HTML; effect unlocks if already verified. */
|
|
const [isProtected, setIsProtected] = useState(true);
|
|
|
|
useEffect(() => {
|
|
if (readDdosVerified()) {
|
|
setIsProtected(false);
|
|
}
|
|
}, []);
|
|
|
|
const handleComplete = useCallback(() => {
|
|
persistDdosVerified();
|
|
setIsProtected(false);
|
|
}, []);
|
|
|
|
return (
|
|
<>
|
|
{isProtected ? (
|
|
<DDoSProtection onComplete={handleComplete} />
|
|
) : (
|
|
<>
|
|
<AppProviders>
|
|
<div className="flex min-h-screen flex-col">
|
|
<div className="flex-1">{children}</div>
|
|
<DarkWebLaunchFooter />
|
|
</div>
|
|
{/* Must stay inside AppProviders — uses useAccount() */}
|
|
<HubChatterPublicStrip />
|
|
</AppProviders>
|
|
<SecretLayer />
|
|
<OnionDisclosureBar />
|
|
</>
|
|
)}
|
|
</>
|
|
);
|
|
}
|