import nodemailer from 'nodemailer'; import { prisma } from './db'; import { getSettings } from './settings'; export async function sendTicketEmail(bookingId: number) { try { // 1. Fetch active settings const settings = await getSettings(); const { brandName, logoImageUrl, logoIcon, primaryColor, smtpHost, smtpPort, smtpUser, smtpPassword, smtpSenderName, smtpSenderEmail, csPhone, csWhatsapp, csEmail, } = settings; // 2. Guard: Verify if SMTP is configured if (!smtpHost || !smtpUser || !smtpPassword) { console.warn(`[SMTP Email] SMTP is not fully configured (host: "${smtpHost}", user: "${smtpUser}"). Skipping email notification.`); return false; } // 3. Fetch Booking with related Schedule and Route const booking = await prisma.booking.findUnique({ where: { id: bookingId }, include: { seats: true, schedule: { include: { route: true, }, }, }, }); if (!booking) { console.error(`[SMTP Email] Booking with ID ${bookingId} not found.`); return false; } if (!booking.passengerEmail) { console.warn(`[SMTP Email] Passenger email is missing for booking ${booking.bookingCode}.`); return false; } // 4. Set up nodemailer transporter const port = Number(smtpPort) || 587; const transporter = nodemailer.createTransport({ host: smtpHost, port: port, secure: port === 465, // true for 465, false for other ports auth: { user: smtpUser, pass: smtpPassword, }, }); // 5. Formats const formatCurrency = (val: number) => { return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', maximumFractionDigits: 0, }).format(val); }; const formatDate = (date: Date) => { return date.toLocaleDateString('id-ID', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', }); }; const formatTime = (date: Date) => { return date.toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit', }); }; const appUrl = process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'; const ticketUrl = `${appUrl}/ticket/${booking.bookingCode}`; const brandColorHex = primaryColor || '#6366f1'; // 6. Build HTML template with brand color matching theme settings const htmlContent = `
Halo ${booking.passengerName},
Pembayaran Anda untuk pemesanan tiket perjalanan telah berhasil dikonfirmasi. Berikut adalah rincian e-ticket resmi Anda:
Silakan bawa Kode Booking atau tunjukkan boarding pass digital Anda saat keberangkatan di lokasi loket resmi kami.