mirror of
https://github.com/marcogll/AnchorOS.git
synced 2026-03-15 20:24:34 +00:00
Major changes: - Add customer registration with email/phone lookup (app/booking/registro) - Add customers API endpoint (app/api/customers/route) - Implement business hours for locations (mon-fri 10-7, sat 10-6, sun closed) - Fix availability function type casting issues - Add business hours utilities (lib/utils/business-hours.ts) - Update Location type to include business_hours JSONB - Add mock payment component for testing - Remove Supabase auth from booking flow - Fix /cita redirect path in booking flow Database migrations: - Add category column to services table - Add business_hours JSONB column to locations table - Fix availability functions with proper type casting - Update get_detailed_availability to use business_hours Features: - Customer lookup by email or phone - Auto-redirect to registration if customer not found - Pre-fill customer data if exists - Business hours per day of week - Location-specific opening/closing times
85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
import type { BusinessHours, DayHours } from '@/lib/db/types'
|
|
|
|
const DAYS = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'] as const
|
|
type DayOfWeek = typeof DAYS[number]
|
|
|
|
export function getDayOfWeek(date: Date): DayOfWeek {
|
|
return DAYS[date.getDay()]
|
|
}
|
|
|
|
export function isOpenNow(businessHours: BusinessHours, date = new Date): boolean {
|
|
const day = getDayOfWeek(date)
|
|
const hours = businessHours[day]
|
|
|
|
if (!hours || hours.is_closed) {
|
|
return false
|
|
}
|
|
|
|
const now = date
|
|
const [openHour, openMinute] = hours.open.split(':').map(Number)
|
|
const [closeHour, closeMinute] = hours.close.split(':').map(Number)
|
|
|
|
const openTime = new Date(now)
|
|
openTime.setHours(openHour, openMinute, 0, 0)
|
|
|
|
const closeTime = new Date(now)
|
|
closeTime.setHours(closeHour, closeMinute, 0, 0)
|
|
|
|
return now >= openTime && now < closeTime
|
|
}
|
|
|
|
export function getNextOpenTime(businessHours: BusinessHours, from = new Date): Date | null {
|
|
const checkDate = new Date(from)
|
|
|
|
for (let i = 0; i < 7; i++) {
|
|
const day = getDayOfWeek(checkDate)
|
|
const hours = businessHours[day]
|
|
|
|
if (hours && !hours.is_closed) {
|
|
const [openHour, openMinute] = hours.open.split(':').map(Number)
|
|
|
|
const openTime = new Date(checkDate)
|
|
openTime.setHours(openHour, openMinute, 0, 0)
|
|
|
|
if (openTime > from) {
|
|
return openTime
|
|
}
|
|
|
|
openTime.setDate(openTime.getDate() + 1)
|
|
return openTime
|
|
}
|
|
|
|
checkDate.setDate(checkDate.getDate() + 1)
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
export function isTimeWithinHours(time: string, dayHours: DayHours): boolean {
|
|
if (dayHours.is_closed) {
|
|
return false
|
|
}
|
|
|
|
const [hour, minute] = time.split(':').map(Number)
|
|
const checkMinutes = hour * 60 + minute
|
|
|
|
const [openHour, openMinute] = dayHours.open.split(':').map(Number)
|
|
const [closeHour, closeMinute] = dayHours.close.split(':').map(Number)
|
|
const openMinutes = openHour * 60 + openMinute
|
|
const closeMinutes = closeHour * 60 + closeMinute
|
|
|
|
return checkMinutes >= openMinutes && checkMinutes < closeMinutes
|
|
}
|
|
|
|
export function getBusinessHoursString(dayHours: DayHours): string {
|
|
if (dayHours.is_closed) {
|
|
return 'Cerrado'
|
|
}
|
|
return `${dayHours.open} - ${dayHours.close}`
|
|
}
|
|
|
|
export function getTodayHours(businessHours: BusinessHours): string {
|
|
const day = getDayOfWeek(new Date())
|
|
return getBusinessHoursString(businessHours[day])
|
|
}
|