Skip to content

fix(dashboard): revert task checkbox on mutation failure - #282

Draft
dccakes wants to merge 1 commit into
mainfrom
claude/sharp-feynman-fy4qjb
Draft

dccakes wants to merge 1 commit into
mainfrom
claude/sharp-feynman-fy4qjb

Conversation

@dccakes

@dccakes dccakes commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Daily Product Improvement

📝 TLDR

Revert the task checkbox optimistic toggle when the server mutation fails so the UI never shows incorrect task state.

📝 Description

When a user clicks a task checkbox on the Dashboard, handleToggle immediately calls toggleTask to flip the visual state before the server confirms. This is the correct optimistic update pattern. However, the onError handler on the completeTask mutation only showed a toast — it did not call toggleTask again to flip the checkbox back. If the network was flaky or the server rejected the request, the checkbox would remain in the wrong position until the next page refresh.

This Change

  • Adds toggleTask(variables.taskId) to the onError callback so the checkbox is reverted on failure
  • Toast error message is preserved
  • No changes to the success path or any other behavior

Summary

When the completeTask mutation fails on the Dashboard Tasks card, the checkbox now reverts to its original position in addition to showing the error toast. Previously the optimistic toggle was never rolled back on failure.

Recommendations Reviewed

Area: Dashboard – VendorsCard
Issue: vendors is undefined while loading, so vendorCount === 0 is true and the "No vendors added yet" empty state flashes before real data arrives
Recommendation: Guard with isLoading before showing empty state
Type: UX/UI
Priority: Medium
Effort: Small
Status: Already covered by open PR #256


Area: Dashboard – TasksCard
Issue: Optimistic task toggle not reverted when completeTask mutation fails — checkbox stays in wrong state
Recommendation: Call toggleTask(variables.taskId) in onError to revert
Type: Bug fix
Priority: Medium
Effort: Small
Status: ✅ Implemented in this PR


Area: Guest List – GuestsView
Issue: "No households yet" shown when active filters return zero results, which is misleading
Recommendation: Check households.length > 0 to distinguish filtered-empty vs truly-empty state
Type: UX/UI
Priority: High
Effort: Small
Status: Already covered by open PR #246


Area: Guest List – EventsTabs
Issue: <Button> is a direct child of <ul> (invalid HTML) and tab strip has no ARIA tab semantics
Recommendation: Wrap in <li>, add role="tablist", role="tab", aria-selected
Type: UX/UI / Accessibility
Priority: Medium
Effort: Small
Status: Already covered by open PR #244


Area: Guest List – GuestSearchFilter
Issue: Switching event tab resets text search and tag/country filters along with RSVP filter — overly aggressive
Recommendation: Only reset RSVP filter on tab change; preserve text search and other filters
Type: Product flow
Priority: Medium
Effort: Small
Status: No open PR


Area: Dashboard – DashboardTopbar
Issue: Date starts as '' and is set after mount via useEffect, causing a visible layout shift on every page load
Recommendation: Initialize date directly (no useEffect), add suppressHydrationWarning on the span
Type: UX/UI
Priority: Low
Effort: Small
Status: No open PR


Area: Guest List – InviteLinkPanel
Issue: Panel always renders even when there are no guests yet, making the self-invite link confusing for brand-new weddings
Recommendation: Conditionally hide the panel until at least one event or guest exists
Type: Product flow
Priority: Low
Effort: Small
Status: No open PR


Area: Dashboard – PlanningOverview
Issue: RSVP summary totals (attending/pending/declined) are computed twice with nearly identical logic in MiniStats and RsvpCard
Recommendation: Extract into a single computeRsvpSummary function, compute once, pass as props
Type: Frontend cleanup
Priority: Low
Effort: Small
Status: No open PR


Area: Guest List – GuestsView
Issue: Component is ~1,000 lines managing drawer state, mutations, sort state, filter state, and communication log queries
Recommendation: Extract drawer state + mutations into useGuestDetailDrawer hook; extract delete confirmation into DeleteHouseholdDialog
Type: Frontend cleanup
Priority: Medium
Effort: Large
Status: No open PR


Area: Dashboard – dashboard/page.tsx
Issue: Root content wrapper uses <div> instead of <main>, breaking landmark structure for screen readers
Recommendation: Replace with <main>
Type: Accessibility
Priority: Medium
Effort: Small
Status: Already covered by open PR #232

Selected Improvement

Fix task checkbox optimistic update revert on mutation failure
File: src/components/dashboard/planning-overview.tsx

Added toggleTask(variables.taskId) to the onError callback of the completeTask mutation so the checkbox reverts to its original state when the server request fails.

Why This Was Selected

This is a correctness bug with direct user impact: after a network hiccup or server error, the task checkbox stays in the wrong position indefinitely. Users could believe a task was completed when it wasn't (or vice versa), leading to planning confusion. The fix is a two-line change confined to a single callback and poses zero risk to the success path.

Changes Made

  • In TasksCard, updated completeTask.useMutation onError callback to receive variables and call toggleTask(variables.taskId) before the error toast, reverting the optimistic toggle.

Files Changed

  • src/components/dashboard/planning-overview.tsx

Verification

  • TypeScript: npx tsc --noEmit — no errors related to this change (one pre-existing unrelated deprecation warning)
  • Diff reviewed: only the onError callback changed; success path, handleToggle, and rendering are untouched
  • Logic verified: variables.taskId matches the taskId sent to completeTask.mutate, which is the same ID passed to the initial toggleTask call

Future Recommendations

Filter reset on event tab change
Recommendation: Only reset RSVP filter on tab change; preserve text search, tag, and country filters
Priority: Medium | Effort: Small | Reason not included: Not a bug; behavioral change needs product review | GitHub issue: No

DashboardTopbar date layout shift
Recommendation: Remove useEffect, compute date inline, add suppressHydrationWarning
Priority: Low | Effort: Small | Reason not included: Polish-only, lower impact than today's bug fix | GitHub issue: No

InviteLinkPanel always visible before guests exist
Recommendation: Hide panel until at least one event or guest is present
Priority: Low | Effort: Small | Reason not included: Minor UX nicety, warrants product input on exact trigger condition | GitHub issue: No

Duplicate RSVP summary computation
Recommendation: Extract computeRsvpSummary, compute once at PlanningOverview level
Priority: Low | Effort: Small | Reason not included: Code cleanup only, no user-visible impact | GitHub issue: No

GuestsView component decomposition
Recommendation: Extract useGuestDetailDrawer hook and DeleteHouseholdDialog from the 1,000-line component
Priority: Medium | Effort: Large | Reason not included: Large refactor, requires careful testing of drawer state, optimistic updates, and delete flow | GitHub issue: Yes — spans multiple interaction flows and needs dedicated review

GitHub Issues Created or Proposed

GuestsView component decomposition — proposed as a GitHub issue. The component has grown to ~1,000 lines with drawer state, mutation logic, sort state, filter state, and communication log queries all co-located. Extracting a useGuestDetailDrawer hook and a DeleteHouseholdDialog would significantly improve maintainability and testability, but the scope warrants a separate PR and careful QA of the drawer open/close/dirty-state lifecycle.


Generated by Claude Code

…ilure

When completeTask mutation fails, the onError handler now calls toggleTask
to flip the checkbox back to its original state, preventing the UI from
showing an incorrect completed/incomplete status after a server error.
@vercel

vercel Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated
scv Error Error Sep 1, 2026 2:24pm UTC

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Jest Test Coverage

Coverage Summary

Lines Statements Branches Functions
Coverage: 83%
83.11% (36264/43632) 82.14% (3813/4642) 69.49% (1073/1544)

This branch had an error being deployed

1 failed deployment
Preview — 74f84b70 Deployed Sep 1, 2026 by vercel[bot]
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