fix(audit-wave-9): adopt StatusPill for berth + user status badges
- Extend StatusPill with berth (available/under_offer/sold) and user (enabled/disabled) variants so every "this thing is in state X" pill shares one primitive and palette. - Swap berth-card, berth-detail-header, berth-columns from ad-hoc bg-green-100 / bg-yellow-100 / bg-red-100 Tailwind tuples to <StatusPill status="...">. - Swap UserList Active/Disabled <Badge> and user-card Inactive pill to StatusPill; Super-Admin chip kept as a domain-specific accent (violet). Closes ui/ux M1+M2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,7 +97,7 @@ function lastActivityFor(interest: ClientInterestRow): string | null {
|
||||
}
|
||||
|
||||
/** Full interest record returned by `/api/v1/interests/[id]`. Only the fields
|
||||
* the drawer actually reads are typed here; the API returns more. */
|
||||
* the preview sheet actually reads are typed here; the API returns more. */
|
||||
interface InterestDetail {
|
||||
id: string;
|
||||
pipelineStage: string;
|
||||
@@ -114,7 +114,7 @@ interface InterestDetail {
|
||||
|
||||
function useInterestDetail(id: string | null) {
|
||||
return useQuery<{ data: InterestDetail }>({
|
||||
queryKey: ['interest-detail-drawer', id],
|
||||
queryKey: ['interest-detail-preview', id],
|
||||
queryFn: () => apiFetch<{ data: InterestDetail }>(`/api/v1/interests/${id}`),
|
||||
enabled: id !== null,
|
||||
// Detail rarely changes during a single drawer-open session; stale-time
|
||||
@@ -132,7 +132,7 @@ function formatDate(value: string | null | undefined): string | null {
|
||||
return format(d, 'MMM d, yyyy');
|
||||
}
|
||||
|
||||
/** A single milestone row inside the drawer's milestone summary. Filled
|
||||
/** A single milestone row inside the preview sheet's milestone summary. Filled
|
||||
* circle when the step is done, hollow when pending. Trailing meta line
|
||||
* shows the date stamp or a "pending" hint. */
|
||||
function MilestoneRow({
|
||||
@@ -162,14 +162,13 @@ function MilestoneRow({
|
||||
}
|
||||
|
||||
/**
|
||||
* Bottom-sheet preview of a single interest. Designed for the mobile
|
||||
* "tap an interest → see what's happening without leaving the client
|
||||
* page" flow. Shows the pipeline progress, a compact milestone summary
|
||||
* (EOI / Deposit / Contract), lead context, last contact, and a notes
|
||||
* teaser. Tap-out / drag-down dismisses; the full edit page is one tap
|
||||
* away via "Open full page →".
|
||||
* Right-side sheet preview of a single interest. "Tap an interest → see
|
||||
* what's happening without leaving the client page". Shows the pipeline
|
||||
* progress, a compact milestone summary (EOI / Deposit / Contract),
|
||||
* lead context, last contact, and a notes teaser. Tap-out / Esc
|
||||
* dismisses; the full edit page is one tap away via "Open full page →".
|
||||
*/
|
||||
function InterestPreviewDrawer({
|
||||
function InterestPreviewSheet({
|
||||
interest,
|
||||
portSlug,
|
||||
onClose,
|
||||
@@ -178,10 +177,10 @@ function InterestPreviewDrawer({
|
||||
portSlug: string;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
// Pin the most recently selected interest so the drawer stays populated
|
||||
// during the close-animation tail (Vaul keeps the content mounted ~250ms
|
||||
// after `open=false`). Conditional setState is safe here - the guard
|
||||
// ensures it only fires when the prop actually changes to a new row.
|
||||
// Pin the most recently selected interest so the sheet stays populated
|
||||
// during the close-animation tail (Radix keeps the content mounted
|
||||
// through the slide-out). Conditional setState is safe here - the
|
||||
// guard ensures it only fires when the prop actually changes.
|
||||
const [pinned, setPinned] = useState<ClientInterestRow | null>(interest);
|
||||
if (interest && interest !== pinned) setPinned(interest);
|
||||
const showing = pinned;
|
||||
@@ -448,7 +447,7 @@ export function ClientInterestsTab({ clientId }: ClientInterestsTabProps) {
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<InterestPreviewDrawer
|
||||
<InterestPreviewSheet
|
||||
interest={previewInterest}
|
||||
portSlug={portSlug}
|
||||
onClose={() => setPreviewInterest(null)}
|
||||
|
||||
Reference in New Issue
Block a user