"use client"; import { useState } from "react"; type FieldErrors = { company?: string; phone?: string; email?: string; }; function getPhoneDigits(input: string) { return input.replace(/\D/g, "").slice(0, 11); } function formatRussianPhoneInput(input: string) { const digits = getPhoneDigits(input); if (!digits) { return ""; } let normalized = digits; if (normalized[0] === "8") { normalized = `7${normalized.slice(1)}`; } if (normalized[0] !== "7") { normalized = `7${normalized.slice(0, 10)}`; } normalized = normalized.slice(0, 11); const country = "+7"; const part1 = normalized.slice(1, 4); const part2 = normalized.slice(4, 7); const part3 = normalized.slice(7, 9); const part4 = normalized.slice(9, 11); let result = country; if (part1) { result += ` (${part1}`; } if (part1.length === 3) { result += ")"; } if (part2) { result += ` ${part2}`; } if (part3) { result += `-${part3}`; } if (part4) { result += `-${part4}`; } return result; } function normalizePhone(input: string) { const digits = getPhoneDigits(input); if (digits.length === 11 && (digits.startsWith("7") || digits.startsWith("8"))) { return `7${digits.slice(1)}`; } if (digits.length === 10) { return `7${digits}`; } return null; } function isValidEmail(email: string) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); } type LeadFormProps = { id?: string; title?: string; description?: string; compact?: boolean; }; export default function LeadForm({ id, title, description, compact = false, }: LeadFormProps) { const [company, setCompany] = useState(""); const [phone, setPhone] = useState(""); const [email, setEmail] = useState(""); const [message, setMessage] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const [resultMessage, setResultMessage] = useState(""); const [submitError, setSubmitError] = useState(false); const [errors, setErrors] = useState({}); function validateFields() { const nextErrors: FieldErrors = {}; const normalizedPhone = normalizePhone(phone); const trimmedCompany = company.trim(); const trimmedEmail = email.trim(); if (trimmedCompany.length < 2) { nextErrors.company = "Укажите название объекта или компании"; } if (!normalizedPhone) { nextErrors.phone = "Введите российский номер в формате +7"; } if (!trimmedEmail) { nextErrors.email = "Введите email"; } else if (!isValidEmail(trimmedEmail)) { nextErrors.email = "Проверьте корректность email"; } return { nextErrors, normalizedPhone, trimmedCompany, trimmedEmail, }; } async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setResultMessage(""); setSubmitError(false); const { nextErrors, normalizedPhone, trimmedCompany, trimmedEmail } = validateFields(); if (Object.keys(nextErrors).length > 0 || !normalizedPhone) { setErrors(nextErrors); return; } setErrors({}); setIsSubmitting(true); try { const response = await fetch("/api/leads", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ company: trimmedCompany, phone: normalizedPhone, email: trimmedEmail, message: message.trim(), }), }); const data = await response.json(); if (!response.ok) { setSubmitError(true); setResultMessage(data.error || "Ошибка отправки"); return; } setSubmitError(false); setResultMessage("Заявка отправлена. Мы свяжемся с вами."); setCompany(""); setPhone(""); setEmail(""); setMessage(""); } catch { setSubmitError(true); setResultMessage("Не удалось сохранить заявку"); } finally { setIsSubmitting(false); } } const fieldClassName = "w-full rounded-2xl border bg-black/30 px-4 py-3.5 text-white outline-none transition-colors placeholder:text-neutral-500 focus:border-emerald-500 sm:px-5 sm:py-4"; const labelClassName = "mb-2 block text-sm font-medium text-neutral-200"; const helperClassName = "mt-2 text-xs text-neutral-500"; const errorClassName = "mt-2 text-xs text-rose-300"; return (
{(title || description) && (
{title && (

{title}

)} {description && (

{description}

)}
)}
{ setCompany(e.target.value); if (errors.company) { setErrors((current) => ({ ...current, company: undefined })); } }} className={`${fieldClassName} ${errors.company ? "border-rose-400/70" : "border-white/10"}`} autoComplete="organization" required /> {errors.company ? (

{errors.company}

) : (

Укажите ЖК, ТСЖ, УК или адрес объекта

)}
{ setPhone(formatRussianPhoneInput(e.target.value)); if (errors.phone) { setErrors((current) => ({ ...current, phone: undefined })); } }} className={`${fieldClassName} ${errors.phone ? "border-rose-400/70" : "border-white/10"}`} inputMode="numeric" autoComplete="tel" required /> {errors.phone ? (

{errors.phone}

) : (

Только мобильные и городские номера РФ

)}
{ setEmail(e.target.value); if (errors.email) { setErrors((current) => ({ ...current, email: undefined })); } }} className={`${fieldClassName} ${errors.email ? "border-rose-400/70" : "border-white/10"}`} autoComplete="email" required /> {errors.email ? (

{errors.email}

) : (

Отправим ответ и детали по этому адресу

)}