Files
GearBox/.planning/debug/crop-preview-edit-state.md
Jean-Luc Makiola 4ccbb2b070
Some checks failed
CI / ci (push) Failing after 1m44s
CI / e2e (push) Has been skipped
CI / deploy (push) Has been skipped
fix: wire catalog add buttons, fix Trans bold rendering, lint cleanup
- CatalogSearchOverlay: replace handleAddStub with real openAddToCollection/openAddToThread routing based on catalogSearchMode
- ConfirmDialog + __root.tsx: swap t() for Trans component on deleteItemMessage, deleteCandidateMessage, pickWinnerMessage — fixes <bold> rendering as literal text
- Biome format pass: fix 23 lint/format errors across scripts, services, tests
- Planning: mark all UAT and verification gaps resolved for phases 07, 11, 16, 20, 21, 22, 24, 32, 34; close debug sessions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 15:36:16 +02:00

3.5 KiB

status, trigger, created, updated
status trigger created updated
resolved crop editor opens on upload correctly, but after cropping the cropped image isn't shown in the edit state always — after clicking save it is shown correctly 2026-04-13T12:30:00Z 2026-04-13T12:35:00Z

Current Focus

hypothesis: GearImage in ImageUpload receives no crop props after cropping — crop values are sent to server via onCropChange but never stored locally or passed to the preview GearImage test: trace data flow from ImageCropEditor.onSave through ImageUpload to GearImage rendering expecting: GearImage in ImageUpload has no cropZoom/cropX/cropY props next_action: return diagnosis

Symptoms

expected: After cropping in the crop editor, the image preview in edit mode should immediately reflect the crop actual: Cropped image not shown in edit state after cropping; shows correctly only after Save errors: None reproduction: Upload image to item -> crop editor opens -> adjust crop -> close editor -> preview shows uncropped image -> Save item -> page re-renders with crop applied started: Since Phase 29 implementation

Eliminated

(none needed — root cause found on first hypothesis)

Evidence

  • timestamp: 2026-04-13T12:32:00Z checked: ImageUpload.tsx lines 83-95 — ImageCropEditor onSave handler found: onSave calls onCropChange(result) then setShowCropEditor(false). The crop values are passed up to the parent but NOT stored in any local state within ImageUpload. implication: After crop editor closes, ImageUpload has no memory of what crop was applied.

  • timestamp: 2026-04-13T12:33:00Z checked: ImageUpload.tsx lines 109-114 — GearImage rendering after crop editor closes found: GearImage is rendered with only src, alt, and dominantColor props. NO cropZoom, cropX, or cropY props are passed. The component never receives crop values. implication: GearImage renders uncropped because it literally has no crop data to apply.

  • timestamp: 2026-04-13T12:34:00Z checked: $itemId.tsx lines 277-294 — onCropChange callback in item detail page found: onCropChange triggers updateItem.mutate() which sends crop values to the server immediately. This is a fire-and-forget mutation — it does NOT update local state or the React Query cache synchronously. implication: Crop values reach the server, but the local component tree has no access to them until the query is invalidated/refetched.

  • timestamp: 2026-04-13T12:34:30Z checked: $itemId.tsx lines 326-335 — GearImage in non-edit view mode found: Non-edit view reads cropZoom, cropX, cropY from item (React Query cache data). After Save, the mutation invalidates the query, item refetches with crop values, and GearImage renders correctly. implication: Confirms the "works after save" behavior — the query refetch provides the crop data.

Resolution

root_cause: ImageUpload component does not track crop values locally after the crop editor closes. When the crop editor's onSave fires, the crop values are forwarded to the parent ($itemId.tsx) which sends them to the server via updateItem.mutate(), but no local state is updated. The GearImage rendered inside ImageUpload receives zero crop-related props (cropZoom, cropX, cropY are never passed). So the preview always shows the uncropped/default image. After the user clicks Save on the item form, the React Query cache is invalidated, the item refetches with server-side crop values, and the page re-renders in view mode with the correct crop applied.

fix: (not applied — diagnosis only) verification: (not applied — diagnosis only) files_changed: []