Skip to content

feat(onboarding): onboarding modals + global auth-flow wiring#9

Merged
0xdevcollins merged 3 commits into
mainfrom
feat/onboarding
Jun 11, 2026
Merged

feat(onboarding): onboarding modals + global auth-flow wiring#9
0xdevcollins merged 3 commits into
mainfrom
feat/onboarding

Conversation

@0xdevcollins

@0xdevcollins 0xdevcollins commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Add the post-signup onboarding modals and wire auth triggers to them.

Modals (src/features/onboarding), responsive (full-screen on mobile for profile setup and role gate):

  • ProfileSetupModal: avatar upload + crop, name/bio/location form.
  • RoleGateModal ("Complete Sign up"): role toggle, source select, use-case multi-select.
  • CropPhotoModal: circular cropper with drag-to-reposition and zoom.
  • New Textarea primitive for the bio field.

Auth-flow orchestration (src/features/auth), mounted globally via Providers:

  • AuthFlowProvider exposes useAuthFlow().requireAuth() so any trigger (buttons, guarded actions) routes to /sign-in or /sign-up with ?redirect.
  • OnboardingGate shows role -> profile for signed-in users missing a profile, remembered per-user in localStorage.
  • GetStartedPopup nudges guests on marketing/discover after ~45s, with a 7-day cooldown; never on auth/app/preview routes.

Summary by CodeRabbit

  • New Features

    • Added multi-step onboarding flow for new users, including profile setup (name, bio, location), avatar upload with crop editor, and interests/role selection
    • Added get started popup for new visitors with 7-day cooldown
    • Added textarea UI component
  • Improvements

    • Enhanced authentication orchestration with automatic onboarding detection for returning users

Add the post-signup onboarding modals and wire auth triggers to them.

Modals (src/features/onboarding), responsive (full-screen on mobile for
profile setup and role gate):
- ProfileSetupModal: avatar upload + crop, name/bio/location form.
- RoleGateModal ("Complete Sign up"): role toggle, source select, use-case
  multi-select.
- CropPhotoModal: circular cropper with drag-to-reposition and zoom.
- New Textarea primitive for the bio field.

Auth-flow orchestration (src/features/auth), mounted globally via Providers:
- AuthFlowProvider exposes useAuthFlow().requireAuth() so any trigger
  (buttons, guarded actions) routes to /sign-in or /sign-up with ?redirect.
- OnboardingGate shows role -> profile for signed-in users missing a profile,
  remembered per-user in localStorage.
- GetStartedPopup nudges guests on marketing/discover after ~45s, with a
  7-day cooldown; never on auth/app/preview routes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
boundless-v2 Ready Ready Preview, Comment Jun 11, 2026 11:43pm

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@0xdevcollins, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 35 minutes and 34 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

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.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aa4f98ce-9566-41bc-a8b8-86315e830080

📥 Commits

Reviewing files that changed from the base of the PR and between e2bb760 and e30c589.

📒 Files selected for processing (4)
  • src/components/ui/textarea.tsx
  • src/features/auth/components/auth-flow-provider.tsx
  • src/features/onboarding/components/avatar-upload.tsx
  • src/features/onboarding/components/profile-setup-modal.tsx
📝 Walkthrough

Walkthrough

This PR introduces a complete authentication and onboarding user experience. It adds an auth orchestration layer that triggers either unauthenticated marketing popups or authenticated user onboarding, implements multi-step modal flows for collecting profile data and role information with image cropping support, and includes supporting UI components and provider integration.

Changes

Auth & Onboarding User Experience Flow

Layer / File(s) Summary
Auth Flow Orchestration & Context
src/features/auth/components/auth-flow-provider.tsx, src/features/auth/index.ts
Establishes AuthFlowProvider context with requireAuth() function that guards routes and redirects on auth failure, alongside useAuthFlow hook for component access. Wires the context to render OnboardingGate and GetStartedPopup underneath.
Get Started Marketing Popup
src/features/auth/components/get-started-popup.tsx
Displays time-delayed marketing modal to unauthenticated users on eligible pages, with 7-day localStorage cooldown and route-based blocking to prevent re-display.
Authenticated User Onboarding Gate
src/features/auth/components/onboarding-gate.tsx
Detects authenticated users missing profile data and orchestrates step-by-step onboarding modal sequence, persisting completion state and invalidating cached user queries on finish.
Role & Interests Selection Modal
src/features/onboarding/components/role-gate-modal.tsx
First onboarding step: collects usage type, source channel, and multi-select interests via toggle buttons, dropdown, and checkboxes with "Go Back" and "Continue" actions.
Avatar Upload & Photo Cropping
src/features/onboarding/components/avatar-upload.tsx, src/features/onboarding/components/crop-photo-modal.tsx
Avatar file picker with hidden input, and canvas-based crop modal supporting zoom and drag interactions, exporting cropped region as PNG data URL.
Profile Setup Form with Avatar Integration
src/features/onboarding/components/profile-setup-modal.tsx
Zod-validated form collecting first/last name, optional bio/location, and integrated avatar upload/crop workflow; submits complete profile with avatar reference via onSubmit callback.
Textarea Component & Provider Integration
src/components/ui/textarea.tsx, src/features/onboarding/index.ts, src/providers/index.tsx
Reusable textarea form component with auto-generated id, label, and helper text; onboarding feature barrel aggregating exports; providers tree updated to wrap children with AuthFlowProvider.
Onboarding Modal Preview Page
src/app/onboarding-preview/page.tsx
Development/demo page rendering ProfileSetupModal and RoleGateModal independently with local state wiring for modal lifecycle testing.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • boundlessfi/boundless-platform#8: Modifies src/features/auth/index.ts exports; this PR's AuthFlowProvider and useAuthFlow re-exports may overlap with concurrent auth entity export changes.

Poem

🐰 A rabbit hops through onboarding gates,
With avatars cropped and forms that wait,
Role-choosing modals, popups that gleam,
Auth flows orchestrate the user's dream!
From sign-up to profile, smooth as a stream.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.71% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(onboarding): onboarding modals + global auth-flow wiring' directly and comprehensively summarizes the main changes: adding onboarding modals and auth-flow orchestration.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/onboarding

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/ui/textarea.tsx`:
- Around line 36-48: The helper text paragraph rendered by the component
(helperText) is not linked to the textarea for screen readers; update the
textarea element to include aria-describedby when helperText is present and give
the <p> helper element a stable id (for example using textareaId + '-helper');
specifically, in the component that renders <textarea ref={ref} id={textareaId}
... {...props} /> add aria-describedby={helperText ? `${textareaId}-helper` :
undefined} (or merge with existing aria-describedby if props includes one) and
set the helper <p> to id={`${textareaId}-helper`} so assistive tech associates
the helper text with the textarea.

In `@src/features/auth/components/auth-flow-provider.tsx`:
- Around line 46-61: The requireAuth callback currently only checks
isAuthenticated and may redirect while the auth hook is still resolving; update
requireAuth (in auth-flow-provider.tsx) to read the auth loading/status flag
from useAuth (e.g., isLoading or status) and short-circuit before performing any
redirect when auth is still loading — do not call router.push or
options.onAuthed while loading; only call options.onAuthed and return true when
isAuthenticated is true and loading is false, and otherwise return a
pending/false result without redirecting until loading completes.

In `@src/features/onboarding/components/avatar-upload.tsx`:
- Around line 33-38: Replace the hand-rolled <button> with the shared shadcn
Button primitive: import and use Button (e.g., from "ui/button" or your Button
export) in the avatar-upload component and keep the existing
props—type="button", onClick={() => inputRef.current?.click()},
aria-label="Upload profile photo"—and the visual classes (pass className as
before). Ensure the Button is rendered where the old <button> was (referencing
inputRef and the onClick handler) so focus/interaction/default variants come
from the shared primitive while preserving the existing size/rounded styling.

In `@src/features/onboarding/components/profile-setup-modal.tsx`:
- Around line 47-55: The modal retains previous avatar and form values across
open/close cycles; add lifecycle reset logic to clear sensitive state when the
modal is closed or reopened by calling form.reset({ firstName: '', lastName: '',
bio: '', location: '' }) and clearing avatar/pendingImage/cropOpen via
setAvatar(null), setPendingImage(null), setCropOpen(false). Implement this in a
useEffect that watches the modal visibility prop (e.g., isOpen) or in the modal
onClose handler so the ProfileSetupValues form (useForm) and the avatar state
are reset at modal boundaries.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c25409a8-dc49-48d0-8ac0-0824a3a48782

📥 Commits

Reviewing files that changed from the base of the PR and between f4fa1ce and e2bb760.

📒 Files selected for processing (12)
  • src/app/onboarding-preview/page.tsx
  • src/components/ui/textarea.tsx
  • src/features/auth/components/auth-flow-provider.tsx
  • src/features/auth/components/get-started-popup.tsx
  • src/features/auth/components/onboarding-gate.tsx
  • src/features/auth/index.ts
  • src/features/onboarding/components/avatar-upload.tsx
  • src/features/onboarding/components/crop-photo-modal.tsx
  • src/features/onboarding/components/profile-setup-modal.tsx
  • src/features/onboarding/components/role-gate-modal.tsx
  • src/features/onboarding/index.ts
  • src/providers/index.tsx

Comment thread src/components/ui/textarea.tsx
Comment thread src/features/auth/components/auth-flow-provider.tsx Outdated
Comment thread src/features/onboarding/components/avatar-upload.tsx Outdated
Comment thread src/features/onboarding/components/profile-setup-modal.tsx
- Textarea: link helper text to the control via aria-describedby (stable id),
  merging any consumer-provided value.
- requireAuth: short-circuit while the session is still resolving (isPending)
  so an authed user is never redirected to sign-in on a race.
- ProfileSetupModal: reset form values and avatar/crop state on close so
  reopening never shows a previous session's data.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the hand-rolled <button> in AvatarUpload with the shared Button
(intent=secondary, appearance=text) so focus/interaction come from the design
system, while preserving the circular avatar layout (size-16, rounded-full,
no padding, primary focus ring).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@0xdevcollins 0xdevcollins merged commit 70e4e72 into main Jun 11, 2026
5 checks passed
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