feat(email): implement professional responsive b2b html email template
All checks were successful
Staging Build / build (push) Successful in 3m9s
All checks were successful
Staging Build / build (push) Successful in 3m9s
This commit is contained in:
@@ -12,7 +12,13 @@ import { buildCustomerSnapshot, buildOrderSnapshot } from '@/lib/license-transfo
|
||||
import type { Category, EndCustomer, Order, Product, Profile, WizardSelections } from '@/lib/types'
|
||||
import { getProducts, getCategories } from '@/lib/actions/products'
|
||||
import { validateWizardSelections } from '@/lib/actions/validation'
|
||||
import { getOrderEmailTemplate, getStatusEmailTemplate, buildEmailItemsSection } from '@/lib/actions/email-templates'
|
||||
import {
|
||||
generateOrderEmailHtml,
|
||||
generateOrderEmailSubject,
|
||||
getOrderEmailTemplate,
|
||||
getStatusEmailTemplate,
|
||||
buildEmailItemsSection,
|
||||
} from '@/lib/actions/email-templates'
|
||||
|
||||
// ─── Hilfsfunktionen ─────────────────────────────────────────────────────────
|
||||
|
||||
@@ -301,24 +307,25 @@ export async function submitOrder(params: {
|
||||
`
|
||||
}
|
||||
|
||||
const itemsSection = buildEmailItemsSection(items)
|
||||
|
||||
const emailTemplate = getOrderEmailTemplate({
|
||||
const emailTemplate = generateOrderEmailHtml({
|
||||
orderNumber,
|
||||
status: 'pending',
|
||||
formattedDate,
|
||||
customerCompanyName: customerSnapshot.company_name,
|
||||
totalDetailsText,
|
||||
totalDetailsHtml,
|
||||
itemsDetailsText: itemsSection.text,
|
||||
itemsDetailsHtml: itemsSection.html,
|
||||
items,
|
||||
partnerCompanyName,
|
||||
partnerUserName,
|
||||
partnerUserEmail
|
||||
}, `${process.env.NEXT_PUBLIC_SITE_URL || 'https://staging.hephex.de'}`, false)
|
||||
partnerUserEmail,
|
||||
taxRate,
|
||||
oneTimeNet,
|
||||
monthlyNet,
|
||||
})
|
||||
|
||||
const mailSubject = generateOrderEmailSubject(orderNumber, 'pending')
|
||||
|
||||
await sendMail({
|
||||
to: user.email,
|
||||
subject: `Anfragebestätigung ${orderNumber}`,
|
||||
subject: mailSubject,
|
||||
text: emailTemplate.text,
|
||||
html: emailTemplate.html,
|
||||
attachments: [
|
||||
@@ -343,7 +350,7 @@ export async function submitOrder(params: {
|
||||
if (adminEmail !== user.email) {
|
||||
await sendMail({
|
||||
to: adminEmail,
|
||||
subject: `[Admin-Kopie] Anfragebestätigung ${orderNumber}`,
|
||||
subject: `[Admin-Kopie] ${mailSubject}`,
|
||||
text: emailTemplate.text,
|
||||
html: emailTemplate.html,
|
||||
attachments: [
|
||||
@@ -455,24 +462,27 @@ export async function updateOrderStatus(
|
||||
|
||||
if (!userError && user && user.email) {
|
||||
const orderNumber = order.order_number || order.id.slice(0, 8)
|
||||
const statusLabelMap: Record<string, string> = {
|
||||
pending: 'Eingegangen',
|
||||
pending_approval: 'Wartet auf Freigabe',
|
||||
in_review: 'In Prüfung',
|
||||
approved: 'Freigegeben',
|
||||
active: 'Aktiviert',
|
||||
completed: 'Abgeschlossen',
|
||||
cancelled: 'Storniert',
|
||||
rejected: 'Abgelehnt',
|
||||
}
|
||||
const oldLabel = statusLabelMap[oldStatus] || oldStatus
|
||||
const newLabel = statusLabelMap[newStatus] || newStatus
|
||||
const customerSnapshot = updatedOrder.customer_data || {}
|
||||
const orderSnapshot = updatedOrder.order_data || {}
|
||||
const formattedDate = new Date(updatedOrder.created_at || Date.now()).toLocaleDateString('de-DE')
|
||||
|
||||
const statusEmail = getStatusEmailTemplate(orderNumber, oldLabel, newLabel, newStatus)
|
||||
const statusEmail = generateOrderEmailHtml({
|
||||
orderNumber,
|
||||
status: newStatus,
|
||||
formattedDate,
|
||||
customerCompanyName: customerSnapshot.company_name || 'Endkunde',
|
||||
items: orderSnapshot.items || [],
|
||||
partnerCompanyName: partnerInfo.partnerCompanyName,
|
||||
partnerUserName: partnerInfo.partnerUserName,
|
||||
partnerUserEmail: partnerInfo.partnerUserEmail,
|
||||
taxRate: orderSnapshot.tax_rate ?? 19,
|
||||
})
|
||||
|
||||
const mailSubject = generateOrderEmailSubject(orderNumber, newStatus)
|
||||
|
||||
const mailOptions: any = {
|
||||
to: user.email,
|
||||
subject: `Statusänderung Ihrer Anfrage ${orderNumber}`,
|
||||
subject: mailSubject,
|
||||
text: statusEmail.text,
|
||||
html: statusEmail.html,
|
||||
}
|
||||
@@ -504,7 +514,7 @@ export async function updateOrderStatus(
|
||||
await sendMail({
|
||||
...mailOptions,
|
||||
to: adminEmail,
|
||||
subject: `[Admin-Kopie] Statusänderung Ihrer Anfrage ${orderNumber}`
|
||||
subject: `[Admin-Kopie] ${mailSubject}`
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -642,11 +652,29 @@ export async function rejectOrder(
|
||||
const { data: { user: orderUser }, error: userError } = await admin.auth.admin.getUserById(order.user_id)
|
||||
if (!userError && orderUser && orderUser.email) {
|
||||
const orderNumber = order.order_number || order.id.slice(0, 8)
|
||||
const statusEmail = getStatusEmailTemplate(orderNumber, 'Wartet auf Freigabe', 'Abgelehnt', 'rejected', reason)
|
||||
const partnerInfo = await fetchOrderPartnerInfo(admin, updatedOrder.company_id, updatedOrder.user_id)
|
||||
const customerSnapshot = updatedOrder.customer_data || {}
|
||||
const orderSnapshot = updatedOrder.order_data || {}
|
||||
const formattedDate = new Date(updatedOrder.created_at || Date.now()).toLocaleDateString('de-DE')
|
||||
|
||||
const statusEmail = generateOrderEmailHtml({
|
||||
orderNumber,
|
||||
status: 'rejected',
|
||||
formattedDate,
|
||||
customerCompanyName: customerSnapshot.company_name || 'Endkunde',
|
||||
rejectionReason: reason,
|
||||
items: orderSnapshot.items || [],
|
||||
partnerCompanyName: partnerInfo.partnerCompanyName,
|
||||
partnerUserName: partnerInfo.partnerUserName,
|
||||
partnerUserEmail: partnerInfo.partnerUserEmail,
|
||||
taxRate: orderSnapshot.tax_rate ?? 19,
|
||||
})
|
||||
|
||||
const mailSubject = generateOrderEmailSubject(orderNumber, 'rejected')
|
||||
|
||||
await sendMail({
|
||||
to: orderUser.email,
|
||||
subject: `Anfrage abgelehnt: ${orderNumber}`,
|
||||
subject: mailSubject,
|
||||
text: statusEmail.text,
|
||||
html: statusEmail.html
|
||||
})
|
||||
@@ -664,7 +692,7 @@ export async function rejectOrder(
|
||||
if (adminEmail !== orderUser.email) {
|
||||
await sendMail({
|
||||
to: adminEmail,
|
||||
subject: `[Admin-Kopie] Anfrage abgelehnt: ${orderNumber}`,
|
||||
subject: `[Admin-Kopie] ${mailSubject}`,
|
||||
text: statusEmail.text,
|
||||
html: statusEmail.html
|
||||
})
|
||||
@@ -672,7 +700,7 @@ export async function rejectOrder(
|
||||
}
|
||||
}
|
||||
} catch (adminMailError) {
|
||||
console.error('Failed to notify admins of order rejection:', adminMailError)
|
||||
console.error('Failed to notify admins of rejected order:', adminMailError)
|
||||
}
|
||||
}
|
||||
} catch (mailError) {
|
||||
|
||||
Reference in New Issue
Block a user