60 lines
1.8 KiB
Markdown
60 lines
1.8 KiB
Markdown
|
|
# Billing Tab
|
||
|
|
|
||
|
|
**Nav id**: `billing`
|
||
|
|
**Icon**: ◈
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## What it shows
|
||
|
|
|
||
|
|
A read-only ledger of all payment transactions for this client — a running total of paid amounts at the top, then a chronological list of individual entries. Status badges distinguish paid / pending / refunded.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Data flow
|
||
|
|
|
||
|
|
`getBillingHistory(token)` — `GET /vip/billing?token=<token>` — returns an array of `VipBillingEntry` objects.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Billing entry object
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface VipBillingEntry {
|
||
|
|
id: string
|
||
|
|
description: string // e.g. "2hr date — March 15"
|
||
|
|
amountCents: number
|
||
|
|
currency: string // ISO 4217, e.g. "usd"
|
||
|
|
status: 'paid' | 'pending' | 'refunded'
|
||
|
|
billedAt: string // ISO 8601
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Display logic
|
||
|
|
|
||
|
|
**Total card** — sums `amountCents` where `status === 'paid'`. Currency is taken from `entries[0].currency` (all entries for a client share the same currency). Formatted via `Intl.NumberFormat` with `style: 'currency'`.
|
||
|
|
|
||
|
|
**Transaction list** — sorted by API (newest first assumed). Each row shows:
|
||
|
|
- Description (left, primary)
|
||
|
|
- Date (`formatDate` — month day year) (left, secondary)
|
||
|
|
- Amount (right, primary)
|
||
|
|
- Status badge (right, secondary)
|
||
|
|
|
||
|
|
**Status badge colors**:
|
||
|
|
|
||
|
|
| Status | Background | Text |
|
||
|
|
|--------|-----------|------|
|
||
|
|
| `paid` | `#1a2d1a` | `#30d158` (green) |
|
||
|
|
| `pending` | `#2d2a1a` | `#ffd60a` (yellow) |
|
||
|
|
| `refunded` | `T.input` | `T.secondary` (muted purple) |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Non-obvious details
|
||
|
|
|
||
|
|
- Currency is not shown as `USD` but rendered by `Intl.NumberFormat` — e.g. `$2,400.00` for usd. This correctly handles non-USD currencies if ever used.
|
||
|
|
- `entries[0]?.currency ?? 'usd'` fallback assumes homogeneous currency per client — mixing currencies on a single ledger is not supported in the UI.
|
||
|
|
- Billing is purely informational — no payment action (pay now, dispute) is available from this tab.
|