versione 1.0
This commit is contained in:
@@ -1,68 +1,132 @@
|
||||
/*
|
||||
* DESIGN: "Clinical Warmth"
|
||||
* Sezione prenotazione: form elegante su sfondo blu petrolio
|
||||
* Layout: testo a sinistra + form a destra
|
||||
* Sezione prenotazione: form to mail con conferma non vincolante.
|
||||
*/
|
||||
import { useState } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { useInView } from "framer-motion";
|
||||
import { motion, useInView } from "framer-motion";
|
||||
import { useRef } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Calendar, Clock, User, Phone, PawPrint, CheckCircle2 } from "lucide-react";
|
||||
import { Calendar, Clock, User, Phone, PawPrint, CheckCircle2, ShieldCheck } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
|
||||
const services = [
|
||||
"Visita generale",
|
||||
"Radiologia / Ecografia",
|
||||
"Chirurgia (consulenza)",
|
||||
"Laboratorio analisi",
|
||||
"Visita clinica generale",
|
||||
"Ecografia",
|
||||
"Radiologia",
|
||||
"Laboratorio",
|
||||
"Vaccinazione",
|
||||
"Dermatologia",
|
||||
"Odontoiatria",
|
||||
"Oncologia",
|
||||
"Dermatologia",
|
||||
"Oculistica",
|
||||
"Nutrizione",
|
||||
"Ortopedia",
|
||||
"Endoscopia",
|
||||
"Laparoscopia",
|
||||
];
|
||||
|
||||
const timeSlots = [
|
||||
"09:00", "09:30", "10:00", "10:30", "11:00", "11:30",
|
||||
"14:30", "15:00", "15:30", "16:00", "16:30", "17:00",
|
||||
"09:00",
|
||||
"09:30",
|
||||
"10:00",
|
||||
"10:30",
|
||||
"11:00",
|
||||
"11:30",
|
||||
"14:30",
|
||||
"15:00",
|
||||
"15:30",
|
||||
"16:00",
|
||||
"16:30",
|
||||
"17:00",
|
||||
];
|
||||
|
||||
type BookingFormState = {
|
||||
name: string;
|
||||
phone: string;
|
||||
petName: string;
|
||||
petType: string;
|
||||
service: string;
|
||||
date: string;
|
||||
time: string;
|
||||
notes: string;
|
||||
};
|
||||
|
||||
const initialForm: BookingFormState = {
|
||||
name: "",
|
||||
phone: "",
|
||||
petName: "",
|
||||
petType: "cane",
|
||||
service: "",
|
||||
date: "",
|
||||
time: "",
|
||||
notes: "",
|
||||
};
|
||||
|
||||
export default function BookingSection() {
|
||||
const ref = useRef(null);
|
||||
const isInView = useInView(ref, { once: true, margin: "-80px" });
|
||||
const [submitted, setSubmitted] = useState(false);
|
||||
const [form, setForm] = useState({
|
||||
name: "",
|
||||
phone: "",
|
||||
petName: "",
|
||||
petType: "cane",
|
||||
service: "",
|
||||
date: "",
|
||||
time: "",
|
||||
notes: "",
|
||||
});
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [submittedName, setSubmittedName] = useState("");
|
||||
const [form, setForm] = useState<BookingFormState>(initialForm);
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!form.name || !form.phone || !form.service || !form.date) {
|
||||
toast.error("Compila tutti i campi obbligatori");
|
||||
return;
|
||||
}
|
||||
setSubmitted(true);
|
||||
toast.success("Richiesta inviata!", {
|
||||
description: "Ti contatteremo entro 24 ore per confermare l'appuntamento.",
|
||||
});
|
||||
|
||||
try {
|
||||
setSubmitting(true);
|
||||
|
||||
const response = await fetch("/api/booking-request", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: form.name,
|
||||
phone: form.phone,
|
||||
pet_name: form.petName,
|
||||
pet_type: form.petType,
|
||||
service: form.service,
|
||||
date: form.date,
|
||||
time: form.time,
|
||||
notes: form.notes,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorPayload = await response.json().catch(() => null);
|
||||
throw new Error(errorPayload?.detail || "Invio non riuscito");
|
||||
}
|
||||
|
||||
const payload = await response.json();
|
||||
|
||||
setSubmittedName(form.name);
|
||||
setSubmitted(true);
|
||||
setForm(initialForm);
|
||||
toast.success("Richiesta inviata", {
|
||||
description: payload.message,
|
||||
});
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Si è verificato un problema durante l'invio.";
|
||||
toast.error("Invio non riuscito", {
|
||||
description: message,
|
||||
});
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section id="prenotazione" className="py-20 md:py-28 bg-[#1B4F72] relative overflow-hidden">
|
||||
{/* Decorazioni di sfondo */}
|
||||
<div className="absolute top-0 right-0 w-96 h-96 rounded-full bg-white/5 -translate-y-1/2 translate-x-1/2" />
|
||||
<div className="absolute bottom-0 left-0 w-64 h-64 rounded-full bg-[#4ECDC4]/10 translate-y-1/2 -translate-x-1/2" />
|
||||
<section id="prenotazione" className="relative overflow-hidden bg-[#1B4F72] py-20 md:py-28">
|
||||
<div className="absolute right-0 top-0 h-96 w-96 translate-x-1/2 -translate-y-1/2 rounded-full bg-white/5" />
|
||||
<div className="absolute bottom-0 left-0 h-64 w-64 -translate-x-1/2 translate-y-1/2 rounded-full bg-[#4ECDC4]/10" />
|
||||
|
||||
<div className="container relative z-10">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 items-start">
|
||||
{/* Colonna sinistra: testo */}
|
||||
<div className="grid grid-cols-1 items-start gap-16 lg:grid-cols-2">
|
||||
<motion.div
|
||||
ref={ref}
|
||||
initial={{ opacity: 0, x: -30 }}
|
||||
@@ -70,15 +134,15 @@ export default function BookingSection() {
|
||||
transition={{ duration: 0.8 }}
|
||||
className="text-white"
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<div className="w-12 h-0.5 bg-[#4ECDC4]" />
|
||||
<span className="text-[#4ECDC4] text-sm font-semibold uppercase tracking-widest">
|
||||
<div className="mb-4 flex items-center gap-3">
|
||||
<div className="h-0.5 w-12 bg-[#4ECDC4]" />
|
||||
<span className="text-sm font-semibold uppercase tracking-widest text-[#4ECDC4]">
|
||||
Prenotazioni
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h2
|
||||
className="text-white mb-6"
|
||||
className="mb-6 text-white"
|
||||
style={{
|
||||
fontFamily: "'Cormorant Garamond', serif",
|
||||
fontSize: "clamp(2rem, 4vw, 3rem)",
|
||||
@@ -86,93 +150,118 @@ export default function BookingSection() {
|
||||
lineHeight: 1.2,
|
||||
}}
|
||||
>
|
||||
Prenota la tua visita{" "}
|
||||
Richiedi una visita{" "}
|
||||
<span className="italic text-[#4ECDC4]">online</span>
|
||||
</h2>
|
||||
|
||||
<p className="text-white/80 leading-relaxed mb-8 text-base">
|
||||
Compila il modulo per richiedere un appuntamento. Ti contatteremo entro 24 ore
|
||||
per confermare la data e l'orario. Per urgenze, chiama direttamente il numero
|
||||
dedicato disponibile 24 ore su 24.
|
||||
<p className="mb-8 text-base leading-relaxed text-white/80">
|
||||
Compila il modulo per inviare una richiesta di appuntamento. La richiesta
|
||||
non è vincolante e dovrà essere confermata dallo staff della clinica, che ti
|
||||
ricontatterà il prima possibile.
|
||||
</p>
|
||||
|
||||
{/* Info box urgenze */}
|
||||
<div className="bg-white/10 backdrop-blur-sm rounded-xl p-5 border border-white/20 mb-8">
|
||||
<p className="text-[#4ECDC4] font-semibold text-sm mb-2 uppercase tracking-wide">
|
||||
<div className="mb-8 rounded-xl border border-white/20 bg-white/10 p-5 backdrop-blur-sm">
|
||||
<p className="mb-2 text-sm font-semibold uppercase tracking-wide text-[#4ECDC4]">
|
||||
Urgenze 24h
|
||||
</p>
|
||||
<a
|
||||
href="tel:3205322439"
|
||||
className="text-white text-2xl font-bold hover:text-[#4ECDC4] transition-colors"
|
||||
className="text-2xl font-bold text-white transition-colors hover:text-[#4ECDC4]"
|
||||
style={{ fontFamily: "'Cormorant Garamond', serif" }}
|
||||
>
|
||||
320 532.24.39
|
||||
</a>
|
||||
<p className="text-white/60 text-xs mt-1">Disponibile 7 giorni su 7</p>
|
||||
<p className="mt-1 text-xs text-white/60">Disponibile 7 giorni su 7</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-8 rounded-2xl border border-[#4ECDC4]/30 bg-[#14384F] p-5">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="mt-0.5 flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-full bg-[#4ECDC4]/15">
|
||||
<ShieldCheck size={18} className="text-[#4ECDC4]" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-semibold text-white">Richiesta non vincolante</p>
|
||||
<p className="mt-1 text-sm leading-relaxed text-white/75">
|
||||
L'invio del modulo non costituisce conferma automatica dell'appuntamento.
|
||||
Il team verificherà disponibilità, tipologia di visita e urgenza del caso prima
|
||||
di confermare data e orario.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Orari */}
|
||||
<div className="space-y-3">
|
||||
<p className="text-white/70 text-sm font-semibold uppercase tracking-wide mb-3">
|
||||
<p className="mb-3 text-sm font-semibold uppercase tracking-wide text-white/70">
|
||||
Orari di apertura
|
||||
</p>
|
||||
{[
|
||||
{ days: "Lunedì — Venerdì", hours: "09:00 — 12:30 · 14:30 — 19:00" },
|
||||
{ days: "Sabato", hours: "09:00 — 12:30" },
|
||||
{ days: "Lunedi - Venerdi", hours: "09:00 - 12:30 · 14:30 - 19:00" },
|
||||
{ days: "Sabato", hours: "09:00 - 12:30" },
|
||||
{ days: "Domenica", hours: "Solo urgenze" },
|
||||
].map((slot) => (
|
||||
<div key={slot.days} className="flex justify-between items-center text-sm">
|
||||
<div key={slot.days} className="flex items-center justify-between text-sm">
|
||||
<span className="text-white/70">{slot.days}</span>
|
||||
<span className="text-white font-medium">{slot.hours}</span>
|
||||
<span className="font-medium text-white">{slot.hours}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Colonna destra: form */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 30 }}
|
||||
animate={isInView ? { opacity: 1, x: 0 } : {}}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
>
|
||||
{submitted ? (
|
||||
<div className="bg-white rounded-2xl p-8 text-center shadow-2xl">
|
||||
<div className="w-16 h-16 rounded-full bg-[#4ECDC4]/15 flex items-center justify-center mx-auto mb-4">
|
||||
<div className="rounded-2xl bg-white p-8 text-center shadow-2xl">
|
||||
<div className="mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-[#4ECDC4]/15">
|
||||
<CheckCircle2 size={32} className="text-[#4ECDC4]" />
|
||||
</div>
|
||||
<h3
|
||||
className="text-[#1B4F72] mb-2"
|
||||
style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: "1.8rem" }}
|
||||
className="mb-2 text-[#1B4F72]"
|
||||
style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: "1.9rem" }}
|
||||
>
|
||||
Richiesta inviata!
|
||||
Grazie {submittedName || "per la tua richiesta"}
|
||||
</h3>
|
||||
<p className="text-gray-600 text-sm mb-6">
|
||||
Abbiamo ricevuto la tua richiesta di appuntamento. Ti contatteremo entro 24 ore
|
||||
per confermare data e orario.
|
||||
<p className="mb-3 text-sm leading-relaxed text-gray-600">
|
||||
La tua richiesta di prenotazione è stata inviata correttamente.
|
||||
</p>
|
||||
<p className="mb-6 text-sm leading-relaxed text-gray-600">
|
||||
Il team della Clinica Veterinaria Formiginese la prenderà in carico il prima
|
||||
possibile e ti ricontatterà per confermare disponibilità, data e orario.
|
||||
</p>
|
||||
<div className="mb-6 rounded-xl border border-[#E4D7C6] bg-[#FFF9F1] px-4 py-3 text-left text-sm text-gray-600">
|
||||
<strong className="text-[#1B4F72]">Nota importante:</strong> la richiesta inviata
|
||||
non equivale a una prenotazione già confermata.
|
||||
</div>
|
||||
<Button
|
||||
className="bg-[#1B4F72] hover:bg-[#163d5a] text-white"
|
||||
className="bg-[#1B4F72] text-white hover:bg-[#163d5a]"
|
||||
onClick={() => setSubmitted(false)}
|
||||
>
|
||||
Nuova prenotazione
|
||||
Invia una nuova richiesta
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<form
|
||||
onSubmit={handleSubmit}
|
||||
className="bg-white rounded-2xl p-6 md:p-8 shadow-2xl space-y-4"
|
||||
className="space-y-4 rounded-2xl bg-white p-6 shadow-2xl md:p-8"
|
||||
>
|
||||
<h3
|
||||
className="text-[#1B4F72] mb-2"
|
||||
style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: "1.5rem", fontWeight: 600 }}
|
||||
>
|
||||
Richiedi un appuntamento
|
||||
</h3>
|
||||
<div>
|
||||
<h3
|
||||
className="mb-2 text-[#1B4F72]"
|
||||
style={{ fontFamily: "'Cormorant Garamond', serif", fontSize: "1.5rem", fontWeight: 600 }}
|
||||
>
|
||||
Richiedi un appuntamento
|
||||
</h3>
|
||||
<p className="text-sm leading-relaxed text-gray-500">
|
||||
Compila i campi richiesti e inviaci una proposta di data: sarà lo staff a
|
||||
confermare la visita.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Nome e telefono */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide block mb-1.5">
|
||||
<label className="mb-1.5 block text-xs font-semibold uppercase tracking-wide text-gray-600">
|
||||
Nome e Cognome *
|
||||
</label>
|
||||
<div className="relative">
|
||||
@@ -183,12 +272,12 @@ export default function BookingSection() {
|
||||
placeholder="Mario Rossi"
|
||||
value={form.name}
|
||||
onChange={(e) => setForm({ ...form, name: e.target.value })}
|
||||
className="w-full pl-9 pr-3 py-2.5 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#4ECDC4] focus:border-transparent transition-all"
|
||||
className="w-full rounded-lg border border-gray-200 py-2.5 pl-9 pr-3 text-sm transition-all focus:border-transparent focus:outline-none focus:ring-2 focus:ring-[#4ECDC4]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide block mb-1.5">
|
||||
<label className="mb-1.5 block text-xs font-semibold uppercase tracking-wide text-gray-600">
|
||||
Telefono *
|
||||
</label>
|
||||
<div className="relative">
|
||||
@@ -199,17 +288,16 @@ export default function BookingSection() {
|
||||
placeholder="333 123 4567"
|
||||
value={form.phone}
|
||||
onChange={(e) => setForm({ ...form, phone: e.target.value })}
|
||||
className="w-full pl-9 pr-3 py-2.5 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#4ECDC4] focus:border-transparent transition-all"
|
||||
className="w-full rounded-lg border border-gray-200 py-2.5 pl-9 pr-3 text-sm transition-all focus:border-transparent focus:outline-none focus:ring-2 focus:ring-[#4ECDC4]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Animale */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide block mb-1.5">
|
||||
Nome dell'animale
|
||||
<label className="mb-1.5 block text-xs font-semibold uppercase tracking-wide text-gray-600">
|
||||
Nome dell'animale
|
||||
</label>
|
||||
<div className="relative">
|
||||
<PawPrint size={15} className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400" />
|
||||
@@ -218,18 +306,18 @@ export default function BookingSection() {
|
||||
placeholder="Fido"
|
||||
value={form.petName}
|
||||
onChange={(e) => setForm({ ...form, petName: e.target.value })}
|
||||
className="w-full pl-9 pr-3 py-2.5 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#4ECDC4] focus:border-transparent transition-all"
|
||||
className="w-full rounded-lg border border-gray-200 py-2.5 pl-9 pr-3 text-sm transition-all focus:border-transparent focus:outline-none focus:ring-2 focus:ring-[#4ECDC4]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide block mb-1.5">
|
||||
<label className="mb-1.5 block text-xs font-semibold uppercase tracking-wide text-gray-600">
|
||||
Tipo di animale
|
||||
</label>
|
||||
<select
|
||||
value={form.petType}
|
||||
onChange={(e) => setForm({ ...form, petType: e.target.value })}
|
||||
className="w-full px-3 py-2.5 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#4ECDC4] focus:border-transparent transition-all bg-white"
|
||||
className="w-full rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm transition-all focus:border-transparent focus:outline-none focus:ring-2 focus:ring-[#4ECDC4]"
|
||||
>
|
||||
<option value="cane">Cane</option>
|
||||
<option value="gatto">Gatto</option>
|
||||
@@ -238,28 +326,28 @@ export default function BookingSection() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Servizio */}
|
||||
<div>
|
||||
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide block mb-1.5">
|
||||
<label className="mb-1.5 block text-xs font-semibold uppercase tracking-wide text-gray-600">
|
||||
Tipo di visita *
|
||||
</label>
|
||||
<select
|
||||
required
|
||||
value={form.service}
|
||||
onChange={(e) => setForm({ ...form, service: e.target.value })}
|
||||
className="w-full px-3 py-2.5 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#4ECDC4] focus:border-transparent transition-all bg-white"
|
||||
className="w-full rounded-lg border border-gray-200 bg-white px-3 py-2.5 text-sm transition-all focus:border-transparent focus:outline-none focus:ring-2 focus:ring-[#4ECDC4]"
|
||||
>
|
||||
<option value="">Seleziona un servizio</option>
|
||||
{services.map((s) => (
|
||||
<option key={s} value={s}>{s}</option>
|
||||
<option key={s} value={s}>
|
||||
{s}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Data e ora */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
<div>
|
||||
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide block mb-1.5">
|
||||
<label className="mb-1.5 block text-xs font-semibold uppercase tracking-wide text-gray-600">
|
||||
Data preferita *
|
||||
</label>
|
||||
<div className="relative">
|
||||
@@ -270,12 +358,12 @@ export default function BookingSection() {
|
||||
value={form.date}
|
||||
min={new Date().toISOString().split("T")[0]}
|
||||
onChange={(e) => setForm({ ...form, date: e.target.value })}
|
||||
className="w-full pl-9 pr-3 py-2.5 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#4ECDC4] focus:border-transparent transition-all"
|
||||
className="w-full rounded-lg border border-gray-200 py-2.5 pl-9 pr-3 text-sm transition-all focus:border-transparent focus:outline-none focus:ring-2 focus:ring-[#4ECDC4]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide block mb-1.5">
|
||||
<label className="mb-1.5 block text-xs font-semibold uppercase tracking-wide text-gray-600">
|
||||
Orario preferito
|
||||
</label>
|
||||
<div className="relative">
|
||||
@@ -283,20 +371,21 @@ export default function BookingSection() {
|
||||
<select
|
||||
value={form.time}
|
||||
onChange={(e) => setForm({ ...form, time: e.target.value })}
|
||||
className="w-full pl-9 pr-3 py-2.5 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#4ECDC4] focus:border-transparent transition-all bg-white"
|
||||
className="w-full rounded-lg border border-gray-200 bg-white py-2.5 pl-9 pr-3 text-sm transition-all focus:border-transparent focus:outline-none focus:ring-2 focus:ring-[#4ECDC4]"
|
||||
>
|
||||
<option value="">Qualsiasi orario</option>
|
||||
{timeSlots.map((t) => (
|
||||
<option key={t} value={t}>{t}</option>
|
||||
<option key={t} value={t}>
|
||||
{t}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Note */}
|
||||
<div>
|
||||
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide block mb-1.5">
|
||||
<label className="mb-1.5 block text-xs font-semibold uppercase tracking-wide text-gray-600">
|
||||
Note aggiuntive
|
||||
</label>
|
||||
<textarea
|
||||
@@ -304,19 +393,20 @@ export default function BookingSection() {
|
||||
placeholder="Descrivi brevemente il motivo della visita..."
|
||||
value={form.notes}
|
||||
onChange={(e) => setForm({ ...form, notes: e.target.value })}
|
||||
className="w-full px-3 py-2.5 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-[#4ECDC4] focus:border-transparent transition-all resize-none"
|
||||
className="w-full resize-none rounded-lg border border-gray-200 px-3 py-2.5 text-sm transition-all focus:border-transparent focus:outline-none focus:ring-2 focus:ring-[#4ECDC4]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full bg-[#4ECDC4] hover:bg-[#3ab5ad] text-white font-bold py-3 text-base shadow-lg shadow-[#4ECDC4]/30 transition-all duration-300 hover:shadow-xl"
|
||||
disabled={submitting}
|
||||
className="w-full bg-[#4ECDC4] py-3 text-base font-bold text-white shadow-lg shadow-[#4ECDC4]/30 transition-all duration-300 hover:bg-[#3ab5ad] hover:shadow-xl disabled:cursor-wait disabled:opacity-80"
|
||||
>
|
||||
Invia Richiesta di Appuntamento
|
||||
{submitting ? "Invio in corso..." : "Invia richiesta di prenotazione"}
|
||||
</Button>
|
||||
|
||||
<p className="text-xs text-gray-400 text-center">
|
||||
* Campi obbligatori. Ti contatteremo entro 24 ore per confermare.
|
||||
<p className="text-center text-xs text-gray-500">
|
||||
* Campi obbligatori. La richiesta sarà valutata e confermata dallo staff.
|
||||
</p>
|
||||
</form>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user