Deploy
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import { useVulaContent } from '@/hooks/useVulaContent'
|
||||
import Button from '@/components/ui/Button'
|
||||
import Input from '@/components/ui/Input'
|
||||
import { ArrowRight, Mail, MapPin, MessageCircle, Phone, Send } from 'lucide-react'
|
||||
|
||||
export default function ContactSection() {
|
||||
const { items, loading } = useVulaContent('business_hours')
|
||||
|
||||
// Form state — MUST be declared before any early return
|
||||
const [formState, setFormState] = useState({ name: '', email: '', message: '' })
|
||||
const [sent, setSent] = useState(false)
|
||||
|
||||
if (loading) {
|
||||
return <div className="flex justify-center py-16 bg-[#18181b]"><div className="w-8 h-8 rounded-full border-2 border-[#d4af37] border-t-transparent animate-spin" /></div>
|
||||
}
|
||||
if (items.length === 0) return null
|
||||
|
||||
const handleChange = (field: string) => (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
setFormState((prev) => ({ ...prev, [field]: e.target.value }))
|
||||
}
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
setSent(true)
|
||||
setFormState({ name: '', email: '', message: '' })
|
||||
}
|
||||
|
||||
return (
|
||||
<section id="contact" data-vula-section="contact" data-vula-cms="business_hours" className="bg-[#18181b] text-white py-24 px-6">
|
||||
{/* Gold top strip */}
|
||||
<div className="absolute top-0 left-0 right-0 h-2 bg-[#d4af37]" />
|
||||
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16">
|
||||
{/* Left column — contact info */}
|
||||
<div>
|
||||
<span className="text-[#d4af37] text-sm tracking-[0.3em] uppercase">Hit Us Up</span>
|
||||
<h2 className="text-4xl md:text-5xl font-bold uppercase mt-4 leading-tight">
|
||||
Connect with the movement
|
||||
</h2>
|
||||
|
||||
{/* Business hours from CMS */}
|
||||
<div className="mt-8 space-y-2">
|
||||
<h3 className="text-xl font-semibold text-[#d4af37]">Pop-up Shop Hours</h3>
|
||||
{items.map((item) => {
|
||||
const d = item.data as {
|
||||
day_of_week?: string
|
||||
open_time?: string
|
||||
close_time?: string
|
||||
is_closed?: boolean
|
||||
note?: string
|
||||
}
|
||||
return (
|
||||
<div key={item.id} className="flex justify-between border-b border-zinc-700 pb-2">
|
||||
<span className="font-medium">{d.day_of_week}</span>
|
||||
<span className="text-zinc-300">
|
||||
{d.is_closed ? 'Closed' : `${d.open_time} – ${d.close_time}`}
|
||||
{d.note && <span className="text-xs text-zinc-500 ml-2">{d.note}</span>}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Contact details */}
|
||||
<div className="mt-10 space-y-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<MapPin className="w-5 h-5 text-[#d4af37] shrink-0" />
|
||||
<span>854 Mofolo Central, Soweto, Johannesburg, 1804</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<Phone className="w-5 h-5 text-[#d4af37] shrink-0" />
|
||||
<span>+27 11 234 5678</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<Mail className="w-5 h-5 text-[#d4af37] shrink-0" />
|
||||
<span>hello@urbanthreads.co.za</span>
|
||||
</div>
|
||||
<a
|
||||
href="https://wa.me/27712345678"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-3 text-[#25D366] hover:text-green-400 transition-colors"
|
||||
>
|
||||
<MessageCircle className="w-5 h-5" />
|
||||
<span>WhatsApp Us</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Social links */}
|
||||
<div className="mt-8 flex gap-6">
|
||||
<a href="https://instagram.com/urbanthreadssa" target="_blank" rel="noopener noreferrer" className="text-zinc-400 hover:text-[#d4af37] transition-colors">
|
||||
<SiInstagram className="w-6 h-6" />
|
||||
</a>
|
||||
<a href="https://x.com/urbanthreadssa" target="_blank" rel="noopener noreferrer" className="text-zinc-400 hover:text-[#d4af37] transition-colors">
|
||||
<SiX className="w-6 h-6" />
|
||||
</a>
|
||||
<a href="https://tiktok.com/@urbanthreadssa" target="_blank" rel="noopener noreferrer" className="text-zinc-400 hover:text-[#d4af37] transition-colors">
|
||||
<SiTiktok className="w-6 h-6" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right column — form */}
|
||||
<div className="bg-zinc-900 p-8 rounded-xl border border-zinc-700">
|
||||
{sent ? (
|
||||
<div className="h-full flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<Send className="w-12 h-12 mx-auto text-[#d4af37]" />
|
||||
<h3 className="text-2xl font-bold mt-4">Message sent!</h3>
|
||||
<p className="text-zinc-400 mt-2">We'll get back to you within 24 hours.</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<h3 className="text-2xl font-bold mb-6 uppercase">Send a message</h3>
|
||||
<form onSubmit={handleSubmit} className="space-y-5">
|
||||
<Input
|
||||
placeholder="Your name"
|
||||
value={formState.name}
|
||||
onChange={handleChange('name')}
|
||||
required
|
||||
className="h-12 bg-zinc-800 border-zinc-600 text-white placeholder:text-zinc-400 focus:border-[#d4af37]"
|
||||
/>
|
||||
<Input
|
||||
type="email"
|
||||
placeholder="Your email"
|
||||
value={formState.email}
|
||||
onChange={handleChange('email')}
|
||||
required
|
||||
className="h-12 bg-zinc-800 border-zinc-600 text-white placeholder:text-zinc-400 focus:border-[#d4af37]"
|
||||
/>
|
||||
<textarea
|
||||
required
|
||||
rows={4}
|
||||
placeholder="What's on your mind? (collabs, stockist enquiries, questions)"
|
||||
value={formState.message}
|
||||
onChange={handleChange('message')}
|
||||
className="w-full p-4 bg-zinc-800 border border-zinc-600 rounded-lg text-white placeholder:text-zinc-400 focus:border-[#d4af37] focus:outline-none resize-none"
|
||||
/>
|
||||
<Button type="submit" size="lg" className="w-full h-12 bg-[#d4af37] text-[#18181b] hover:bg-[#c49a2f] font-bold uppercase tracking-wider">
|
||||
Send
|
||||
<ArrowRight className="ml-2 w-5 h-5" />
|
||||
</Button>
|
||||
</form>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user