fix(ux): T4 polish wave — empty-contact filter, redirect-on-create, friendly stage errors

F19: client form drops empty-value contacts on submit; auto-promotes first remaining row to primary if none flagged.
F20: new-interest dialog redirects to the detail page on create instead of bouncing back to the list.
F21: stage-transition validation errors render with STAGE_LABELS — "Yacht is required before leaving the Enquiry stage." (was "yachtId is required before leaving stage=enquiry").
F22: blocked-stage marker swapped from the ⚑ unicode glyph to a Lucide AlertTriangle with aria-label.
F25: documents-hub folder selection moves to ?folder=<id> querystring so deep-link / browser-back / refresh round-trip the current folder.
F26: reopen-outcome action now toasts "Outcome cleared — interest is open again."
F27: stage PATCH where target === current short-circuits to a no-op return; downstream callers don't see a phantom stage_change audit row.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-14 23:42:27 +02:00
parent 3e78c2d4ab
commit 84468386d9
6 changed files with 97 additions and 17 deletions

View File

@@ -2,6 +2,7 @@
import { useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import {
Pencil,
Archive,
@@ -144,6 +145,9 @@ export function InterestDetailHeader({ portSlug, interest }: InterestDetailHeade
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['interests', interest.id] });
queryClient.invalidateQueries({ queryKey: ['interests'] });
// F26: confirm to the user that the action ran — pre-fix the
// button gave no feedback and reps weren't sure if it took.
toast.success('Outcome cleared — interest is open again.');
},
});