Rename invoice-settings to company-settings, add its own Live Preview, and refine invoice PDF layout

Company data now has its own Payload admin group and a live in-browser
PDF preview (react-pdf's PDFViewer) instead of just a plain settings
form. Invoice header is a brand-colored rule instead of a filled band,
and the footer is now pinned to the page bottom instead of following
content flow.
This commit is contained in:
Marco
2026-07-22 11:11:58 +00:00
parent f144ad25f2
commit e50d43ea44
8 changed files with 261 additions and 75 deletions
+10 -10
View File
@@ -1,15 +1,15 @@
import { getInvoiceSettings, type InvoiceSettings } from "./payload";
import { getCompanySettings, type CompanySettings } from "./payload";
import { renderInvoicePdf, type InvoiceOrder } from "./invoicePdf";
import { renderCorrectionInvoicePdf, type CorrectionInvoiceKind, type CorrectionInvoiceOrder } from "./correctionInvoicePdf";
export type { InvoiceSettings };
export type { CompanySettings };
// Fetched once by callers that need seller data for more than one purpose
// in the same request (e.g. orderEmail.ts also needs it for the email
// footer's companyLine) — avoids a second identical invoice-settings round
// trip, unlike calling getInvoiceSettings() again inside each generator.
export async function getSellerForInvoice(): Promise<InvoiceSettings | null> {
return getInvoiceSettings();
// footer's companyLine) — avoids a second identical company-settings round
// trip, unlike calling getCompanySettings() again inside each generator.
export async function getSellerForInvoice(): Promise<CompanySettings | null> {
return getCompanySettings();
}
// Shared by app/lib/orderEmail.ts (checkout — attaches to the confirmation
@@ -18,9 +18,9 @@ export async function getSellerForInvoice(): Promise<InvoiceSettings | null> {
// later always matches what they were emailed. `seller` is passed in
// rather than fetched here, so a caller that already has it (see above)
// doesn't fetch it twice.
export async function generateInvoicePdf(order: InvoiceOrder, seller: InvoiceSettings | null): Promise<Buffer | null> {
export async function generateInvoicePdf(order: InvoiceOrder, seller: CompanySettings | null): Promise<Buffer | null> {
if (!seller) {
console.error("generateInvoicePdf: no invoice-settings row found for tenant");
console.error("generateInvoicePdf: no company-settings row found for tenant");
return null;
}
return renderInvoicePdf(order, seller);
@@ -35,10 +35,10 @@ export async function generateInvoicePdf(order: InvoiceOrder, seller: InvoiceSet
export async function generateCorrectionInvoicePdf(
kind: CorrectionInvoiceKind,
order: CorrectionInvoiceOrder,
seller: InvoiceSettings | null,
seller: CompanySettings | null,
): Promise<Buffer | null> {
if (!seller) {
console.error("generateCorrectionInvoicePdf: no invoice-settings row found for tenant");
console.error("generateCorrectionInvoicePdf: no company-settings row found for tenant");
return null;
}
return renderCorrectionInvoicePdf(kind, order, seller);