Skip to content

feat(ui): add onboarding tags of interest step (#2387) - #2394

Open
Orlandohub wants to merge 4 commits into
feat/2386-starter-pack-stream-sourcefrom
feat/2387-onboarding-tags-step
Open

feat(ui): add onboarding tags of interest step (#2387)#2394
Orlandohub wants to merge 4 commits into
feat/2386-starter-pack-stream-sourcefrom
feat/2387-onboarding-tags-step

Conversation

@Orlandohub

@Orlandohub Orlandohub commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Implements the onboarding "Tags of interest" step from #2387 (closes #2387). Stacked on #2391 (feat/2386-starter-pack-stream-source) for STARTER_PACK_MAX_TAGS via GitHub stack #2395 — when #2391 merges, GitHub automatically re-targets this PR to dev and cascades the rebase.

  • New /onboarding/tags route after profile creation: 21 popular chips from hot tags (useHotTags, month timeframe) + free-text TagInput, capped at 5 ordered, canonical (trimmed/lowercase, isValidTagLabel) tags via the new useInterestTags hook. Selection order is preserved — it becomes the starter pack stream ID order in [Feature]: Starter Packs — onboarding "Follow your best matches" step + Follow All & landing feed #2388.
  • Onboarding stepper remapped to the 4-step design model (account 1, keys 2, profile 3, Experience 4); Header logic that keyed on step === 5 now keys on the profile/tags paths.
  • Onboarding store gains interestTags (persisted, cleared by reset() to prevent cross-account leakage) and experienceCompletedByPubky (persisted and preserved through reset(), keyed per pubky) so a completed account is never re-prompted after logout/re-login, while a different account on the same browser still is.
  • Back is enabled per design: the profile step now renders in edit mode (prefilled, commitUpdate, redirect back to tags) when the user already has a profile, removing the double-commitCreate hazard.
  • PostTag props widened to ButtonHTMLAttributes so chips accept disabled; at the 5-tag cap only unselected popular chips lock — selected chips stay removable.

Temporary placement (synced to #2388)

markExperienceCompleted is written on Tags Continue (marked TEMPORARY(#2388)) because Tags is currently the last Experience screen. #2388 relocates the write to the Follow screen's Finish and retargets Continue — tracked as an explicit checklist item on #2388.

Test plan

  • useInterestTags: order, cap, dedupe (case-insensitive), canonicalization, invalid labels, removal at cap
  • TagsOfInterest template: chip rendering, "(N selected)" header, accessible pressed/disabled states, free-text→popular dedupe, Continue with 0 tags, ordered persistence + completion write, Back navigation, re-prompt guard (completed pubky redirects, other pubky still prompted, hydration gate)
  • Onboarding store: per-pubky completion, reset() preserves completion but clears interestTags
  • useProfileForm: create-success → /onboarding/tags, edit default → /profile, edit redirectTo override
  • CreateProfileForm: revisit renders prefilled edit mode, Back enabled → tags, submit runs commitUpdate (no commitCreate/bootstrap)
  • Header/stepper: 4-step remap, tags step title "Experience", logo noLink on profile+tags
  • npm run typecheck, npm run lint, npm run format:check all green

VRT is out of scope per the issue (QA team handles it later).

Insert a "Tags of interest" step after profile creation where users
pick up to 5 ordered interest tags (21 popular hot-tag chips + free
text) that seed the starter pack follow recommendations in #2388.

Changes:
- Add /onboarding/tags route, page, template, and organisms
- Remap onboarding stepper to the 4-step design model
- Persist interestTags and per-pubky experienceCompletedByPubky in the
  onboarding store; completion survives reset() so an account is never
  re-prompted after logout/re-login
- Redirect profile create success to the tags step; enable safe Back by
  rendering the profile step in edit mode when a profile already exists
- Widen PostTag props to ButtonHTMLAttributes so chips accept disabled

Completion is written on Tags Continue as a TEMPORARY(#2388) placement;
#2388 relocates it to the Follow screen's Finish action.

Refs: #2387
@Orlandohub Orlandohub self-assigned this Aug 21, 2026
@greptile-apps

greptile-apps Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The follow-up adds persisted interest-tag restoration, prevents profile revisits from submitting unloaded defaults, and supplies colocated tests for the new onboarding organisms.

  • Seeds and continuously persists ordered interest selections across onboarding navigation.
  • Gates profile updates until existing profile details are available.
  • Adds direct component and interaction coverage for the tags form and header.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/components/organisms/TagsOfInterestForm/TagsOfInterestForm.tsx Restores ordered selections from hydrated persisted state and synchronizes subsequent changes before onboarding navigation.
src/components/organisms/CreateProfileForm/CreateProfileForm.tsx Detects profile revisits, uses edit mode, and blocks submission until the existing profile is loaded.
src/hooks/useProfileForm/useProfileForm.tsx Supports an onboarding-specific edit redirect while preserving create and settings-edit behavior.
src/core/stores/onboarding/onboarding.store.ts Persists selected interests and per-account Experience completion state.
src/components/organisms/TagsOfInterestForm/TagsOfInterestForm.test.tsx Adds colocated rendering, persistence, and navigation coverage for the form.
src/components/organisms/TagsOfInterestHeader/TagsOfInterestHeader.test.tsx Adds colocated content and snapshot coverage for the header.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Tags["Tags of interest"] -->|"selection persisted"| Store["Onboarding store"]
  Tags -->|"Back"| Profile["Profile revisit"]
  Profile -->|"load existing details"| Edit["Edit mode"]
  Edit -->|"Save or Back"| Tags
  Tags -->|"Continue"| Home["Home"]
Loading

Reviews (2): Last reviewed commit: "fix(ui): persist interest selection acro..." | Re-trigger Greptile

Comment thread src/components/organisms/TagsOfInterestForm/TagsOfInterestForm.tsx
Comment thread src/components/organisms/CreateProfileForm/CreateProfileForm.tsx
Comment thread src/components/organisms/TagsOfInterestForm/TagsOfInterestForm.tsx
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

URL: https://pubky-app-pr-2394-fzxmjul7ya-oa.a.run.app

pubky-app-pr-239453ec9c0

…submit

Address PR review findings:
- Seed useInterestTags from the persisted store selection (sanitized
  through the same canonical/validity/dedupe/cap invariants) and sync
  the store on every change, so Back, browser back, and guard redirects
  no longer discard the selected tags or their order
- Disable the profile revisit submit while the current profile is still
  loading, preventing an empty edit form from overwriting the existing
  bio, links, and avatar when local data is absent and the fetch fails
- Add colocated tests for TagsOfInterestForm and TagsOfInterestHeader
  per docs/component-testing.md

Refs: #2387
@Orlandohub

Copy link
Copy Markdown
Contributor Author

@greptile-apps review

- Hide the FAB on onboarding routes so it no longer overlaps Continue
- Render a skeleton during profile revisit hydration instead of an
  interactive form (promotes the Settings skeleton to a shared
  ProfileFormSkeleton per the skeleton promotion rule)
- Match Figma interest-section hierarchy: muted regular "(N selected)"
  counter and both helper subtitles
- Restructure title JSX so the snapshot has no trailing whitespace
@infin1t3
infin1t3 self-requested a review August 24, 2026 06:09
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.

[Feature]: Starter Packs — onboarding "Tags of interest" step

1 participant