Deploy
This commit is contained in:
@@ -0,0 +1,76 @@
|
|||||||
|
'use client'
|
||||||
|
import { useVulaContent } from '@/hooks/useVulaContent'
|
||||||
|
import Badge from '@/components/ui/Badge'
|
||||||
|
|
||||||
|
const DAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
|
||||||
|
|
||||||
|
function parseTime(value?: string): number | null {
|
||||||
|
if (!value) return null
|
||||||
|
const parts = value.split(':')
|
||||||
|
const hours = Number(parts[0])
|
||||||
|
const minutes = parts[1] ? Number(parts[1]) : 0
|
||||||
|
if (Number.isNaN(hours) || Number.isNaN(minutes)) return null
|
||||||
|
return hours * 60 + minutes
|
||||||
|
}
|
||||||
|
|
||||||
|
function isOpenNow(d: { day_of_week?: string; open_time?: string; close_time?: string; is_closed?: boolean }) {
|
||||||
|
if (String(d.is_closed).toLowerCase() === 'true') return false
|
||||||
|
const now = new Date()
|
||||||
|
if (String(d.day_of_week ?? '').toLowerCase() !== DAYS[now.getDay()].toLowerCase()) return false
|
||||||
|
const current = now.getHours() * 60 + now.getMinutes()
|
||||||
|
const open = parseTime(d.open_time)
|
||||||
|
const close = parseTime(d.close_time)
|
||||||
|
if (open === null || close === null) return false
|
||||||
|
return current >= open && current < close
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function BusinessHoursSection() {
|
||||||
|
const { items = [], loading } = useVulaContent('business_hours')
|
||||||
|
|
||||||
|
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 (items.length === 0) return null
|
||||||
|
|
||||||
|
const weekOrder = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
|
||||||
|
const sortedItems = [...items].sort((a, b) => {
|
||||||
|
const da = (a.data as { day_of_week?: string }).day_of_week ?? ''
|
||||||
|
const db = (b.data as { day_of_week?: string }).day_of_week ?? ''
|
||||||
|
return weekOrder.indexOf(da) - weekOrder.indexOf(db)
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section id="business-hours" data-vula-section="business-hours" data-vula-cms="business_hours" className="bg-[#F0F8FF] py-20">
|
||||||
|
<div className="mx-auto max-w-4xl px-4">
|
||||||
|
<div className="mb-10 text-center">
|
||||||
|
<p className="mb-2 text-sm font-semibold uppercase tracking-[0.2em] text-[#00A8CC]">Fourways, Johannesburg</p>
|
||||||
|
<h2 className="font-sora text-3xl font-bold text-[#1A2B3C]">Our week at <span className="text-[#00A8CC]">Zama Salon</span></h2>
|
||||||
|
<p className="mx-auto mt-3 max-w-[44ch] text-[#1A2B3C]/70">Walk-ins welcome, but booking ahead saves your chair.</p>
|
||||||
|
</div>
|
||||||
|
<div className="overflow-hidden rounded-xl bg-white shadow-md">
|
||||||
|
{sortedItems.map((item) => {
|
||||||
|
const d = item.data as { day_of_week?: string; open_time?: string; close_time?: string; is_closed?: boolean; note?: string }
|
||||||
|
const closed = String(d.is_closed).toLowerCase() === 'true'
|
||||||
|
const open = isOpenNow(d)
|
||||||
|
const hours = closed ? 'Closed' : `${d.open_time} – ${d.close_time}`
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={item.id}
|
||||||
|
className={`flex flex-col gap-1 border-b border-[#d4dadd] px-5 py-4 last:border-0 sm:flex-row sm:items-center sm:justify-between ${
|
||||||
|
open ? 'bg-[#0077BE] text-white' : ''
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<span className="w-28 font-semibold">{d.day_of_week}</span>
|
||||||
|
<span className={`text-sm ${open ? 'text-white/80' : 'text-[#1A2B3C]/60'}`}>{hours}</span>
|
||||||
|
</div>
|
||||||
|
{open && (
|
||||||
|
<Badge className="bg-[#00A8CC] text-white">Open now</Badge>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user