Skip to content

Portal UX fixes: clean landing video player, outage-safe role verification, rebranded 404#903

Merged
JoaquinBN merged 4 commits into
devfrom
JoaquinBN/portal-ux-fixes
Jul 6, 2026
Merged

Portal UX fixes: clean landing video player, outage-safe role verification, rebranded 404#903
JoaquinBN merged 4 commits into
devfrom
JoaquinBN/portal-ux-fixes

Conversation

@JoaquinBN

Copy link
Copy Markdown
Collaborator

What changed

Landing videos show only the player

The video on the builder, validator, and community landings no longer renders the eyebrow, title, and description overlay. Only the media, the center play button, and the bottom control bar (play, time, seek, mute, fullscreen) remain. The left-side darkening gradient that existed to back the text was removed too; the title is kept solely as the player's accessible label.

Members stay recognized when the backend is down or overloaded

Under high load, backend failures were interpreted as "not a member", which produced a broken experience for existing members across all three roles:

  • A failed /api/auth/verify/ marked the user unauthenticated, deleted the saved auth from localStorage, and cached the logged-out state for the rest of the session.
  • A failed /users/me/ cleared the loaded user, so every role check (user.creator / user.builder / user.validator) returned false.
  • The shared route guard then bounced members off locked routes (POAPs, tasks, contributions, etc.) to the journey or funnel as if they were starting from scratch.
  • The community and builder journey pages could even fire the journey-start mutation for a member whose profile simply failed to load.

The fix distinguishes "couldn't verify" from a definitive rejection everywhere:

  • Auth verify only demotes the session on a definitive sub-500 response; network errors and 5xx keep the current state and retry later.
  • The user store only clears the loaded user on 401/403.
  • Role-gated routes fail open when membership cannot be verified. This is safe because the backend enforces real permissions on every API call; the worst case is an inline error state instead of ejecting a member to the start of their journey.
  • Journey auto-start now runs in a one-shot reactive effect that waits for a loaded user profile, so direct visits that mount before the profile resolves still set the welcome marker, and outages never trigger the mutation.

Rebranded 404 page

The not-found view was rewritten in the portal design language: mono "Error 404" kicker, large display-font headline, muted body copy, and the standard rounded button pair (dark primary back home, bordered secondary to the contributions explorer).

Testing

  • npm run build passes.
  • npx vitest run: 165 passed / 23 failed, matching the pre-existing baseline exactly (failures in Profile, api, routes, AuthButton, meta predate this branch on dev).
  • The two 404 tests were updated to the new copy and pass.

JoaquinBN added 3 commits July 6, 2026 18:24
The landing video player on the builder, validator, and community
landings now shows only the media, the center play button, and the
bottom control bar. The copy overlay (eyebrow, title, description) and
the left-side darkening gradient that backed it are gone; the title
now serves only as the player's accessible label.

## Implementation Notes
- frontend/src/components/funnel/RoleLandingVideo.svelte: Removed the landing-video-copy block, its styles, and the horizontal sheen gradient layer; dropped the eyebrow/description props; the group now uses aria-label={title} instead of aria-labelledby.
- frontend/src/components/funnel/BuilderLanding.svelte, CommunityLanding.svelte, ValidatorLanding.svelte: Call sites pass only variant and title.
Backend failures were read as "not a member": a failed auth verify
logged the user out for the session and wiped saved auth, a failed
profile fetch cleared the loaded user, role-gated routes bounced
members back to the start of their journey, and the journey pages
could even fire the journey-start mutation for an existing member.
Verification now distinguishes "couldn't verify" from a definitive
rejection: only 401/403 (or sub-500 verify responses) demote the
session or clear the user, while network errors and 5xx keep the
current state and retry later. Role guards fail open on unverifiable
membership since the backend enforces real permissions on every API
call, and journey auto-start waits reactively for a loaded user
profile instead of deciding at mount.

## Implementation Notes
- frontend/src/lib/auth.js: performVerification only calls setAuthenticated(false) on sub-500 responses; network/5xx keeps state and leaves hasVerified unset so verifyAuth retries later.
- frontend/src/lib/userStore.js: loadUser keeps the previously loaded user unless the failure is 401/403.
- frontend/src/App.svelte: requireRoleForRoute returns true (fail open) when loadUser fails with a non-auth error instead of redirecting to the journey/funnel.
- frontend/src/routes/BuilderJourney.svelte, CommunityJourney.svelte: journey-start moved from onMount to a one-shot $effect gated on a non-null user, so direct visits that mount before /users/me/ resolves still set the welcome marker, and outages never fire the mutation.
- frontend/CLAUDE.md: Documented the guard error semantics under Routing.
The not-found view now uses the portal look: a mono "Error 404"
kicker, a large display-font headline, muted body copy, and the
standard rounded button pair (dark primary back home, bordered
secondary to the contributions explorer). Navigation uses plain
anchors handled by the router's link interceptor.

## Implementation Notes
- frontend/src/routes/NotFound.svelte: Full rewrite with font-display headline, font-mono kicker, and CTASection-style buttons; dropped the push() click handlers in favor of intercepted anchors.
- frontend/src/tests/NotFound.test.js, frontend/src/tests/routes.test.js: Assertions updated to the new copy (error 404, back to home).
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@JoaquinBN, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: eca3752d-a34f-41dd-8f6a-1edad9fbeabf

📥 Commits

Reviewing files that changed from the base of the PR and between e411ff4 and 77b25cc.

📒 Files selected for processing (14)
  • CHANGELOG.md
  • frontend/CLAUDE.md
  • frontend/src/App.svelte
  • frontend/src/components/funnel/BuilderLanding.svelte
  • frontend/src/components/funnel/CommunityLanding.svelte
  • frontend/src/components/funnel/RoleLandingVideo.svelte
  • frontend/src/components/funnel/ValidatorLanding.svelte
  • frontend/src/lib/auth.js
  • frontend/src/lib/userStore.js
  • frontend/src/routes/BuilderJourney.svelte
  • frontend/src/routes/CommunityJourney.svelte
  • frontend/src/routes/NotFound.svelte
  • frontend/src/tests/NotFound.test.js
  • frontend/src/tests/routes.test.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch JoaquinBN/portal-ux-fixes

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.

@JoaquinBN JoaquinBN force-pushed the JoaquinBN/portal-ux-fixes branch from 0b80ce8 to 2fae1b0 Compare July 6, 2026 16:25
@JoaquinBN JoaquinBN force-pushed the JoaquinBN/portal-ux-fixes branch from 2fae1b0 to 77b25cc Compare July 6, 2026 16:26
@JoaquinBN JoaquinBN merged commit 797dc63 into dev Jul 6, 2026
2 of 3 checks passed
@JoaquinBN JoaquinBN deleted the JoaquinBN/portal-ux-fixes branch July 6, 2026 16:40
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.

1 participant