Skip to content

feat(billing): load latest invoice from /api/invoices - #1359

Merged
greatest0fallt1me merged 1 commit into
CalloraOrg:mainfrom
chuks68:feat/billing-invoice-api
Oct 21, 2026
Merged

greatest0fallt1me merged 1 commit into
CalloraOrg:mainfrom
chuks68:feat/billing-invoice-api

Conversation

@chuks68

@chuks68 chuks68 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Closes #1321

Summary

Replaces the hardcoded INV-1001 ($4,200, Due in 7 days) invoice card on the Billing page with live data loaded from GET /api/invoices.

Changes

  • API Client (src/api/invoicesApi.ts):
    • Added fetchLatestInvoices({ limit, cursor, signal, baseUrl, fetchImpl }) using the shared authenticated fetch helper (getSharedAuthenticatedFetch) or an injected fetchImpl.
    • Validates the { data, meta } response shape and adapts backend snake_case fields (invoice_number, status, total_amount_usdc, currency, period_start, period_end).
    • Added selectNewestPendingInvoice to pick the most recent pending invoice.
    • Normalizes unknown statuses to a safe "unknown" fallback (normalizeInvoiceStatus).
  • Exact USDC Decimal Formatting (src/utils/format.ts):
    • Added formatUsdcDecimal to format total_amount_usdc directly from the decimal string without passing through parseFloat, preserving up to all 7 Stellar USDC decimal places and omitting any $ prefix.
  • Invoice Card & Container States (src/pages/InvoiceCard.tsx, src/App.tsx):
    • Added BillingInvoiceSection container handling:
      • Loading: Skeleton card with aria-busy="true".
      • Pending invoice: Displays invoiceNumber, exact USDC amountDue, period_end formatted in the active account's timezone (useAccountContext), and StatusBadge.
      • Empty / all paid: Displays "No outstanding invoices" with a link to /billing/history (Billing History).
      • 401 Unauthorized: Announces a "Not signed in" prompt (role="alert").
      • Error (e.g. 500): Announces the error (role="alert") with a Retry button that refetches.
      • Unknown status: Maps unknown status strings (e.g. "weird") to a neutral StatusBadge variant (maintenance / "Unknown").
      • Lifecycle & Race Safety: Aborts in-flight requests on unmount and when switching accounts, ignoring stale responses.
      • Demo Mode: When VITE_API_BASE_URL is unset, renders a clearly labelled Demo invoice (DEMO-INV-001) without making network calls.
    • Replaced <InvoiceCard invoiceNumber="INV-1001" amountDue="$4,200" dueDate="Due in 7 days" /> in src/App.tsx with <BillingInvoiceSection onPay={() => openDeposit()} />.

Test Output

 RUN  v1.6.1 C:/Users/MCCARTH/drips/chuks68/Callora-Frontend
      Coverage enabled with v8

 ✓ src/api/invoicesApi.test.ts  (18 tests) 191ms
 ✓ src/pages/InvoiceCard.test.tsx  (14 tests) 1222ms

 Test Files  2 passed (2)
      Tests  32 passed (32)

 % Coverage report from v8
------------------|---------|----------|---------|---------|--------------------
File              | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s  
------------------|---------|----------|---------|---------|--------------------
All files         |   98.71 |    91.77 |     100 |   98.71 |                    
 api              |   98.35 |    93.81 |     100 |   98.35 |                    
  invoicesApi.ts  |   98.35 |    93.81 |     100 |   98.35 | ...333-334,343-344 
 pages            |   99.03 |    88.52 |     100 |   99.03 |                    
  InvoiceCard.tsx |   99.03 |    88.52 |     100 |   99.03 | 58,60,62,282       
------------------|---------|----------|---------|---------|--------------------

@drips-wave

drips-wave Bot commented Oct 20, 2026

Copy link
Copy Markdown

@chuks68 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@greatest0fallt1me
greatest0fallt1me merged commit a19fe44 into CalloraOrg:main Oct 21, 2026
1 check passed
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.

Load the Billing invoice card from /api/invoices instead of a hardcoded INV-1001

2 participants