- Add seed data for 3 Shumiland articles (Сезон пригод, Капсула часу, Травень) - Create public/images/blog/ with placeholder hero images - Full Lexical body content for each post - Add makeLexical() helper for paragraph formatting in seed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
111 lines
3.7 KiB
TypeScript
111 lines
3.7 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
|
|
interface LeadFormBlockProps {
|
|
title?: string | null
|
|
subtitle?: string | null
|
|
formSource?: string | null
|
|
showPhone?: boolean | null
|
|
showEmail?: boolean | null
|
|
ctaLabel?: string | null
|
|
successMessage?: string | null
|
|
}
|
|
|
|
export function LeadFormBlockComponent({
|
|
title,
|
|
subtitle,
|
|
formSource,
|
|
showPhone,
|
|
showEmail,
|
|
ctaLabel,
|
|
successMessage,
|
|
}: LeadFormBlockProps) {
|
|
const [name, setName] = useState('')
|
|
const [phone, setPhone] = useState('')
|
|
const [email, setEmail] = useState('')
|
|
const [submitted, setSubmitted] = useState(false)
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
async function handleSubmit(e: React.FormEvent) {
|
|
e.preventDefault()
|
|
setLoading(true)
|
|
try {
|
|
await fetch('/api/leads', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
name,
|
|
phone: showPhone ? phone : undefined,
|
|
email: showEmail ? email : undefined,
|
|
source: formSource ?? 'block-form',
|
|
}),
|
|
})
|
|
} catch {
|
|
/* noop */
|
|
}
|
|
setSubmitted(true)
|
|
setLoading(false)
|
|
}
|
|
|
|
return (
|
|
<section className="py-[20px] md:py-[60px] lg:py-[40px]">
|
|
<div className="mx-auto max-w-[600px] px-8">
|
|
{title && (
|
|
<h2
|
|
className="mb-4 text-[24px] font-bold text-[#272727] uppercase md:text-[32px]"
|
|
style={{ fontFamily: 'var(--font-montserrat, Montserrat), sans-serif' }}
|
|
>
|
|
{title}
|
|
</h2>
|
|
)}
|
|
{subtitle && <p className="mb-8 text-[16px] text-[#272727]">{subtitle}</p>}
|
|
{submitted ? (
|
|
<div className="rounded-[20px] bg-[#d6f2c0] p-8 text-center">
|
|
<p className="text-[18px] font-bold text-[#396817]">
|
|
{successMessage ?? "Дякуємо! Ми зв'яжемося з вами найближчим часом."}
|
|
</p>
|
|
</div>
|
|
) : (
|
|
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
|
|
<input
|
|
type="text"
|
|
required
|
|
value={name}
|
|
onChange={(e) => setName(e.target.value)}
|
|
placeholder="Ваше ім'я"
|
|
className="w-full rounded-[10px] border border-[#272727]/20 px-5 py-3 text-[16px] text-[#272727] outline-none focus:ring-2 focus:ring-[#f28b4a]"
|
|
/>
|
|
{showPhone && (
|
|
<input
|
|
type="tel"
|
|
required
|
|
value={phone}
|
|
onChange={(e) => setPhone(e.target.value)}
|
|
placeholder="Телефон"
|
|
className="w-full rounded-[10px] border border-[#272727]/20 px-5 py-3 text-[16px] text-[#272727] outline-none focus:ring-2 focus:ring-[#f28b4a]"
|
|
/>
|
|
)}
|
|
{showEmail && (
|
|
<input
|
|
type="email"
|
|
value={email}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
placeholder="Email"
|
|
className="w-full rounded-[10px] border border-[#272727]/20 px-5 py-3 text-[16px] text-[#272727] outline-none focus:ring-2 focus:ring-[#f28b4a]"
|
|
/>
|
|
)}
|
|
<button
|
|
type="submit"
|
|
disabled={loading}
|
|
className="rounded-[64px] bg-[#f28b4a] px-[30px] py-[10px] text-[20px] font-bold text-white transition-shadow hover:shadow-[0_0_20px_0_#f28b4a] disabled:opacity-50"
|
|
style={{ fontFamily: 'var(--font-montserrat, Montserrat), sans-serif' }}
|
|
>
|
|
{loading ? '...' : (ctaLabel ?? 'Відправити')}
|
|
</button>
|
|
</form>
|
|
)}
|
|
</div>
|
|
</section>
|
|
)
|
|
}
|