mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-23 10:11:13 -05:00
feat: Implement ticket system and reply button
This commit is contained in:
@@ -66,7 +66,7 @@ const handler = async (req: Request): Promise<Response> => {
|
||||
// Fetch submission
|
||||
const { data: submission, error: fetchError } = await supabase
|
||||
.from('contact_submissions')
|
||||
.select('id, email, name, subject, thread_id, response_count')
|
||||
.select('id, email, name, subject, thread_id, response_count, ticket_number')
|
||||
.eq('id', submissionId)
|
||||
.single();
|
||||
|
||||
@@ -89,8 +89,9 @@ const handler = async (req: Request): Promise<Response> => {
|
||||
}, 429, corsHeaders);
|
||||
}
|
||||
|
||||
const messageId = `<${crypto.randomUUID()}@thrillwiki.com>`;
|
||||
const finalSubject = replySubject || `Re: ${submission.subject}`;
|
||||
const ticketNumber = submission.ticket_number || 'UNKNOWN';
|
||||
const messageId = `<${ticketNumber}.${crypto.randomUUID()}@thrillwiki.com>`;
|
||||
const finalSubject = replySubject || `Re: [${ticketNumber}] ${submission.subject}`;
|
||||
|
||||
// Get previous message for threading
|
||||
const { data: previousMessages } = await supabase
|
||||
@@ -100,7 +101,13 @@ const handler = async (req: Request): Promise<Response> => {
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(1);
|
||||
|
||||
const inReplyTo = previousMessages?.[0]?.message_id || `<${submission.thread_id}@thrillwiki.com>`;
|
||||
const originalMessageId = `<${ticketNumber}.${submission.id}@thrillwiki.com>`;
|
||||
const inReplyTo = previousMessages?.[0]?.message_id || originalMessageId;
|
||||
|
||||
// Build reference chain for threading
|
||||
const referenceChain = previousMessages?.[0]?.message_id
|
||||
? [originalMessageId, previousMessages[0].message_id].join(' ')
|
||||
: originalMessageId;
|
||||
|
||||
// Send email via ForwardEmail
|
||||
const forwardEmailResponse = await fetch('https://api.forwardemail.net/v1/emails', {
|
||||
@@ -117,8 +124,9 @@ const handler = async (req: Request): Promise<Response> => {
|
||||
headers: {
|
||||
'Message-ID': messageId,
|
||||
'In-Reply-To': inReplyTo,
|
||||
'References': inReplyTo,
|
||||
'X-Thread-ID': submission.thread_id
|
||||
'References': referenceChain,
|
||||
'X-Thread-ID': submission.thread_id,
|
||||
'X-Ticket-Number': ticketNumber
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
@@ -139,7 +139,7 @@ const handler = async (req: Request): Promise<Response> => {
|
||||
userId = user?.id || null;
|
||||
}
|
||||
|
||||
// Insert contact submission
|
||||
// Insert contact submission (ticket number auto-generated by trigger)
|
||||
const { data: submission, error: insertError } = await supabase
|
||||
.from('contact_submissions')
|
||||
.insert({
|
||||
@@ -153,7 +153,7 @@ const handler = async (req: Request): Promise<Response> => {
|
||||
ip_address_hash: ipHash,
|
||||
status: 'pending'
|
||||
})
|
||||
.select()
|
||||
.select('*, ticket_number')
|
||||
.single();
|
||||
|
||||
if (insertError) {
|
||||
@@ -174,6 +174,9 @@ const handler = async (req: Request): Promise<Response> => {
|
||||
const fromEmail = Deno.env.get('FROM_EMAIL_ADDRESS') || 'noreply@thrillwiki.com';
|
||||
const forwardEmailKey = Deno.env.get('FORWARDEMAIL_API_KEY');
|
||||
|
||||
const ticketNumber = submission.ticket_number || 'PENDING';
|
||||
const messageId = `<${ticketNumber}.${submission.id}@thrillwiki.com>`;
|
||||
|
||||
if (forwardEmailKey) {
|
||||
// Send admin notification
|
||||
fetch('https://api.forwardemail.net/v1/emails', {
|
||||
@@ -185,9 +188,10 @@ const handler = async (req: Request): Promise<Response> => {
|
||||
body: JSON.stringify({
|
||||
from: fromEmail,
|
||||
to: adminEmail,
|
||||
subject: `New Contact Form Submission - ${category.charAt(0).toUpperCase() + category.slice(1)}`,
|
||||
subject: `[${ticketNumber}] New Contact - ${category.charAt(0).toUpperCase() + category.slice(1)}`,
|
||||
text: `A new contact message has been received:
|
||||
|
||||
Ticket: ${ticketNumber}
|
||||
From: ${name} (${email})
|
||||
Category: ${category.charAt(0).toUpperCase() + category.slice(1)}
|
||||
Subject: ${subject}
|
||||
@@ -199,6 +203,10 @@ Reference ID: ${submission.id}
|
||||
Submitted: ${new Date(submission.created_at).toLocaleString()}
|
||||
|
||||
View in admin panel: https://thrillwiki.com/admin/contact`,
|
||||
headers: {
|
||||
'Message-ID': messageId,
|
||||
'X-Ticket-Number': ticketNumber
|
||||
}
|
||||
}),
|
||||
}).catch(err => {
|
||||
edgeLogger.error('Failed to send admin notification', { requestId, error: err.message });
|
||||
@@ -214,25 +222,37 @@ View in admin panel: https://thrillwiki.com/admin/contact`,
|
||||
body: JSON.stringify({
|
||||
from: fromEmail,
|
||||
to: email,
|
||||
subject: "We've received your message - ThrillWiki Support",
|
||||
subject: `[${ticketNumber}] We've received your message - ThrillWiki Support`,
|
||||
text: `Hi ${name},
|
||||
|
||||
Thank you for contacting ThrillWiki! We've received your message and will respond within 24-48 hours.
|
||||
|
||||
Your Message Details:
|
||||
Ticket Number: ${ticketNumber}
|
||||
Category: ${category.charAt(0).toUpperCase() + category.slice(1)}
|
||||
Subject: ${subject}
|
||||
|
||||
Reference ID: ${submission.id}
|
||||
When replying to this email, please keep the ticket number in the subject line to ensure your response is properly tracked.
|
||||
|
||||
Our support team will review your message and get back to you as soon as possible.
|
||||
|
||||
Best regards,
|
||||
The ThrillWiki Team`,
|
||||
headers: {
|
||||
'Message-ID': messageId,
|
||||
'X-Ticket-Number': ticketNumber,
|
||||
'References': messageId
|
||||
}
|
||||
}),
|
||||
}).catch(err => {
|
||||
edgeLogger.error('Failed to send confirmation email', { requestId, error: err.message });
|
||||
});
|
||||
|
||||
// Update thread_id with ticket number
|
||||
await supabase
|
||||
.from('contact_submissions')
|
||||
.update({ thread_id: `ticket-${ticketNumber}` })
|
||||
.eq('id', submission.id);
|
||||
}
|
||||
|
||||
const duration = Date.now() - startTime;
|
||||
@@ -246,7 +266,8 @@ The ThrillWiki Team`,
|
||||
JSON.stringify({
|
||||
success: true,
|
||||
submissionId: submission.id,
|
||||
message: 'Your message has been received. We will respond within 24-48 hours.'
|
||||
ticketNumber: ticketNumber,
|
||||
message: `Your message has been received (Ticket: ${ticketNumber}). We will respond within 24-48 hours.`
|
||||
}),
|
||||
{
|
||||
status: 200,
|
||||
|
||||
Reference in New Issue
Block a user