This commit is contained in:
Vula Builder
2026-09-15 18:02:58 +00:00
parent 4b6797f79d
commit dec3aee7cb
@@ -0,0 +1,130 @@
'use client'
import { useState, type ChangeEvent } from 'react'
import Link from 'next/link'
import { ArrowRight } from 'lucide-react'
import Button from '@/components/ui/Button'
import Input from '@/components/ui/Input'
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/Card'
import BusinessContact from '@/components/BusinessContact'
import BusinessHours from '@/components/BusinessHours'
import BusinessMap from '@/components/BusinessMap'
import { useEnquiry } from '@/hooks/useEnquiry'
type Form = { name: string; phone: string; email: string; message: string }
export default function VisitTheClinicSection() {
const enquiry = useEnquiry()
const [form, setForm] = useState<Form>({ name: '', phone: '', email: '', message: '' })
const [result, setResult] = useState<{ ok: boolean; message: string } | null>(null)
const [sending, setSending] = useState(false)
const set =
(key: keyof Form) =>
(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) =>
setForm((f) => ({ ...f, [key]: e.target.value }))
return (
<section data-vula-section="visittheclinic" id="visit-the-clinic" className="bg-muted text-foreground py-20 sm:py-24">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="grid gap-12 lg:grid-cols-12">
<div className="lg:col-span-7">
<span className="text-xs font-semibold uppercase tracking-[0.18em] text-primary">Visit the clinic</span>
<h2 className="mt-3 text-3xl font-bold leading-tight sm:text-4xl">
Come in for an adjustment, or send us a message first.
</h2>
<p className="mt-4 max-w-[44ch] text-base text-muted-foreground">
The practice is set up for families: a pram fits through the door, there is room for kids in the waiting area, and a newborn check does not need a full adult appointment slot.
</p>
<div className="mt-8 space-y-6">
<div>
<h3 className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">Where to find us</h3>
<BusinessContact className="mt-2 text-sm text-muted-foreground" />
</div>
<BusinessHours title="Clinic hours" />
</div>
<div className="mt-8">
<BusinessMap />
</div>
</div>
<div className="lg:col-span-5">
<Card>
<CardHeader>
<CardTitle>Send a message</CardTitle>
</CardHeader>
<CardContent>
{result?.ok ? (
<p className="text-sm leading-relaxed text-foreground">{result.message}</p>
) : enquiry.available ? (
<div className="space-y-4">
<Input label="Your name" value={form.name} onChange={set('name')} />
<Input label="Phone or WhatsApp number" value={form.phone} onChange={set('phone')} />
<Input label="Email (optional)" type="email" value={form.email} onChange={set('email')} />
<div>
<label htmlFor="visit-message" className="mb-1 block text-sm font-medium text-foreground">
What would you like help with?
</label>
<textarea
id="visit-message"
rows={4}
value={form.message}
onChange={set('message')}
className="w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground outline-none transition-all duration-200 ease-out focus:border-primary focus:ring-2 focus:ring-primary/30"
/>
</div>
{result && !result.ok ? (
<p className="text-sm font-medium text-foreground">{result.message}</p>
) : null}
<div className="flex flex-col gap-3 pt-2">
{enquiry.channels.map((channel) => (
<Button
key={channel}
type="button"
fullWidth
disabled={sending}
variant={channel === 'whatsapp' ? 'default' : 'outline'}
onClick={async () => {
if (!form.name.trim() || !form.phone.trim()) {
setResult({ ok: false, message: 'Please add your name and a contact number so the practice can reach you.' })
return
}
setSending(true)
const res = await enquiry.send(form, channel)
setResult(res)
setSending(false)
}}
>
{channel === 'whatsapp' ? 'Send on WhatsApp' : 'Send by email'}
</Button>
))}
</div>
</div>
) : (
<p className="text-sm leading-relaxed text-muted-foreground">
Online messaging is not switched on yet. Book a time from the services page and the practice will confirm it with you directly.
</p>
)}
</CardContent>
</Card>
<div className="mt-6 rounded-lg bg-card p-6 shadow-md transition-all duration-200 ease-out hover:-translate-y-1 hover:shadow-xl">
<p className="text-base font-semibold text-foreground">Prefer to pick a time yourself?</p>
<p className="mt-1 text-sm text-muted-foreground">Choose a slot online and the practice confirms it with you.</p>
<Button asChild fullWidth className="mt-4">
<Link href="/services">
Book an appointment
<ArrowRight className="ml-2 h-4 w-4" />
</Link>
</Button>
</div>
</div>
</div>
</div>
</section>
)
}