feat: complete website implementation
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
"use server";
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
import { Resend } from "resend";
|
||||
|
||||
const resend = new Resend(process.env.RESEND_API_KEY);
|
||||
|
||||
// Schemat walidacji zgodny z tym po stronie klienta
|
||||
const contactFormSchema = z.object({
|
||||
name: z.string().min(2, "Imię musi mieć min. 2 znaki"),
|
||||
phone: z.string().min(9, "Wprowadź poprawny numer telefonu"),
|
||||
email: z.string().email("Niepoprawny adres e-mail"),
|
||||
subject: z.string().min(1, "Wybierz temat"),
|
||||
message: z.string().min(10, "Wiadomość musi mieć min. 10 znaków"),
|
||||
consent: z.boolean().refine((val) => val === true, "Zgoda RODO jest wymagana"),
|
||||
});
|
||||
|
||||
export async function submitContactForm(prevState: any, formData: FormData) {
|
||||
try {
|
||||
// 1. Walidacja danych z formularza
|
||||
const rawData = {
|
||||
name: formData.get("name"),
|
||||
phone: formData.get("phone"),
|
||||
email: formData.get("email"),
|
||||
subject: formData.get("subject"),
|
||||
message: formData.get("message"),
|
||||
consent: formData.get("consent") === "true" || formData.get("consent") === "on",
|
||||
};
|
||||
|
||||
const validatedData = contactFormSchema.parse(rawData);
|
||||
|
||||
// 2. Wysłanie e-maila przez Resend
|
||||
const { data, error } = await resend.emails.send({
|
||||
from: process.env.RESEND_FROM_EMAIL || "[email protected]",
|
||||
to: process.env.RESEND_TO_EMAIL || "[email protected]", // Docelowy e-mail (odbiorca)
|
||||
replyTo: validatedData.email,
|
||||
subject: `Nowa wiadomość ze strony: ${validatedData.subject}`,
|
||||
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;">Nowe zapytanie z formularza</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}</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;"><strong>Temat:</strong></td>
|
||||
<td style="padding: 8px 0; border-bottom: 1px solid #f1f5f9;">${validatedData.subject}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2 style="font-size: 18px; border-bottom: 2px solid #f1f5f9; padding-bottom: 10px;">Treść wiadomości:</h2>
|
||||
<div style="background-color: #f8fafc; padding: 15px; border-radius: 6px; font-size: 15px; line-height: 1.6; white-space: pre-wrap;">
|
||||
${validatedData.message}
|
||||
</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 kontaktowego 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.",
|
||||
};
|
||||
}
|
||||
|
||||
console.log("Wysłano e-mail (ID):", data?.id);
|
||||
|
||||
// 3. Zwrotka o sukcesie
|
||||
return {
|
||||
success: true,
|
||||
message: "Dziękujemy za wiadomość! 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.",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Metadata } from 'next';
|
||||
import { HeroSection } from '@/components/sections/HeroSection';
|
||||
import { ContactSection } from '@/components/sections/ContactSection';
|
||||
import { MapEmbed } from '@/components/sections/MapEmbed';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Kontakt | AirProject',
|
||||
description: 'Skontaktuj się z nami! Odpowiemy na Twoje pytania, doradzimy w wyborze urządzeń i przygotujemy bezpłatną wycenę. Jesteśmy do Twojej dyspozycji.',
|
||||
alternates: {
|
||||
canonical: '/kontakt',
|
||||
}
|
||||
};
|
||||
|
||||
export default function KontaktPage() {
|
||||
return (
|
||||
<main>
|
||||
<HeroSection
|
||||
eyebrow="Kontakt"
|
||||
title="Jesteśmy do Twojej dyspozycji"
|
||||
subtitle="Zastanawiasz się nad montażem klimatyzacji? Planujesz remont? A może masz awarię, która wymaga natychmiastowej interwencji hydraulika? Napisz lub zadzwoń."
|
||||
ctaText="Zadzwoń do nas"
|
||||
ctaLink="tel:+48123456789" // TODO: Use real phone from config
|
||||
secondaryCtaText="Napisz maila"
|
||||
secondaryCtaLink="mailto:[email protected]" // TODO: Use real email
|
||||
backgroundImage="https://images.unsplash.com/photo-1516387938699-a93567ec168e?w=1600&q=80"
|
||||
/>
|
||||
|
||||
<ContactSection />
|
||||
|
||||
<MapEmbed />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user