'use server'; import client, { ensureAuthenticated } from '@/lib/directus'; import { createItem } from '@directus/sdk'; import { sendEmail } from '@/lib/mail/mailer'; import { render, ContactFormNotification, ConfirmationMessage } from '@mintel/mail'; import React from 'react'; import { getServerAppServices } from '@/lib/services/create-services.server'; export async function sendContactFormAction(formData: FormData) { const services = getServerAppServices(); const logger = services.logger.child({ action: 'sendContactFormAction' }); // Set analytics context from request headers for high-fidelity server-side tracking const { headers } = await import('next/headers'); const requestHeaders = await headers(); if ('setServerContext' in services.analytics) { (services.analytics as any).setServerContext({ userAgent: requestHeaders.get('user-agent') || undefined, language: requestHeaders.get('accept-language')?.split(',')[0] || undefined, referrer: requestHeaders.get('referer') || undefined, ip: requestHeaders.get('x-forwarded-for')?.split(',')[0] || undefined, }); } // Track attempt services.analytics.track('contact-form-attempt'); const name = formData.get('name') as string; const email = formData.get('email') as string; const message = formData.get('message') as string; const productName = formData.get('productName') as string | null; if (!name || !email || !message) { logger.warn('Missing required fields in contact form', { name: !!name, email: !!email, message: !!message, }); return { success: false, error: 'Missing required fields' }; } // 1. Save to Directus try { await ensureAuthenticated(); if (productName) { await client.request( createItem('product_requests', { product_name: productName, email, message, }), ); logger.info('Product request stored in Directus'); } else { await client.request( createItem('contact_submissions', { name, email, message, }), ); logger.info('Contact submission stored in Directus'); } } catch (error) { logger.error('Failed to store submission in Directus', { error }); services.errors.captureException(error, { action: 'directus_store_submission' }); } // 2. Send Emails logger.info('Sending branded emails', { email, productName }); const notificationSubject = productName ? `Product Inquiry: ${productName}` : 'New Contact Form Submission'; const confirmationSubject = 'Thank you for your inquiry'; try { // 2a. Send notification to Mintel/Client const notificationHtml = await render( React.createElement(ContactFormNotification, { name, email, message, productName: productName || undefined, }), ); const notificationResult = await sendEmail({ replyTo: email, subject: notificationSubject, html: notificationHtml, }); if (notificationResult.success) { logger.info('Notification email sent successfully', { messageId: notificationResult.messageId, }); } // 2b. Send confirmation to Customer (branded as KLZ Cables) const confirmationHtml = await render( React.createElement(ConfirmationMessage, { name, clientName: 'KLZ Cables', // brandColor: '#82ed20', // Optional: could be KLZ specific }), ); const confirmationResult = await sendEmail({ to: email, subject: confirmationSubject, html: confirmationHtml, }); if (confirmationResult.success) { logger.info('Confirmation email sent successfully', { messageId: confirmationResult.messageId, }); } // Notify via Gotify (Internal) await services.notifications.notify({ title: `📩 ${notificationSubject}`, message: `New message from ${name} (${email}):\n\n${message}`, priority: 5, }); // Track success services.analytics.track('contact-form-success', { is_product_request: !!productName, }); return { success: true }; } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); logger.error('Failed to send branded emails', { error: errorMsg, stack: error instanceof Error ? error.stack : undefined, }); services.errors.captureException(error, { action: 'sendContactFormAction', email }); await services.notifications.notify({ title: '🚨 Contact Form Error', message: `Failed to send emails for ${name} (${email}). Error: ${errorMsg}`, priority: 8, }); return { success: false, error: errorMsg }; } }