This commit is contained in:
Alan Daniel committed 2026-03-27 10:40:34 -04:00
1 parent 295c002882
commit a994c9478e
4 files changed
+16 -8

No files matched your search

@@ -47,8 +47,9 @@ export async function POST(request: NextRequest) {
if (!res.ok) {
const text = await res.text()
console.error('[HubSpot booking error]', { status: res.status, body: text })
return NextResponse.json(
{ error: 'HubSpot booking failed', detail: text },
{ error: 'Booking failed. Please try again or contact support.' },
{ status: res.status }
)
}
@@ -1,6 +1,5 @@
'use client'
import { Loader2 } from 'lucide-react'
import { useEffect, useMemo, useRef, useState } from 'react'
import type { GoHubSpotMeetingSection } from '../schemas'
@@ -75,7 +74,7 @@ export default function HubSpotMeetingSection({ section }: { section: GoHubSpotM
<div className="max-w-md mx-auto border border-muted rounded-xl bg-surface-100 p-6 min-h-[440px] flex flex-col h-full">
{state.step === 'loading' && (
<div className="flex items-center justify-center h-full min-h-[inherit]">
<Loader2 size={24} className="animate-spinner text-foreground-muted" />
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="animate-spinner text-foreground-muted"><path d="M21 12a9 9 0 1 1-6.219-8.56" /></svg>
</div>
)}
@@ -114,7 +114,7 @@ function getUtcOffset(tzId: string): { label: string; minutes: number } {
function buildGroups(userTz: string): { userEntry: TimezoneEntry; groups: TimezoneGroup[] } {
const entries: TimezoneEntry[] = TIMEZONE_DATA.map((tz) => {
const offset = getUtcOffset(tz.id)
return { id: tz.id, label: tz.label, offset: offset.label, offsetMinutes: offset.offsetMinutes }
return { id: tz.id, label: tz.label, offset: offset.label, offsetMinutes: offset.minutes }
})
// Build user entry
@@ -41,8 +41,14 @@ export interface SchedulerState {
}
export function useScheduler(slug: string, enabled = true) {
const [timezone, setTimezoneState] = useState(() => getUserTimezone())
const locale = useMemo(() => getUserLocale(), [])
const [timezone, setTimezoneState] = useState('America/New_York')
const [locale, setLocale] = useState('en-US')
// Hydrate timezone/locale from browser after mount to avoid SSR mismatches
useEffect(() => {
setTimezoneState(getUserTimezone())
setLocale(getUserLocale())
}, [])
/** Cached booking info keyed by month offset */
const [monthCache, setMonthCache] = useState<Record<number, BookingInfo>>({})
@@ -208,13 +214,15 @@ export function useScheduler(slug: string, enabled = true) {
/** Month offsets that have at least one available slot */
const availableMonthOffsets = useMemo(() => {
const now = new Date()
// Compute "now" in the selected timezone to avoid ±1 month drift near boundaries
const nowStr = new Date().toLocaleDateString('en-CA', { timeZone: timezone })
const [nowY, nowM] = nowStr.split('-').map(Number)
const offsets = new Set<number>()
for (const slot of allSlots) {
const date = new Date(slot.startMillisUtc)
const localDateStr = date.toLocaleDateString('en-CA', { timeZone: timezone })
const [y, m] = localDateStr.split('-').map(Number)
const offset = (y - now.getFullYear()) * 12 + (m - 1 - now.getMonth())
const offset = (y - nowY) * 12 + (m - nowM)
if (offset >= 0 && offset < MONTHS_TO_FETCH) {
offsets.add(offset)
}