A full settings shell with working section tabs, profile editor, live notification toggles, billing cards and a danger zone — the account pages nobody wants to design twice.
Settings Shell
Ayush Kumar
ayush@uidrops.dev
Sidebar section nav with a working active state — click Profile, Notifications or Billing to switch panels.
| 1 | function SettingsShell() { |
| 2 | const [section, setSection] = useState("Profile"); |
| 3 | const sections = ["Profile", "Notifications", "Billing", "Security"]; |
| 4 | |
| 5 | return ( |
| 6 | <div "color:#79c0ff">className="flex overflow-hidden rounded-2xl border border-white/10 bg-[#08080f]"> |
| 7 | {/* section nav */} |
| 8 | <nav "color:#79c0ff">className="w-44 shrink-0 space-y-1 border-r border-white/8 p-3"> |
| 9 | <p "color:#79c0ff">className="px-3 pb-2 pt-1 text-[10px] font-bold uppercase tracking-widest text-white/25">Settings</p> |
| 10 | {sections.map((s) => ( |
| 11 | <button "color:#79c0ff">key={s} "color:#79c0ff">onClick={() => setSection(s)} |
| 12 | "color:#79c0ff">className={"block w-full rounded-xl px-3 py-2 text-left text-sm font-medium transition " + |
| 13 | (section === s |
| 14 | ? "bg-violet-500/15 font-semibold text-violet-300 ring-1 ring-inset ring-violet-400/25" |
| 15 | : "text-white/45 hover:bg-white/5 hover:text-white")}> |
| 16 | {s} |
| 17 | </button> |
| 18 | ))} |
| 19 | </nav> |
| 20 | |
| 21 | {/* panel — swap content by section */} |
| 22 | <div "color:#79c0ff">className="min-w-0 flex-1 p-6"> |
| 23 | <h3 "color:#79c0ff">className="text-base font-extrabold text-white">{section}</h3> |
| 24 | {/* … render the matching panel here … */} |
| 25 | </div> |
| 26 | </div> |
| 27 | ); |
| 28 | } |
Profile Editor Card
Public profile
This appears on your posts and comments.
34 / 160
Last saved 2 min ago
Avatar with upload ring, paired inputs, a bio counter and sticky save bar.
| 1 | <div "color:#79c0ff">className="w-full max-w-md rounded-3xl border border-white/10 bg-white/[0.03]"> |
| 2 | <div "color:#79c0ff">className="p-6"> |
| 3 | <p "color:#79c0ff">className="text-sm font-extrabold text-white">Public profile</p> |
| 4 | <p "color:#79c0ff">className="mt-0.5 text-xs text-white/35">This appears on your posts and comments.</p> |
| 5 | |
| 6 | {/* avatar row */} |
| 7 | <div "color:#79c0ff">className="mt-5 flex items-center gap-4"> |
| 8 | <div "color:#79c0ff">className="relative"> |
| 9 | <span "color:#79c0ff">className="flex h-16 w-16 items-center justify-center rounded-full bg-gradient-to-br from-violet-500 to-indigo-600 text-lg font-black text-white">AK</span> |
| 10 | <button "color:#79c0ff">className="absolute -bottom-1 -right-1 flex h-6 w-6 items-center justify-center rounded-full bg-white text-[10px] text-slate-900 shadow-lg">✎</button> |
| 11 | </div> |
| 12 | <div "color:#79c0ff">className="text-xs"> |
| 13 | <button "color:#79c0ff">className="rounded-lg bg-white/[0.06] px-3 py-1.5 font-bold text-white/75 ring-1 ring-inset ring-white/12 hover:bg-white/10">Upload new</button> |
| 14 | <button "color:#79c0ff">className="ml-2 font-semibold text-white/30 hover:text-rose-300">Remove</button> |
| 15 | </div> |
| 16 | </div> |
| 17 | |
| 18 | {/* fields */} |
| 19 | <div "color:#79c0ff">className="mt-5 grid grid-cols-2 gap-3"> |
| 20 | <input "color:#79c0ff">defaultValue="Ayush" "color:#79c0ff">className="rounded-xl border border-white/12 bg-white/[0.04] px-3.5 py-2.5 text-sm text-white outline-none focus:border-violet-400/60" /> |
| 21 | <input "color:#79c0ff">defaultValue="Kumar" "color:#79c0ff">className="rounded-xl border border-white/12 bg-white/[0.04] px-3.5 py-2.5 text-sm text-white outline-none focus:border-violet-400/60" /> |
| 22 | </div> |
| 23 | <div "color:#79c0ff">className="mt-3"> |
| 24 | <textarea rows={3} "color:#79c0ff">defaultValue="Design engineer building UIDrops." |
| 25 | "color:#79c0ff">className="w-full rounded-xl border border-white/12 bg-white/[0.04] px-3.5 py-2.5 text-sm text-white outline-none focus:border-violet-400/60" /> |
| 26 | <p "color:#79c0ff">className="mt-1 text-right text-[10px] text-white/25">34 / 160</p> |
| 27 | </div> |
| 28 | </div> |
| 29 | |
| 30 | {/* save bar */} |
| 31 | <div "color:#79c0ff">className="flex items-center justify-between border-t border-white/8 bg-white/[0.02] px-6 py-3.5"> |
| 32 | <p "color:#79c0ff">className="text-[11px] text-white/30">Last saved 2 min ago</p> |
| 33 | <div "color:#79c0ff">className="flex gap-2"> |
| 34 | <button "color:#79c0ff">className="rounded-xl px-4 py-2 text-xs font-semibold text-white/50 hover:text-white">Cancel</button> |
| 35 | <button "color:#79c0ff">className="rounded-xl bg-gradient-to-r from-violet-600 to-indigo-600 px-5 py-2 text-xs font-bold text-white shadow-lg shadow-violet-500/25">Save changes</button> |
| 36 | </div> |
| 37 | </div> |
| 38 | </div> |
Notification Preferences
Product updates
New features and improvements
Weekly digest
Top components, every Friday
Comments
When someone replies to you
Mentions
When someone @mentions you
Security alertsREQUIRED
Sign-ins and password changes
Grouped preference rows with live gradient switches — every toggle works.
| 1 | function NotificationPrefs() { |
| 2 | const [prefs, setPrefs] = useState({ |
| 3 | productUpdates: true, weeklyDigest: true, comments: false, |
| 4 | mentions: true, security: true, |
| 5 | }); |
| 6 | |
| 7 | const rows = [ |
| 8 | { key: "productUpdates", label: "Product updates", desc: "New features and improvements" }, |
| 9 | { key: "weeklyDigest", label: "Weekly digest", desc: "Top components, every Friday" }, |
| 10 | { key: "comments", label: "Comments", desc: "When someone replies to you" }, |
| 11 | { key: "mentions", label: "Mentions", desc: "When someone @mentions you" }, |
| 12 | { key: "security", label: "Security alerts", desc: "Sign-ins and password changes", locked: true }, |
| 13 | ]; |
| 14 | |
| 15 | return ( |
| 16 | <div "color:#79c0ff">className="w-full max-w-md divide-y divide-white/8 rounded-3xl border border-white/10 bg-white/[0.03]"> |
| 17 | {rows.map((r) => ( |
| 18 | <div "color:#79c0ff">key={r.key} "color:#79c0ff">className="flex items-center gap-4 px-5 py-4"> |
| 19 | <div "color:#79c0ff">className="min-w-0 flex-1"> |
| 20 | <p "color:#79c0ff">className="text-sm font-semibold text-white">{r.label} |
| 21 | {r.locked && <span "color:#79c0ff">className="ml-2 rounded bg-white/10 px-1.5 py-0.5 text-[9px] font-bold text-white/40">REQUIRED</span>} |
| 22 | </p> |
| 23 | <p "color:#79c0ff">className="text-xs text-white/35">{r.desc}</p> |
| 24 | </div> |
| 25 | <button |
| 26 | "color:#79c0ff">disabled={r.locked} |
| 27 | "color:#79c0ff">onClick={() => setPrefs((p) => ({ ...p, [r.key]: !p[r.key] }))} |
| 28 | "color:#79c0ff">className={"flex h-6 w-11 shrink-0 items-center rounded-full p-0.5 transition-all duration-300 disabled:opacity-60 " + |
| 29 | (prefs[r.key] |
| 30 | ? "justify-end bg-gradient-to-r from-violet-600 to-indigo-600" |
| 31 | : "justify-start bg-white/12")}> |
| 32 | <span "color:#79c0ff">className="h-5 w-5 rounded-full bg-white shadow" /> |
| 33 | </button> |
| 34 | </div> |
| 35 | ))} |
| 36 | </div> |
| 37 | ); |
| 38 | } |
Billing & Plan
Pro planACTIVE
$15/month · renews Aug 7, 2026
•••• 4242
Expires 12/28
Current plan card with usage meter, payment method row and invoice history.
| 1 | <div "color:#79c0ff">className="w-full max-w-md space-y-4"> |
| 2 | {/* plan card */} |
| 3 | <div "color:#79c0ff">className="rounded-3xl bg-gradient-to-b from-violet-500/35 to-transparent p-px"> |
| 4 | <div "color:#79c0ff">className="rounded-[23px] bg-[#0b0b16] p-6"> |
| 5 | <div "color:#79c0ff">className="flex items-center justify-between"> |
| 6 | <div> |
| 7 | <p "color:#79c0ff">className="flex items-center gap-2 text-sm font-extrabold text-white"> |
| 8 | Pro plan |
| 9 | <span "color:#79c0ff">className="rounded-full bg-emerald-500/15 px-2 py-0.5 text-[9px] font-bold text-emerald-400">ACTIVE</span> |
| 10 | </p> |
| 11 | <p "color:#79c0ff">className="mt-0.5 text-xs text-white/35">$15/month · renews Aug 7, 2026</p> |
| 12 | </div> |
| 13 | <button "color:#79c0ff">className="rounded-xl border border-white/12 px-3.5 py-2 text-xs font-bold text-white/70 hover:bg-white/5"> |
| 14 | Change plan |
| 15 | </button> |
| 16 | </div> |
| 17 | {/* usage */} |
| 18 | <div "color:#79c0ff">className="mt-5"> |
| 19 | <div "color:#79c0ff">className="flex justify-between text-[11px]"> |
| 20 | <span "color:#79c0ff">className="text-white/40">AI credits used</span> |
| 21 | <span "color:#79c0ff">className="font-bold text-white/75">1.42M / 2M</span> |
| 22 | </div> |
| 23 | <div "color:#79c0ff">className="mt-1.5 h-2 rounded-full bg-white/8"> |
| 24 | <div "color:#79c0ff">className="h-full w-[71%] rounded-full bg-gradient-to-r from-violet-500 via-fuchsia-500 to-cyan-400" /> |
| 25 | </div> |
| 26 | </div> |
| 27 | </div> |
| 28 | </div> |
| 29 | |
| 30 | {/* payment method */} |
| 31 | <div "color:#79c0ff">className="flex items-center gap-3 rounded-2xl border border-white/10 bg-white/[0.03] px-5 py-4"> |
| 32 | <span "color:#79c0ff">className="flex h-9 w-12 items-center justify-center rounded-lg bg-white/8 text-[10px] font-black italic text-white/70">VISA</span> |
| 33 | <div "color:#79c0ff">className="flex-1 text-xs"> |
| 34 | <p "color:#79c0ff">className="font-semibold text-white">•••• 4242</p> |
| 35 | <p "color:#79c0ff">className="text-white/35">Expires 12/28</p> |
| 36 | </div> |
| 37 | <button "color:#79c0ff">className="text-xs font-bold text-violet-300 hover:text-violet-200">Update</button> |
| 38 | </div> |
| 39 | |
| 40 | {/* invoices */} |
| 41 | <div "color:#79c0ff">className="divide-y divide-white/8 rounded-2xl border border-white/10 bg-white/[0.03]"> |
| 42 | {invoices.map((inv) => ( |
| 43 | <div "color:#79c0ff">key={inv.id} "color:#79c0ff">className="flex items-center gap-3 px-5 py-3 text-xs"> |
| 44 | <span "color:#79c0ff">className="font-mono text-white/40">{inv.id}</span> |
| 45 | <span "color:#79c0ff">className="flex-1 text-white/60">{inv.date}</span> |
| 46 | <span "color:#79c0ff">className="font-bold text-white/80">{inv.amount}</span> |
| 47 | <button "color:#79c0ff">className="font-bold text-violet-300 hover:text-violet-200">PDF ↓</button> |
| 48 | </div> |
| 49 | ))} |
| 50 | </div> |
| 51 | </div> |
Danger Zone
⚠ Danger zone
Transfer ownership
Move this project to another workspace.
Delete this project
Type nebula-app to confirm. This cannot be undone.
Red-bordered destructive actions with a type-to-confirm delete — try typing the project name.
| 1 | function DangerZone() { |
| 2 | const [confirm, setConfirm] = useState(""); |
| 3 | const armed = confirm === "nebula-app"; |
| 4 | |
| 5 | return ( |
| 6 | <div "color:#79c0ff">className="w-full max-w-xl overflow-hidden rounded-3xl border border-rose-500/25"> |
| 7 | <div "color:#79c0ff">className="border-b border-rose-500/20 bg-rose-500/[0.06] px-6 py-4"> |
| 8 | <p "color:#79c0ff">className="text-sm font-extrabold text-rose-300">⚠ Danger zone</p> |
| 9 | </div> |
| 10 | |
| 11 | <div "color:#79c0ff">className="divide-y divide-white/8 bg-white/[0.02]"> |
| 12 | {/* transfer */} |
| 13 | <div "color:#79c0ff">className="flex items-center gap-4 px-6 py-4"> |
| 14 | <div "color:#79c0ff">className="flex-1"> |
| 15 | <p "color:#79c0ff">className="text-sm font-semibold text-white">Transfer ownership</p> |
| 16 | <p "color:#79c0ff">className="text-xs text-white/35">Move this project to another workspace.</p> |
| 17 | </div> |
| 18 | <button "color:#79c0ff">className="rounded-xl border border-white/12 px-4 py-2 text-xs font-bold text-white/70 hover:bg-white/5"> |
| 19 | Transfer |
| 20 | </button> |
| 21 | </div> |
| 22 | |
| 23 | {/* delete with confirm */} |
| 24 | <div "color:#79c0ff">className="px-6 py-4"> |
| 25 | <p "color:#79c0ff">className="text-sm font-semibold text-white">Delete this project</p> |
| 26 | <p "color:#79c0ff">className="text-xs text-white/35"> |
| 27 | Type <b "color:#79c0ff">className="font-mono text-rose-300">nebula-app</b> to confirm. This cannot be undone. |
| 28 | </p> |
| 29 | <div "color:#79c0ff">className="mt-3 flex gap-2.5"> |
| 30 | <input |
| 31 | "color:#79c0ff">value={confirm} |
| 32 | "color:#79c0ff">onChange={(e) => setConfirm(e.target.value)} |
| 33 | "color:#79c0ff">placeholder="nebula-app" |
| 34 | "color:#79c0ff">className="min-w-0 flex-1 rounded-xl border border-white/12 bg-white/[0.04] px-3.5 py-2.5 font-mono text-xs text-white placeholder-white/20 outline-none focus:border-rose-400/60" |
| 35 | /> |
| 36 | <button |
| 37 | "color:#79c0ff">disabled={!armed} |
| 38 | "color:#79c0ff">className={"shrink-0 rounded-xl px-5 py-2.5 text-xs font-bold transition-all " + |
| 39 | (armed |
| 40 | ? "bg-rose-500 text-white shadow-lg shadow-rose-500/30 hover:bg-rose-400" |
| 41 | : "cursor-not-allowed bg-white/[0.05] text-white/25")}> |
| 42 | Delete forever |
| 43 | </button> |
| 44 | </div> |
| 45 | </div> |
| 46 | </div> |
| 47 | </div> |
| 48 | ); |
| 49 | } |