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