Deploy
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
'use client'
|
||||
|
||||
import { useVulaContent } from '@/hooks/useVulaContent'
|
||||
import Button from '@/components/ui/Button'
|
||||
import Input from '@/components/ui/Input'
|
||||
import { Camera, Globe, Mail, MapPin, MessageCircle, Phone, X } from 'lucide-react'
|
||||
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import { useState } from 'react'
|
||||
|
||||
export default function ContactKhulumaSection() {
|
||||
const { items: hours, loading } = useVulaContent('business_hours')
|
||||
const [form, setForm] = useState({ name: '', email: '', message: '' })
|
||||
const [submitted, setSubmitted] = useState(false)
|
||||
|
||||
if (loading) return <div className="flex justify-center py-16"><div className="w-8 h-8 rounded-full border-2 border-current border-t-transparent animate-spin" /></div>
|
||||
if (hours.length === 0) return null
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
setForm((prev) => ({ ...prev, [e.target.name]: e.target.value }))
|
||||
}
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
e.preventDefault()
|
||||
if (form.name && form.email && form.message) setSubmitted(true)
|
||||
}
|
||||
|
||||
const socialLinks = [
|
||||
{ icon: Camera, label: "Instagram", href: "https://instagram.com/joziwear" },
|
||||
{ icon: Globe, label: "Facebook", href: "https://facebook.com/joziwear" },
|
||||
{ icon: MessageCircle, label: "WhatsApp", href: "https://wa.me/27731234567" },
|
||||
{ icon: X, label: "X", href: "https://x.com/joziwear" },
|
||||
]
|
||||
|
||||
return (
|
||||
<section id="contact" data-vula-section="contactkhuluma" data-vula-cms="business_hours" className="py-20 bg-[#18181b] text-white">
|
||||
<div className="max-w-6xl mx-auto px-6 grid grid-cols-1 lg:grid-cols-2 gap-12">
|
||||
<div>
|
||||
<h2 className="text-4xl font-bold uppercase tracking-tight">Khuluma Nawe</h2>
|
||||
<p className="mt-2 text-lg text-gray-300">Reach out or come through to our Soweto spot.</p>
|
||||
<div className="mt-6 space-y-4">
|
||||
<div className="flex items-center gap-2 text-gray-300">
|
||||
<MapPin className="w-5 h-5 text-[#ea580c]" />
|
||||
<span>123 Vilakazi Street, Orlando West, Soweto, 1804</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-gray-300">
|
||||
<Phone className="w-5 h-5 text-[#ea580c]" />
|
||||
<span>+27 73 123 4567</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-gray-300">
|
||||
<Mail className="w-5 h-5 text-[#ea580c]" />
|
||||
<span>info@joziwear.co.za</span>
|
||||
</div>
|
||||
</div>
|
||||
{!submitted ? (
|
||||
<form onSubmit={handleSubmit} className="mt-8 space-y-4">
|
||||
<Input
|
||||
name="name"
|
||||
placeholder="Your name"
|
||||
value={form.name}
|
||||
onChange={handleChange}
|
||||
required
|
||||
className="bg-transparent border-2 border-[#ea580c] text-white placeholder-gray-400"
|
||||
/>
|
||||
<Input
|
||||
name="email"
|
||||
type="email"
|
||||
placeholder="Your email"
|
||||
value={form.email}
|
||||
onChange={handleChange}
|
||||
required
|
||||
className="bg-transparent border-2 border-[#ea580c] text-white placeholder-gray-400"
|
||||
/>
|
||||
<textarea
|
||||
name="message"
|
||||
placeholder="Your message"
|
||||
value={form.message}
|
||||
onChange={handleChange}
|
||||
required
|
||||
rows={4}
|
||||
className="w-full bg-transparent border-2 border-[#ea580c] text-white placeholder-gray-400 p-3 rounded-none focus:outline-none"
|
||||
/>
|
||||
<Button type="submit" variant="default" className="bg-[#ea580c] hover:bg-[#d94d0a] border-2 border-[#ea580c] shadow-[4px_4px_0_0_#d4a017] w-full">
|
||||
Send Message
|
||||
</Button>
|
||||
</form>
|
||||
) : (
|
||||
<div className="mt-8 p-4 border-2 border-[#16a34a] text-[#16a34a]">
|
||||
<p className="font-semibold">Sizo thinta (We'll be in touch)!</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-8 flex gap-4">
|
||||
{socialLinks.map((link) => {
|
||||
const Icon = link.icon
|
||||
return (
|
||||
<a
|
||||
key={link.label}
|
||||
href={link.href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="p-3 border-2 border-[#ea580c] hover:bg-[#ea580c] transition-colors duration-200"
|
||||
aria-label={link.label}
|
||||
>
|
||||
<Icon className="w-5 h-5" />
|
||||
</a>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="border-2 border-[#ea580c] p-6">
|
||||
<h3 className="text-xl font-bold uppercase tracking-wide mb-4">Trading Hours</h3>
|
||||
<ul className="space-y-2">
|
||||
{hours.map((item) => {
|
||||
const d = item.data as { day_of_week?: string; open_time?: string; close_time?: string; is_closed?: boolean; note?: string }
|
||||
return (
|
||||
<li key={item.id} className="flex justify-between text-sm">
|
||||
<span className="font-medium">{d.day_of_week}</span>
|
||||
<span className={d.is_closed ? "text-red-400" : "text-gray-300"}>
|
||||
{d.is_closed ? 'Closed' : `${d.open_time} \u2013 ${d.close_time}`}
|
||||
{d.note && <span className="ml-2 italic text-xs">{d.note}</span>}
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
<p className="mt-4 text-xs text-gray-400">Closed on SA public holidays.</p>
|
||||
</div>
|
||||
<div className="mt-6">
|
||||
<Link href="#policies" className="text-[#ea580c] underline hover:no-underline">View our store policies</Link>
|
||||
</div>
|
||||
<div className="mt-6 relative h-48 border-2 border-[#ea580c] overflow-hidden">
|
||||
<Image
|
||||
src="https://images.pexels.com/photos/4612687/pexels-photo-4612687.jpeg?auto=compress&cs=tinysrgb&h=350"
|
||||
alt="Soweto map area"
|
||||
fill
|
||||
className="object-cover"
|
||||
sizes="(max-width: 768px) 100vw, 50vw"
|
||||
/>
|
||||
<div className="absolute inset-0 flex items-center justify-center">
|
||||
<MapPin className="w-10 h-10 text-[#ea580c] drop-shadow-lg" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user