Fix signup flow skipping profile + recovery steps (1.3.16)

Root cause: the multi-step SignupDialog is hosted inside LoginArea, but
both the mobile header and the onboarding hero only rendered LoginArea
while logged OUT ({user ? menu : <LoginArea/>}). The signup flow logs the
user in at its FIRST step (to publish the profile), which flipped `user`
truthy and instantly UNMOUNTED LoginArea — destroying the dialog before
the profile and recovery steps could show. The skater was dumped on the
map with no recovery prompt (exactly the reported bug).

Fix: keep LoginArea mounted after login and merely hide its trigger
(dialog renders in a portal, so hiding the trigger is purely cosmetic).
MobileHeaderUserMenu / logged-in CTAs render alongside. The in-progress
signup now survives login and reaches the redesigned recovery step.

Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
shakespeare.diy 2026-09-09 11:34:23 +07:00
parent 3cc3b623cc
commit aede706fd3
2 changed files with 27 additions and 14 deletions

View file

@ -708,17 +708,27 @@ export function Layout({ children, noPadding }: LayoutProps) {
<div className="flex items-center gap-1 flex-shrink-0"> <div className="flex items-center gap-1 flex-shrink-0">
{/* Notifications (crew invites & membership requests) */} {/* Notifications (crew invites & membership requests) */}
{user && <NotificationBell />} {user && <NotificationBell />}
{/* User menu when logged in / Login button when not */} {/* User menu when logged in / Login button when not.
{user ? ( IMPORTANT: LoginArea hosts the SignupDialog. The signup flow logs
<MobileHeaderUserMenu the user in at the *first* step (to publish their profile), then
pubkey={user.pubkey} continues to the profile + recovery steps. If we unmount LoginArea
the instant `user` becomes truthy, the dialog is destroyed and the
skater is dumped on the map with no recovery step — the exact bug
reported. So we keep LoginArea mounted always and just hide its
trigger when logged in; MobileHeaderUserMenu becomes the visible
control. The dialog renders in a portal, so hiding the trigger is
purely cosmetic and never interrupts an in-progress signup. */}
{user && (
<MobileHeaderUserMenu
pubkey={user.pubkey}
onLogout={() => removeLogin(currentAccount?.id || '')} onLogout={() => removeLogin(currentAccount?.id || '')}
onSetStatus={() => setShowStatusDialog(true)} onSetStatus={() => setShowStatusDialog(true)}
onAddAccount={() => setShowAddAccount(true)} onAddAccount={() => setShowAddAccount(true)}
/> />
) : (
<LoginArea compact className="flex flex-row gap-1" />
)} )}
<div className={cn(user && 'hidden')}>
<LoginArea compact className="flex flex-row gap-1" />
</div>
<Sheet open={mobileMenuOpen} onOpenChange={setMobileMenuOpen}> <Sheet open={mobileMenuOpen} onOpenChange={setMobileMenuOpen}>
<SheetTrigger asChild> <SheetTrigger asChild>

View file

@ -215,14 +215,17 @@ export default function OnboardingPage() {
<FeaturePill emoji="👥" label="Crews" /> <FeaturePill emoji="👥" label="Crews" />
</div> </div>
{/* Primary CTA */} {/* Primary CTA.
{!user ? ( LoginArea (which hosts the multi-step SignupDialog) is kept mounted
<div className="flex flex-col items-center gap-3"> even after login and merely hidden — otherwise logging in at the
<p className="text-sm text-gray-500 uppercase tracking-wider font-bold mb-1">Create your free account</p> first signup step would unmount the dialog and skip the profile +
<LoginArea className="flex justify-center" /> recovery steps. */}
<p className="text-xs text-gray-600 mt-2">No email. No password. Own your identity forever.</p> <div className={cn('flex-col items-center gap-3', user ? 'hidden' : 'flex')}>
</div> <p className="text-sm text-gray-500 uppercase tracking-wider font-bold mb-1">Create your free account</p>
) : ( <LoginArea className="flex justify-center" />
<p className="text-xs text-gray-600 mt-2">No email. No password. Own your identity forever.</p>
</div>
{user && (
<div className="flex flex-wrap gap-3 justify-center"> <div className="flex flex-wrap gap-3 justify-center">
<Link to="/map"> <Link to="/map">
<Button size="lg" className="bg-[#ff0040] hover:bg-[#ff0040]/90 gap-2 font-black uppercase shadow-[0_0_30px_rgba(255,0,64,0.3)]"> <Button size="lg" className="bg-[#ff0040] hover:bg-[#ff0040]/90 gap-2 font-black uppercase shadow-[0_0_30px_rgba(255,0,64,0.3)]">