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
173 lines
6.6 KiB
TypeScript
173 lines
6.6 KiB
TypeScript
"use client";
|
||
|
||
import Link from "next/link";
|
||
import { useState } from "react";
|
||
|
||
const AccountCreation = () => {
|
||
const [step, setStep] = useState(1);
|
||
const [username, setUsername] = useState("");
|
||
const [password, setPassword] = useState("");
|
||
const [recoveryPhrase, setRecoveryPhrase] = useState("");
|
||
const [encryptionKey, setEncryptionKey] = useState("");
|
||
const [generated, setGenerated] = useState(false);
|
||
|
||
const generateRecovery = () => {
|
||
const phrases = [
|
||
"phantom quantum glacier nexus",
|
||
"crimson velvet paradox silence",
|
||
"neon abyss whisper eclipse",
|
||
"zero trace ghost protocol",
|
||
];
|
||
const randomPhrase = phrases[Math.floor(Math.random() * phrases.length)];
|
||
setRecoveryPhrase(randomPhrase);
|
||
setEncryptionKey(btoa(Date.now().toString()).slice(0, 16));
|
||
setGenerated(true);
|
||
};
|
||
|
||
const handleSubmit = (e: React.FormEvent) => {
|
||
e.preventDefault();
|
||
if (step < 3) {
|
||
setStep(step + 1);
|
||
} else {
|
||
alert("Identity provisioned. Keys derived locally — backup your recovery phrase offline.");
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="glass mx-auto max-w-2xl rounded-3xl border border-white/10 p-10">
|
||
<h2 className="mb-8 font-orbitron text-4xl font-bold text-center">CREATE SHADOW IDENTITY</h2>
|
||
|
||
{/* Steps */}
|
||
<div className="mb-10 flex justify-between">
|
||
{[1, 2, 3].map((s) => (
|
||
<div key={s} className="flex flex-col items-center">
|
||
<div
|
||
className={`flex h-12 w-12 items-center justify-center rounded-full border-2 text-lg font-bold ${step >= s
|
||
? "border-neon-cyan bg-neon-cyan/20 text-neon-cyan"
|
||
: "border-white/20 text-foreground/40"
|
||
}`}
|
||
>
|
||
{s}
|
||
</div>
|
||
<div className="mt-2 text-sm">
|
||
{s === 1 && "Credentials"}
|
||
{s === 2 && "Recovery"}
|
||
{s === 3 && "Encryption"}
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
|
||
<form onSubmit={handleSubmit}>
|
||
{step === 1 && (
|
||
<div className="space-y-6">
|
||
<div>
|
||
<label className="mb-2 block font-medium">Shadow Alias</label>
|
||
<input
|
||
type="text"
|
||
className="glass w-full rounded-xl border border-white/10 bg-transparent p-4"
|
||
placeholder="e.g., Ghost_23"
|
||
value={username}
|
||
onChange={(e) => setUsername(e.target.value)}
|
||
required
|
||
/>
|
||
<p className="mt-2 text-sm text-foreground/60">Never your real name. This alias is encrypted.</p>
|
||
</div>
|
||
<div>
|
||
<label className="mb-2 block font-medium">Zero‑Knowledge Password</label>
|
||
<input
|
||
type="password"
|
||
className="glass w-full rounded-xl border border-white/10 bg-transparent p-4"
|
||
placeholder="••••••••••"
|
||
value={password}
|
||
onChange={(e) => setPassword(e.target.value)}
|
||
required
|
||
/>
|
||
<p className="mt-2 text-sm text-foreground/60">We never store your password. It’s used to derive your encryption key.</p>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{step === 2 && (
|
||
<div className="space-y-6">
|
||
<div>
|
||
<label className="mb-2 block font-medium">Recovery Phrase</label>
|
||
<div className="glass rounded-xl border border-neon-cyan/30 p-6 font-mono text-center text-lg">
|
||
{generated ? recoveryPhrase : "Click generate to create"}
|
||
</div>
|
||
<button
|
||
type="button"
|
||
className="mt-4 w-full rounded-full bg-gradient-to-r from-neon-cyan to-neon-purple py-3 font-bold text-background"
|
||
onClick={generateRecovery}
|
||
>
|
||
GENERATE RECOVERY PHRASE
|
||
</button>
|
||
<p className="mt-4 text-sm text-foreground/60">
|
||
Write this down physically. It’s the only way to recover your account. We do not store it.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{step === 3 && (
|
||
<div className="space-y-6">
|
||
<div>
|
||
<label className="mb-2 block font-medium">Encryption Key</label>
|
||
<div className="glass rounded-xl border border-neon-green/30 p-6 font-mono text-center text-lg">
|
||
{encryptionKey || "Not generated"}
|
||
</div>
|
||
<p className="mt-4 text-sm text-foreground/60">
|
||
This key encrypts all your data locally. It is derived from your password and never leaves your device.
|
||
</p>
|
||
</div>
|
||
<div className="rounded-xl bg-gradient-to-r from-neon-cyan/10 to-neon-purple/10 p-6">
|
||
<h3 className="font-bold">Identity Summary</h3>
|
||
<div className="mt-4 grid grid-cols-2 gap-4 text-sm">
|
||
<div>Alias</div>
|
||
<div className="font-mono">{username || "—"}</div>
|
||
<div>Recovery Phrase</div>
|
||
<div className="font-mono truncate">{recoveryPhrase || "—"}</div>
|
||
<div>Encryption</div>
|
||
<div className="font-mono text-neon-green">AES‑256‑GCM</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
<div className="mt-10 flex justify-between">
|
||
<button
|
||
type="button"
|
||
className="glass rounded-full px-8 py-3 font-medium disabled:opacity-30"
|
||
onClick={() => setStep(step - 1)}
|
||
disabled={step === 1}
|
||
>
|
||
← Back
|
||
</button>
|
||
<button
|
||
type="submit"
|
||
className="rounded-full bg-gradient-to-r from-neon-cyan to-neon-purple px-10 py-3 font-bold text-background"
|
||
>
|
||
{step === 3 ? "COMPLETE IDENTITY CREATION" : "CONTINUE →"}
|
||
</button>
|
||
</div>
|
||
</form>
|
||
|
||
<div className="mt-10 border-t border-white/10 pt-8 text-center text-sm text-foreground/40">
|
||
<p>Keys and aliases never leave this browser profile. Clear storage = identity loss.</p>
|
||
<p className="mt-4 text-foreground/55">
|
||
For a <strong className="text-neon-cyan/90">live stall session</strong> tied to wallet and activity feeds, use{" "}
|
||
<Link href="/sign-up" className="text-neon-cyan underline hover:text-neon-purple">
|
||
create account
|
||
</Link>{" "}
|
||
or{" "}
|
||
<Link href="/sign-in" className="text-neon-cyan underline hover:text-neon-purple">
|
||
sign in
|
||
</Link>
|
||
.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default AccountCreation; |