Skip to content

Task 21: First-run onboarding & empty states#101

Merged
Pan14ek merged 6 commits into
mainfrom
feature/ui-21-onboarding-empty-states
Jul 18, 2026
Merged

Task 21: First-run onboarding & empty states#101
Pan14ek merged 6 commits into
mainfrom
feature/ui-21-onboarding-empty-states

Conversation

@Pan14ek

@Pan14ek Pan14ek commented Jul 18, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds a shared EmptyState primitive (card/inline variants, optional icon and button-or-link action) and sweeps every bare "nothing here" text in the app onto it: dashboard's My Lobbies / Upcoming Events / My Tasks, Sidebar's "No lobbies yet", kanban's per-column empty message, and the lobby Tasks tab.
  • Adds a DashboardHero shown in place of "My Lobbies" when a fresh account has zero lobbies and zero pending invites — greeting, the four lobby-type cards (each opens the create-lobby modal with that type preselected via a new openCreateLobby(lobbyType?) on the create-menu store), and a primary "+ Create your first lobby" CTA. A pending invite always wins and keeps the normal empty state below the invites banner instead.
  • Adds a WeekEmptyBanner (shared by the global CalendarPage and the lobby LobbyCalendarView) shown above the week grid when the visible week has zero events, with a "Create event" / "Invite someone" action respectively. WeekGrid/MonthGrid are unchanged — a blank day cell is normal in a populated week.
  • LobbyTaskList's empty state now links to that lobby's Members tab ("Invite someone").
  • Marks UI task 21 as DONE in docs/UI_TASKS.md.

Reviewed with /simplify (4 parallel angles: reuse, simplification, efficiency, altitude) after the initial implementation; applied the confirmed fixes (readability of the hero's show/hide condition, deduping the lobby-type tagline map into constants.ts, reusing EmptyState for one remaining bare <p>, and extracting the shared WeekEmptyBanner to remove duplicated empty-week logic between the two calendar views).

Test plan

  • npm run lint, npm run typecheck, npm run test:run (79 files / 550 tests), npm run build all pass
  • New/updated tests: EmptyState, WeekEmptyBanner, DashboardPage (hero renders/hidden, type preselection, invites-win-over-hero), LobbyTaskList, LobbyCalendarView, CalendarPage
  • Manually verified in-browser against the mock API (MSW) with lobbies/invites forced empty: hero renders exactly per the dashboard-empty mockup screen, clicking a type card preselects it in the modal (verified Family → radio checked), the primary CTA opens with no type preselected, and the modal's default correctly falls back to Couple afterward
  • Real backend verification — no backend changes were needed for this task (client-only, using data already fetched by useMyLobbies/useMyInvites)

🤖 Generated with Claude Code

Pan14ek and others added 6 commits July 18, 2026 16:56
…onstants

Task 21 groundwork: a reusable icon+message+action empty-state component
(card/inline variants) that every list in the app will render on zero
items, plus dedup LOBBY_TYPES (was duplicated in LobbyTypePicker) and a
new LOBBY_TYPE_TAGLINES map for the upcoming dashboard hero.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…obby modal

openCreateLobby now takes an optional LobbyType, stored as lobbyTypeInitial
and read by CreateLobbyModal to seed its type picker. Existing call sites
(CreateMenu, Sidebar) are wrapped in arrow functions so the DOM click event
isn't passed through as the type argument. Sidebar's "No lobbies yet" text
now goes through the new EmptyState primitive.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
DashboardHero renders a welcome message, the four lobby-type cards (each
opening CreateLobbyModal with that type preselected), and a primary
"Create your first lobby" CTA. DashboardPage swaps it in for the "My
Lobbies" section only when both lobbies and pending invites are loaded
and empty, so an invited-but-lobby-less account still sees the invites
banner instead of the hero.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
LobbyCardGrid, UpcomingEventsList, MyTasksList, kanban's per-column "No
tasks in {status}", and the lobby Tasks tab's "No tasks yet." all now
render through the shared primitive. LobbyTaskList's empty state also
gains an "Invite someone" link to that lobby's Members tab, and its
"no tasks match this filter" branch reuses the same component instead of
a bare <p>.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
WeekEmptyBanner is a shared wrapper around EmptyState used by both the
global CalendarPage ("No events this week — create one.") and the lobby
LobbyCalendarView ("No events yet." + an Invite someone link), so the
zero-events check and banner styling live in one place instead of being
duplicated per call site. WeekGrid/MonthGrid themselves are unchanged —
a blank day cell is normal even in a populated week.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Pan14ek
Pan14ek merged commit 73d03c7 into main Jul 18, 2026
1 check failed
@sonarqubecloud

Copy link
Copy Markdown

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