Deploy
This commit is contained in:
@@ -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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user