| Client | ${invoice.client.name} |
| Subtotal | ${formatCurrency(subtotal)} |
| Tax (${invoice.taxRate}%) | ${formatCurrency(taxAmount)} |
| Total | ${formatCurrency(total)} |
interface InvoiceEmailTemplateProps {
invoice: {
invoiceNumber: string;
issueDate: Date;
dueDate: Date;
status: string;
totalAmount: number;
taxRate: number;
currency?: string | null;
client: {
name: string;
email: string | null;
};
business?: {
name: string;
nickname?: string | null;
email?: string | null;
phone?: string | null;
addressLine1?: string | null;
addressLine2?: string | null;
city?: string | null;
state?: string | null;
postalCode?: string | null;
country?: string | null;
} | null;
items: Array<{
date: Date;
description: string;
hours: number;
rate: number;
amount: number;
}>;
};
customContent?: string;
customMessage?: string;
userName?: string;
userEmail?: string;
baseUrl?: string;
}
export function generateInvoiceEmailTemplate({
invoice,
customContent,
customMessage,
userName,
userEmail,
baseUrl: _baseUrl = "https://beenvoice.app",
}: InvoiceEmailTemplateProps): { html: string; text: string } {
const formatDate = (date: Date) => {
return new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric",
}).format(new Date(date));
};
const formatCurrency = (amount: number) => {
return new Intl.NumberFormat("en-US", {
style: "currency",
currency: invoice.currency ?? "USD",
}).format(amount);
};
const getTimeOfDayGreeting = () => {
const hour = new Date().getHours();
if (hour < 12) return "Good morning";
if (hour < 17) return "Good afternoon";
return "Good evening";
};
const subtotal = invoice.items.reduce((sum, item) => sum + item.amount, 0);
const taxAmount = subtotal * (invoice.taxRate / 100);
const total = subtotal + taxAmount;
const businessAddress = invoice.business
? [
invoice.business.addressLine1,
invoice.business.addressLine2,
invoice.business.city && invoice.business.state
? `${invoice.business.city}, ${invoice.business.state} ${invoice.business.postalCode ?? ""}`.trim()
: (invoice.business.city ?? invoice.business.state),
invoice.business.country !== "United States"
? invoice.business.country
: null,
]
.filter(Boolean)
.join("
")
: "";
const html = `
| Client | ${invoice.client.name} |
| Subtotal | ${formatCurrency(subtotal)} |
| Tax (${invoice.taxRate}%) | ${formatCurrency(taxAmount)} |
| Total | ${formatCurrency(total)} |