This commit is contained in:
Vula Builder
2026-10-11 14:20:28 +00:00
parent b70a0da6eb
commit 5d524eb23b
@@ -0,0 +1,185 @@
'use client'
import { useState } from 'react'
import Link from 'next/link'
import { ArrowRight, Clock, MapPin } from 'lucide-react'
import Button from '@/components/ui/Button'
import Input from '@/components/ui/Input'
import BusinessContact from '@/components/BusinessContact'
import BusinessHours from '@/components/BusinessHours'
import BusinessMap from '@/components/BusinessMap'
import { useEnquiry } from '@/hooks/useEnquiry'
export default function VisitTheWokContactSection() {
const enquiry = useEnquiry()
const [name, setName] = useState('')
const [phone, setPhone] = useState('')
const [email, setEmail] = useState('')
const [message, setMessage] = useState('')
const [formError, setFormError] = useState('')
const [sending, setSending] = useState(false)
const [result, setResult] = useState<{ ok: boolean; message: string } | null>(null)
const sentOk = enquiry.available && result !== null && result.ok
const showForm = enquiry.available && !sentOk
const handleSend = async (channel: 'whatsapp' | 'email') => {
setFormError('')
if (!name.trim() || !phone.trim()) {
setFormError('Add your name and a number we can reach you on, then send again.')
return
}
setSending(true)
const outcome = await enquiry.send({ name, phone, email, message }, channel)
setSending(false)
setResult(outcome)
}
return (
<section
id="visit-the-wok"
data-vula-section="visitthewokcontact"
className="bg-background text-foreground py-24 sm:py-32"
>
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="grid gap-14 lg:grid-cols-12 lg:gap-16">
<div className="lg:col-span-7">
<div className="flex items-center gap-4">
<span className="h-px w-14 bg-accent" aria-hidden="true" />
<span className="text-[11px] uppercase tracking-[0.32em] text-muted-foreground">
Madadeni Section 4 · Newcastle
</span>
</div>
<h2 className="mt-6 text-4xl font-light leading-tight tracking-tight sm:text-5xl">
Order on the way, collect it <span className="italic text-accent">still steaming.</span>
</h2>
<p className="mt-5 max-w-xl text-base leading-relaxed text-muted-foreground sm:text-lg">
The wok is on from early until the last box leaves the counter. Come past for a takeaway, or send your order through first and pick it up at the corner — no long wait, nothing sitting under a lamp.
</p>
<div className="mt-9 flex flex-wrap items-center gap-4">
<Link href="/menu">
<Button
size="lg"
className="gap-2 border border-accent bg-accent text-accent-foreground transition-all duration-200 ease-out hover:bg-accent/90"
>
Order Online
<ArrowRight className="h-4 w-4" aria-hidden="true" />
</Button>
</Link>
</div>
<div className="mt-14 grid gap-10 border-t border-foreground/15 pt-10 sm:grid-cols-2">
<div>
<div className="flex items-center gap-3">
<MapPin className="h-4 w-4 text-accent" aria-hidden="true" />
<span className="text-[11px] uppercase tracking-[0.28em] text-muted-foreground">Find the corner</span>
</div>
<BusinessContact className="mt-4 text-sm leading-relaxed text-muted-foreground" />
</div>
<div>
<div className="flex items-center gap-3">
<Clock className="h-4 w-4 text-accent" aria-hidden="true" />
<span className="text-[11px] uppercase tracking-[0.28em] text-muted-foreground">Counter hours</span>
</div>
<div className="mt-4">
<BusinessHours compact />
</div>
</div>
</div>
</div>
<div className="lg:col-span-5">
<div className="rounded-lg border border-foreground/20 bg-foreground/10 p-8 backdrop-blur-md sm:p-10">
<p className="text-[11px] uppercase tracking-[0.32em] text-accent">Talk to the counter</p>
<h3 className="mt-4 text-2xl font-light leading-snug">
A question about an order, a big box, or noodles for a whole class?
</h3>
<p className="mt-4 text-sm leading-relaxed text-muted-foreground">
Send it through. We answer between tosses.
</p>
{sentOk && result ? (
<p className="mt-8 rounded-lg border border-accent/40 bg-accent/10 p-5 text-sm leading-relaxed text-foreground">
{result.message}
</p>
) : null}
{showForm ? (
<form className="mt-8 space-y-5" onSubmit={(event) => event.preventDefault()}>
{result && !result.ok ? (
<p className="rounded-lg border border-accent/40 bg-accent/10 p-4 text-sm leading-relaxed text-foreground">
{result.message}
</p>
) : null}
<Input
label="Your name"
value={name}
onChange={(event) => setName(event.target.value)}
placeholder="The name we should ask for"
/>
<Input
label="Phone"
type="tel"
value={phone}
onChange={(event) => setPhone(event.target.value)}
placeholder="A number we can reach you on"
/>
<Input
label="Email (optional)"
type="email"
value={email}
onChange={(event) => setEmail(event.target.value)}
placeholder="you@example.co.za"
/>
<div>
<label
htmlFor="visit-the-wok-message"
className="text-[11px] uppercase tracking-[0.28em] text-muted-foreground"
>
Message
</label>
<textarea
id="visit-the-wok-message"
rows={4}
value={message}
onChange={(event) => setMessage(event.target.value)}
placeholder="What can we put in the wok for you?"
className="mt-3 w-full rounded-lg border border-foreground/20 bg-foreground/5 px-4 py-3 text-sm text-foreground placeholder:text-muted-foreground transition-all duration-200 ease-out focus:border-accent focus:outline-none"
/>
</div>
{formError ? (
<p className="text-sm leading-relaxed text-accent">{formError}</p>
) : null}
<div className="flex flex-col gap-3 sm:flex-row">
{enquiry.channels.map((channel) => (
<Button
key={channel}
type="button"
fullWidth
variant={channel === 'whatsapp' ? 'default' : 'outline'}
disabled={sending}
onClick={() => handleSend(channel as 'whatsapp' | 'email')}
className="transition-all duration-200 ease-out"
>
{channel === 'whatsapp' ? 'Send on WhatsApp' : 'Send by email'}
</Button>
))}
</div>
</form>
) : null}
</div>
</div>
</div>
<div className="mt-16">
<BusinessMap />
</div>
</div>
</section>
)
}