feat: [PULSE-32] Invoice history and download — Billing tab invoice list and PDF/view links #3

Merged
uz1mani merged 2 commits from staging into main 2026-02-03 20:03:43 +00:00
uz1mani commented 2026-02-03 19:31:52 +00:00 (Migrated from github.com)

Work Item

PULSE-32

Summary

  • Add an "Invoice History" section in Org Settings → Billing that lists past invoices for the current organization.
  • Each row shows date, amount, status (Paid/Open) and links to view hosted invoice or download PDF.
  • Data is loaded from GET /api/billing/invoices when the Billing tab is active.

Changes

  • lib/api/billing.ts: Added Invoice interface and getInvoices() calling GET /api/billing/invoices.
  • components/settings/OrganizationSettings.tsx: Added invoices / isLoadingInvoices state and loadInvoices(); "Invoice History" block below Current Plan with amount, date, status badge, PDF and hosted-invoice links (using BookOpenIcon, DownloadIcon, ExternalLinkIcon from @ciphera-net/ui). Empty and loading states.

Test Plan

  • Open Org Settings → Billing with an org that has a Stripe subscription; invoice list loads.
  • Check date, amount, status; "Download" opens PDF, "View" opens Stripe hosted page.
  • With no billing/invoices, section shows "No invoices found".
  • Personal workspace (no org) does not show Billing tab (existing behavior).
## Work Item PULSE-32 ## Summary - Add an "Invoice History" section in Org Settings → Billing that lists past invoices for the current organization. - Each row shows date, amount, status (Paid/Open) and links to view hosted invoice or download PDF. - Data is loaded from `GET /api/billing/invoices` when the Billing tab is active. ## Changes - **`lib/api/billing.ts`**: Added `Invoice` interface and `getInvoices()` calling `GET /api/billing/invoices`. - **`components/settings/OrganizationSettings.tsx`**: Added `invoices` / `isLoadingInvoices` state and `loadInvoices()`; "Invoice History" block below Current Plan with amount, date, status badge, PDF and hosted-invoice links (using `BookOpenIcon`, `DownloadIcon`, `ExternalLinkIcon` from `@ciphera-net/ui`). Empty and loading states. ## Test Plan - [ ] Open Org Settings → Billing with an org that has a Stripe subscription; invoice list loads. - [ ] Check date, amount, status; "Download" opens PDF, "View" opens Stripe hosted page. - [ ] With no billing/invoices, section shows "No invoices found". - [ ] Personal workspace (no org) does not show Billing tab (existing behavior).
greptile-apps[bot] commented 2026-02-03 19:34:28 +00:00 (Migrated from github.com)

Greptile Overview

Greptile Summary

Added Invoice History section to Organization Settings Billing tab that displays past invoices with amounts, dates, statuses, and download/view links. Data is fetched from GET /api/billing/invoices when the Billing tab is active.

  • Added Invoice interface and getInvoices() API function in lib/api/billing.ts
  • Implemented invoice state management and loading logic in OrganizationSettings.tsx
  • Rendered invoice list with status badges (Paid/Open), PDF download, and hosted invoice links
  • Included proper loading and empty states

Confidence Score: 4/5

  • Safe to merge with minimal risk
  • Clean implementation following existing patterns with proper state management, loading states, and error handling; minor improvement would be consistent error messaging
  • No files require special attention

Important Files Changed

Filename Overview
lib/api/billing.ts Added Invoice interface and getInvoices() function following existing API patterns
components/settings/OrganizationSettings.tsx Added invoice history UI with loading states, status badges, and PDF/hosted invoice links

Sequence Diagram

sequenceDiagram
    participant User
    participant UI as OrganizationSettings
    participant API as billing.ts
    participant Backend as /api/billing/invoices

    User->>UI: Navigate to Billing tab
    activate UI
    UI->>UI: Check activeTab === 'billing' && currentOrgId
    UI->>API: loadInvoices() → getInvoices()
    activate API
    API->>Backend: GET /api/billing/invoices
    activate Backend
    Backend-->>API: Invoice[] (id, amount_paid, currency, status, etc.)
    deactivate Backend
    API-->>UI: Invoice[]
    deactivate API
    UI->>UI: setInvoices(invs)
    UI->>UI: setIsLoadingInvoices(false)
    UI-->>User: Display invoice list
    deactivate UI
    
    alt User clicks Download PDF
        User->>UI: Click DownloadIcon link
        UI->>Backend: Open invoice.invoice_pdf URL
        Backend-->>User: PDF file download
    else User clicks View Invoice
        User->>UI: Click ExternalLinkIcon link
        UI->>Backend: Open invoice.hosted_invoice_url
        Backend-->>User: Stripe hosted invoice page
    end
<h2>Greptile Overview</h2> <h3>Greptile Summary</h3> Added Invoice History section to Organization Settings Billing tab that displays past invoices with amounts, dates, statuses, and download/view links. Data is fetched from `GET /api/billing/invoices` when the Billing tab is active. - Added `Invoice` interface and `getInvoices()` API function in `lib/api/billing.ts` - Implemented invoice state management and loading logic in `OrganizationSettings.tsx` - Rendered invoice list with status badges (Paid/Open), PDF download, and hosted invoice links - Included proper loading and empty states <h3>Confidence Score: 4/5</h3> - Safe to merge with minimal risk - Clean implementation following existing patterns with proper state management, loading states, and error handling; minor improvement would be consistent error messaging - No files require special attention <details><summary><h3>Important Files Changed</h3></summary> | Filename | Overview | |----------|----------| | lib/api/billing.ts | Added Invoice interface and getInvoices() function following existing API patterns | | components/settings/OrganizationSettings.tsx | Added invoice history UI with loading states, status badges, and PDF/hosted invoice links | </details> </details> <h3>Sequence Diagram</h3> ```mermaid sequenceDiagram participant User participant UI as OrganizationSettings participant API as billing.ts participant Backend as /api/billing/invoices User->>UI: Navigate to Billing tab activate UI UI->>UI: Check activeTab === 'billing' && currentOrgId UI->>API: loadInvoices() → getInvoices() activate API API->>Backend: GET /api/billing/invoices activate Backend Backend-->>API: Invoice[] (id, amount_paid, currency, status, etc.) deactivate Backend API-->>UI: Invoice[] deactivate API UI->>UI: setInvoices(invs) UI->>UI: setIsLoadingInvoices(false) UI-->>User: Display invoice list deactivate UI alt User clicks Download PDF User->>UI: Click DownloadIcon link UI->>Backend: Open invoice.invoice_pdf URL Backend-->>User: PDF file download else User clicks View Invoice User->>UI: Click ExternalLinkIcon link UI->>Backend: Open invoice.hosted_invoice_url Backend-->>User: Stripe hosted invoice page end ```
Sign in to join this conversation.
No description provided.