Shumiland/src/components/forms/BirthdayBookingForm.tsx
Vadym Samoilenko ca41ec2c09
Some checks are pending
CI / Type Check (push) Waiting to run
CI / Lint (push) Waiting to run
CI / Unit Tests (push) Waiting to run
Deploy / Build & Push Image (push) Waiting to run
Deploy / Deploy to VPS (push) Blocked by required conditions
fix(ui): restore dyvolis hero PNG, new dino hero image + reposition, fix birthday form date field width
2026-06-03 17:33:41 +01:00

218 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import { useState, useTransition } from 'react'
import { getUtmParams } from '@/lib/utm'
const FONT = 'var(--font-montserrat, Montserrat), sans-serif'
const PACKAGES = [
{ value: 'standard', label: 'Стандарт — 4 500 ₴' },
{ value: 'premium', label: 'Преміум — 8 900 ₴' },
{ value: 'vip', label: 'VIP — 15 000 ₴' },
]
interface BirthdayBookingFormProps {
defaultPackage?: string
}
export function BirthdayBookingForm({ defaultPackage }: BirthdayBookingFormProps) {
const [name, setName] = useState('')
const [phone, setPhone] = useState('')
const [email, setEmail] = useState('')
const [childAge, setChildAge] = useState('')
const [packageSlug, setPackageSlug] = useState(defaultPackage ?? '')
const [guestCount, setGuestCount] = useState('')
const [preferredDate, setPreferredDate] = useState('')
const [wishes, setWishes] = useState('')
const [success, setSuccess] = useState(false)
const [error, setError] = useState<string | null>(null)
const [isPending, startTransition] = useTransition()
function handleSubmit(e: React.FormEvent) {
e.preventDefault()
setError(null)
startTransition(async () => {
try {
const utm = getUtmParams()
const res = await fetch('/api/leads', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name,
phone,
email: email || undefined,
formSource: 'birthday-booking',
packageSlug: packageSlug || undefined,
groupSize: guestCount ? Number(guestCount) : undefined,
preferredDate: preferredDate || undefined,
message:
[childAge ? `Вік іменинника: ${childAge}` : '', wishes].filter(Boolean).join('\n') ||
undefined,
...utm,
}),
})
const data = (await res.json()) as { ok?: boolean; error?: string }
if (!res.ok) {
setError(data.error ?? 'Щось пішло не так. Спробуйте ще раз.')
return
}
setSuccess(true)
} catch {
setError("Помилка мережі. Перевірте з'єднання та спробуйте ще раз.")
}
})
}
if (success) {
return (
<div className="flex flex-col items-center gap-4 py-10 text-center">
<div className="text-[48px]">🎂</div>
<h3 className="text-[24px] font-bold text-white" style={{ fontFamily: FONT }}>
Заявку отримано!
</h3>
<p className="text-[16px] text-white/70" style={{ fontFamily: FONT }}>
Менеджер зв&apos;яжеться з вами протягом 30 хвилин для уточнення деталей свята.
</p>
</div>
)
}
return (
<form onSubmit={handleSubmit} className="flex flex-col gap-5">
<div className="grid grid-cols-1 gap-5 md:grid-cols-2">
<Field label="Ваше ім'я *" htmlFor="bd-name">
<input
id="bd-name"
type="text"
required
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Іван Іванов"
className={INPUT_CLS}
style={{ fontFamily: FONT }}
/>
</Field>
<Field label="Телефон *" htmlFor="bd-phone">
<input
id="bd-phone"
type="tel"
required
value={phone}
onChange={(e) => setPhone(e.target.value)}
placeholder="+38 (0__) ___-__-__"
className={INPUT_CLS}
style={{ fontFamily: FONT }}
/>
</Field>
<Field label="Email" htmlFor="bd-email">
<input
id="bd-email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="your@email.com"
className={INPUT_CLS}
style={{ fontFamily: FONT }}
/>
</Field>
<Field label="Вік іменинника" htmlFor="bd-age">
<input
id="bd-age"
type="number"
min={1}
max={18}
value={childAge}
onChange={(e) => setChildAge(e.target.value)}
placeholder="7"
className={INPUT_CLS}
style={{ fontFamily: FONT }}
/>
</Field>
<Field label="Кількість гостей" htmlFor="bd-guests">
<input
id="bd-guests"
type="number"
min={1}
max={100}
value={guestCount}
onChange={(e) => setGuestCount(e.target.value)}
placeholder="15"
className={INPUT_CLS}
style={{ fontFamily: FONT }}
/>
</Field>
<Field label="Бажана дата *" htmlFor="bd-date">
<input
id="bd-date"
type="date"
required
value={preferredDate}
onChange={(e) => setPreferredDate(e.target.value)}
className={INPUT_CLS}
style={{ fontFamily: FONT }}
/>
</Field>
</div>
<Field label="Побажання" htmlFor="bd-wishes">
<textarea
id="bd-wishes"
rows={4}
value={wishes}
onChange={(e) => setWishes(e.target.value)}
placeholder="Тема свята, улюблені герої, особливі побажання..."
className={INPUT_CLS + ' resize-none'}
style={{ fontFamily: FONT }}
/>
</Field>
{error && (
<div className="rounded-xl border border-red-400 bg-red-900/30 px-4 py-3 text-[14px] text-red-300">
{error}
</div>
)}
<button
type="submit"
disabled={isPending}
className="mt-2 inline-flex items-center justify-center rounded-[64px] bg-[#f28b4a] px-10 py-4 text-[16px] font-bold text-white transition-shadow hover:shadow-[0_0_20px_0_#f28b4a] disabled:opacity-60"
style={{ fontFamily: FONT }}
>
{isPending ? 'Надсилаємо...' : 'Замовити святкування'}
</button>
</form>
)
}
function Field({
label,
htmlFor,
children,
}: {
label: string
htmlFor: string
children: React.ReactNode
}) {
return (
<div className="flex flex-col gap-2">
<label
htmlFor={htmlFor}
className="text-[14px] font-medium text-white/80"
style={{ fontFamily: FONT }}
>
{label}
</label>
{children}
</div>
)
}
const INPUT_CLS =
'w-full rounded-[12px] border-2 border-white/20 bg-white/10 px-4 py-3 text-[15px] text-white placeholder-white/40 focus:border-[#f28b4a] focus:outline-none'