Skip to content

fix: QA batch — calendar polish, achievement i18n, sub-habit icon, onboarding/tour - #333

Merged
thomasluizon merged 3 commits into
mainfrom
fix/qa-fixes
Jun 27, 2026
Merged

fix: QA batch — calendar polish, achievement i18n, sub-habit icon, onboarding/tour#333
thomasluizon merged 3 commits into
mainfrom
fix/qa-fixes

Conversation

@thomasluizon

Copy link
Copy Markdown
Owner

QA fixes from device testing

A batch of fixes found while testing the merged build. (The local AdMob test-ads build fix is separate — #332.)

Calendar / date-picker

  • Show-recurring toggle added to the Week + Interval views (was only on the single-day view) — shared ShowRecurringToggle + filterRecurringEntries.
  • Interval capped at 14 days — the time-grid was cramped past that; clampRangeToMaxDays + an amber notice.
  • "Agosto de" — the date-picker header title-cased the connector ("Agosto De"); splitMonthYear now capitalizes only the month.
  • Year picker replaces the year-skip arrows («/») on both the calendar header and the date-picker (both platforms) — click the year to jump.

Note: the Week/Interval views are web-only today (a #326 parity gap — the mobile calendar is month-only), so the toggle/cap apply where the views exist. Porting those views to mobile is a separate feature, flagged for a decision.

Achievements + sub-habits (both platforms)

  • onboarding_complete achievement rendered its raw i18n key — added name/description (both locales) + 4 missing achievement emoji that fell back to the generic sparkle.
  • Sub-habit icon showed a letter fallback on the open-sub-habits page — the drill-navigation normalizer dropped the child emoji; one-line passthrough (API already sends it).

Onboarding + feature tour (both platforms)

  • CTA button ("Começar"/"Continuar") was a full-bleed bar → compact centered pill.
  • Coach-mark tour rendered raw tour.sections.coach-* keys and showed "PASSO 1 DE 1" with an immediate "Finalizar" — each coach section fired as an isolated 1-step tour. Rebuilt into one connected 3-step coach tour (today → calendar → astra) with global progress, added the missing i18n, and fixed a state-reset bug that wrongly marked the full tour complete.
  • Import-from-another-app prematurely completed onboarding (auto-starting the tour mid-onboarding) — now routes to Astra via an ephemeral handoff flag without completing onboarding; the tour only starts after onboarding genuinely finishes.

Validation

type-check 3/3; lint 0 errors; tests shared 1235, web 1744, mobile 713.

🤖 Generated with Claude Code

thomasluizon and others added 3 commits June 27, 2026 15:54
… "de", year picker

Four calendar/date-picker QA fixes, on both platforms where the surface exists.

- C: "Show recurring" toggle added to the Week and Interval views (web),
  reusing the day-view control plus a shared filterRecurringEntries helper.
  Mobile's only calendar surface (the day-detail sheet) already has the toggle.
- E: interval day-selection capped at MAX_RANGE_DAYS (14) with subtle i18n
  feedback; clampRangeToMaxDays keeps the time grid readable (web; the interval
  view is web-only).
- F: pt-BR month-year connector is no longer title-cased ("Agosto de 2028", not
  "Agosto De 2028"). splitMonthYear capitalizes only the leading letter and the
  blanket capitalize transform is removed. en is unaffected (both platforms).
- G: year-skip double arrows removed from the calendar month header and the
  date-picker popover; tapping the year opens a compact YearPicker. Single
  month arrows kept (both platforms).

Tests: shared splitMonthYear / buildYearRange / filterRecurringEntries / range
clamp, plus updated web and mobile header and date-picker component tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…b-habit drill icon

B: backend emits 29 achievement keys; locales had 28 — add onboarding_complete name/description to en + pt-BR, and 4 achievement emoji that fell back to the generic sparkle (onboarding_complete, half_year_hero, streak_titan, first_cheer).
D: the drill-navigation normalizer dropped child emoji, so sub-habits showed a letter fallback on the open-sub-habits page. One-line passthrough fix (the API already sends child emoji).

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

H: onboarding footer CTA is now a compact, horizontally-centered pill instead
of a full-bleed bar (drop fullWidth on the goNext PillButton; web + mobile).

I-1: add the missing tour.sections.coach-today / coach-astra / coach-calendar
labels to en + pt-BR so coach-mark tooltips show a real section name instead of
the raw key.

I-2: run the first-run coach marks as ONE sequenced multi-step tour
(today, calendar, astra) with global "step x of N" counts, instead of three
isolated single-step tours. Adds startCoachTour + isCoachTour to the shared tour
store, global progress for the coach tour, a single useCoachTour trigger on
Today, and stops the coach tour from marking the full feature tour complete.

I-3: "Import from another app" now routes to Astra WITHOUT completing onboarding
or starting the feature tour mid-flow. The flow is parked via an ephemeral
onboardingHandedOff UI flag; the tour only begins after onboarding genuinely
finishes.

Tests: coach-tour sequencing + counts, coach section i18n parity, import does
not complete onboarding, coach-tour trigger gating.

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

vercel Bot commented Jun 27, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
orbit-ui-mobile-web Ignored Ignored Jun 27, 2026 7:31pm

Request Review

@sonarqubecloud

Copy link
Copy Markdown

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

PR Review 333 QA Batch - Decision: APPROVE - 0 Critical, 0 High, 1 Medium (splitMonthYear year-first locale edge case, unreachable with current en/pt-BR locale set). Parity: PAIRED. i18n: IN SYNC. No API contract changes. Reviewed by claude[bot] via /pr-review rubric.

@thomasluizon
thomasluizon merged commit ba72f77 into main Jun 27, 2026
10 checks passed
@thomasluizon
thomasluizon deleted the fix/qa-fixes branch June 27, 2026 19:40
thomasluizon added a commit that referenced this pull request Jun 27, 2026
…338)

#333 hid the onboarding overlay during the "Import from another app"
handoff with a sticky in-memory `onboardingHandedOff` UI flag that never
reset, stranding users on an empty Today (onboarding neither completed
nor resumed) once they left Astra.

Replace the one-way flag with route-scoped suppression so the overlay
hides only while on the chat/Astra screen and reappears (onboarding
still incomplete) on every other route:

- shared: drop the `onboardingHandedOff` flag + setter from ui-store.
- web: the overlay lives in the (app) layout and already unmounts when
  navigating into the (chat) route group, so removing the flag is enough
  -- returning to (app) remounts it while onboarding is incomplete.
- mobile: the overlay is a Modal in the always-mounted root layout, so
  gate it on the active route (usePathname) -- hidden on /chat, shown
  elsewhere.

Import still does NOT complete onboarding, so the first-run coach tour
stays gated on genuine completion and never fires mid-detour.

Tests: web + mobile import handoff routes to chat without completing
onboarding; returning from chat re-shows the overlay (the stranded-user
regression); shared/web/mobile suites green.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
thomasluizon added a commit that referenced this pull request Jun 27, 2026
…339)

#326/#333 shipped the calendar Week (7-day) and Interval (N-day) time-grid
views to apps/web only. Mirror them to apps/mobile for cross-platform parity.

Mobile:
- Mês / Semana / Intervalo view switch on the calendar screen.
- Week view: 7-day time grid with week-granularity nav + show-recurring toggle.
- Interval view: range-picker mini-calendar (14-day cap + clamped notice) plus
  an N-day time grid + show-recurring toggle.
- New CalendarTimeGrid, CalendarWeekView, CalendarRangeView, ShowRecurringToggle
  and CalendarWeekNav; CalendarGrid gains an optional range-highlight mode;
  useCalendarRange hook.

Shared:
- Lift clampRangeToMaxDays + MAX_RANGE_DAYS from apps/web/lib/calendar-range to
  packages/shared/src/utils/calendar-range.ts so both platforms consume one
  copy (web re-points its import; no duplication). filterRecurringEntries was
  already shared and is reused.

Web:
- Make the shared CalendarTimeGrid horizontally scrollable: day columns keep an
  ~80px minimum width and scroll left/right with the left time gutter and the
  header/all-day rows pinned, instead of compressing at narrow widths. Applies
  to both the web week and interval views; mobile mirrors the same behavior.

Tests: shared 14-day clamp; mobile time-grid render (timed + all-day, N
columns, header tap), view switch, and show-recurring filtering.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
thomasluizon added a commit that referenced this pull request Aug 19, 2026
)

The canvas run is complete. The screens project holds 20 documents and 21
pages, all new canon, and no document survives from the first run.

Screens built: Hoje, habit create, habit detail, Calendario, Progresso, the
Astra conversation, onboarding, auth, Perfil, notifications, the Pro pitch, the
subscription manage view, the surviving celebration, the error and static
surfaces, offline, search, step up, the overlay primitives, Wrapped, the four
static screens, and the Android widget.

Three design system rounds ran alongside the screens, each from gaps a build
reported rather than from a guess:

- D  the four defects found on the first Hoje: icon centring, emoji used as
     iconography, frozen and skip as habit statuses, and a hand drawn mark
- D2 DayStrip, Checkbox, a shell header slot, TimeField, StatTile states, Menu
- D3 BlockFrame's control, proposed and irreversible rows plus a risk slot,
     Composer's busy state and its discriminated atLimit, and an authorable
     conversation slot

Two of those are enforced by contract rather than by prose, because the same
bug came back twice under different disguises. DayStrip discriminates on scope,
so passing frozen to a habit strip is a type error. Composer discriminates on
state, so atLimit cannot render without its message and no other state can pass
one.

Six open questions were put to Thomas and answered: a rejected preview
collapses to one line, step up is a hand off, a partially failed bulk create
keeps what it created, the day arc is the exact fraction, Calendario pages on
an empty account, and the month rate has a definition.

DESIGN.md gains that definition, because Calendario computed it and correctly
flagged that no endpoint states the window, which means the next surface would
compute a different number from the same data.

Four API tickets were filed from what the screens reported they needed: #331
the streak repair endpoint, #332 the achievements payload, #333 the Astra
metrics schema, #334 the notification urls.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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