first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
# invoice
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
The `invoiceTemplate` is the receipt / invoice / order-confirmation
email. It renders a heading carrying the invoice number, a metadata line
(date, optional due date), a line-items table with description /
quantity / unit-price / total columns, a subtotal-tax-total summary, and
an optional "Pay Now" CTA when `paymentUrl` is supplied.
The template is intentionally generic — it does not assume a specific
tax-jurisdiction or currency formatting; consumers pass pre-formatted
strings (date, currency symbol) and pre-computed numbers (subtotal,
tax, total). The template focuses on layout, not arithmetic.
## Features
- Line-items table with description, quantity, unit price, total columns.
- Subtotal + optional tax + total summary at right-align.
- Optional `paymentUrl` renders a "Pay Now" CTA.
- Currency symbol is configurable (`currency` defaults to `"$"`).
- Optional `dueDate` appears alongside the invoice date.
## Usage: Basic
```ts
import { renderToHtml } from "@suaveplan/email-templates/renderer";
import { invoiceTemplate } from "@suaveplan/email-templates/templates";
renderToHtml(invoiceTemplate, {
recipientName: "Jane",
invoiceNumber: "INV-001",
invoiceDate: "2026-01-15",
items: [
{ description: "Pro plan – Jan 2026", quantity: 1, unitPrice: 29, total: 29 },
],
subtotal: 29,
total: 29,
});
```
## Usage: Advanced
A multi-line invoice with tax, a due date, a payment CTA, and a
non-USD currency:
```ts
import { renderToHtml } from "@suaveplan/email-templates/renderer";
import { invoiceTemplate } from "@suaveplan/email-templates/templates";
renderToHtml(invoiceTemplate, {
recipientName: "Jane",
invoiceNumber: "INV-001",
invoiceDate: "2026-01-15",
dueDate: "2026-01-31",
currency: "€",
items: [
{ description: "Pro plan – Jan 2026", quantity: 1, unitPrice: 29, total: 29 },
{ description: "Add-on: extra seat", quantity: 2, unitPrice: 5, total: 10 },
],
subtotal: 39,
tax: 3.9,
total: 42.9,
paymentUrl: "https://billing.example.test/pay?invoice=INV-001",
});
```
## API Reference
| Symbol | Kind | Description |
| ----------------- | -------- | ---------------------------------------------------- |
| `invoiceTemplate` | const | `EmailTemplate<InvoiceProps>`. |
| `InvoiceEmail` | function | Component returning a `VNode`. |
| `InvoiceProps` | type | `{ recipientName, invoiceNumber, invoiceDate, dueDate?, items, subtotal, tax?, total, currency?, paymentUrl?, companyName? }` |
| `InvoiceLineItem` | type | `{ description, quantity, unitPrice, total }`. |
## Implementation Notes
Currency formatting uses `Number.prototype.toFixed(2)` — locale-agnostic
two-decimal-place rendering. Consumers needing locale-aware grouping
separators (e.g. `1,234.56` vs `1 234,56`) should pre-format the strings
upstream; the template intentionally does not depend on `Intl.NumberFormat`
because email-template environments span Node, Bun, and browsers where
the Intl data sets vary.
The line-items table renders a single `<tbody>` per call; the table
header sits in its own `<thead>` so accessibility scanners report the
correct table-with-headers structure even though most email clients
ignore the distinction.