Skip to content

fix: Insert a new route after the existing /profile route and before the /:selection_plan_id catch-all#87

Open
matiasperrone-exo wants to merge 1 commit into
masterfrom
fix/my-bio-link-not-working-profile-url-does-not-work-when-path-includes-a-selectionplanid---cu-86b959jmg
Open

fix: Insert a new route after the existing /profile route and before the /:selection_plan_id catch-all#87
matiasperrone-exo wants to merge 1 commit into
masterfrom
fix/my-bio-link-not-working-profile-url-does-not-work-when-path-includes-a-selectionplanid---cu-86b959jmg

Conversation

@matiasperrone-exo
Copy link
Copy Markdown

@matiasperrone-exo matiasperrone-exo commented Apr 14, 2026

Task:

Ref.: https://app.clickup.com/t/86b959jmg

Context

When a user with no speaker profile lands on /app/{summit}/all-plans/{id}/profile, the following redirect loop occurs:

  1. SummitLayout detects no speaker profile and redirects to /app/{summit}/all-plans/{SP_LANDING}/profile
  2. That URL hits AllPlansLayout then is matched by /:selection_plan_id(\\d+) catch-all, so it enters SelectionPlanLayout
  3. SelectionPlanLayout checks summit.selection_plans (only active/submittable plans), so if plan not found, redirects to /app/{summit}/all-plans
  4. Back at step 1, and then the infinite loop

The root cause: the profile sub-route (/all-plans/{id}/profile) is caught by SelectionPlanLayout's allowed-plan guard even though the profile page has nothing to do with submission access.

Proposed Fix:

Add a dedicated route for /:selection_plan_id/profile before the /:selection_plan_id catch-all that leads to SelectionPlanLayout. This intercepts the profile URL and renders ProfilePage directly, bypassing the allowed-plan guard entirely.

Fix - One file change: src/layouts/all-plans-layout.js:

Add a dedicated route for /:selection_plan_id/profile before the /:selection_plan_id catch-all that leads to SelectionPlanLayout. This intercepts the profile URL and renders ProfilePage directly, bypassing the allowed-plan guard
entirely.

Change:

File: src/layouts/all-plans-layout.js

In the <Switch> block (currently lines 47–54), insert a new route after the existing /profile route and before the /:selection_plan_id catch-all:

// Before (lines 47-54):
<Switch>
  <Route strict exact path={match.url} component={AllSelectionPlansPage}/>
  <Route strict exact path={`${match.url}/profile`} component={ProfilePage}/>
  <Route path={`${match.url}/:selection_plan_id(\\d+)`} component={SelectionPlanLayout}/>
  ...
</Switch>
// After:
<Switch>
  <Route strict exact path={match.url} component={AllSelectionPlansPage}/>
  <Route strict exact path={`${match.url}/profile`} component={ProfilePage}/>
  <Route strict exact path={`${match.url}/:selection_plan_id(\\d+)/profile`}
    render={props => <ProfilePage {...props} selectionPlanId={parseInt(props.match.params.selection_plan_id)} />}
  />
  <Route path={`${match.url}/:selection_plan_id(\\d+)`} component={SelectionPlanLayout}/>
  ...
</Switch>

Why this works:

  • React Router <Switch> matches the first route that fits. The new strict exact route for /:id/profile is more specific and appears before the /:id catch-all, so it wins.
  • ProfilePage already accepts and uses selectionPlanId as a prop (for selectionPlansSettings[selectionPlanId] customization), so passing it here is correct.
  • No changes to SelectionPlanLayout needed; it still handles presentations and other sub-routes as before.
  • The existing /all-plans/profile route (no plan ID) is unaffected.

Critical files:

  • src/layouts/all-plans-layout.js: only file to modify
  • src/layouts/selection-plan-layout.js: read-only reference (no changes)
  • src/layouts/summit-layout.js: read-only reference (contains the redirect-to-profile logic that triggers the loop)

Verification:

  1. Redirect loop fixed: Navigate to /app/{summit}/all-plans/{any_id}/profile as a user with no speaker profile: page should render the profile form without looping.
  2. Allowed plan, with profile: Navigate to /app/{summit}/all-plans/{valid_id}/profile as a user with a speaker profile: profile page renders.
  3. Disallowed plan, with profile: Navigate to /app/{summit}/all-plans/{invalid_id}/profile: profile page renders (no redirect, plan guard is bypassed intentionally for profile).
  4. Global profile still works: Navigate to /app/{summit}/all-plans/profile: profile page renders as before.
  5. Presentations route unaffected: Navigate to /app/{summit}/all-plans/{id}/presentations: still goes through SelectionPlanLayout with full allowed-plan guard.

@matiasperrone-exo matiasperrone-exo self-assigned this Apr 14, 2026
@matiasperrone-exo matiasperrone-exo marked this pull request as ready for review April 14, 2026 20:05
Copy link
Copy Markdown

@martinquiroga-exo martinquiroga-exo left a comment

Choose a reason for hiding this comment

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

@matiasperrone-exo please see comments. Thanks.

Comment thread src/layouts/all-plans-layout.js
Comment thread src/layouts/all-plans-layout.js
Copy link
Copy Markdown

@caseylocker caseylocker left a comment

Choose a reason for hiding this comment

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

LGTM

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.

3 participants