119 lines
5.7 KiB
TypeScript
119 lines
5.7 KiB
TypeScript
"use server";
|
|
|
|
import { z } from "zod";
|
|
import { Resend } from "resend";
|
|
import { verifyRecaptcha } from "@/lib/recaptcha";
|
|
|
|
const resend = new Resend(process.env.RESEND_API_KEY);
|
|
|
|
const multisplitFormSchema = z.object({
|
|
name: z.string().min(2, "Imię musi mieć min. 2 znaki"),
|
|
phone: z.string().min(9, "Wprowadź poprawny numer telefonu"),
|
|
email: z.union([z.literal(''), z.string().email("Niepoprawny adres e-mail")]).optional(),
|
|
city: z.string().min(1, "Wybierz miasto"),
|
|
rooms: z.string().optional(),
|
|
message: z.string().optional(),
|
|
consent: z.boolean().refine((val) => val === true, "Zgoda RODO jest wymagana"),
|
|
productName: z.string(),
|
|
productSku: z.string(),
|
|
});
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
export async function submitMultisplitForm(data: Record<string, any>) {
|
|
try {
|
|
if (process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY && process.env.RECAPTCHA_SECRET_KEY) {
|
|
if (!data.recaptchaToken) {
|
|
return { success: false, message: "Weryfikacja bezpieczeństwa nie powiodła się. Odśwież stronę i spróbuj ponownie." };
|
|
}
|
|
const { success } = await verifyRecaptcha(data.recaptchaToken);
|
|
if (!success) {
|
|
return { success: false, message: "Weryfikacja bezpieczeństwa nie powiodła się. Odśwież stronę i spróbuj ponownie." };
|
|
}
|
|
}
|
|
|
|
const validatedData = multisplitFormSchema.parse(data);
|
|
|
|
const { error } = await resend.emails.send({
|
|
from: process.env.RESEND_FROM_EMAIL || "[email protected]",
|
|
to: process.env.RESEND_TO_EMAIL || "[email protected]",
|
|
replyTo: validatedData.email || undefined,
|
|
subject: `Zapytanie o multisplit: ${validatedData.productName} (${validatedData.productSku})`,
|
|
html: `
|
|
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden; background-color: #ffffff;">
|
|
<div style="background-color: #0F2A47; padding: 20px; text-align: center;">
|
|
<h1 style="color: #ffffff; margin: 0; font-size: 24px;">Zapytanie o multisplit</h1>
|
|
<p style="color: #2BA8E0; margin: 5px 0 0 0; font-size: 14px;">Domena: thermcool.pl</p>
|
|
</div>
|
|
<div style="padding: 24px; color: #1e293b;">
|
|
<h2 style="font-size: 18px; margin-top: 0; border-bottom: 2px solid #f1f5f9; padding-bottom: 10px;">Dane kontaktowe:</h2>
|
|
<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;">
|
|
<tr>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9; width: 120px;"><strong>Imię:</strong></td>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;">${validatedData.name}</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><strong>Telefon:</strong></td>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><a href="tel:${validatedData.phone}" style="color: #0F2A47; text-decoration: none;">${validatedData.phone}</a></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><strong>E-mail:</strong></td>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><a href="mailto:${validatedData.email}" style="color: #0F2A47; text-decoration: none;">${validatedData.email || 'Brak'}</a></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><strong>Miasto:</strong></td>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;">${validatedData.city}</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><strong>Produkt:</strong></td>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;">${validatedData.productName} (${validatedData.productSku})</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><strong>Pokoje:</strong></td>
|
|
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;">${validatedData.rooms}</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<h2 style="font-size: 18px; border-bottom: 2px solid #f1f5f9; padding-bottom: 10px;">Dodatkowe informacje:</h2>
|
|
<div style="background-color: #f8fafc; padding: 15px; border-radius: 6px; font-size: 15px; line-height: 1.6; white-space: pre-wrap;">
|
|
${validatedData.message || 'Brak'}
|
|
</div>
|
|
|
|
<p style="margin-top: 24px; font-size: 12px; color: #64748b; text-align: center;">
|
|
Zgoda RODO została zaakceptowana: <strong>${validatedData.consent ? "Tak" : "Nie"}</strong>
|
|
</p>
|
|
</div>
|
|
<div style="background-color: #f1f5f9; padding: 15px; text-align: center; font-size: 12px; color: #64748b;">
|
|
Wiadomość wygenerowana automatycznie z formularza multisplit na stronie thermcool.pl
|
|
</div>
|
|
</div>
|
|
`,
|
|
});
|
|
|
|
if (error) {
|
|
console.error("Resend Error:", error);
|
|
return {
|
|
success: false,
|
|
message: "Nie udało się wysłać wiadomości ze względu na błąd serwera pocztowego.",
|
|
};
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
message: "Dziękujemy za zapytanie! Skontaktujemy się z Tobą najszybciej jak to możliwe.",
|
|
};
|
|
} catch (error) {
|
|
if (error instanceof z.ZodError) {
|
|
return {
|
|
success: false,
|
|
message: "Wystąpił błąd walidacji. Sprawdź poprawność danych.",
|
|
errors: error.flatten().fieldErrors,
|
|
};
|
|
}
|
|
|
|
return {
|
|
success: false,
|
|
message: "Wystąpił nieoczekiwany błąd serwera. Spróbuj ponownie później.",
|
|
};
|
|
}
|
|
}
|