2.3 KiB
Recent Quotes Status Derivation (v2)
The Bug
In the Recent Quotes panel (src/pages/QuoteGenerator.tsx), the status badge was showing "Draft" even when ALL services had been decided (approved or declined) by shop staff in the QuoteGenerator.
Root Cause
The quote's status field in PocketBase is only a lifecycle field:
'draft'— set on Save (QuoteSummary.tsx:123)'sent'— set on Share (QuoteSummary.tsx:246)'approved'/'declined'— set by the customer via QuoteApprove.tsx:221-225
When shop staff approve/decline individual services in the QuoteGenerator, the customerDecision values are saved inside the services JSON blob, but the quote-level status field is NOT updated. It stays 'draft'.
The Fix
In loadRecentQuotes() (QuoteGenerator.tsx:196), derive the display status from individual service decisions when ALL services have been decided:
const hasPending = servicesList.some((s: any) => !s.customerDecision || s.customerDecision === 'pending');
let derivedStatus: QuoteRecord['status'] = record.status;
if (!hasPending && servicesList.length > 0) {
const allApproved = servicesList.every((s: any) => s.customerDecision === 'approved');
const allDeclined = servicesList.every((s: any) => s.customerDecision === 'declined');
if (allApproved) derivedStatus = 'approved';
else if (allDeclined) derivedStatus = 'declined';
}
// Use derivedStatus in the returned object's `status` field
This overrides status to:
'approved'— when ALL services havecustomerDecision === 'approved''declined'— when ALL services havecustomerDecision === 'declined'- Keeps original PocketBase status — when some services are still pending, or when decisions are mixed (some approved, some declined)
Because the mapped object's status field feeds both the RecentStatusBadge component and the filter/count logic (recentCounts, matchesRecentStatusFilter), this single change fixes the badge, the filter tabs, and the filter counts.
Also Fixed
The hasPending check was previously servicesList.some(s => s.customerDecision === 'pending'). A service with no customerDecision field at all would NOT be counted as pending. Changed to servicesList.some(s => !s.customerDecision || s.customerDecision === 'pending') to handle services that don't have the field yet (edge case with legacy data).