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