"use client"; import { useState } from "react"; type FieldErrors = { name?: string; phone?: string; email?: string; }; type LeadFormProps = { id?: string; title?: string; description?: string; compact?: boolean; }; 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); } export default function LeadForm({ id, title, description, compact = false, }: LeadFormProps) { const [name, setName] = 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 trimmedName = name.trim(); const trimmedEmail = email.trim(); const normalizedPhone = normalizePhone(phone); if (trimmedName.length < 2) { nextErrors.name = "Укажите название объекта или компании"; } if (!normalizedPhone) { nextErrors.phone = "Введите российский номер в формате +7"; } if (trimmedEmail && !isValidEmail(trimmedEmail)) { nextErrors.email = "Проверьте корректность email"; } return { nextErrors, trimmedName, trimmedEmail, normalizedPhone, }; } async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setResultMessage(""); setSubmitError(false); const { nextErrors, trimmedName, trimmedEmail, normalizedPhone } = 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({ name: trimmedName, phone: normalizedPhone, email: trimmedEmail || null, message: message.trim() || null, }), }); const data = await response.json(); if (!response.ok) { setSubmitError(true); setResultMessage(data.error || "Не удалось отправить заявку"); return; } setName(""); setPhone(""); setEmail(""); setMessage(""); setResultMessage("Заявка отправлена. Мы свяжемся с вами."); setSubmitError(false); } 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}

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

{errors.name}

) : (

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

)}
{ 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" /> {errors.email ? (

{errors.email}

) : (

Необязательно, но удобно для ответа

)}