Files
dzinesco 8ed7ae95d1 feat: comprehensive project completion and documentation
- Enhanced event creation wizard with multi-step validation
- Added advanced QR scanning system with offline support
- Implemented comprehensive territory management features
- Expanded analytics with export functionality and KPIs
- Created complete design token system with theme switching
- Added 25+ Playwright test files for comprehensive coverage
- Implemented enterprise-grade permission system
- Enhanced component library with 80+ React components
- Added Firebase integration for deployment
- Completed Phase 3 development goals substantially

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 15:04:37 -06:00

132 lines
5.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sendTicketEmail = sendTicketEmail;
exports.logTicketEmail = logTicketEmail;
const firebase_functions_1 = require("firebase-functions");
const resend_1 = require("resend");
const resend = new resend_1.Resend(process.env.EMAIL_API_KEY);
const APP_URL = process.env.APP_URL || "https://staging.blackcanyontickets.com";
/**
* Sends ticket confirmation email with QR codes
*/
async function sendTicketEmail({ to, eventName, tickets, organizationName = "Black Canyon Tickets", }) {
try {
const ticketList = tickets
.map((ticket) => `
<div style="border: 1px solid #e5e7eb; border-radius: 8px; padding: 16px; margin: 8px 0;">
<h3 style="margin: 0 0 8px 0; color: #1f2937;">${ticket.ticketTypeName}</h3>
<p style="margin: 4px 0; color: #6b7280;">Ticket ID: ${ticket.ticketId}</p>
<p style="margin: 4px 0; color: #6b7280;">Event: ${eventName}</p>
<p style="margin: 4px 0; color: #6b7280;">Date: ${new Date(ticket.startAt).toLocaleString()}</p>
<div style="margin: 12px 0;">
<a href="${APP_URL}/t/${ticket.ticketId}"
style="background: #3b82f6; color: white; padding: 8px 16px; text-decoration: none; border-radius: 4px; display: inline-block;">
View Ticket
</a>
</div>
<p style="margin: 8px 0 0 0; font-size: 12px; color: #9ca3af;">
QR Code: ${ticket.qr}
</p>
</div>
`)
.join("");
const html = `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Your Tickets - ${eventName}</title>
</head>
<body style="font-family: system-ui, -apple-system, sans-serif; line-height: 1.6; color: #374151; max-width: 600px; margin: 0 auto; padding: 20px;">
<div style="text-align: center; margin-bottom: 32px;">
<h1 style="color: #1f2937; margin: 0;">${organizationName}</h1>
<p style="color: #6b7280; margin: 8px 0;">Your ticket confirmation</p>
</div>
<div style="background: #f9fafb; border-radius: 8px; padding: 24px; margin: 24px 0;">
<h2 style="margin: 0 0 16px 0; color: #1f2937;">Your Tickets for ${eventName}</h2>
<p style="margin: 0 0 16px 0; color: #6b7280;">
Thank you for your purchase! Your tickets are ready. Please save this email for your records.
</p>
${ticketList}
</div>
<div style="background: #fef3c7; border: 1px solid #f59e0b; border-radius: 8px; padding: 16px; margin: 24px 0;">
<h3 style="margin: 0 0 8px 0; color: #92400e;">Important Information</h3>
<ul style="margin: 0; padding-left: 20px; color: #92400e;">
<li>Present your QR code at the venue for entry</li>
<li>Each ticket can only be scanned once</li>
<li>Arrive early to avoid delays</li>
<li>Contact support if you have any issues</li>
</ul>
</div>
<div style="text-align: center; margin-top: 32px; padding-top: 24px; border-top: 1px solid #e5e7eb;">
<p style="color: #9ca3af; font-size: 14px; margin: 0;">
Need help? Contact us at support@blackcanyontickets.com
</p>
</div>
</body>
</html>
`;
const text = `
Your Tickets for ${eventName}
Thank you for your purchase! Your tickets are ready:
${tickets
.map((ticket) => `
Ticket: ${ticket.ticketTypeName}
ID: ${ticket.ticketId}
QR: ${ticket.qr}
View: ${APP_URL}/t/${ticket.ticketId}
`)
.join("\n")}
Important:
- Present your QR code at the venue for entry
- Each ticket can only be scanned once
- Arrive early to avoid delays
Need help? Contact support@blackcanyontickets.com
`;
await resend.emails.send({
from: "tickets@blackcanyontickets.com",
to,
subject: `Your tickets ${eventName}`,
html,
text,
});
firebase_functions_1.logger.info("Ticket email sent successfully", {
to,
eventName,
ticketCount: tickets.length,
});
}
catch (error) {
firebase_functions_1.logger.error("Failed to send ticket email", {
error: error instanceof Error ? error.message : String(error),
to,
eventName,
ticketCount: tickets.length,
});
throw error;
}
}
/**
* Development helper - logs email instead of sending
*/
async function logTicketEmail(options) {
firebase_functions_1.logger.info("DEV: Would send ticket email", {
to: options.to,
eventName: options.eventName,
tickets: options.tickets.map((t) => ({
id: t.ticketId,
qr: t.qr,
type: t.ticketTypeName,
url: `${APP_URL}/t/${t.ticketId}`,
})),
});
}
//# sourceMappingURL=email.js.map