Skip to content

Fix profile side-panel close behavior for activate and purchase flows#2016

Merged
alexprate merged 6 commits intomainfrom
cursor/issue-1938-investigation-0146
Mar 24, 2026
Merged

Fix profile side-panel close behavior for activate and purchase flows#2016
alexprate merged 6 commits intomainfrom
cursor/issue-1938-investigation-0146

Conversation

@webguru-hypha
Copy link
Contributor

@webguru-hypha webguru-hypha commented Mar 16, 2026

Summary

  • auto-closes profile side panels after success in both Activate Spaces and Purchase Hypha Tokens flows
  • uses router.replace(...) for delayed panel close navigation so browser Back does not reopen completed forms
  • preserves scroll position during delayed panel close via router.replace(..., { scroll: false })
  • isolates post-purchase manualUpdate() refresh errors from purchase transaction errors to avoid showing false purchase failures
  • applies Prettier formatting to pass CI format:check
  • resolves merge conflicts with latest main while preserving both:
    • upstream translation/localized validation resolver updates
    • branch-specific side-panel auto-close and review-driven fixes

Commits addressing review comments

  1. da3e288f5fix(profile): replace history entry after activate spaces success
  2. 978255b9efix(profile): isolate post-purchase asset refresh errors
  3. 4a390dd76fix(profile): replace history entry after token purchase success
  4. 7deb23035style(profile): apply prettier formatting for CI
  5. 2ba6131b5merge: resolve main branch conflicts in profile activation/purchase flows
  6. 428116476fix(profile): preserve scroll when auto-closing side panels

Validation

  • pnpm run format:check

Issues

Open in Web Open in Cursor 

Summary by CodeRabbit

  • Improvements

    • Success messages now appear immediately after activating spaces or purchasing tokens and remain visible while the user is automatically redirected to their profile after 3 seconds.
    • Post-purchase backend sync occurs without delaying the visible success flow.
  • Bug Fixes

    • Pending scheduled redirects are cleared when leaving forms to prevent unexpected or duplicate navigation.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 16, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4dde84c9-2eb4-4a7d-a451-28cf43663592

📥 Commits

Reviewing files that changed from the base of the PR and between 4281164 and 9298d01.

📒 Files selected for processing (2)
  • packages/epics/src/people/components/activate-spaces-form.tsx
  • packages/epics/src/people/components/people-purchase-hypha-tokens.tsx

Walkthrough

Components now read typed route params (lang, personSlug), show a success message, schedule a 3s programmatic navigation to the user's profile via Next router, and use a timeout ref plus unmount cleanup to avoid stale redirects.

Changes

Cohort / File(s) Summary
Auto-close / routing changes
packages/epics/src/people/components/activate-spaces-form.tsx, packages/epics/src/people/components/people-purchase-hypha-tokens.tsx
Use typed useParams<{ lang; personSlug }>() and useRouter(); compute closePanelUrl and introduce closePanelTimeoutRef with unmount cleanup to clear scheduled redirects.
Success flow / timing adjustments
packages/epics/src/people/components/activate-spaces-form.tsx, packages/epics/src/people/components/people-purchase-hypha-tokens.tsx
On success: clear existing timeout, set showSuccessMessage, schedule router.replace(closePanelUrl, { scroll: false }) after 3s. In purchase flow, manualUpdate() is moved to run after scheduling (separate try/catch) and is not called on purchase failure.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant User
participant Component
participant Router
participant API
User->>Component: click activate / purchase
Component->>Component: clear existing timeout\nset showSuccessMessage = true\nstart 3s timeout
Note over Component: timeout stored in closePanelTimeoutRef
Component->>Router: replace(closePanelUrl) after 3s (scroll: false)
Component->>API: manualUpdate() (async, try/catch, non-blocking)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • evgenibir
  • sergey3bv
  • DSanich
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title does not follow the conventional commits format required (type(scope): description). Update title to follow format: fix(profile): auto-close side panels after activate and purchase flows or similar.
Out of Scope Changes check ❓ Inconclusive The PR includes changes to both activate-spaces-form.tsx and people-purchase-hypha-tokens.tsx, but only #1938 requires side-panel auto-close for activate flow; purchase flow changes appear tangentially related. Clarify whether the purchase flow auto-close behavior should be included or if it should be a separate PR addressing a different issue.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR successfully implements auto-closing of the side panel after activation success in activate-spaces-form.tsx (#1938) with delayed router.replace() navigation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/issue-1938-investigation-0146

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cursor cursor bot changed the title Fix side panel auto-close after space activation success Fix side panel auto-close after profile activation and token purchase success Mar 24, 2026
@alexprate alexprate changed the title Fix side panel auto-close after profile activation and token purchase success Fix side panel auto-close after space activation and buy hypha token success Mar 24, 2026
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/epics/src/people/components/activate-spaces-form.tsx`:
- Around line 126-128: Replace the router.push call inside the timeout with
router.replace to avoid adding a new history entry and prevent the browser Back
button from reopening the completed form; specifically update the setTimeout
callback that currently calls router.push(closePanelUrl) (refer to
closePanelTimeoutRef and closePanelUrl) to call router.replace(closePanelUrl)
instead while leaving the timeout logic intact.

In `@packages/epics/src/people/components/people-purchase-hypha-tokens.tsx`:
- Around line 141-151: The try block currently mixes the successful purchase
flow (investInHypha -> setShowSuccessMessage -> arming closePanelTimeoutRef and
router.push) with the post-purchase refresh (manualUpdate), so any error in
manualUpdate surfaces as a purchase failure; to fix, move the manualUpdate call
out of the purchase try/catch into its own try/catch after the success path so
that investInHypha, setShowSuccessMessage, form.reset, and the timer
(closePanelTimeoutRef + router.push) always run on success, and handle/log
errors from manualUpdate separately (use manualUpdate in a separate try/catch
and do not rethrow to avoid changing the user-facing success state).
- Around line 147-149: The timeout handler currently uses router.push to
navigate (closePanelTimeoutRef.current setTimeout calling
router.push(closePanelUrl)), which creates a new history entry; change that call
to router.replace(closePanelUrl) so the navigation replaces the current history
entry and prevents the Back button from reopening the purchase panel (update the
setTimeout callback where closePanelTimeoutRef.current is assigned to use
router.replace instead of router.push).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9fee8f46-3a6c-4c30-ae16-77639609ff52

📥 Commits

Reviewing files that changed from the base of the PR and between 6d3ff9a and 7084cde.

📒 Files selected for processing (2)
  • packages/epics/src/people/components/activate-spaces-form.tsx
  • packages/epics/src/people/components/people-purchase-hypha-tokens.tsx

@cursor cursor bot changed the title Fix side panel auto-close after space activation and buy hypha token success Fix profile side-panel close behavior for activate and purchase flows Mar 24, 2026
@alexprate alexprate marked this pull request as ready for review March 24, 2026 16:32
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/epics/src/people/components/people-purchase-hypha-tokens.tsx (1)

54-77: 🧹 Nitpick | 🔵 Trivial

Extract the delayed side-panel close flow into a shared hook.

This is now the second copy of the same route construction, timeout cleanup, and delayed replace() scheduling added in this PR. The earlier follow-up fixes already had to touch both copies, so this will drift again the next time the close behavior changes.

♻️ Refactor sketch
-  const router = useRouter();
-  const { lang } = useParams<{ lang: string }>();
-  const closePanelTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(
-    null,
-  );
-  const closePanelUrl = useMemo(
-    () => `/${lang}/profile/${personSlug}`,
-    [lang, personSlug],
-  );
+  const { scheduleClosePanel } = useDelayedProfilePanelClose({ personSlug });
...
-      if (closePanelTimeoutRef.current) {
-        clearTimeout(closePanelTimeoutRef.current);
-      }
-      closePanelTimeoutRef.current = setTimeout(() => {
-        router.replace(closePanelUrl);
-      }, 3000);
+      scheduleClosePanel();
function useDelayedProfilePanelClose({
  personSlug,
  delayMs = 3000,
}: {
  personSlug: string;
  delayMs?: number;
}) {
  const router = useRouter();
  const { lang } = useParams<{ lang: string }>();
  const timeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  useEffect(() => {
    return () => {
      if (timeoutRef.current) clearTimeout(timeoutRef.current);
    };
  }, []);

  return {
    scheduleClosePanel() {
      if (timeoutRef.current) clearTimeout(timeoutRef.current);
      timeoutRef.current = setTimeout(() => {
        router.replace(`/${lang}/profile/${personSlug}`);
      }, delayMs);
    },
  };
}

As per coding guidelines "Components are composable and follow single-responsibility principle".

Also applies to: 182-188, 221-225

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/epics/src/people/components/people-purchase-hypha-tokens.tsx` around
lines 54 - 77, Extract the delayed side-panel close logic (the timeout ref
closePanelTimeoutRef, closePanelUrl construction, and the delayed router.replace
scheduling currently in this component) into a shared hook named
useDelayedProfilePanelClose that accepts personSlug and optional delayMs; inside
the hook use useRouter and useParams to build the route and keep a timeoutRef
with useEffect cleanup, and expose a scheduleClosePanel() method that clears any
existing timeout and sets a new setTimeout to call
router.replace(`/${lang}/profile/${personSlug}`) after delayMs; then replace
usages of closePanelTimeoutRef and direct router.replace calls in this file (and
the other occurrences noted) to call
useDelayedProfilePanelClose(...).scheduleClosePanel() and remove duplicated
URL/timeout code from the component.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/epics/src/people/components/people-purchase-hypha-tokens.tsx`:
- Around line 224-225: The router.replace call currently used inside the
setTimeout (referenced by closePanelTimeoutRef.current and closePanelUrl)
scrolls the page to top; modify the router.replace invocation in
people-purchase-hypha-tokens (inside the setTimeout callback) to pass { scroll:
false } as the second argument (i.e., router.replace(closePanelUrl, undefined, {
scroll: false })) so the page preserves scroll position when the panel closes,
and apply the same change to the analogous router.replace call in
activate-spaces-form (the closePanelTimeoutRef/current setTimeout callback
referencing closePanelUrl).

---

Outside diff comments:
In `@packages/epics/src/people/components/people-purchase-hypha-tokens.tsx`:
- Around line 54-77: Extract the delayed side-panel close logic (the timeout ref
closePanelTimeoutRef, closePanelUrl construction, and the delayed router.replace
scheduling currently in this component) into a shared hook named
useDelayedProfilePanelClose that accepts personSlug and optional delayMs; inside
the hook use useRouter and useParams to build the route and keep a timeoutRef
with useEffect cleanup, and expose a scheduleClosePanel() method that clears any
existing timeout and sets a new setTimeout to call
router.replace(`/${lang}/profile/${personSlug}`) after delayMs; then replace
usages of closePanelTimeoutRef and direct router.replace calls in this file (and
the other occurrences noted) to call
useDelayedProfilePanelClose(...).scheduleClosePanel() and remove duplicated
URL/timeout code from the component.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b83ef887-3b34-4cd8-9952-91d64d902907

📥 Commits

Reviewing files that changed from the base of the PR and between 7deb230 and 2ba6131.

📒 Files selected for processing (2)
  • packages/epics/src/people/components/activate-spaces-form.tsx
  • packages/epics/src/people/components/people-purchase-hypha-tokens.tsx

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/epics/src/people/components/activate-spaces-form.tsx (1)

151-158: 🧹 Nitpick | 🔵 Trivial

Consider adding form to the dependency array for completeness.

The effect uses form.getValues and form.setValue, but the dependency array only includes person?.address. While the form object from react-hook-form is stable in practice, ESLint's exhaustive-deps rule would flag this.

♻️ Proposed fix
   useEffect(() => {
     if (person?.address) {
       const currentBuyer = form.getValues('buyer');
       if (currentBuyer !== person.address) {
         form.setValue('buyer', person.address);
       }
     }
-  }, [person?.address]);
+  }, [person?.address, form]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/epics/src/people/components/activate-spaces-form.tsx` around lines
151 - 158, The useEffect reads and writes via form.getValues and form.setValue
while only depending on person?.address; add the form reference to the
dependency array (i.e. change dependencies from [person?.address] to
[person?.address, form]) so the effect includes the react-hook-form instance
used inside useEffect; if form is not stable, wrap or memoize the form instance
where it is created (or otherwise ensure stability) before adding it to the
dependency list.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/epics/src/people/components/activate-spaces-form.tsx`:
- Around line 151-158: The useEffect reads and writes via form.getValues and
form.setValue while only depending on person?.address; add the form reference to
the dependency array (i.e. change dependencies from [person?.address] to
[person?.address, form]) so the effect includes the react-hook-form instance
used inside useEffect; if form is not stable, wrap or memoize the form instance
where it is created (or otherwise ensure stability) before adding it to the
dependency list.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 94736afd-43c5-434f-ad06-c8e20b76c886

📥 Commits

Reviewing files that changed from the base of the PR and between 2ba6131 and 4281164.

📒 Files selected for processing (2)
  • packages/epics/src/people/components/activate-spaces-form.tsx
  • packages/epics/src/people/components/people-purchase-hypha-tokens.tsx

cursoragent and others added 6 commits March 24, 2026 18:43
Co-authored-by: webguru-hypha <webguru-hypha@users.noreply.github.com>
Co-authored-by: webguru-hypha <webguru-hypha@users.noreply.github.com>
Co-authored-by: webguru-hypha <webguru-hypha@users.noreply.github.com>
Co-authored-by: webguru-hypha <webguru-hypha@users.noreply.github.com>
Co-authored-by: webguru-hypha <webguru-hypha@users.noreply.github.com>
Co-authored-by: webguru-hypha <webguru-hypha@users.noreply.github.com>
@plitzenberger plitzenberger force-pushed the cursor/issue-1938-investigation-0146 branch from 4281164 to 9298d01 Compare March 24, 2026 17:44
@plitzenberger
Copy link
Member

Autofix / review thread resolved

The CodeRabbit thread about passing { scroll: false } to router.replace() when auto-closing the activate-spaces and purchase-hypha side panels is already addressed on this branch.

Both call sites use router.replace(closePanelUrl, { scroll: false }) inside the success setTimeout (see 9298d01816fix(profile): preserve scroll when auto-closing side panels).

The review thread has been resolved in the GitHub UI.

@alexprate alexprate merged commit d056ad9 into main Mar 24, 2026
7 checks passed
@alexprate alexprate deleted the cursor/issue-1938-investigation-0146 branch March 24, 2026 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Activate space

4 participants