@clicka1/booking 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../lib/salon-services.ts","../../../lib/salon-opening-hours.ts","../../../lib/booking-blocks.ts","../../../lib/tracking-events.ts","../../../components/booking/useBookingFlow.ts","../../../components/booking/BookingWidget.tsx","../../../components/booking/BookingProvider.tsx","../../../components/booking/useBooking.ts","../../../components/booking/BookingButton.tsx"],"names":["id","t","BookingWidget","useMemo","useRef","useState","useEffect","useCallback","jsx","forwardRef","BookingButton"],"mappings":"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","file":"index.js","sourcesContent":["function randomHex(bytes: number): string {\n const buf = new Uint8Array(bytes);\n globalThis.crypto.getRandomValues(buf);\n return Array.from(buf, b => b.toString(16).padStart(2, '0')).join('');\n}\n\nexport type PaymentType = 'none' | 'deposit' | 'full';\nexport type CancelPolicyAction = 'full_refund' | 'keep_deposit' | 'keep_full';\n\nexport type ServiceItem = {\n id?: string;\n name: string;\n nameEn?: string;\n description?: string;\n descriptionEn?: string;\n category?: string;\n price: number;\n duration_min: number;\n images?: string[];\n variants?: { label: string; price: number; duration?: number }[];\n assignedTeamMemberIds?: string[];\n payment_type?: PaymentType;\n deposit_amount?: number; // euros (e.g. 20 = €20)\n requires_confirmation?: boolean;\n cancel_policy_hours?: number; // hours before which free cancel is allowed\n cancel_policy_action?: CancelPolicyAction; // what happens after the deadline\n};\n\nexport type ParsedSalonService = {\n id: string;\n name: string;\n nameEn?: string;\n description?: string;\n descriptionEn?: string;\n category?: string;\n price?: number;\n duration: number;\n images?: string[];\n variants?: { label: string; price: number; duration?: number }[];\n assignedTeamMemberIds?: string[];\n payment_type?: PaymentType;\n deposit_amount?: number;\n requires_confirmation?: boolean;\n cancel_policy_hours?: number;\n cancel_policy_action?: CancelPolicyAction;\n};\n\nfunction pickFirstNonEmptyString(...values: unknown[]): string {\n for (const value of values) {\n const text = String(value ?? '').trim();\n if (text) return text;\n }\n return '';\n}\n\n/** Returns true for index-based IDs that are positionally unstable (svc-0, svc-1, svc-2-3, …). */\nfunction isUnstableId(id: string): boolean {\n return /^svc-\\d/.test(id);\n}\n\nfunction assignUniqueServiceId(candidate: string, usedIds: Set<string>): string {\n const trimmed = candidate.trim();\n // Keep the candidate if it exists, is not a positional svc-N id, and is unique.\n if (trimmed && !isUnstableId(trimmed) && !usedIds.has(trimmed)) {\n usedIds.add(trimmed);\n return trimmed;\n }\n // Generate a stable random ID (8 hex chars, same pattern as onboarding_code).\n let id = randomHex(4);\n while (usedIds.has(id)) id = randomHex(4);\n usedIds.add(id);\n return id;\n}\n\n/** Parse salon services JSON for public UI and admin (skips unnamed rows, guarantees unique ids). */\nexport function parseSalonServices(raw: unknown): ParsedSalonService[] {\n if (typeof raw === 'string') {\n try {\n raw = JSON.parse(raw) as unknown;\n } catch {\n return [];\n }\n }\n let items: unknown[] = [];\n if (Array.isArray(raw)) {\n items = raw;\n } else if (raw && typeof raw === 'object') {\n items = Object.values(raw as Record<string, unknown>);\n } else {\n return [];\n }\n\n const usedIds = new Set<string>();\n const out: ParsedSalonService[] = [];\n\n items.forEach((item, index) => {\n const row = item as Record<string, unknown>;\n const name = pickFirstNonEmptyString(row.name, row.service_name, row.serviceName, row.title);\n if (!name) return;\n\n const id = assignUniqueServiceId(String(row.id ?? ''), usedIds);\n const duration = Number(row.duration ?? row.duration_min ?? row.durationMin ?? 30) || 30;\n const priceRaw = row.price ?? row.service_price ?? row.servicePrice;\n const price = priceRaw != null ? Number(priceRaw) : undefined;\n const variants = Array.isArray(row.variants)\n ? (row.variants as unknown[])\n .map((variant): { label: string; price: number; duration?: number } | null => {\n if (!variant || typeof variant !== 'object') return null;\n const v = variant as Record<string, unknown>;\n const label = String(v.label ?? '').trim();\n if (!label) return null;\n const priceNum = Number(v.price ?? NaN);\n if (!Number.isFinite(priceNum)) return null;\n const durationNum = Number(v.duration ?? NaN);\n return {\n label,\n price: Math.max(0, priceNum),\n duration: Number.isFinite(durationNum) ? Math.max(5, Math.round(durationNum)) : undefined,\n };\n })\n .filter((variant): variant is { label: string; price: number; duration?: number } => variant !== null)\n : undefined;\n const images = Array.isArray(row.images)\n ? (row.images as unknown[])\n .map((image) => String(image ?? '').trim())\n .filter(Boolean)\n : undefined;\n const assignedTeamMemberIds = Array.isArray(row.assignedTeamMemberIds)\n ? [...new Set((row.assignedTeamMemberIds as unknown[])\n .map((id) => String(id ?? '').trim())\n .filter(Boolean))]\n : undefined;\n\n const paymentTypeRaw = String(row.payment_type ?? '');\n const paymentType: PaymentType | undefined = ['none', 'deposit', 'full'].includes(paymentTypeRaw)\n ? (paymentTypeRaw as PaymentType)\n : undefined;\n const depositAmountRaw = Number(row.deposit_amount ?? NaN);\n const depositAmount = Number.isFinite(depositAmountRaw) ? Math.max(0, depositAmountRaw) : undefined;\n\n const cancelPolicyHoursRaw = Number(row.cancel_policy_hours ?? NaN);\n const cancelPolicyHours = Number.isFinite(cancelPolicyHoursRaw) && cancelPolicyHoursRaw > 0\n ? cancelPolicyHoursRaw\n : undefined;\n const cancelPolicyActionRaw = String(row.cancel_policy_action ?? '');\n const cancelPolicyAction: CancelPolicyAction | undefined = (\n ['full_refund', 'keep_deposit', 'keep_full'] as CancelPolicyAction[]\n ).includes(cancelPolicyActionRaw as CancelPolicyAction)\n ? (cancelPolicyActionRaw as CancelPolicyAction)\n : undefined;\n\n out.push({\n id,\n name,\n nameEn: String(row.nameEn ?? '').trim() || undefined,\n description: String(row.description ?? '').trim() || undefined,\n descriptionEn: String(row.descriptionEn ?? '').trim() || undefined,\n category:\n pickFirstNonEmptyString(\n row.category,\n row.category_name,\n row.categoryName,\n row.service_category,\n row.serviceCategory,\n ) || undefined,\n price: price != null && Number.isFinite(price) ? price : undefined,\n duration,\n images,\n variants: variants && variants.length > 0 ? variants : undefined,\n ...(assignedTeamMemberIds && assignedTeamMemberIds.length > 0\n ? { assignedTeamMemberIds }\n : {}),\n ...(paymentType !== undefined ? { payment_type: paymentType } : {}),\n ...(depositAmount !== undefined ? { deposit_amount: depositAmount } : {}),\n ...(row.requires_confirmation === true ? { requires_confirmation: true } : {}),\n ...(cancelPolicyHours !== undefined ? { cancel_policy_hours: cancelPolicyHours } : {}),\n ...(cancelPolicyAction !== undefined ? { cancel_policy_action: cancelPolicyAction } : {}),\n });\n });\n\n return out;\n}\n\n/** Returns a copy of the service with name/description resolved for the given locale. */\nexport function localizeService<T extends { name: string; nameEn?: string; description?: string; descriptionEn?: string }>(\n service: T,\n locale: string,\n): T {\n if (locale !== 'en') return service;\n const name = service.nameEn?.trim() || service.name;\n const description = service.descriptionEn?.trim() || service.description;\n return { ...service, name, description };\n}\n\nexport function normalizeServices(raw: unknown): ServiceItem[] {\n return parseSalonServices(raw).map((s) => {\n const normalizedVariants = Array.isArray(s.variants)\n ? s.variants\n .map((variant) => ({\n label: String(variant.label ?? '').trim(),\n price: Math.max(0, Number(variant.price) || 0),\n duration:\n variant.duration != null && Number.isFinite(Number(variant.duration))\n ? Math.max(5, Math.round(Number(variant.duration)))\n : undefined,\n }))\n .filter((variant) => variant.label.length > 0)\n : [];\n\n const basePrice =\n normalizedVariants.length > 0\n ? normalizedVariants[0]!.price\n : Math.max(0, Number(s.price ?? 0) || 0);\n const baseDuration =\n normalizedVariants.length > 0\n ? Math.max(5, Number(normalizedVariants[0]!.duration ?? s.duration ?? 30) || 30)\n : Math.max(5, s.duration);\n\n return {\n id: s.id,\n name: s.name,\n ...(s.nameEn ? { nameEn: s.nameEn } : {}),\n description: s.description,\n ...(s.descriptionEn ? { descriptionEn: s.descriptionEn } : {}),\n category: s.category,\n price: basePrice,\n duration_min: baseDuration,\n ...(Array.isArray(s.images) && s.images.length > 0 ? { images: s.images } : {}),\n ...(normalizedVariants.length > 0 ? { variants: normalizedVariants } : {}),\n ...(Array.isArray(s.assignedTeamMemberIds) && s.assignedTeamMemberIds.length > 0\n ? { assignedTeamMemberIds: s.assignedTeamMemberIds }\n : {}),\n ...(['none', 'deposit', 'full'].includes(String((s as unknown as ServiceItem).payment_type ?? ''))\n ? { payment_type: (s as unknown as ServiceItem).payment_type }\n : {}),\n ...((s as unknown as ServiceItem).deposit_amount != null && Number.isFinite(Number((s as unknown as ServiceItem).deposit_amount))\n ? { deposit_amount: Math.max(0, Number((s as unknown as ServiceItem).deposit_amount)) }\n : {}),\n ...((s as unknown as ServiceItem).requires_confirmation === true ? { requires_confirmation: true } : {}),\n ...(s.cancel_policy_hours !== undefined ? { cancel_policy_hours: s.cancel_policy_hours } : {}),\n ...(s.cancel_policy_action !== undefined ? { cancel_policy_action: s.cancel_policy_action } : {}),\n };\n });\n}\n","/** Работно време в стил BOOKA уеб: ключове Monday..Sunday, стойност null = затворено. */\n\nconst DAY_NAMES_EN = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] as const;\n\nconst CLICKA_TO_EN: Record<string, (typeof DAY_NAMES_EN)[number]> = {\n monday: 'Monday',\n tuesday: 'Tuesday',\n wednesday: 'Wednesday',\n thursday: 'Thursday',\n friday: 'Friday',\n saturday: 'Saturday',\n sunday: 'Sunday',\n};\n\nexport type OpeningDayRecord = Record<string, { open: string; close: string } | null>;\n\nconst DEFAULT_OPENING_HOURS: Record<(typeof DAY_NAMES_EN)[number], { open: string; close: string }> = {\n Monday: { open: '09:00', close: '18:00' },\n Tuesday: { open: '09:00', close: '18:00' },\n Wednesday: { open: '09:00', close: '18:00' },\n Thursday: { open: '09:00', close: '18:00' },\n Friday: { open: '09:00', close: '18:00' },\n Saturday: { open: '10:00', close: '16:00' },\n Sunday: { open: '10:00', close: '16:00' },\n};\n\n/** Clicka `working_hours` (monday..sunday) + опционален `opening_hours` JSON от Neon → Monday..Sunday. */\nexport function mergeOpeningHours(\n workingHours: Record<string, { open?: string; close?: string; closed?: boolean }> | null | undefined,\n openingHoursOverride: unknown\n): OpeningDayRecord {\n const out: OpeningDayRecord = {};\n for (const d of DAY_NAMES_EN) out[d] = null;\n\n const fromOverride = normalizeOpeningOverride(openingHoursOverride);\n if (fromOverride) {\n for (const d of DAY_NAMES_EN) {\n if (fromOverride[d] !== undefined) out[d] = fromOverride[d];\n }\n return out;\n }\n\n if (workingHours && typeof workingHours === 'object') {\n for (const [k, v] of Object.entries(workingHours)) {\n const en = CLICKA_TO_EN[k.toLowerCase()];\n if (!en) continue;\n if (!v || v.closed || !v.open || !v.close) out[en] = null;\n else out[en] = { open: v.open, close: v.close };\n }\n }\n return out;\n}\n\nfunction normalizeOpeningOverride(raw: unknown): OpeningDayRecord | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\n const o = raw as Record<string, unknown>;\n const out: OpeningDayRecord = {};\n let any = false;\n for (const d of DAY_NAMES_EN) {\n const v = o[d];\n if (v && typeof v === 'object' && !Array.isArray(v)) {\n const open = String((v as { open?: unknown }).open ?? '');\n const close = String((v as { close?: unknown }).close ?? '');\n if (open && close) {\n out[d] = { open, close };\n any = true;\n } else {\n out[d] = null;\n }\n }\n }\n return any ? out : null;\n}\n\nexport function getCurrentStatusString(openingHours: OpeningDayRecord): string {\n const hasAny = Object.keys(openingHours).some((k) => openingHours[k] != null);\n const now = new Date();\n const dayIndex = (now.getDay() + 6) % 7;\n const dayName = DAY_NAMES_EN[dayIndex];\n const hours = hasAny ? (openingHours[dayName] ?? null) : (DEFAULT_OPENING_HOURS[dayName] ?? null);\n if (!hours) return 'Затворено';\n const [openH, openM] = hours.open.split(':').map(Number);\n const [closeH, closeM] = hours.close.split(':').map(Number);\n const nowMins = now.getHours() * 60 + now.getMinutes();\n const openMins = openH * 60 + openM;\n const closeMins = closeH * 60 + closeM;\n const formatTime = (h: number, m: number) =>\n `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}\\u00a0ч`;\n if (nowMins < openMins) return `Затворено - отваря в ${formatTime(openH, openM)}`;\n if (nowMins >= closeMins) return `Затворено - отваря утре в ${formatTime(openH, openM)}`;\n return `Отворено - затваря в ${formatTime(closeH, closeM)}`;\n}\n\nexport function getEffectiveHours(\n openingHours: OpeningDayRecord,\n dayName: (typeof DAY_NAMES_EN)[number]\n): { open: string; close: string } | null {\n const hasAnyHours = Object.keys(openingHours).some((k) => openingHours[k] != null);\n if (hasAnyHours) {\n return openingHours[dayName] ?? null;\n }\n return DEFAULT_OPENING_HOURS[dayName] ?? null;\n}\n\nexport const DAY_LABELS_BG: Record<string, string> = {\n Monday: 'Понеделник',\n Tuesday: 'Вторник',\n Wednesday: 'Сряда',\n Thursday: 'Четвъртък',\n Friday: 'Петък',\n Saturday: 'Събота',\n Sunday: 'Неделя',\n};\n\nexport { DAY_NAMES_EN };\n","export type BookingBlock = {\n date: string; // YYYY-MM-DD\n allDay: boolean;\n start?: string; // HH:mm\n end?: string; // HH:mm\n note?: string;\n};\n\nfunction isIsoDate(value: string): boolean {\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(value);\n}\n\nfunction isTime(value: string): boolean {\n return /^([01]\\d|2[0-3]):[0-5]\\d$/.test(value);\n}\n\nfunction toMinutes(value: string): number {\n const [h, m] = value.split(':').map(Number);\n return h * 60 + m;\n}\n\nexport function normalizeBookingBlocks(raw: unknown): BookingBlock[] {\n if (!Array.isArray(raw)) return [];\n const out: BookingBlock[] = [];\n for (const item of raw) {\n if (!item || typeof item !== 'object') continue;\n const row = item as Record<string, unknown>;\n const date = String(row.date ?? '').trim();\n if (!isIsoDate(date)) continue;\n const allDay = row.allDay === true;\n const start = String(row.start ?? '').trim();\n const end = String(row.end ?? '').trim();\n const note = String(row.note ?? '').trim();\n if (!allDay) {\n if (!isTime(start) || !isTime(end)) continue;\n if (toMinutes(end) <= toMinutes(start)) continue;\n out.push({ date, allDay: false, start, end, ...(note ? { note } : {}) });\n continue;\n }\n out.push({ date, allDay: true, ...(note ? { note } : {}) });\n }\n out.sort((a, b) => `${a.date}-${a.start ?? ''}`.localeCompare(`${b.date}-${b.start ?? ''}`));\n return out;\n}\n\nexport function isDateBlockedAllDay(blocks: BookingBlock[], date: string): boolean {\n return blocks.some((b) => b.date === date && b.allDay);\n}\n\nexport function isBlockedForStartTime(\n blocks: BookingBlock[],\n date: string,\n startTime: string,\n durationMin: number\n): boolean {\n if (isDateBlockedAllDay(blocks, date)) return true;\n if (!isTime(startTime)) return false;\n const start = toMinutes(startTime);\n const end = start + Math.max(1, durationMin);\n for (const block of blocks) {\n if (block.date !== date || block.allDay || !block.start || !block.end) continue;\n const blockStart = toMinutes(block.start);\n const blockEnd = toMinutes(block.end);\n const overlaps = start < blockEnd && end > blockStart;\n if (overlaps) return true;\n }\n return false;\n}\n\n","declare global {\n interface Window {\n fbq?: (...args: unknown[]) => void;\n gtag?: (...args: unknown[]) => void;\n dataLayer?: unknown[];\n }\n}\n\nexport type BookingEventData = {\n serviceName?: string;\n value?: number; // EUR\n currency?: string;\n};\n\n// Session key — resets on new browser session (tab close)\nconst BOOKING_STARTED_KEY = 'tracking_booking_started';\n\nexport function trackPageView() {\n window.fbq?.('track', 'PageView');\n window.gtag?.('event', 'page_view');\n}\n\nexport function trackViewContent() {\n window.fbq?.('track', 'ViewContent');\n}\n\nexport function trackLead() {\n window.fbq?.('track', 'Lead');\n window.gtag?.('event', 'generate_lead');\n}\n\nexport function trackSignUp() {\n window.fbq?.('track', 'CompleteRegistration');\n window.gtag?.('event', 'sign_up');\n}\n\n/**\n * Fires booking_started only once per browser session.\n * Resets after a successful booking_completed so a new attempt in the same\n * tab counts again — but 5 modal opens without booking = 1 event.\n */\nexport function trackBookingStarted() {\n if (typeof sessionStorage === 'undefined') return;\n if (sessionStorage.getItem(BOOKING_STARTED_KEY)) return;\n sessionStorage.setItem(BOOKING_STARTED_KEY, '1');\n window.gtag?.('event', 'booking_started');\n}\n\nexport function trackBookingCompleted({ serviceName, value, currency = 'EUR' }: BookingEventData = {}) {\n // Reset so a second booking in the same session fires booking_started again\n if (typeof sessionStorage !== 'undefined') {\n sessionStorage.removeItem(BOOKING_STARTED_KEY);\n }\n\n const metaParams: Record<string, unknown> = {};\n if (value != null && value > 0) {\n metaParams.value = value;\n metaParams.currency = currency;\n }\n if (serviceName) metaParams.content_name = serviceName;\n\n // Standard Meta event — агенции, оптимизиращи по стандартни Facebook события\n window.fbq?.('track', 'Schedule', metaParams);\n // Custom Meta event — агенции с custom конверсии в Events Manager\n window.fbq?.('trackCustom', 'BookingCompleted', { ...metaParams, service_name: serviceName });\n\n const ga4Params: Record<string, unknown> = {};\n if (value != null && value > 0) {\n ga4Params.value = value;\n ga4Params.currency = currency;\n }\n if (serviceName) ga4Params.service_name = serviceName;\n\n window.gtag?.('event', 'booking_completed', ga4Params);\n}\n\n/**\n * Fires a test custom event visible in Meta Events Manager.\n * Use from the admin Marketing tab to verify the pixel is loaded.\n */\nexport function trackMetaTest() {\n if (!window.fbq) return false;\n window.fbq('trackCustom', 'EngineTest', { source: 'admin_test' });\n return true;\n}\n","'use client';\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { isDateBlockedAllDay, isBlockedForStartTime } from '@/lib/booking-blocks';\nimport { trackBookingStarted, trackBookingCompleted } from '@/lib/tracking-events';\nimport { useT } from '@/lib/i18n-react';\nimport type {\n UseBookingFlowOptions,\n UseBookingFlowReturn,\n BookingServiceItem,\n BookingSuccessDetails,\n OccupiedSlot,\n PublicStaffMember,\n} from './types';\n\nconst DAY_KEYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] as const;\n\nfunction pad(n: number): string {\n return String(n).padStart(2, '0');\n}\n\nfunction toLocalISODate(d: Date): string {\n return new Date(d.getTime() - d.getTimezoneOffset() * 60000).toISOString().split('T')[0]!;\n}\n\nexport function useBookingFlow({\n slug,\n openingHours,\n bookingBlocks,\n slotIntervalMin,\n bookingAdvanceDays,\n bookingServices,\n engineUrl = '',\n successUrl,\n cancelUrl,\n locale = 'bg-BG',\n onEvent,\n}: UseBookingFlowOptions): UseBookingFlowReturn {\n const t = useT();\n const api = engineUrl.replace(/\\/$/, '');\n const slugPath = `/api/public/v1/salons/${encodeURIComponent(slug)}`;\n\n // ── Modal visibility ─────────────────────────────────────────────────\n const [bookingOpen, setBookingOpen] = useState(false);\n\n // ── Service selection ────────────────────────────────────────────────\n const [selectedServiceIdxs, setSelectedServiceIdxs] = useState<number[]>([]);\n\n // ── Date / time ──────────────────────────────────────────────────────\n const [selectedDate, setSelectedDate] = useState('');\n const [selectedTime, setSelectedTime] = useState('');\n const [occupiedByDate, setOccupiedByDate] = useState<Record<string, OccupiedSlot[]>>({});\n const [minDate, setMinDate] = useState('');\n const [maxDate, setMaxDate] = useState('');\n\n // ── Contact fields ───────────────────────────────────────────────────\n const [clientName, setClientName] = useState('');\n const [clientPhone, setClientPhone] = useState('');\n const [clientEmail, setClientEmail] = useState('');\n const [notes, setNotes] = useState('');\n\n // ── Staff (TEAM plan) ────────────────────────────────────────────────\n const [staffMembers, setStaffMembers] = useState<PublicStaffMember[]>([]);\n const [selectedStaffMemberId, setSelectedStaffMemberIdState] = useState<string | null>(null);\n const staffFetchedRef = useRef(false);\n\n // ── Submission ───────────────────────────────────────────────────────\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [bookingError, setBookingError] = useState('');\n const [bookingSuccess, setBookingSuccess] = useState('');\n const [bookingSuccessDetails, setBookingSuccessDetails] = useState<BookingSuccessDetails | null>(null);\n\n // ── Compute min/max dates on mount ──────────────────────────────────\n useEffect(() => {\n const today = new Date();\n setMinDate(toLocalISODate(today));\n const max = new Date(today);\n max.setDate(today.getDate() + Math.max(1, bookingAdvanceDays));\n setMaxDate(toLocalISODate(max));\n }, [bookingAdvanceDays]);\n\n // ── Fetch staff members once when modal first opens ──────────────────\n useEffect(() => {\n if (!bookingOpen || staffFetchedRef.current) return;\n staffFetchedRef.current = true;\n fetch(`${api}${slugPath}/staff`, { cache: 'no-store' })\n .then((r) => r.json())\n .then((d: { staff?: PublicStaffMember[] }) => {\n if (Array.isArray(d.staff)) setStaffMembers(d.staff);\n })\n .catch(() => {});\n }, [bookingOpen, slug]);\n\n // ── Fetch occupied slots whenever date or staff changes ──────────────\n useEffect(() => {\n if (!selectedDate) return;\n let cancelled = false;\n const staffParam = selectedStaffMemberId\n ? `&staffMemberId=${encodeURIComponent(selectedStaffMemberId)}`\n : '';\n fetch(\n `${api}${slugPath}/slots?date=${encodeURIComponent(selectedDate)}${staffParam}`,\n { cache: 'no-store' },\n )\n .then((r) => r.json())\n .then((d: { occupied?: Array<{ time?: string; duration?: number }> }) => {\n if (cancelled || !Array.isArray(d.occupied)) return;\n const slots: OccupiedSlot[] = d.occupied\n .map((x) => ({\n time: String(x?.time ?? ''),\n duration: Math.max(5, Number(x?.duration ?? 30) || 30),\n }))\n .filter((x) => x.time.length >= 4);\n const cacheKey = selectedStaffMemberId\n ? `${selectedDate}:${selectedStaffMemberId}`\n : selectedDate;\n if (!cancelled) setOccupiedByDate((prev) => ({ ...prev, [cacheKey]: slots }));\n })\n .catch(() => {});\n return () => { cancelled = true; };\n }, [slug, selectedDate, selectedStaffMemberId]);\n\n // ── Derived: selected service objects ────────────────────────────────\n const selectedServices = useMemo<BookingServiceItem[]>(\n () =>\n selectedServiceIdxs\n .map((i) => bookingServices[i])\n .filter((s): s is BookingServiceItem => Boolean(s)),\n [selectedServiceIdxs, bookingServices],\n );\n\n const totalDuration = useMemo(\n () => selectedServices.reduce((sum, s) => sum + (Number(s.duration) || 0), 0),\n [selectedServices],\n );\n\n const totalPrice = useMemo(\n () => selectedServices.reduce((sum, s) => sum + (Number(s.price) || 0), 0),\n [selectedServices],\n );\n\n // ── Slot calculation ─────────────────────────────────────────────────\n const slotsForDate = useCallback(\n (date: string, durationMin: number): string[] | 'closed' | null => {\n if (!date) return null;\n const dayKey = DAY_KEYS[new Date(`${date}T12:00:00`).getDay()];\n const h = openingHours[dayKey] as { open?: string; close?: string } | null | undefined;\n if (!h?.open || !h?.close) return 'closed';\n if (isDateBlockedAllDay(bookingBlocks, date)) return 'closed';\n\n const dur = Math.max(5, durationMin || 30);\n const cacheKey = selectedStaffMemberId\n ? `${date}:${selectedStaffMemberId}`\n : date;\n const occupied = occupiedByDate[cacheKey] ?? [];\n\n const [oh = 0, om = 0] = h.open.split(':').map(Number);\n const [ch = 0, cm = 0] = h.close.split(':').map(Number);\n const start = oh * 60 + om;\n const latestStart = ch * 60 + cm - dur;\n const slots: string[] = [];\n\n for (let t = start; t <= latestStart; t += slotIntervalMin) {\n const slot = `${pad(Math.floor(t / 60))}:${pad(t % 60)}`;\n const slotEnd = t + dur;\n const overlaps = occupied.some(({ time, duration: d }) => {\n const [bh = 0, bm = 0] = time.split(':').map(Number);\n const existStart = bh * 60 + bm;\n const existEnd = existStart + Math.max(5, d);\n return existStart < slotEnd && existEnd > t;\n });\n if (!overlaps && !isBlockedForStartTime(bookingBlocks, date, slot, dur)) {\n slots.push(slot);\n }\n }\n return slots;\n },\n [openingHours, bookingBlocks, occupiedByDate, selectedStaffMemberId, slotIntervalMin],\n );\n\n const timeSlots = useMemo<string[] | 'closed' | null>(\n () =>\n selectedServiceIdxs.length === 0\n ? null\n : slotsForDate(selectedDate, totalDuration || 30),\n [selectedServiceIdxs.length, slotsForDate, selectedDate, totalDuration],\n );\n\n // ── Actions ──────────────────────────────────────────────────────────\n const open = useCallback((serviceId?: string) => {\n setBookingError('');\n setBookingSuccess('');\n setBookingSuccessDetails(null);\n if (serviceId) {\n const idx = bookingServices.findIndex((s) => s.id === serviceId);\n setSelectedServiceIdxs(idx >= 0 ? [idx] : []);\n } else {\n setSelectedServiceIdxs([]);\n }\n setSelectedDate('');\n setSelectedTime('');\n setClientName('');\n setClientPhone('');\n setClientEmail('');\n setNotes('');\n setBookingOpen(true);\n if (onEvent) onEvent('booking_started');\n else trackBookingStarted();\n }, [bookingServices, onEvent]);\n\n const close = useCallback(() => {\n setBookingOpen(false);\n setBookingSuccessDetails(null);\n setSelectedStaffMemberIdState(null);\n setSelectedDate('');\n setSelectedTime('');\n }, []);\n\n const toggleService = useCallback((idx: number) => {\n setSelectedServiceIdxs((prev) => {\n const has = prev.includes(idx);\n return has ? prev.filter((x) => x !== idx) : [...prev, idx];\n });\n setSelectedTime('');\n }, []);\n\n const setDate = useCallback((d: string) => {\n setSelectedDate(d);\n setSelectedTime('');\n }, []);\n\n const setStaffMemberId = useCallback((id: string) => {\n setSelectedStaffMemberIdState(id);\n setSelectedDate('');\n setSelectedTime('');\n }, []);\n\n const markSlotOccupied = useCallback((date: string, time: string, duration: number) => {\n if (!date || !time) return;\n const dur = Math.max(5, Number(duration) || 30);\n setOccupiedByDate((prev) => {\n const day = prev[date] ?? [];\n if (day.some((s) => s.time === time)) return prev;\n return { ...prev, [date]: [...day, { time, duration: dur }] };\n });\n }, []);\n\n const submit = useCallback(async (e: React.FormEvent) => {\n e.preventDefault();\n setBookingError('');\n setBookingSuccess('');\n\n if (selectedServices.length === 0) { setBookingError(t('booking.errors.noService')); return; }\n if (!clientName.trim()) { setBookingError(t('booking.errors.noName')); return; }\n if (!clientPhone.trim()) { setBookingError(t('booking.errors.noPhone')); return; }\n if (!clientEmail.trim()) { setBookingError(t('booking.errors.noEmail')); return; }\n if (!selectedDate) { setBookingError(t('booking.errors.noDate')); return; }\n if (!selectedTime) { setBookingError(t('booking.errors.noTime')); return; }\n\n const serviceName = selectedServices.map((s) => s.name).join(' + ');\n const duration = totalDuration || 30;\n const firstSvc = selectedServices[0];\n const paymentType = firstSvc?.payment_type ?? 'none';\n const depositAmt = firstSvc?.deposit_amount ?? 0;\n const amountEuros =\n paymentType === 'deposit' ? depositAmt :\n paymentType === 'full' ? (totalPrice ?? 0) : 0;\n const requiresPayment = paymentType !== 'none' && amountEuros > 0;\n\n setIsSubmitting(true);\n try {\n const res = await fetch(`${api}${slugPath}/bookings`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n clientName: clientName.trim(),\n clientPhone: clientPhone.trim(),\n clientEmail: clientEmail.trim().toLowerCase(),\n serviceName,\n servicePrice: totalPrice,\n serviceDuration: duration,\n date: selectedDate,\n time: selectedTime,\n notes: notes.trim() || undefined,\n requiresPayment,\n staffMemberId: selectedStaffMemberId ?? undefined,\n }),\n });\n\n const json = (await res.json().catch(() => ({}))) as {\n error?: string; bookingId?: string; id?: string;\n };\n if (!res.ok) {\n throw new Error(\n json.error ??\n (res.status === 500\n ? t('booking.errors.saveFailed')\n : t('booking.errors.httpError', { status: res.status })),\n );\n }\n\n // Stripe Checkout redirect for paid bookings\n const bookingId = json.bookingId ?? json.id;\n if (requiresPayment && bookingId) {\n const payRes = await fetch(`${api}${slugPath}/booking-checkout`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n bookingId,\n salonSlug: slug,\n serviceName,\n amountEuros,\n paymentType,\n successUrl,\n cancelUrl,\n }),\n });\n const payJson = (await payRes.json().catch(() => ({}))) as {\n checkoutUrl?: string; error?: string;\n };\n if (!payRes.ok || !payJson.checkoutUrl) {\n throw new Error(payJson.error ?? t('booking.errors.paymentFailed'));\n }\n window.location.href = payJson.checkoutUrl;\n return;\n }\n\n const dateLabel = new Date(`${selectedDate}T12:00:00`).toLocaleDateString(locale, {\n weekday: 'long', day: 'numeric', month: 'long',\n });\n markSlotOccupied(selectedDate, selectedTime, duration);\n setBookingSuccessDetails({ serviceName, dateLabel, time: selectedTime });\n setBookingSuccess(`${serviceName} — ${dateLabel} ${selectedTime}`);\n const eventPayload = {\n serviceName,\n value: totalPrice > 0 ? totalPrice : undefined,\n currency: 'EUR',\n };\n if (onEvent) onEvent('booking_completed', eventPayload);\n else trackBookingCompleted(eventPayload);\n } catch (err) {\n setBookingError(err instanceof Error ? err.message : t('booking.errors.generic'));\n } finally {\n setIsSubmitting(false);\n }\n }, [\n slug, selectedServices, clientName, clientPhone, clientEmail,\n selectedDate, selectedTime, notes,\n totalDuration, totalPrice, selectedStaffMemberId, markSlotOccupied,\n successUrl, cancelUrl, locale, onEvent,\n ]);\n\n return {\n bookingOpen, open, close,\n selectedServiceIdxs, toggleService, totalDuration, totalPrice, selectedServices,\n selectedDate, setDate,\n selectedTime, setTime: setSelectedTime,\n timeSlots, minDate, maxDate,\n clientName, setClientName,\n clientPhone, setClientPhone,\n clientEmail, setClientEmail,\n notes, setNotes,\n staffMembers, selectedStaffMemberId, setStaffMemberId,\n isSubmitting, bookingError, bookingSuccess, bookingSuccessDetails,\n submit,\n };\n}\n","'use client';\n\nimport {\n forwardRef,\n lazy,\n Suspense,\n useImperativeHandle,\n useMemo,\n} from 'react';\nimport { parseSalonServices, localizeService } from '@/lib/salon-services';\nimport {\n enrichServiceCategories,\n buildServiceCategoryTabs,\n} from '@/lib/salon-service-categories';\nimport { mergeOpeningHours } from '@/lib/salon-opening-hours';\nimport { normalizeBookingBlocks } from '@/lib/booking-blocks';\nimport type { BookingCatalogService } from '@/lib/booking-modal-catalog';\nimport { useBookingFlow } from './useBookingFlow';\nimport type { BookingServiceItem, BookingWidgetHandle, BookingWidgetProps } from './types';\nimport { I18nProvider } from '@/lib/i18n-react';\nimport { normalizeLocale } from '@/lib/i18n';\n\nconst SalonBookingModal = lazy(() =>\n import('@/components/salon/SalonBookingModal').then((m) => ({ default: m.SalonBookingModal })),\n);\n\n// ── Inner component ────────────────────────────────────────────────────────────\n// Must live *inside* I18nProvider so that useBookingFlow → useT() reads the\n// correct locale. If useBookingFlow were called in the outer BookingWidget,\n// it would be outside the provider and always get the 'bg' default.\n\ntype InnerProps = {\n forwardedRef: React.Ref<BookingWidgetHandle>;\n slug: string;\n openingHours: ReturnType<typeof mergeOpeningHours>;\n bookingBlocks: ReturnType<typeof normalizeBookingBlocks>;\n slotIntervalMin: number;\n bookingAdvanceDays: number;\n bookingServices: BookingServiceItem[];\n serviceCatalog: BookingCatalogService[];\n categoryTabs: ReturnType<typeof buildServiceCategoryTabs>;\n engineUrl: string;\n primaryColor: string;\n accentGradient?: string;\n successUrl?: string;\n cancelUrl?: string;\n locale: string;\n formatPrice?: (amount: number) => string;\n onEvent?: (\n name: 'booking_started' | 'booking_completed',\n payload?: { serviceName?: string; value?: number; currency?: string },\n ) => void;\n salonName: string;\n basePath: string;\n};\n\nfunction BookingWidgetInner({\n forwardedRef,\n slug,\n openingHours,\n bookingBlocks,\n slotIntervalMin,\n bookingAdvanceDays,\n bookingServices,\n serviceCatalog,\n categoryTabs,\n engineUrl,\n primaryColor,\n accentGradient,\n successUrl,\n cancelUrl,\n locale,\n formatPrice,\n onEvent,\n salonName,\n basePath,\n}: InnerProps) {\n const flow = useBookingFlow({\n slug,\n openingHours,\n bookingBlocks,\n slotIntervalMin,\n bookingAdvanceDays,\n bookingServices,\n engineUrl,\n successUrl,\n cancelUrl,\n locale,\n onEvent,\n });\n\n useImperativeHandle(forwardedRef, () => ({\n open: (serviceId?: string) => flow.open(serviceId),\n close: () => flow.close(),\n }), [flow.open, flow.close]);\n\n const firstSelected = flow.selectedServices[0];\n\n return (\n <Suspense fallback={null}>\n <SalonBookingModal\n open={flow.bookingOpen}\n primaryColor={primaryColor}\n accentGradient={accentGradient}\n locale={locale}\n formatPrice={formatPrice}\n serviceCatalog={serviceCatalog}\n categoryTabs={categoryTabs}\n services={bookingServices}\n selectedServiceIdxs={flow.selectedServiceIdxs}\n selectedDate={flow.selectedDate}\n selectedTime={flow.selectedTime}\n totalDuration={flow.totalDuration}\n totalPrice={flow.totalPrice}\n clientName={flow.clientName}\n clientPhone={flow.clientPhone}\n clientEmail={flow.clientEmail}\n notes={flow.notes}\n salonName={salonName}\n termsHref={`${basePath}/terms`}\n privacyHref={`${basePath}/privacy`}\n minDate={flow.minDate}\n maxDate={flow.maxDate}\n timeSlots={flow.timeSlots}\n paymentType={firstSelected?.payment_type ?? 'none'}\n depositAmount={firstSelected?.deposit_amount}\n cancelPolicyHours={firstSelected?.cancel_policy_hours}\n cancelPolicyAction={firstSelected?.cancel_policy_action}\n isSubmitting={flow.isSubmitting}\n bookingError={flow.bookingError}\n bookingSuccess={flow.bookingSuccess}\n bookingSuccessDetails={flow.bookingSuccessDetails}\n staffMembers={flow.staffMembers}\n selectedStaffMemberId={flow.selectedStaffMemberId}\n onClose={flow.close}\n onToggleService={flow.toggleService}\n onDateChange={flow.setDate}\n onTimeChange={flow.setTime}\n onClientNameChange={flow.setClientName}\n onClientPhoneChange={flow.setClientPhone}\n onClientEmailChange={flow.setClientEmail}\n onNotesChange={flow.setNotes}\n onStaffMemberChange={flow.setStaffMemberId}\n onSubmit={flow.submit}\n />\n </Suspense>\n );\n}\n\n// ── Public component ───────────────────────────────────────────────────────────\n\nexport const BookingWidget = forwardRef<BookingWidgetHandle, BookingWidgetProps>(\n function BookingWidget({ slug, salon, openingHours: openingHoursProp, bookingBlocks: blocksProp, basePath = '', engineUrl = '', accentGradient, successUrl, cancelUrl, locale: localeProp, formatPrice, onEvent }, ref) {\n\n // ── Opening hours ──────────────────────────────────────────────────\n const openingHours = useMemo(\n () => mergeOpeningHours(\n salon.working_hours as Record<string, { open?: string; close?: string; closed?: boolean }> | undefined,\n salon.opening_hours,\n ),\n [salon.working_hours, salon.opening_hours],\n );\n\n const resolvedHours = openingHoursProp ?? openingHours;\n const resolvedBlocks = blocksProp ?? normalizeBookingBlocks(\n salon.opening_hours && typeof salon.opening_hours === 'object'\n ? (salon.opening_hours as Record<string, unknown>).booking_blocks\n : null,\n );\n\n // ── Slot config from salon settings ───────────────────────────────\n const slotIntervalMin = useMemo((): number => {\n const oh = salon.opening_hours;\n if (oh && typeof oh === 'object') {\n const v = Number((oh as Record<string, unknown>).slot_interval_min);\n if ([15, 20, 30, 45, 60].includes(v)) return v;\n }\n return 30;\n }, [salon.opening_hours]);\n\n const bookingAdvanceDays = useMemo((): number => {\n const oh = salon.opening_hours;\n if (oh && typeof oh === 'object') {\n const v = Number((oh as Record<string, unknown>).booking_advance_days);\n if (Number.isFinite(v) && v >= 1) return Math.round(v);\n }\n return 60;\n }, [salon.opening_hours]);\n\n // ── Locale ────────────────────────────────────────────────────────\n const providerLocale = normalizeLocale(\n localeProp ?? (typeof salon.language === 'string' ? salon.language : 'bg'),\n );\n const resolvedLocale = localeProp ?? (providerLocale === 'en' ? 'en-US' : 'bg-BG');\n\n // ── Services processing ────────────────────────────────────────────\n const serviceCatalog = useMemo(\n () => enrichServiceCategories(\n parseSalonServices(salon.services).map((s) => localizeService(s, providerLocale))\n ) as BookingCatalogService[],\n [salon.services, providerLocale],\n );\n\n const categoryTabs = useMemo(\n () => buildServiceCategoryTabs(serviceCatalog),\n [serviceCatalog],\n );\n\n const bookingServices = useMemo<BookingServiceItem[]>(() => {\n const out: BookingServiceItem[] = [];\n for (const svc of serviceCatalog) {\n const variants = Array.isArray(svc.variants) ? svc.variants : [];\n if (variants.length === 0) {\n out.push(svc as unknown as BookingServiceItem);\n continue;\n }\n for (const v of variants) {\n out.push({\n ...(svc as unknown as BookingServiceItem),\n id: `${svc.id}::${v.label}`,\n name: `${svc.name} – ${v.label}`,\n price: Number(v.price ?? svc.price ?? 0) || 0,\n duration: Math.max(5, Number(v.duration ?? svc.duration ?? 30) || 30),\n variants: undefined,\n });\n }\n }\n return out;\n }, [serviceCatalog]);\n\n // ── Derived display props ─────────────────────────────────────────\n const primaryColor = typeof salon.primary_color === 'string' && salon.primary_color\n ? salon.primary_color\n : '#5B21B6';\n\n return (\n <I18nProvider locale={providerLocale}>\n <BookingWidgetInner\n forwardedRef={ref}\n slug={slug}\n openingHours={resolvedHours}\n bookingBlocks={resolvedBlocks}\n slotIntervalMin={slotIntervalMin}\n bookingAdvanceDays={bookingAdvanceDays}\n bookingServices={bookingServices}\n serviceCatalog={serviceCatalog}\n categoryTabs={categoryTabs}\n engineUrl={engineUrl}\n primaryColor={primaryColor}\n accentGradient={accentGradient}\n successUrl={successUrl}\n cancelUrl={cancelUrl}\n locale={resolvedLocale}\n formatPrice={formatPrice}\n onEvent={onEvent}\n salonName={String(salon.name ?? '')}\n basePath={basePath}\n />\n </I18nProvider>\n );\n },\n);\n","'use client';\n\nimport React, {\n createContext,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { BookingWidget } from './BookingWidget';\nimport type { BookingWidgetHandle } from './types';\n\nexport type BookingContextValue = {\n /**\n * Open the booking modal. Pass a service id to pre-select it. If the salon\n * record hasn't loaded yet, the call is queued and fired as soon as it does.\n */\n open: (service?: string) => void;\n /** Close the booking modal. No-op if it isn't open. */\n close: () => void;\n /** True once the salon record is loaded and the modal is mountable. */\n isReady: boolean;\n /** Non-null if the salon fetch failed (network, 404, etc.). */\n error: Error | null;\n /** The raw salon record once loaded, or null while loading / on error. */\n salon: Record<string, unknown> | null;\n};\n\nexport const BookingContext = createContext<BookingContextValue | null>(null);\n\nexport type BookingProviderProps = {\n children?: React.ReactNode;\n /**\n * Salon slug. If omitted, the provider tries (in order):\n * 1. `window.__CLICKA_SALON_SLUG`\n * 2. `<meta name=\"clicka:salon\" content=\"...\">`\n * 3. `process.env.NEXT_PUBLIC_SALON_SLUG` (Next.js / Vite-replaced)\n * 4. `process.env.NEXT_PUBLIC_CLICKA_SALON`\n */\n salonSlug?: string;\n /**\n * Engine origin. If omitted, the provider tries (in order):\n * 1. `window.__CLICKA_ENGINE_URL`\n * 2. `<meta name=\"clicka:engine\" content=\"...\">`\n * 3. `process.env.NEXT_PUBLIC_CLICKA_ENGINE`\n * 4. `process.env.NEXT_PUBLIC_CLICKA_API_URL`\n * 5. Default: `https://clicka.bg`\n */\n engineUrl?: string;\n /**\n * BCP-47 locale. If omitted, the provider derives it from\n * `<html lang>`, then `<body data-lang>`, then `navigator.language`,\n * defaulting to `bg-BG`.\n */\n locale?: string;\n /** Stripe success URL. Defaults to current page with `?booked=1`. */\n successUrl?: string;\n /** Stripe cancel URL. Defaults to current page with `?cancelled=1`. */\n cancelUrl?: string;\n /** CSS gradient for accent fills. */\n accentGradient?: string;\n /** Custom price formatter. */\n formatPrice?: (amount: number) => string;\n /** Analytics callback (replaces internal fbq/gtag). */\n onEvent?: (\n name: 'booking_started' | 'booking_completed',\n payload?: { serviceName?: string; value?: number; currency?: string },\n ) => void;\n /** Prefix for `/terms` and `/privacy` legal links. */\n basePath?: string;\n /**\n * When true (default), the provider attaches a document-level click handler\n * that opens the modal for any element matching `[data-clicka-book]`.\n * The attribute value (when non-empty) is passed as the service id.\n */\n autoTriggers?: boolean;\n /**\n * When true (default), the provider opens the modal on mount if the URL\n * contains `?service=<id>` or `?book=1`.\n */\n honorUrlParams?: boolean;\n};\n\nfunction readGlobalString(key: string): string | undefined {\n if (typeof window === 'undefined') return undefined;\n const v = (window as unknown as Record<string, unknown>)[key];\n return typeof v === 'string' && v ? v : undefined;\n}\n\nfunction readMeta(name: string): string | undefined {\n if (typeof document === 'undefined') return undefined;\n return (\n document.querySelector<HTMLMetaElement>(`meta[name=\"${name}\"]`)?.content || undefined\n );\n}\n\nfunction readEnv(key: string): string | undefined {\n try {\n const p = (typeof process !== 'undefined' ? process : undefined) as unknown as {\n env?: Record<string, string | undefined>;\n };\n const v = p?.env?.[key];\n return typeof v === 'string' && v ? v : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction resolveSlug(prop?: string): string | undefined {\n return (\n prop ||\n readGlobalString('__CLICKA_SALON_SLUG') ||\n readMeta('clicka:salon') ||\n readEnv('NEXT_PUBLIC_SALON_SLUG') ||\n readEnv('NEXT_PUBLIC_CLICKA_SALON')\n );\n}\n\nfunction resolveEngine(prop?: string): string {\n return (\n prop ||\n readGlobalString('__CLICKA_ENGINE_URL') ||\n readMeta('clicka:engine') ||\n readEnv('NEXT_PUBLIC_ENGINE_URL') ||\n readEnv('NEXT_PUBLIC_CLICKA_ENGINE') ||\n readEnv('NEXT_PUBLIC_CLICKA_API_URL') ||\n // Canonical host (with www). The bare clicka.bg returns a 308 redirect\n // which kills cross-origin fetches because the redirect response itself\n // carries no CORS headers — browsers reject the whole chain.\n 'https://www.clicka.bg'\n );\n}\n\nfunction resolveLocale(prop?: string): string {\n if (prop) return prop;\n if (typeof document !== 'undefined') {\n const htmlLang = document.documentElement.lang?.trim();\n if (htmlLang) {\n if (htmlLang === 'bg') return 'bg-BG';\n if (htmlLang === 'en') return 'en-US';\n return htmlLang;\n }\n const bodyLang = document.body?.dataset?.lang?.trim();\n if (bodyLang) return bodyLang === 'bg' ? 'bg-BG' : 'en-US';\n }\n if (typeof navigator !== 'undefined' && navigator.language) {\n return navigator.language;\n }\n return 'bg-BG';\n}\n\nfunction defaultReturnUrl(flag: 'booked' | 'cancelled'): string | undefined {\n if (typeof window === 'undefined') return undefined;\n return `${location.origin}${location.pathname}?${flag}=1`;\n}\n\nexport function BookingProvider({\n children,\n salonSlug,\n engineUrl,\n locale,\n successUrl,\n cancelUrl,\n accentGradient,\n formatPrice,\n onEvent,\n basePath,\n autoTriggers = true,\n honorUrlParams = true,\n}: BookingProviderProps) {\n const slug = useMemo(() => resolveSlug(salonSlug), [salonSlug]);\n const resolvedEngineUrl = useMemo(() => resolveEngine(engineUrl), [engineUrl]);\n const resolvedLocale = useMemo(() => resolveLocale(locale), [locale]);\n const resolvedSuccessUrl = useMemo(\n () => successUrl ?? defaultReturnUrl('booked'),\n [successUrl],\n );\n const resolvedCancelUrl = useMemo(\n () => cancelUrl ?? defaultReturnUrl('cancelled'),\n [cancelUrl],\n );\n\n const widgetRef = useRef<BookingWidgetHandle>(null);\n // pendingRef: undefined = no queued open. null = open without service.\n // string = open with that service id.\n const pendingRef = useRef<string | null | undefined>(undefined);\n const urlAutoOpenedRef = useRef(false);\n\n const [salon, setSalon] = useState<Record<string, unknown> | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n // ── Salon fetch ────────────────────────────────────────────────────────\n useEffect(() => {\n if (!slug) {\n console.error(\n '[@clicka/booking] BookingProvider has no salon slug. Pass `salonSlug` ' +\n 'or set NEXT_PUBLIC_SALON_SLUG / <meta name=\"clicka:salon\"> / ' +\n 'window.__CLICKA_SALON_SLUG.',\n );\n return;\n }\n let cancelled = false;\n const url = `${resolvedEngineUrl.replace(/\\/$/, '')}/api/public/v1/salons/${encodeURIComponent(slug)}`;\n fetch(url, { cache: 'no-store' })\n .then((r) => {\n if (!r.ok) throw new Error(`Salon fetch failed: HTTP ${r.status}`);\n return r.json();\n })\n .then((d: { salon?: Record<string, unknown> }) => {\n if (cancelled) return;\n if (!d.salon) throw new Error('Empty salon response');\n setSalon(d.salon);\n setError(null);\n })\n .catch((e: unknown) => {\n if (cancelled) return;\n const err = e instanceof Error ? e : new Error(String(e));\n console.error('[@clicka/booking] salon fetch failed:', err);\n setError(err);\n });\n return () => {\n cancelled = true;\n };\n }, [resolvedEngineUrl, slug]);\n\n // ── Public open/close ──────────────────────────────────────────────────\n const open = useCallback(\n (service?: string) => {\n if (widgetRef.current && salon) {\n widgetRef.current.open(service || undefined);\n } else {\n pendingRef.current = service ?? null;\n }\n },\n [salon],\n );\n\n const close = useCallback(() => widgetRef.current?.close(), []);\n\n // ── Flush pending open() when salon finishes loading ───────────────────\n useEffect(() => {\n if (salon && widgetRef.current && pendingRef.current !== undefined) {\n const s = pendingRef.current;\n pendingRef.current = undefined;\n widgetRef.current.open(s || undefined);\n }\n }, [salon]);\n\n // ── Document-level click delegation ────────────────────────────────────\n // Listens to multiple attribute names so existing sites can keep their\n // markup. Primary: [data-clicka-book]. Legacy: [data-book-service],\n // [data-book]. The attribute *value* (when not empty / 'true') is passed\n // as the service id; otherwise the modal opens without preselect.\n useEffect(() => {\n if (!autoTriggers || typeof document === 'undefined') return;\n const SELECTOR = '[data-clicka-book],[data-book-service],[data-book]';\n const handler = (ev: Event) => {\n const t = ev.target as Element | null;\n if (!t) return;\n const trigger = t.closest<HTMLElement>(SELECTOR);\n if (!trigger) return;\n ev.preventDefault();\n const raw =\n trigger.getAttribute('data-clicka-book') ??\n trigger.getAttribute('data-book-service') ??\n trigger.getAttribute('data-book') ??\n '';\n const service = raw && raw !== 'true' ? raw : undefined;\n open(service);\n };\n document.addEventListener('click', handler);\n return () => document.removeEventListener('click', handler);\n }, [autoTriggers, open]);\n\n // ── URL ?service=… / ?book=1 auto-open (once, on first salon load) ─────\n useEffect(() => {\n if (!honorUrlParams || !salon || urlAutoOpenedRef.current) return;\n if (typeof location === 'undefined') return;\n const params = new URLSearchParams(location.search);\n const initial = params.get('service');\n if (initial || params.has('book')) {\n urlAutoOpenedRef.current = true;\n open(initial || undefined);\n }\n }, [honorUrlParams, salon, open]);\n\n const value = useMemo<BookingContextValue>(\n () => ({ open, close, isReady: !!salon, error, salon }),\n [open, close, salon, error],\n );\n\n // Render the modal via portal into document.body so it escapes any\n // ancestor `transform`, `filter`, `perspective`, `contain`, or\n // `will-change: transform` — any of those create a containing block\n // for fixed-positioned descendants and would jail the modal inside\n // the consumer's component subtree instead of the viewport.\n const modalNode =\n salon && slug ? (\n <BookingWidget\n ref={widgetRef}\n slug={slug}\n salon={salon}\n engineUrl={resolvedEngineUrl}\n locale={resolvedLocale}\n successUrl={resolvedSuccessUrl}\n cancelUrl={resolvedCancelUrl}\n accentGradient={accentGradient}\n formatPrice={formatPrice}\n onEvent={onEvent}\n basePath={basePath}\n />\n ) : null;\n\n return (\n <BookingContext.Provider value={value}>\n {children}\n {modalNode && typeof document !== 'undefined'\n ? createPortal(modalNode, document.body)\n : modalNode}\n </BookingContext.Provider>\n );\n}\n","'use client';\n\nimport { useContext } from 'react';\nimport { BookingContext, type BookingContextValue } from './BookingProvider';\n\n/**\n * Access the booking modal from anywhere inside a `<BookingProvider>`.\n *\n * @throws if called outside a `<BookingProvider>` tree.\n */\nexport function useBooking(): BookingContextValue {\n const ctx = useContext(BookingContext);\n if (!ctx) {\n throw new Error(\n '[@clicka/booking] useBooking() must be called inside <BookingProvider>.',\n );\n }\n return ctx;\n}\n","'use client';\n\nimport React, { forwardRef } from 'react';\nimport { useBooking } from './useBooking';\n\nexport type BookingButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n /** Pre-select this service id when opening the modal. */\n service?: string;\n};\n\n/**\n * Drop-in button that opens the booking modal. Must be used inside a\n * `<BookingProvider>`. Accepts every native `<button>` prop so consumers\n * keep their own classes, styles, ARIA, etc.\n *\n * @example\n * <BookingButton>Reserve</BookingButton>\n * <BookingButton service=\"balayage\" className=\"btn btn_solid\">Book balayage</BookingButton>\n */\nexport const BookingButton = forwardRef<HTMLButtonElement, BookingButtonProps>(\n function BookingButton(\n { service, onClick, type = 'button', children, ...rest },\n ref,\n ) {\n const { open } = useBooking();\n return (\n <button\n ref={ref}\n type={type}\n onClick={(e) => {\n onClick?.(e);\n if (!e.defaultPrevented) open(service);\n }}\n {...rest}\n >\n {children}\n </button>\n );\n },\n);\n"]}
1
+ {"version":3,"sources":["../../../lib/salon-services.ts","../../../lib/salon-opening-hours.ts","../../../lib/booking-blocks.ts","../../../lib/tracking-events.ts","../../../components/booking/useBookingFlow.ts","../../../components/booking/BookingWidget.tsx","../../../components/booking/BookingProvider.tsx","../../../components/booking/useBooking.ts","../../../components/booking/BookingButton.tsx"],"names":["id","t","BookingWidget","useMemo","useRef","useState","useEffect","useCallback","jsx","forwardRef","BookingButton"],"mappings":"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","file":"index.js","sourcesContent":["function randomHex(bytes: number): string {\n const buf = new Uint8Array(bytes);\n globalThis.crypto.getRandomValues(buf);\n return Array.from(buf, b => b.toString(16).padStart(2, '0')).join('');\n}\n\nexport type PaymentType = 'none' | 'deposit' | 'full';\nexport type CancelPolicyAction = 'full_refund' | 'keep_deposit' | 'keep_full';\n\nexport type ServiceItem = {\n id?: string;\n name: string;\n nameEn?: string;\n description?: string;\n descriptionEn?: string;\n category?: string;\n price: number;\n duration_min: number;\n images?: string[];\n variants?: { label: string; price: number; duration?: number }[];\n assignedTeamMemberIds?: string[];\n payment_type?: PaymentType;\n deposit_amount?: number; // euros (e.g. 20 = €20)\n requires_confirmation?: boolean;\n cancel_policy_hours?: number; // hours before which free cancel is allowed\n cancel_policy_action?: CancelPolicyAction; // what happens after the deadline\n};\n\nexport type ParsedSalonService = {\n id: string;\n name: string;\n nameEn?: string;\n description?: string;\n descriptionEn?: string;\n category?: string;\n price?: number;\n duration: number;\n images?: string[];\n variants?: { label: string; price: number; duration?: number }[];\n assignedTeamMemberIds?: string[];\n payment_type?: PaymentType;\n deposit_amount?: number;\n requires_confirmation?: boolean;\n cancel_policy_hours?: number;\n cancel_policy_action?: CancelPolicyAction;\n};\n\nfunction pickFirstNonEmptyString(...values: unknown[]): string {\n for (const value of values) {\n const text = String(value ?? '').trim();\n if (text) return text;\n }\n return '';\n}\n\n/** Returns true for index-based IDs that are positionally unstable (svc-0, svc-1, svc-2-3, …). */\nfunction isUnstableId(id: string): boolean {\n return /^svc-\\d/.test(id);\n}\n\nfunction assignUniqueServiceId(candidate: string, usedIds: Set<string>): string {\n const trimmed = candidate.trim();\n // Keep the candidate if it exists, is not a positional svc-N id, and is unique.\n if (trimmed && !isUnstableId(trimmed) && !usedIds.has(trimmed)) {\n usedIds.add(trimmed);\n return trimmed;\n }\n // Generate a stable random ID (8 hex chars, same pattern as onboarding_code).\n let id = randomHex(4);\n while (usedIds.has(id)) id = randomHex(4);\n usedIds.add(id);\n return id;\n}\n\n/** Parse salon services JSON for public UI and admin (skips unnamed rows, guarantees unique ids). */\nexport function parseSalonServices(raw: unknown): ParsedSalonService[] {\n if (typeof raw === 'string') {\n try {\n raw = JSON.parse(raw) as unknown;\n } catch {\n return [];\n }\n }\n let items: unknown[] = [];\n if (Array.isArray(raw)) {\n items = raw;\n } else if (raw && typeof raw === 'object') {\n items = Object.values(raw as Record<string, unknown>);\n } else {\n return [];\n }\n\n const usedIds = new Set<string>();\n const out: ParsedSalonService[] = [];\n\n items.forEach((item, index) => {\n const row = item as Record<string, unknown>;\n const name = pickFirstNonEmptyString(row.name, row.service_name, row.serviceName, row.title);\n if (!name) return;\n\n const id = assignUniqueServiceId(String(row.id ?? ''), usedIds);\n const duration = Number(row.duration ?? row.duration_min ?? row.durationMin ?? 30) || 30;\n const priceRaw = row.price ?? row.service_price ?? row.servicePrice;\n const price = priceRaw != null ? Number(priceRaw) : undefined;\n const variants = Array.isArray(row.variants)\n ? (row.variants as unknown[])\n .map((variant): { label: string; price: number; duration?: number } | null => {\n if (!variant || typeof variant !== 'object') return null;\n const v = variant as Record<string, unknown>;\n const label = String(v.label ?? '').trim();\n if (!label) return null;\n const priceNum = Number(v.price ?? NaN);\n if (!Number.isFinite(priceNum)) return null;\n const durationNum = Number(v.duration ?? NaN);\n return {\n label,\n price: Math.max(0, priceNum),\n duration: Number.isFinite(durationNum) ? Math.max(5, Math.round(durationNum)) : undefined,\n };\n })\n .filter((variant): variant is { label: string; price: number; duration?: number } => variant !== null)\n : undefined;\n const images = Array.isArray(row.images)\n ? (row.images as unknown[])\n .map((image) => String(image ?? '').trim())\n .filter(Boolean)\n : undefined;\n const assignedTeamMemberIds = Array.isArray(row.assignedTeamMemberIds)\n ? [...new Set((row.assignedTeamMemberIds as unknown[])\n .map((id) => String(id ?? '').trim())\n .filter(Boolean))]\n : undefined;\n\n const paymentTypeRaw = String(row.payment_type ?? '');\n const paymentType: PaymentType | undefined = ['none', 'deposit', 'full'].includes(paymentTypeRaw)\n ? (paymentTypeRaw as PaymentType)\n : undefined;\n const depositAmountRaw = Number(row.deposit_amount ?? NaN);\n const depositAmount = Number.isFinite(depositAmountRaw) ? Math.max(0, depositAmountRaw) : undefined;\n\n const cancelPolicyHoursRaw = Number(row.cancel_policy_hours ?? NaN);\n const cancelPolicyHours = Number.isFinite(cancelPolicyHoursRaw) && cancelPolicyHoursRaw > 0\n ? cancelPolicyHoursRaw\n : undefined;\n const cancelPolicyActionRaw = String(row.cancel_policy_action ?? '');\n const cancelPolicyAction: CancelPolicyAction | undefined = (\n ['full_refund', 'keep_deposit', 'keep_full'] as CancelPolicyAction[]\n ).includes(cancelPolicyActionRaw as CancelPolicyAction)\n ? (cancelPolicyActionRaw as CancelPolicyAction)\n : undefined;\n\n out.push({\n id,\n name,\n nameEn: String(row.nameEn ?? '').trim() || undefined,\n description: String(row.description ?? '').trim() || undefined,\n descriptionEn: String(row.descriptionEn ?? '').trim() || undefined,\n category:\n pickFirstNonEmptyString(\n row.category,\n row.category_name,\n row.categoryName,\n row.service_category,\n row.serviceCategory,\n ) || undefined,\n price: price != null && Number.isFinite(price) ? price : undefined,\n duration,\n images,\n variants: variants && variants.length > 0 ? variants : undefined,\n ...(assignedTeamMemberIds && assignedTeamMemberIds.length > 0\n ? { assignedTeamMemberIds }\n : {}),\n ...(paymentType !== undefined ? { payment_type: paymentType } : {}),\n ...(depositAmount !== undefined ? { deposit_amount: depositAmount } : {}),\n ...(row.requires_confirmation === true ? { requires_confirmation: true } : {}),\n ...(cancelPolicyHours !== undefined ? { cancel_policy_hours: cancelPolicyHours } : {}),\n ...(cancelPolicyAction !== undefined ? { cancel_policy_action: cancelPolicyAction } : {}),\n });\n });\n\n return out;\n}\n\n/** Returns a copy of the service with name/description resolved for the given locale. */\nexport function localizeService<T extends { name: string; nameEn?: string; description?: string; descriptionEn?: string }>(\n service: T,\n locale: string,\n): T {\n if (locale !== 'en') return service;\n const name = service.nameEn?.trim() || service.name;\n const description = service.descriptionEn?.trim() || service.description;\n return { ...service, name, description };\n}\n\nexport function normalizeServices(raw: unknown): ServiceItem[] {\n return parseSalonServices(raw).map((s) => {\n const normalizedVariants = Array.isArray(s.variants)\n ? s.variants\n .map((variant) => ({\n label: String(variant.label ?? '').trim(),\n price: Math.max(0, Number(variant.price) || 0),\n duration:\n variant.duration != null && Number.isFinite(Number(variant.duration))\n ? Math.max(5, Math.round(Number(variant.duration)))\n : undefined,\n }))\n .filter((variant) => variant.label.length > 0)\n : [];\n\n const basePrice =\n normalizedVariants.length > 0\n ? normalizedVariants[0]!.price\n : Math.max(0, Number(s.price ?? 0) || 0);\n const baseDuration =\n normalizedVariants.length > 0\n ? Math.max(5, Number(normalizedVariants[0]!.duration ?? s.duration ?? 30) || 30)\n : Math.max(5, s.duration);\n\n return {\n id: s.id,\n name: s.name,\n ...(s.nameEn ? { nameEn: s.nameEn } : {}),\n description: s.description,\n ...(s.descriptionEn ? { descriptionEn: s.descriptionEn } : {}),\n category: s.category,\n price: basePrice,\n duration_min: baseDuration,\n ...(Array.isArray(s.images) && s.images.length > 0 ? { images: s.images } : {}),\n ...(normalizedVariants.length > 0 ? { variants: normalizedVariants } : {}),\n ...(Array.isArray(s.assignedTeamMemberIds) && s.assignedTeamMemberIds.length > 0\n ? { assignedTeamMemberIds: s.assignedTeamMemberIds }\n : {}),\n ...(['none', 'deposit', 'full'].includes(String((s as unknown as ServiceItem).payment_type ?? ''))\n ? { payment_type: (s as unknown as ServiceItem).payment_type }\n : {}),\n ...((s as unknown as ServiceItem).deposit_amount != null && Number.isFinite(Number((s as unknown as ServiceItem).deposit_amount))\n ? { deposit_amount: Math.max(0, Number((s as unknown as ServiceItem).deposit_amount)) }\n : {}),\n ...((s as unknown as ServiceItem).requires_confirmation === true ? { requires_confirmation: true } : {}),\n ...(s.cancel_policy_hours !== undefined ? { cancel_policy_hours: s.cancel_policy_hours } : {}),\n ...(s.cancel_policy_action !== undefined ? { cancel_policy_action: s.cancel_policy_action } : {}),\n };\n });\n}\n","/** Работно време в стил BOOKA уеб: ключове Monday..Sunday, стойност null = затворено. */\n\nconst DAY_NAMES_EN = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] as const;\n\nconst CLICKA_TO_EN: Record<string, (typeof DAY_NAMES_EN)[number]> = {\n monday: 'Monday',\n tuesday: 'Tuesday',\n wednesday: 'Wednesday',\n thursday: 'Thursday',\n friday: 'Friday',\n saturday: 'Saturday',\n sunday: 'Sunday',\n};\n\nexport type OpeningDayRecord = Record<string, { open: string; close: string } | null>;\n\nconst DEFAULT_OPENING_HOURS: Record<(typeof DAY_NAMES_EN)[number], { open: string; close: string }> = {\n Monday: { open: '09:00', close: '18:00' },\n Tuesday: { open: '09:00', close: '18:00' },\n Wednesday: { open: '09:00', close: '18:00' },\n Thursday: { open: '09:00', close: '18:00' },\n Friday: { open: '09:00', close: '18:00' },\n Saturday: { open: '10:00', close: '16:00' },\n Sunday: { open: '10:00', close: '16:00' },\n};\n\n/** Clicka `working_hours` (monday..sunday) + опционален `opening_hours` JSON от Neon → Monday..Sunday. */\nexport function mergeOpeningHours(\n workingHours: Record<string, { open?: string; close?: string; closed?: boolean }> | null | undefined,\n openingHoursOverride: unknown\n): OpeningDayRecord {\n const out: OpeningDayRecord = {};\n for (const d of DAY_NAMES_EN) out[d] = null;\n\n const fromOverride = normalizeOpeningOverride(openingHoursOverride);\n if (fromOverride) {\n for (const d of DAY_NAMES_EN) {\n if (fromOverride[d] !== undefined) out[d] = fromOverride[d];\n }\n return out;\n }\n\n if (workingHours && typeof workingHours === 'object') {\n for (const [k, v] of Object.entries(workingHours)) {\n const en = CLICKA_TO_EN[k.toLowerCase()];\n if (!en) continue;\n if (!v || v.closed || !v.open || !v.close) out[en] = null;\n else out[en] = { open: v.open, close: v.close };\n }\n }\n return out;\n}\n\nfunction normalizeOpeningOverride(raw: unknown): OpeningDayRecord | null {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return null;\n const o = raw as Record<string, unknown>;\n const out: OpeningDayRecord = {};\n let any = false;\n for (const d of DAY_NAMES_EN) {\n const v = o[d];\n if (v && typeof v === 'object' && !Array.isArray(v)) {\n const open = String((v as { open?: unknown }).open ?? '');\n const close = String((v as { close?: unknown }).close ?? '');\n if (open && close) {\n out[d] = { open, close };\n any = true;\n } else {\n out[d] = null;\n }\n }\n }\n return any ? out : null;\n}\n\nexport function getCurrentStatusString(openingHours: OpeningDayRecord): string {\n const hasAny = Object.keys(openingHours).some((k) => openingHours[k] != null);\n const now = new Date();\n const dayIndex = (now.getDay() + 6) % 7;\n const dayName = DAY_NAMES_EN[dayIndex];\n const hours = hasAny ? (openingHours[dayName] ?? null) : (DEFAULT_OPENING_HOURS[dayName] ?? null);\n if (!hours) return 'Затворено';\n const [openH, openM] = hours.open.split(':').map(Number);\n const [closeH, closeM] = hours.close.split(':').map(Number);\n const nowMins = now.getHours() * 60 + now.getMinutes();\n const openMins = openH * 60 + openM;\n const closeMins = closeH * 60 + closeM;\n const formatTime = (h: number, m: number) =>\n `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}\\u00a0ч`;\n if (nowMins < openMins) return `Затворено - отваря в ${formatTime(openH, openM)}`;\n if (nowMins >= closeMins) return `Затворено - отваря утре в ${formatTime(openH, openM)}`;\n return `Отворено - затваря в ${formatTime(closeH, closeM)}`;\n}\n\nexport function getEffectiveHours(\n openingHours: OpeningDayRecord,\n dayName: (typeof DAY_NAMES_EN)[number]\n): { open: string; close: string } | null {\n const hasAnyHours = Object.keys(openingHours).some((k) => openingHours[k] != null);\n if (hasAnyHours) {\n return openingHours[dayName] ?? null;\n }\n return DEFAULT_OPENING_HOURS[dayName] ?? null;\n}\n\nexport const DAY_LABELS_BG: Record<string, string> = {\n Monday: 'Понеделник',\n Tuesday: 'Вторник',\n Wednesday: 'Сряда',\n Thursday: 'Четвъртък',\n Friday: 'Петък',\n Saturday: 'Събота',\n Sunday: 'Неделя',\n};\n\nexport { DAY_NAMES_EN };\n","export type BookingBlock = {\n date: string; // YYYY-MM-DD\n allDay: boolean;\n start?: string; // HH:mm\n end?: string; // HH:mm\n note?: string;\n};\n\nfunction isIsoDate(value: string): boolean {\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(value);\n}\n\nfunction isTime(value: string): boolean {\n return /^([01]\\d|2[0-3]):[0-5]\\d$/.test(value);\n}\n\nfunction toMinutes(value: string): number {\n const [h, m] = value.split(':').map(Number);\n return h * 60 + m;\n}\n\nexport function normalizeBookingBlocks(raw: unknown): BookingBlock[] {\n if (!Array.isArray(raw)) return [];\n const out: BookingBlock[] = [];\n for (const item of raw) {\n if (!item || typeof item !== 'object') continue;\n const row = item as Record<string, unknown>;\n const date = String(row.date ?? '').trim();\n if (!isIsoDate(date)) continue;\n const allDay = row.allDay === true;\n const start = String(row.start ?? '').trim();\n const end = String(row.end ?? '').trim();\n const note = String(row.note ?? '').trim();\n if (!allDay) {\n if (!isTime(start) || !isTime(end)) continue;\n if (toMinutes(end) <= toMinutes(start)) continue;\n out.push({ date, allDay: false, start, end, ...(note ? { note } : {}) });\n continue;\n }\n out.push({ date, allDay: true, ...(note ? { note } : {}) });\n }\n out.sort((a, b) => `${a.date}-${a.start ?? ''}`.localeCompare(`${b.date}-${b.start ?? ''}`));\n return out;\n}\n\nexport function isDateBlockedAllDay(blocks: BookingBlock[], date: string): boolean {\n return blocks.some((b) => b.date === date && b.allDay);\n}\n\nexport function isBlockedForStartTime(\n blocks: BookingBlock[],\n date: string,\n startTime: string,\n durationMin: number\n): boolean {\n if (isDateBlockedAllDay(blocks, date)) return true;\n if (!isTime(startTime)) return false;\n const start = toMinutes(startTime);\n const end = start + Math.max(1, durationMin);\n for (const block of blocks) {\n if (block.date !== date || block.allDay || !block.start || !block.end) continue;\n const blockStart = toMinutes(block.start);\n const blockEnd = toMinutes(block.end);\n const overlaps = start < blockEnd && end > blockStart;\n if (overlaps) return true;\n }\n return false;\n}\n\n","declare global {\n interface Window {\n fbq?: (...args: unknown[]) => void;\n gtag?: (...args: unknown[]) => void;\n dataLayer?: unknown[];\n }\n}\n\nexport type BookingEventData = {\n serviceName?: string;\n value?: number; // EUR\n currency?: string;\n};\n\n// Session key — resets on new browser session (tab close)\nconst BOOKING_STARTED_KEY = 'tracking_booking_started';\n\nexport function trackPageView() {\n window.fbq?.('track', 'PageView');\n window.gtag?.('event', 'page_view');\n}\n\nexport function trackViewContent() {\n window.fbq?.('track', 'ViewContent');\n}\n\nexport function trackLead() {\n window.fbq?.('track', 'Lead');\n window.gtag?.('event', 'generate_lead');\n}\n\nexport function trackSignUp() {\n window.fbq?.('track', 'CompleteRegistration');\n window.gtag?.('event', 'sign_up');\n}\n\n/**\n * Fires booking_started only once per browser session.\n * Resets after a successful booking_completed so a new attempt in the same\n * tab counts again — but 5 modal opens without booking = 1 event.\n */\nexport function trackBookingStarted() {\n if (typeof sessionStorage === 'undefined') return;\n if (sessionStorage.getItem(BOOKING_STARTED_KEY)) return;\n sessionStorage.setItem(BOOKING_STARTED_KEY, '1');\n window.gtag?.('event', 'booking_started');\n}\n\nexport function trackBookingCompleted({ serviceName, value, currency = 'EUR' }: BookingEventData = {}) {\n // Reset so a second booking in the same session fires booking_started again\n if (typeof sessionStorage !== 'undefined') {\n sessionStorage.removeItem(BOOKING_STARTED_KEY);\n }\n\n const metaParams: Record<string, unknown> = {};\n if (value != null && value > 0) {\n metaParams.value = value;\n metaParams.currency = currency;\n }\n if (serviceName) metaParams.content_name = serviceName;\n\n // Standard Meta event — агенции, оптимизиращи по стандартни Facebook события\n window.fbq?.('track', 'Schedule', metaParams);\n // Custom Meta event — агенции с custom конверсии в Events Manager\n window.fbq?.('trackCustom', 'BookingCompleted', { ...metaParams, service_name: serviceName });\n\n const ga4Params: Record<string, unknown> = {};\n if (value != null && value > 0) {\n ga4Params.value = value;\n ga4Params.currency = currency;\n }\n if (serviceName) ga4Params.service_name = serviceName;\n\n window.gtag?.('event', 'booking_completed', ga4Params);\n}\n\n/**\n * Fires a test custom event visible in Meta Events Manager.\n * Use from the admin Marketing tab to verify the pixel is loaded.\n */\nexport function trackMetaTest() {\n if (!window.fbq) return false;\n window.fbq('trackCustom', 'EngineTest', { source: 'admin_test' });\n return true;\n}\n","'use client';\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { isDateBlockedAllDay, isBlockedForStartTime } from '@/lib/booking-blocks';\nimport { trackBookingStarted, trackBookingCompleted } from '@/lib/tracking-events';\nimport { useT } from '@/lib/i18n-react';\nimport type {\n UseBookingFlowOptions,\n UseBookingFlowReturn,\n BookingServiceItem,\n BookingSuccessDetails,\n OccupiedSlot,\n PublicStaffMember,\n} from './types';\n\nconst DAY_KEYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] as const;\n\nfunction pad(n: number): string {\n return String(n).padStart(2, '0');\n}\n\nfunction toLocalISODate(d: Date): string {\n return new Date(d.getTime() - d.getTimezoneOffset() * 60000).toISOString().split('T')[0]!;\n}\n\nexport function useBookingFlow({\n slug,\n openingHours,\n bookingBlocks,\n slotIntervalMin,\n bookingAdvanceDays,\n bookingServices,\n engineUrl = '',\n apiKey,\n successUrl,\n cancelUrl,\n locale = 'bg-BG',\n onEvent,\n}: UseBookingFlowOptions): UseBookingFlowReturn {\n const t = useT();\n const api = engineUrl.replace(/\\/$/, '');\n const slugPath = `/api/public/v1/salons/${encodeURIComponent(slug)}`;\n const requestHeaders = useMemo(\n () => ({\n 'Content-Type': 'application/json',\n ...(apiKey ? { 'X-API-Key': apiKey } : {}),\n }),\n [apiKey],\n );\n\n // ── Modal visibility ─────────────────────────────────────────────────\n const [bookingOpen, setBookingOpen] = useState(false);\n\n // ── Service selection ────────────────────────────────────────────────\n const [selectedServiceIdxs, setSelectedServiceIdxs] = useState<number[]>([]);\n\n // ── Date / time ──────────────────────────────────────────────────────\n const [selectedDate, setSelectedDate] = useState('');\n const [selectedTime, setSelectedTime] = useState('');\n const [occupiedByDate, setOccupiedByDate] = useState<Record<string, OccupiedSlot[]>>({});\n const [minDate, setMinDate] = useState('');\n const [maxDate, setMaxDate] = useState('');\n\n // ── Contact fields ───────────────────────────────────────────────────\n const [clientName, setClientName] = useState('');\n const [clientPhone, setClientPhone] = useState('');\n const [clientEmail, setClientEmail] = useState('');\n const [notes, setNotes] = useState('');\n\n // ── Staff (TEAM plan) ────────────────────────────────────────────────\n const [staffMembers, setStaffMembers] = useState<PublicStaffMember[]>([]);\n const [selectedStaffMemberId, setSelectedStaffMemberIdState] = useState<string | null>(null);\n const staffFetchedRef = useRef(false);\n\n // ── Submission ───────────────────────────────────────────────────────\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [bookingError, setBookingError] = useState('');\n const [bookingSuccess, setBookingSuccess] = useState('');\n const [bookingSuccessDetails, setBookingSuccessDetails] = useState<BookingSuccessDetails | null>(null);\n\n // ── Compute min/max dates on mount ──────────────────────────────────\n useEffect(() => {\n const today = new Date();\n setMinDate(toLocalISODate(today));\n const max = new Date(today);\n max.setDate(today.getDate() + Math.max(1, bookingAdvanceDays));\n setMaxDate(toLocalISODate(max));\n }, [bookingAdvanceDays]);\n\n // ── Fetch staff members once when modal first opens ──────────────────\n useEffect(() => {\n if (!bookingOpen || staffFetchedRef.current) return;\n staffFetchedRef.current = true;\n fetch(`${api}${slugPath}/staff`, {\n cache: 'no-store',\n headers: requestHeaders,\n })\n .then((r) => r.json())\n .then((d: { staff?: PublicStaffMember[] }) => {\n if (Array.isArray(d.staff)) setStaffMembers(d.staff);\n })\n .catch(() => {});\n }, [api, bookingOpen, requestHeaders, slugPath]);\n\n // ── Fetch occupied slots whenever date or staff changes ──────────────\n useEffect(() => {\n if (!selectedDate) return;\n let cancelled = false;\n const staffParam = selectedStaffMemberId\n ? `&staffMemberId=${encodeURIComponent(selectedStaffMemberId)}`\n : '';\n fetch(\n `${api}${slugPath}/slots?date=${encodeURIComponent(selectedDate)}${staffParam}`,\n { cache: 'no-store', headers: requestHeaders },\n )\n .then((r) => r.json())\n .then((d: { occupied?: Array<{ time?: string; duration?: number }> }) => {\n if (cancelled || !Array.isArray(d.occupied)) return;\n const slots: OccupiedSlot[] = d.occupied\n .map((x) => ({\n time: String(x?.time ?? ''),\n duration: Math.max(5, Number(x?.duration ?? 30) || 30),\n }))\n .filter((x) => x.time.length >= 4);\n const cacheKey = selectedStaffMemberId\n ? `${selectedDate}:${selectedStaffMemberId}`\n : selectedDate;\n if (!cancelled) setOccupiedByDate((prev) => ({ ...prev, [cacheKey]: slots }));\n })\n .catch(() => {});\n return () => { cancelled = true; };\n }, [api, requestHeaders, selectedDate, selectedStaffMemberId, slugPath]);\n\n // ── Derived: selected service objects ────────────────────────────────\n const selectedServices = useMemo<BookingServiceItem[]>(\n () =>\n selectedServiceIdxs\n .map((i) => bookingServices[i])\n .filter((s): s is BookingServiceItem => Boolean(s)),\n [selectedServiceIdxs, bookingServices],\n );\n\n const totalDuration = useMemo(\n () => selectedServices.reduce((sum, s) => sum + (Number(s.duration) || 0), 0),\n [selectedServices],\n );\n\n const totalPrice = useMemo(\n () => selectedServices.reduce((sum, s) => sum + (Number(s.price) || 0), 0),\n [selectedServices],\n );\n\n // ── Slot calculation ─────────────────────────────────────────────────\n const slotsForDate = useCallback(\n (date: string, durationMin: number): string[] | 'closed' | null => {\n if (!date) return null;\n const dayKey = DAY_KEYS[new Date(`${date}T12:00:00`).getDay()];\n const h = openingHours[dayKey] as { open?: string; close?: string } | null | undefined;\n if (!h?.open || !h?.close) return 'closed';\n if (isDateBlockedAllDay(bookingBlocks, date)) return 'closed';\n\n const dur = Math.max(5, durationMin || 30);\n const cacheKey = selectedStaffMemberId\n ? `${date}:${selectedStaffMemberId}`\n : date;\n const occupied = occupiedByDate[cacheKey] ?? [];\n\n const [oh = 0, om = 0] = h.open.split(':').map(Number);\n const [ch = 0, cm = 0] = h.close.split(':').map(Number);\n const start = oh * 60 + om;\n const latestStart = ch * 60 + cm - dur;\n const slots: string[] = [];\n\n for (let t = start; t <= latestStart; t += slotIntervalMin) {\n const slot = `${pad(Math.floor(t / 60))}:${pad(t % 60)}`;\n const slotEnd = t + dur;\n const overlaps = occupied.some(({ time, duration: d }) => {\n const [bh = 0, bm = 0] = time.split(':').map(Number);\n const existStart = bh * 60 + bm;\n const existEnd = existStart + Math.max(5, d);\n return existStart < slotEnd && existEnd > t;\n });\n if (!overlaps && !isBlockedForStartTime(bookingBlocks, date, slot, dur)) {\n slots.push(slot);\n }\n }\n return slots;\n },\n [openingHours, bookingBlocks, occupiedByDate, selectedStaffMemberId, slotIntervalMin],\n );\n\n const timeSlots = useMemo<string[] | 'closed' | null>(\n () =>\n selectedServiceIdxs.length === 0\n ? null\n : slotsForDate(selectedDate, totalDuration || 30),\n [selectedServiceIdxs.length, slotsForDate, selectedDate, totalDuration],\n );\n\n // ── Actions ──────────────────────────────────────────────────────────\n const open = useCallback((serviceId?: string) => {\n setBookingError('');\n setBookingSuccess('');\n setBookingSuccessDetails(null);\n if (serviceId) {\n const idx = bookingServices.findIndex((s) => s.id === serviceId);\n setSelectedServiceIdxs(idx >= 0 ? [idx] : []);\n } else {\n setSelectedServiceIdxs([]);\n }\n setSelectedDate('');\n setSelectedTime('');\n setClientName('');\n setClientPhone('');\n setClientEmail('');\n setNotes('');\n setBookingOpen(true);\n if (onEvent) onEvent('booking_started');\n else trackBookingStarted();\n }, [bookingServices, onEvent]);\n\n const close = useCallback(() => {\n setBookingOpen(false);\n setBookingSuccessDetails(null);\n setSelectedStaffMemberIdState(null);\n setSelectedDate('');\n setSelectedTime('');\n }, []);\n\n const toggleService = useCallback((idx: number) => {\n setSelectedServiceIdxs((prev) => {\n const has = prev.includes(idx);\n return has ? prev.filter((x) => x !== idx) : [...prev, idx];\n });\n setSelectedTime('');\n }, []);\n\n const setDate = useCallback((d: string) => {\n setSelectedDate(d);\n setSelectedTime('');\n }, []);\n\n const setStaffMemberId = useCallback((id: string) => {\n setSelectedStaffMemberIdState(id);\n setSelectedDate('');\n setSelectedTime('');\n }, []);\n\n const markSlotOccupied = useCallback((date: string, time: string, duration: number) => {\n if (!date || !time) return;\n const dur = Math.max(5, Number(duration) || 30);\n setOccupiedByDate((prev) => {\n const day = prev[date] ?? [];\n if (day.some((s) => s.time === time)) return prev;\n return { ...prev, [date]: [...day, { time, duration: dur }] };\n });\n }, []);\n\n const submit = useCallback(async (e: React.FormEvent) => {\n e.preventDefault();\n setBookingError('');\n setBookingSuccess('');\n\n if (selectedServices.length === 0) { setBookingError(t('booking.errors.noService')); return; }\n if (!clientName.trim()) { setBookingError(t('booking.errors.noName')); return; }\n if (!clientPhone.trim()) { setBookingError(t('booking.errors.noPhone')); return; }\n if (!clientEmail.trim()) { setBookingError(t('booking.errors.noEmail')); return; }\n if (!selectedDate) { setBookingError(t('booking.errors.noDate')); return; }\n if (!selectedTime) { setBookingError(t('booking.errors.noTime')); return; }\n\n const serviceName = selectedServices.map((s) => s.name).join(' + ');\n const duration = totalDuration || 30;\n const firstSvc = selectedServices[0];\n const paymentType = firstSvc?.payment_type ?? 'none';\n const depositAmt = firstSvc?.deposit_amount ?? 0;\n const amountEuros =\n paymentType === 'deposit' ? depositAmt :\n paymentType === 'full' ? (totalPrice ?? 0) : 0;\n const requiresPayment = paymentType !== 'none' && amountEuros > 0;\n\n setIsSubmitting(true);\n try {\n const res = await fetch(`${api}${slugPath}/bookings`, {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify({\n clientName: clientName.trim(),\n clientPhone: clientPhone.trim(),\n clientEmail: clientEmail.trim().toLowerCase(),\n serviceName,\n servicePrice: totalPrice,\n serviceDuration: duration,\n date: selectedDate,\n time: selectedTime,\n notes: notes.trim() || undefined,\n requiresPayment,\n staffMemberId: selectedStaffMemberId ?? undefined,\n }),\n });\n\n const json = (await res.json().catch(() => ({}))) as {\n error?: string; bookingId?: string; id?: string;\n };\n if (!res.ok) {\n throw new Error(\n json.error ??\n (res.status === 500\n ? t('booking.errors.saveFailed')\n : t('booking.errors.httpError', { status: res.status })),\n );\n }\n\n // Stripe Checkout redirect for paid bookings\n const bookingId = json.bookingId ?? json.id;\n if (requiresPayment && bookingId) {\n const payRes = await fetch(`${api}${slugPath}/booking-checkout`, {\n method: 'POST',\n headers: requestHeaders,\n body: JSON.stringify({\n bookingId,\n salonSlug: slug,\n serviceName,\n amountEuros,\n paymentType,\n successUrl,\n cancelUrl,\n }),\n });\n const payJson = (await payRes.json().catch(() => ({}))) as {\n checkoutUrl?: string; error?: string;\n };\n if (!payRes.ok || !payJson.checkoutUrl) {\n throw new Error(payJson.error ?? t('booking.errors.paymentFailed'));\n }\n window.location.href = payJson.checkoutUrl;\n return;\n }\n\n const dateLabel = new Date(`${selectedDate}T12:00:00`).toLocaleDateString(locale, {\n weekday: 'long', day: 'numeric', month: 'long',\n });\n markSlotOccupied(selectedDate, selectedTime, duration);\n setBookingSuccessDetails({ serviceName, dateLabel, time: selectedTime });\n setBookingSuccess(`${serviceName} — ${dateLabel} ${selectedTime}`);\n const eventPayload = {\n serviceName,\n value: totalPrice > 0 ? totalPrice : undefined,\n currency: 'EUR',\n };\n if (onEvent) onEvent('booking_completed', eventPayload);\n else trackBookingCompleted(eventPayload);\n } catch (err) {\n setBookingError(err instanceof Error ? err.message : t('booking.errors.generic'));\n } finally {\n setIsSubmitting(false);\n }\n }, [\n api, cancelUrl, clientEmail, clientName, clientPhone, locale, markSlotOccupied, notes,\n onEvent, requestHeaders, selectedDate, selectedServices, selectedStaffMemberId, selectedTime,\n slug, slugPath, successUrl, t, totalDuration, totalPrice,\n ]);\n\n return {\n bookingOpen, open, close,\n selectedServiceIdxs, toggleService, totalDuration, totalPrice, selectedServices,\n selectedDate, setDate,\n selectedTime, setTime: setSelectedTime,\n timeSlots, minDate, maxDate,\n clientName, setClientName,\n clientPhone, setClientPhone,\n clientEmail, setClientEmail,\n notes, setNotes,\n staffMembers, selectedStaffMemberId, setStaffMemberId,\n isSubmitting, bookingError, bookingSuccess, bookingSuccessDetails,\n submit,\n };\n}\n","'use client';\n\nimport {\n forwardRef,\n lazy,\n Suspense,\n useImperativeHandle,\n useMemo,\n} from 'react';\nimport { parseSalonServices, localizeService } from '@/lib/salon-services';\nimport {\n enrichServiceCategories,\n buildServiceCategoryTabs,\n} from '@/lib/salon-service-categories';\nimport { mergeOpeningHours } from '@/lib/salon-opening-hours';\nimport { normalizeBookingBlocks } from '@/lib/booking-blocks';\nimport type { BookingCatalogService } from '@/lib/booking-modal-catalog';\nimport { useBookingFlow } from './useBookingFlow';\nimport type { BookingServiceItem, BookingWidgetHandle, BookingWidgetProps } from './types';\nimport { I18nProvider } from '@/lib/i18n-react';\nimport { normalizeLocale } from '@/lib/i18n';\n\nconst SalonBookingModal = lazy(() =>\n import('@/components/salon/SalonBookingModal').then((m) => ({ default: m.SalonBookingModal })),\n);\n\n// ── Inner component ────────────────────────────────────────────────────────────\n// Must live *inside* I18nProvider so that useBookingFlow → useT() reads the\n// correct locale. If useBookingFlow were called in the outer BookingWidget,\n// it would be outside the provider and always get the 'bg' default.\n\ntype InnerProps = {\n forwardedRef: React.Ref<BookingWidgetHandle>;\n slug: string;\n openingHours: ReturnType<typeof mergeOpeningHours>;\n bookingBlocks: ReturnType<typeof normalizeBookingBlocks>;\n slotIntervalMin: number;\n bookingAdvanceDays: number;\n bookingServices: BookingServiceItem[];\n serviceCatalog: BookingCatalogService[];\n categoryTabs: ReturnType<typeof buildServiceCategoryTabs>;\n engineUrl: string;\n apiKey?: string;\n primaryColor: string;\n accentGradient?: string;\n successUrl?: string;\n cancelUrl?: string;\n locale: string;\n formatPrice?: (amount: number) => string;\n onEvent?: (\n name: 'booking_started' | 'booking_completed',\n payload?: { serviceName?: string; value?: number; currency?: string },\n ) => void;\n salonName: string;\n basePath: string;\n};\n\nfunction BookingWidgetInner({\n forwardedRef,\n slug,\n openingHours,\n bookingBlocks,\n slotIntervalMin,\n bookingAdvanceDays,\n bookingServices,\n serviceCatalog,\n categoryTabs,\n engineUrl,\n apiKey,\n primaryColor,\n accentGradient,\n successUrl,\n cancelUrl,\n locale,\n formatPrice,\n onEvent,\n salonName,\n basePath,\n}: InnerProps) {\n const flow = useBookingFlow({\n slug,\n openingHours,\n bookingBlocks,\n slotIntervalMin,\n bookingAdvanceDays,\n bookingServices,\n engineUrl,\n apiKey,\n successUrl,\n cancelUrl,\n locale,\n onEvent,\n });\n\n useImperativeHandle(forwardedRef, () => ({\n open: (serviceId?: string) => flow.open(serviceId),\n close: () => flow.close(),\n }), [flow.open, flow.close]);\n\n const firstSelected = flow.selectedServices[0];\n\n return (\n <Suspense fallback={null}>\n <SalonBookingModal\n open={flow.bookingOpen}\n primaryColor={primaryColor}\n accentGradient={accentGradient}\n locale={locale}\n formatPrice={formatPrice}\n serviceCatalog={serviceCatalog}\n categoryTabs={categoryTabs}\n services={bookingServices}\n selectedServiceIdxs={flow.selectedServiceIdxs}\n selectedDate={flow.selectedDate}\n selectedTime={flow.selectedTime}\n totalDuration={flow.totalDuration}\n totalPrice={flow.totalPrice}\n clientName={flow.clientName}\n clientPhone={flow.clientPhone}\n clientEmail={flow.clientEmail}\n notes={flow.notes}\n salonName={salonName}\n termsHref={`${basePath}/terms`}\n privacyHref={`${basePath}/privacy`}\n minDate={flow.minDate}\n maxDate={flow.maxDate}\n timeSlots={flow.timeSlots}\n paymentType={firstSelected?.payment_type ?? 'none'}\n depositAmount={firstSelected?.deposit_amount}\n cancelPolicyHours={firstSelected?.cancel_policy_hours}\n cancelPolicyAction={firstSelected?.cancel_policy_action}\n isSubmitting={flow.isSubmitting}\n bookingError={flow.bookingError}\n bookingSuccess={flow.bookingSuccess}\n bookingSuccessDetails={flow.bookingSuccessDetails}\n staffMembers={flow.staffMembers}\n selectedStaffMemberId={flow.selectedStaffMemberId}\n onClose={flow.close}\n onToggleService={flow.toggleService}\n onDateChange={flow.setDate}\n onTimeChange={flow.setTime}\n onClientNameChange={flow.setClientName}\n onClientPhoneChange={flow.setClientPhone}\n onClientEmailChange={flow.setClientEmail}\n onNotesChange={flow.setNotes}\n onStaffMemberChange={flow.setStaffMemberId}\n onSubmit={flow.submit}\n />\n </Suspense>\n );\n}\n\n// ── Public component ───────────────────────────────────────────────────────────\n\nexport const BookingWidget = forwardRef<BookingWidgetHandle, BookingWidgetProps>(\n function BookingWidget({ slug, salon, openingHours: openingHoursProp, bookingBlocks: blocksProp, basePath = '', engineUrl = '', apiKey, accentGradient, successUrl, cancelUrl, locale: localeProp, formatPrice, onEvent }, ref) {\n\n // ── Opening hours ──────────────────────────────────────────────────\n const openingHours = useMemo(\n () => mergeOpeningHours(\n salon.working_hours as Record<string, { open?: string; close?: string; closed?: boolean }> | undefined,\n salon.opening_hours,\n ),\n [salon.working_hours, salon.opening_hours],\n );\n\n const resolvedHours = openingHoursProp ?? openingHours;\n const resolvedBlocks = blocksProp ?? normalizeBookingBlocks(\n salon.opening_hours && typeof salon.opening_hours === 'object'\n ? (salon.opening_hours as Record<string, unknown>).booking_blocks\n : null,\n );\n\n // ── Slot config from salon settings ───────────────────────────────\n const slotIntervalMin = useMemo((): number => {\n const oh = salon.opening_hours;\n if (oh && typeof oh === 'object') {\n const v = Number((oh as Record<string, unknown>).slot_interval_min);\n if ([15, 20, 30, 45, 60].includes(v)) return v;\n }\n return 30;\n }, [salon.opening_hours]);\n\n const bookingAdvanceDays = useMemo((): number => {\n const oh = salon.opening_hours;\n if (oh && typeof oh === 'object') {\n const v = Number((oh as Record<string, unknown>).booking_advance_days);\n if (Number.isFinite(v) && v >= 1) return Math.round(v);\n }\n return 60;\n }, [salon.opening_hours]);\n\n // ── Locale ────────────────────────────────────────────────────────\n const providerLocale = normalizeLocale(\n localeProp ?? (typeof salon.language === 'string' ? salon.language : 'bg'),\n );\n const resolvedLocale = localeProp ?? (providerLocale === 'en' ? 'en-US' : 'bg-BG');\n\n // ── Services processing ────────────────────────────────────────────\n const serviceCatalog = useMemo(\n () => enrichServiceCategories(\n parseSalonServices(salon.services).map((s) => localizeService(s, providerLocale))\n ) as BookingCatalogService[],\n [salon.services, providerLocale],\n );\n\n const categoryTabs = useMemo(\n () => buildServiceCategoryTabs(serviceCatalog),\n [serviceCatalog],\n );\n\n const bookingServices = useMemo<BookingServiceItem[]>(() => {\n const out: BookingServiceItem[] = [];\n for (const svc of serviceCatalog) {\n const variants = Array.isArray(svc.variants) ? svc.variants : [];\n if (variants.length === 0) {\n out.push(svc as unknown as BookingServiceItem);\n continue;\n }\n for (const v of variants) {\n out.push({\n ...(svc as unknown as BookingServiceItem),\n id: `${svc.id}::${v.label}`,\n name: `${svc.name} – ${v.label}`,\n price: Number(v.price ?? svc.price ?? 0) || 0,\n duration: Math.max(5, Number(v.duration ?? svc.duration ?? 30) || 30),\n variants: undefined,\n });\n }\n }\n return out;\n }, [serviceCatalog]);\n\n // ── Derived display props ─────────────────────────────────────────\n const primaryColor = typeof salon.primary_color === 'string' && salon.primary_color\n ? salon.primary_color\n : '#5B21B6';\n\n return (\n <I18nProvider locale={providerLocale}>\n <BookingWidgetInner\n forwardedRef={ref}\n slug={slug}\n openingHours={resolvedHours}\n bookingBlocks={resolvedBlocks}\n slotIntervalMin={slotIntervalMin}\n bookingAdvanceDays={bookingAdvanceDays}\n bookingServices={bookingServices}\n serviceCatalog={serviceCatalog}\n categoryTabs={categoryTabs}\n engineUrl={engineUrl}\n apiKey={apiKey}\n primaryColor={primaryColor}\n accentGradient={accentGradient}\n successUrl={successUrl}\n cancelUrl={cancelUrl}\n locale={resolvedLocale}\n formatPrice={formatPrice}\n onEvent={onEvent}\n salonName={String(salon.name ?? '')}\n basePath={basePath}\n />\n </I18nProvider>\n );\n },\n);\n","'use client';\n\nimport React, {\n createContext,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createPortal } from 'react-dom';\nimport { BookingWidget } from './BookingWidget';\nimport type { BookingWidgetHandle } from './types';\n\nexport type BookingContextValue = {\n /**\n * Open the booking modal. Pass a service id to pre-select it. If the salon\n * record hasn't loaded yet, the call is queued and fired as soon as it does.\n */\n open: (service?: string) => void;\n /** Close the booking modal. No-op if it isn't open. */\n close: () => void;\n /** True once the salon record is loaded and the modal is mountable. */\n isReady: boolean;\n /** Non-null if the salon fetch failed (network, 404, etc.). */\n error: Error | null;\n /** The raw salon record once loaded, or null while loading / on error. */\n salon: Record<string, unknown> | null;\n};\n\nexport const BookingContext = createContext<BookingContextValue | null>(null);\n\nexport type BookingProviderProps = {\n children?: React.ReactNode;\n /**\n * Salon slug. If omitted, the provider tries (in order):\n * 1. `window.__CLICKA_SALON_SLUG`\n * 2. `<meta name=\"clicka:salon\" content=\"...\">`\n * 3. `process.env.NEXT_PUBLIC_SALON_SLUG` (Next.js / Vite-replaced)\n * 4. `process.env.NEXT_PUBLIC_CLICKA_SALON`\n */\n salonSlug?: string;\n /**\n * Engine origin. If omitted, the provider tries (in order):\n * 1. `window.__CLICKA_ENGINE_URL`\n * 2. `<meta name=\"clicka:engine\" content=\"...\">`\n * 3. `process.env.NEXT_PUBLIC_CLICKA_ENGINE`\n * 4. `process.env.NEXT_PUBLIC_CLICKA_API_URL`\n * 5. Default: `https://app.alternine.co`\n */\n engineUrl?: string;\n /**\n * Public API key used for white-label engine access.\n * If omitted, the provider tries env/meta/global fallbacks.\n */\n apiKey?: string;\n /**\n * BCP-47 locale. If omitted, the provider derives it from\n * `<html lang>`, then `<body data-lang>`, then `navigator.language`,\n * defaulting to `bg-BG`.\n */\n locale?: string;\n /** Stripe success URL. Defaults to current page with `?booked=1`. */\n successUrl?: string;\n /** Stripe cancel URL. Defaults to current page with `?cancelled=1`. */\n cancelUrl?: string;\n /** CSS gradient for accent fills. */\n accentGradient?: string;\n /** Custom price formatter. */\n formatPrice?: (amount: number) => string;\n /** Analytics callback (replaces internal fbq/gtag). */\n onEvent?: (\n name: 'booking_started' | 'booking_completed',\n payload?: { serviceName?: string; value?: number; currency?: string },\n ) => void;\n /** Prefix for `/terms` and `/privacy` legal links. */\n basePath?: string;\n /**\n * When true (default), the provider attaches a document-level click handler\n * that opens the modal for any element matching `[data-clicka-book]`.\n * The attribute value (when non-empty) is passed as the service id.\n */\n autoTriggers?: boolean;\n /**\n * When true (default), the provider opens the modal on mount if the URL\n * contains `?service=<id>` or `?book=1`.\n */\n honorUrlParams?: boolean;\n};\n\nfunction readGlobalString(key: string): string | undefined {\n if (typeof window === 'undefined') return undefined;\n const v = (window as unknown as Record<string, unknown>)[key];\n return typeof v === 'string' && v ? v : undefined;\n}\n\nfunction readMeta(name: string): string | undefined {\n if (typeof document === 'undefined') return undefined;\n return (\n document.querySelector<HTMLMetaElement>(`meta[name=\"${name}\"]`)?.content || undefined\n );\n}\n\nfunction readEnv(key: string): string | undefined {\n try {\n const p = (typeof process !== 'undefined' ? process : undefined) as unknown as {\n env?: Record<string, string | undefined>;\n };\n const v = p?.env?.[key];\n return typeof v === 'string' && v ? v : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction resolveSlug(prop?: string): string | undefined {\n return (\n prop ||\n readGlobalString('__CLICKA_SALON_SLUG') ||\n readMeta('clicka:salon') ||\n readEnv('NEXT_PUBLIC_SALON_SLUG') ||\n readEnv('NEXT_PUBLIC_CLICKA_SALON')\n );\n}\n\nfunction resolveEngine(prop?: string): string {\n return (\n prop ||\n readGlobalString('__CLICKA_ENGINE_URL') ||\n readMeta('clicka:engine') ||\n readEnv('NEXT_PUBLIC_ENGINE_URL') ||\n readEnv('NEXT_PUBLIC_CLICKA_ENGINE') ||\n readEnv('NEXT_PUBLIC_CLICKA_API_URL') ||\n // Canonical engine host. Avoid bare-domain redirects in cross-origin fetches\n // which kills cross-origin fetches because the redirect response itself\n // carries no CORS headers — browsers reject the whole chain.\n 'https://app.alternine.co'\n );\n}\n\nfunction resolveApiKey(prop?: string): string | undefined {\n return (\n prop ||\n readGlobalString('__CLICKA_BOOKING_API_KEY') ||\n readMeta('clicka:api-key') ||\n readEnv('NEXT_PUBLIC_BOOKING_API_KEY') ||\n readEnv('NEXT_PUBLIC_CLICKA_BOOKING_API_KEY')\n );\n}\n\nfunction resolveLocale(prop?: string): string {\n if (prop) return prop;\n if (typeof document !== 'undefined') {\n const htmlLang = document.documentElement.lang?.trim();\n if (htmlLang) {\n if (htmlLang === 'bg') return 'bg-BG';\n if (htmlLang === 'en') return 'en-US';\n return htmlLang;\n }\n const bodyLang = document.body?.dataset?.lang?.trim();\n if (bodyLang) return bodyLang === 'bg' ? 'bg-BG' : 'en-US';\n }\n if (typeof navigator !== 'undefined' && navigator.language) {\n return navigator.language;\n }\n return 'bg-BG';\n}\n\nfunction defaultReturnUrl(flag: 'booked' | 'cancelled'): string | undefined {\n if (typeof window === 'undefined') return undefined;\n return `${location.origin}${location.pathname}?${flag}=1`;\n}\n\nexport function BookingProvider({\n children,\n salonSlug,\n engineUrl,\n apiKey,\n locale,\n successUrl,\n cancelUrl,\n accentGradient,\n formatPrice,\n onEvent,\n basePath,\n autoTriggers = true,\n honorUrlParams = true,\n}: BookingProviderProps) {\n const slug = useMemo(() => resolveSlug(salonSlug), [salonSlug]);\n const resolvedEngineUrl = useMemo(() => resolveEngine(engineUrl), [engineUrl]);\n const resolvedApiKey = useMemo(() => resolveApiKey(apiKey), [apiKey]);\n const resolvedLocale = useMemo(() => resolveLocale(locale), [locale]);\n const resolvedSuccessUrl = useMemo(\n () => successUrl ?? defaultReturnUrl('booked'),\n [successUrl],\n );\n const resolvedCancelUrl = useMemo(\n () => cancelUrl ?? defaultReturnUrl('cancelled'),\n [cancelUrl],\n );\n\n const widgetRef = useRef<BookingWidgetHandle>(null);\n // pendingRef: undefined = no queued open. null = open without service.\n // string = open with that service id.\n const pendingRef = useRef<string | null | undefined>(undefined);\n const urlAutoOpenedRef = useRef(false);\n\n const [salon, setSalon] = useState<Record<string, unknown> | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n // ── Salon fetch ────────────────────────────────────────────────────────\n useEffect(() => {\n if (!slug) {\n console.error(\n '[@clicka1/booking] BookingProvider has no salon slug. Pass `salonSlug` ' +\n 'or set NEXT_PUBLIC_SALON_SLUG / <meta name=\"clicka:salon\"> / ' +\n 'window.__CLICKA_SALON_SLUG.',\n );\n return;\n }\n let cancelled = false;\n const url = `${resolvedEngineUrl.replace(/\\/$/, '')}/api/public/v1/salons/${encodeURIComponent(slug)}`;\n fetch(url, {\n cache: 'no-store',\n headers: resolvedApiKey ? { 'X-API-Key': resolvedApiKey } : undefined,\n })\n .then((r) => {\n if (!r.ok) throw new Error(`Salon fetch failed: HTTP ${r.status}`);\n return r.json();\n })\n .then((d: { salon?: Record<string, unknown> }) => {\n if (cancelled) return;\n if (!d.salon) throw new Error('Empty salon response');\n setSalon(d.salon);\n setError(null);\n })\n .catch((e: unknown) => {\n if (cancelled) return;\n const err = e instanceof Error ? e : new Error(String(e));\n console.error('[@clicka1/booking] salon fetch failed:', err);\n setError(err);\n });\n return () => {\n cancelled = true;\n };\n }, [resolvedApiKey, resolvedEngineUrl, slug]);\n\n // ── Public open/close ──────────────────────────────────────────────────\n const open = useCallback(\n (service?: string) => {\n if (widgetRef.current && salon) {\n widgetRef.current.open(service || undefined);\n } else {\n pendingRef.current = service ?? null;\n }\n },\n [salon],\n );\n\n const close = useCallback(() => widgetRef.current?.close(), []);\n\n // ── Flush pending open() when salon finishes loading ───────────────────\n useEffect(() => {\n if (salon && widgetRef.current && pendingRef.current !== undefined) {\n const s = pendingRef.current;\n pendingRef.current = undefined;\n widgetRef.current.open(s || undefined);\n }\n }, [salon]);\n\n // ── Document-level click delegation ────────────────────────────────────\n // Listens to multiple attribute names so existing sites can keep their\n // markup. Primary: [data-clicka-book]. Legacy: [data-book-service],\n // [data-book]. The attribute *value* (when not empty / 'true') is passed\n // as the service id; otherwise the modal opens without preselect.\n useEffect(() => {\n if (!autoTriggers || typeof document === 'undefined') return;\n const SELECTOR = '[data-clicka-book],[data-book-service],[data-book]';\n const handler = (ev: Event) => {\n const t = ev.target as Element | null;\n if (!t) return;\n const trigger = t.closest<HTMLElement>(SELECTOR);\n if (!trigger) return;\n ev.preventDefault();\n const raw =\n trigger.getAttribute('data-clicka-book') ??\n trigger.getAttribute('data-book-service') ??\n trigger.getAttribute('data-book') ??\n '';\n const service = raw && raw !== 'true' ? raw : undefined;\n open(service);\n };\n document.addEventListener('click', handler);\n return () => document.removeEventListener('click', handler);\n }, [autoTriggers, open]);\n\n // ── URL ?service=… / ?book=1 auto-open (once, on first salon load) ─────\n useEffect(() => {\n if (!honorUrlParams || !salon || urlAutoOpenedRef.current) return;\n if (typeof location === 'undefined') return;\n const params = new URLSearchParams(location.search);\n const initial = params.get('service');\n if (initial || params.has('book')) {\n urlAutoOpenedRef.current = true;\n open(initial || undefined);\n }\n }, [honorUrlParams, salon, open]);\n\n const value = useMemo<BookingContextValue>(\n () => ({ open, close, isReady: !!salon, error, salon }),\n [open, close, salon, error],\n );\n\n // Render the modal via portal into document.body so it escapes any\n // ancestor `transform`, `filter`, `perspective`, `contain`, or\n // `will-change: transform` — any of those create a containing block\n // for fixed-positioned descendants and would jail the modal inside\n // the consumer's component subtree instead of the viewport.\n const modalNode =\n salon && slug ? (\n <BookingWidget\n ref={widgetRef}\n slug={slug}\n salon={salon}\n engineUrl={resolvedEngineUrl}\n apiKey={resolvedApiKey}\n locale={resolvedLocale}\n successUrl={resolvedSuccessUrl}\n cancelUrl={resolvedCancelUrl}\n accentGradient={accentGradient}\n formatPrice={formatPrice}\n onEvent={onEvent}\n basePath={basePath}\n />\n ) : null;\n\n return (\n <BookingContext.Provider value={value}>\n {children}\n {modalNode && typeof document !== 'undefined'\n ? createPortal(modalNode, document.body)\n : modalNode}\n </BookingContext.Provider>\n );\n}\n","'use client';\n\nimport { useContext } from 'react';\nimport { BookingContext, type BookingContextValue } from './BookingProvider';\n\n/**\n * Access the booking modal from anywhere inside a `<BookingProvider>`.\n *\n * @throws if called outside a `<BookingProvider>` tree.\n */\nexport function useBooking(): BookingContextValue {\n const ctx = useContext(BookingContext);\n if (!ctx) {\n throw new Error(\n '[@clicka1/booking] useBooking() must be called inside <BookingProvider>.',\n );\n }\n return ctx;\n}\n","'use client';\n\nimport React, { forwardRef } from 'react';\nimport { useBooking } from './useBooking';\n\nexport type BookingButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n /** Pre-select this service id when opening the modal. */\n service?: string;\n};\n\n/**\n * Drop-in button that opens the booking modal. Must be used inside a\n * `<BookingProvider>`. Accepts every native `<button>` prop so consumers\n * keep their own classes, styles, ARIA, etc.\n *\n * @example\n * <BookingButton>Reserve</BookingButton>\n * <BookingButton service=\"balayage\" className=\"btn btn_solid\">Book balayage</BookingButton>\n */\nexport const BookingButton = forwardRef<HTMLButtonElement, BookingButtonProps>(\n function BookingButton(\n { service, onClick, type = 'button', children, ...rest },\n ref,\n ) {\n const { open } = useBooking();\n return (\n <button\n ref={ref}\n type={type}\n onClick={(e) => {\n onClick?.(e);\n if (!e.defaultPrevented) open(service);\n }}\n {...rest}\n >\n {children}\n </button>\n );\n },\n);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clicka1/booking",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "White-label booking widget for salon sites powered by the Clicka engine API.",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../lib/service-category-inference.ts","../../../lib/salon-service-categories.ts","../../../locales/bg.json","../../../locales/en.json","../../../lib/i18n.ts","../../../lib/i18n-react.tsx"],"names":[],"mappings":"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","file":"chunk-HA7DFBYI.js","sourcesContent":["/** Heuristic + cleanup for service categories (price-list import, admin). */\n\nconst RULES: { category: string; patterns: RegExp[] }[] = [\n {\n category: 'Маникюр',\n patterns: [/маникюр/i, /ноктопласт/i, /гел\\s*лак/i, /нокти/i, /олиг/i, /нокът/i],\n },\n {\n category: 'Педикюр',\n patterns: [/педикюр/i, /крака/i, /стъпал/i],\n },\n {\n category: 'Боядисване',\n patterns: [\n /боядис/i,\n /боя\\b/i,\n /тонир/i,\n /колорист/i,\n /балаяж/i,\n /омбре/i,\n /airtouch/i,\n /корен/i,\n /изрусв/i,\n /изрусяв/i,\n ],\n },\n {\n category: 'Мелиране и кичури',\n patterns: [/мелир/i, /кичур/i, /фоли/i, /highlight/i, /плитк/i],\n },\n {\n category: 'Подстригване',\n patterns: [/подстриг/i, /стрижк/i, /прическ/i, /фризьор/i, /коса\\b/i, /детск/i],\n },\n {\n category: 'Брада и бръснене',\n patterns: [/брад/i, /бръсн/i, /мустак/i, /брада/i],\n },\n {\n category: 'Вежди и мигли',\n patterns: [/вежд/i, /мигл/i, /ламинир/i, /оформ.*вежд/i],\n },\n {\n category: 'Грим',\n patterns: [/грим/i, /макиаж/i, /make\\s*up/i],\n },\n {\n category: 'Козметика',\n patterns: [/почистван/i, /пилинг/i, /маска\\b/i, /хидрат/i, /лице\\b/i, /козмет/i, /фacial/i],\n },\n {\n category: 'Епилация',\n patterns: [/епилац/i, /кола\\s*маска/i, /вакс/i, /лазер/i, /депилац/i],\n },\n {\n category: 'Масаж',\n patterns: [/масаж/i, /терапи/i, /релакс/i],\n },\n {\n category: 'Сватбени и прически',\n patterns: [/сватб/i, /прическа/i, /плитк/i, /кок/i],\n },\n];\n\nexport function inferServiceCategory(serviceName: string, salonCategory?: string): string | undefined {\n const name = serviceName.trim();\n if (!name) return undefined;\n\n for (const rule of RULES) {\n if (rule.patterns.some((p) => p.test(name))) return rule.category;\n }\n\n const salon = (salonCategory ?? '').trim();\n if (salon) return salon;\n\n return undefined;\n}\n\nexport function normalizeCategoryLabel(raw: string): string {\n const t = raw.trim().replace(/\\s+/g, ' ');\n if (!t) return '';\n return t.charAt(0).toUpperCase() + t.slice(1);\n}\n\n/** Carry section headers down the list when only some rows have category. */\nexport function fillMissingCategories(\n items: { name: string; category?: string }[],\n salonCategory?: string,\n): void {\n let last = '';\n for (const item of items) {\n const c = normalizeCategoryLabel(item.category ?? '');\n if (c) {\n last = c;\n item.category = c;\n continue;\n }\n if (last) {\n item.category = last;\n continue;\n }\n const inferred = inferServiceCategory(item.name, salonCategory);\n if (inferred) item.category = inferred;\n }\n}\n","import { normalizeCategoryLabel } from '@/lib/service-category-inference';\n\nexport type ServiceCategoryTab = { id: string | null; label: string };\n\n/** Category saved on the service row in admin (no guessing from service name). */\nexport function resolveServiceCategory(service: { category?: string }): string {\n return normalizeCategoryLabel(service.category ?? '');\n}\n\n/**\n * Price lists often tag only the first row in a section — carry that category down\n * to following services until the next explicit category (same as admin import).\n */\nexport function enrichServiceCategories<T extends { category?: string }>(services: T[]): T[] {\n const out = services.map((s) => ({\n ...s,\n category: resolveServiceCategory(s) || undefined,\n }));\n let last = '';\n for (const item of out) {\n if (item.category) {\n last = item.category;\n } else if (last) {\n item.category = last;\n }\n }\n return out;\n}\n\nexport function buildServiceCategoryTabs(\n services: { category?: string }[],\n): ServiceCategoryTab[] {\n const labels = new Set<string>();\n for (const svc of services) {\n const cat = resolveServiceCategory(svc);\n if (cat) labels.add(cat);\n }\n const sorted = [...labels].sort((a, b) => a.localeCompare(b, 'bg'));\n return [{ id: null, label: 'Всички' }, ...sorted.map((cat) => ({ id: cat, label: cat }))];\n}\n\nexport function serviceMatchesCategory(\n service: { category?: string },\n selectedCategory: string | null,\n): boolean {\n if (!selectedCategory) return true;\n return resolveServiceCategory(service) === selectedCategory;\n}\n","{\n \"booking\": {\n \"modal\": {\n \"ariaLabel\": \"Резервация\",\n \"titleDefault\": \"Резервация\",\n \"titleWithStaff\": \"при {name}\",\n \"closeAria\": \"Затвори\",\n \"confirmClose\": \"Сигурни ли сте, че искате да затворите резервацията?\",\n \"stepService\": \"Услуга\",\n \"stepSpecialist\": \"Специалист\",\n \"stepTime\": \"Час\",\n \"stepDetails\": \"Данни\",\n \"stepAria\": \"Стъпка {n}: {label}\",\n \"selectedServices\": \"Избрани услуги\",\n \"services\": \"Услуги\",\n \"serviceCountOne\": \"{count} услуга\",\n \"serviceCountMany\": \"{count} услуги\",\n \"minSuffix\": \"мин\",\n \"remove\": \"Премахни\",\n \"removeAria\": \"Премахни услуга\",\n \"addMoreServices\": \"Добави още услуги\",\n \"hideList\": \"Скрий списъка · {count} избрани\",\n \"add\": \"Добави\",\n \"addService\": \"Добави услуга\",\n \"noServicesInCategory\": \"Няма услуги в избраната категория.\",\n \"selectSpecialist\": \"Избери специалист\",\n \"availableFor\": \"Налични за\",\n \"serviceUnavailable\": \"Тази услуга не е налична за резервация в момента.\",\n \"selectOtherService\": \"Избери друга услуга\",\n \"dateTime\": \"Дата и час\",\n \"timeWithStaff\": \"Час при {name}\",\n \"date\": \"Дата\",\n \"time\": \"Час\",\n \"selectDateFirst\": \"Първо изберете дата.\",\n \"dayClosed\": \"В този ден салонът е затворен.\",\n \"noSlots\": \"Няма свободни часове за избраните услуги.\",\n \"selectServiceFirst\": \"Първо изберете услуга.\",\n \"contactDetails\": \"Данни за контакт\",\n \"name\": \"Име\",\n \"phone\": \"Телефон\",\n \"email\": \"Имейл\",\n \"notes\": \"Бележки (по желание)\",\n \"smsConsentPre\": \"Съгласявам се да получавам SMS напомняния за резервацията от\",\n \"smsConsentPost\": \"на посочения телефон. Прочетох\",\n \"smsConsentAnd\": \"и\",\n \"terms\": \"Общите условия\",\n \"privacy\": \"Политиката за поверителност\",\n \"smsConsentNote\": \"Без отметка резервацията ви остава валидна, но няма да получите SMS напомняние от салона.\",\n \"totalDuration\": \"Общо: {min} мин\",\n \"totalPrice\": \"Общо: {price}\",\n \"startTime\": \"Старт {start} · Готови около {end}\",\n \"depositRequired\": \"Изисква се депозит от\",\n \"paymentFrom\": \"Плащане от\",\n \"securePayment\": \"Защитено плащане чрез\",\n \"back\": \"Назад\",\n \"continue\": \"Продължи\",\n \"sendRequest\": \"Изпрати заявка\",\n \"payAndBook\": \"Плати и резервирай\",\n \"disclaimerPre\": \"За да завършиш резервацията са нужни име, телефон и имейл — използваме ги само за управление на резервацията, потвърждения и напомняния.\",\n \"disclaimerAccept\": \"С изпращането приемаш\"\n },\n \"success\": {\n \"confirmed\": \"Резервацията е потвърдена\",\n \"waitingAt\": \"Очакваме ви в\",\n \"labelService\": \"Услуга\",\n \"labelWhen\": \"Кога\",\n \"timeFormat\": \"{date}, {time} ч.\",\n \"done\": \"Готово\"\n },\n \"errors\": {\n \"noService\": \"Моля, изберете поне една услуга.\",\n \"noName\": \"Моля, въведете вашето име.\",\n \"noPhone\": \"Моля, въведете телефонен номер.\",\n \"noEmail\": \"Моля, въведете имейл.\",\n \"noDate\": \"Моля, изберете дата.\",\n \"noTime\": \"Моля, изберете час.\",\n \"saveFailed\": \"Резервацията не можа да бъде записана. Моля опитайте отново.\",\n \"httpError\": \"Грешка {status}\",\n \"paymentFailed\": \"Грешка при инициализиране на плащането.\",\n \"generic\": \"Грешка при резервация.\"\n }\n },\n \"adminAuth\": {\n \"loading\": \"Зареждане…\",\n \"signIn\": {\n \"title\": \"Вход\",\n \"subtitle\": \"Въведете имейл и парола за достъп до панела.\",\n \"emailLabel\": \"Имейл\",\n \"emailPlaceholder\": \"ime@example.com\",\n \"passwordLabel\": \"Парола\",\n \"passwordPlaceholder\": \"••••••••\",\n \"showPassword\": \"Покажи паролата\",\n \"hidePassword\": \"Скрий паролата\",\n \"submit\": \"Влез\",\n \"submitting\": \"Влизане…\",\n \"forgot\": \"Забравена парола?\",\n \"errorGeneric\": \"Грешка\",\n \"errorLogin\": \"Грешка при вход\"\n },\n \"forgot\": {\n \"back\": \"← Назад\",\n \"title\": \"Забравена парола\",\n \"subtitle\": \"Въведете имейла на акаунта. Ще изпратим линк за задаване на нова парола.\",\n \"submit\": \"Изпрати линк\",\n \"submitting\": \"Изпращане…\",\n \"sentTitle\": \"Провери пощата си\",\n \"sentBody\": \"Изпратихме линк за задаване на нова парола.\",\n \"backToSignIn\": \"Назад към вход\"\n },\n \"setPassword\": {\n \"invalidLink\": \"Невалиден линк.\",\n \"invalidLinkHint\": \"Поискайте нов от страницата за вход.\",\n \"titleCreate\": \"Задай парола\",\n \"titleReset\": \"Нова парола\",\n \"subtitleCreate\": \"Въведи името си и избери парола за достъп до панела.\",\n \"subtitleReset\": \"Въведи нова парола за твоя панел.\",\n \"nameLabel\": \"Име\",\n \"namePlaceholder\": \"Вашето име\",\n \"emailLabel\": \"Имейл\",\n \"emailPlaceholder\": \"ime@example.com\",\n \"passwordLabel\": \"Парола\",\n \"passwordPlaceholder\": \"Поне 8 символа\",\n \"confirmLabel\": \"Потвърди паролата\",\n \"confirmPlaceholder\": \"Повтори паролата\",\n \"show\": \"Покажи\",\n \"hide\": \"Скрий\",\n \"submitCreate\": \"Създай акаунт →\",\n \"submitReset\": \"Смени паролата →\",\n \"submittingCreate\": \"Създаване…\",\n \"submittingReset\": \"Запазване…\",\n \"mismatch\": \"Паролите не съвпадат.\",\n \"doneCreate\": \"Акаунтът е създаден!\",\n \"doneReset\": \"Паролата е сменена!\",\n \"doneRedirect\": \"Влизаш в панела…\",\n \"haveAccount\": \"Вече имаш акаунт?\",\n \"signInLink\": \"Влез\",\n \"errorGeneric\": \"Грешка\"\n }\n },\n \"common\": {\n \"days\": {\n \"monday\": \"Понеделник\",\n \"tuesday\": \"Вторник\",\n \"wednesday\": \"Сряда\",\n \"thursday\": \"Четвъртък\",\n \"friday\": \"Петък\",\n \"saturday\": \"Събота\",\n \"sunday\": \"Неделя\"\n }\n },\n \"adminDashboard\": {\n \"navigation\": \"Навигация\",\n \"tabs\": {\n \"site\": \"Сайт\",\n \"images\": \"Снимки за сайта\",\n \"specialist\": \"Профил на собственика\",\n \"staff\": \"Екип\",\n \"services\": \"Услуги за резервации\",\n \"offers\": \"Оферти\",\n \"brands\": \"Брандове\",\n \"blog\": \"Блог\",\n \"hours\": \"Работно време\",\n \"bookings\": \"Резервации\",\n \"clients\": \"Клиенти\",\n \"domain\": \"Собствен домейн\",\n \"payments\": \"Плащания\",\n \"integrations\": \"Интеграции\",\n \"marketing\": \"Маркетинг\",\n \"legal\": \"Правни\",\n \"account\": \"Акаунт\"\n },\n \"groups\": {\n \"navigation\": \"Навигация\",\n \"content\": \"Съдържание\",\n \"team\": \"Екип\",\n \"settings\": \"Настройки\",\n \"site\": \"Сайт\",\n \"engine\": \"Резервационен модул\",\n \"publicSite\": \"Публичен сайт\",\n \"delivery\": \"Доставка и домейн\",\n \"account\": \"Акаунт\"\n },\n \"actions\": {\n \"save\": \"Запази\",\n \"copyLink\": \"Копирай линка\",\n \"qrCode\": \"QR код\",\n \"closeMenu\": \"Затвори менюто\"\n },\n \"notices\": {\n \"siteSaved\": \"Информацията е запазена.\",\n \"profileSaved\": \"Профилът е запазен.\",\n \"imagesSaved\": \"Снимките са запазени.\",\n \"imagesUploadNeedsSave\": \"Снимките са качени, но не успяхме да ги запазим. Натисни „Запази\\\".\",\n \"servicesSaved\": \"Услугите са запазени.\",\n \"hoursSaved\": \"Работното време е запазено.\",\n \"linkCopied\": \"Линкът е копиран!\"\n },\n \"siteTab\": {\n \"sections\": {\n \"basics\": \"Контакти\",\n \"address\": \"WWW.\",\n \"addressMobile\": \"Адрес / WWW\",\n \"about\": \"За салона\",\n \"faq\": \"FAQ\",\n \"amenities\": \"Допълнителна\",\n \"amenitiesMobile\": \"Доп. информация\"\n },\n \"fields\": {\n \"salonName\": \"Име на салона\",\n \"category\": \"Категория\",\n \"phone\": \"Телефон\",\n \"email\": \"Имейл\",\n \"city\": \"Град\",\n \"language\": \"Език\",\n \"address\": \"Адрес\"\n },\n \"languageOptions\": {\n \"bg\": \"Български\",\n \"en\": \"Английски\"\n },\n \"locationFallback\": \"Локация\",\n \"viewAppleMaps\": \"Виж в Apple Maps\",\n \"socialPlaceholder\": \"salonnaprimer\",\n \"connectedDomain\": \"Свързан домейн\",\n \"manage\": \"Управлявай\",\n \"connectOwnDomain\": \"Свържи собствен домейн\",\n \"connectOwnDomainHint\": \"Въведи домейн, който вече си купил, и го насочи към сайта.\"\n }\n }\n}\n","{\n \"booking\": {\n \"modal\": {\n \"ariaLabel\": \"Booking\",\n \"titleDefault\": \"Book\",\n \"titleWithStaff\": \"with {name}\",\n \"closeAria\": \"Close\",\n \"confirmClose\": \"Are you sure you want to close the booking?\",\n \"stepService\": \"Service\",\n \"stepSpecialist\": \"Specialist\",\n \"stepTime\": \"Time\",\n \"stepDetails\": \"Details\",\n \"stepAria\": \"Step {n}: {label}\",\n \"selectedServices\": \"Selected services\",\n \"services\": \"Services\",\n \"serviceCountOne\": \"{count} service\",\n \"serviceCountMany\": \"{count} services\",\n \"minSuffix\": \"min\",\n \"remove\": \"Remove\",\n \"removeAria\": \"Remove service\",\n \"addMoreServices\": \"Add more services\",\n \"hideList\": \"Hide list · {count} selected\",\n \"add\": \"Add\",\n \"addService\": \"Add service\",\n \"noServicesInCategory\": \"No services in this category.\",\n \"selectSpecialist\": \"Choose a specialist\",\n \"availableFor\": \"Available for\",\n \"serviceUnavailable\": \"This service is not available for booking right now.\",\n \"selectOtherService\": \"Choose a different service\",\n \"dateTime\": \"Date & time\",\n \"timeWithStaff\": \"Time with {name}\",\n \"date\": \"Date\",\n \"time\": \"Time\",\n \"selectDateFirst\": \"Please select a date first.\",\n \"dayClosed\": \"The salon is closed on this day.\",\n \"noSlots\": \"No available slots for the selected services.\",\n \"selectServiceFirst\": \"Please select a service first.\",\n \"contactDetails\": \"Your details\",\n \"name\": \"Name\",\n \"phone\": \"Phone\",\n \"email\": \"Email\",\n \"notes\": \"Notes (optional)\",\n \"smsConsentPre\": \"I agree to receive SMS reminders for this booking from\",\n \"smsConsentPost\": \"to the phone number provided. I have read the\",\n \"smsConsentAnd\": \"and\",\n \"terms\": \"Terms & Conditions\",\n \"privacy\": \"Privacy Policy\",\n \"smsConsentNote\": \"Without this, your booking is still valid — you just won't receive SMS reminders from the salon.\",\n \"totalDuration\": \"Total: {min} min\",\n \"totalPrice\": \"Total: {price}\",\n \"startTime\": \"Starts {start} · Done around {end}\",\n \"depositRequired\": \"Deposit required:\",\n \"paymentFrom\": \"Payment of\",\n \"securePayment\": \"Secure payment via\",\n \"back\": \"Back\",\n \"continue\": \"Continue\",\n \"sendRequest\": \"Request booking\",\n \"payAndBook\": \"Pay & book\",\n \"disclaimerPre\": \"To complete your booking we need your name, phone and email — used only to manage your appointment, send confirmations and reminders.\",\n \"disclaimerAccept\": \"By submitting you accept the\"\n },\n \"success\": {\n \"confirmed\": \"Booking confirmed\",\n \"waitingAt\": \"We'll see you at\",\n \"labelService\": \"Service\",\n \"labelWhen\": \"When\",\n \"timeFormat\": \"{date} at {time}\",\n \"done\": \"Done\"\n },\n \"errors\": {\n \"noService\": \"Please select at least one service.\",\n \"noName\": \"Please enter your name.\",\n \"noPhone\": \"Please enter your phone number.\",\n \"noEmail\": \"Please enter your email.\",\n \"noDate\": \"Please select a date.\",\n \"noTime\": \"Please select a time.\",\n \"saveFailed\": \"Your booking could not be saved. Please try again.\",\n \"httpError\": \"Error {status}\",\n \"paymentFailed\": \"Could not initialise payment. Please try again.\",\n \"generic\": \"Something went wrong. Please try again.\"\n }\n },\n \"adminAuth\": {\n \"loading\": \"Loading…\",\n \"signIn\": {\n \"title\": \"Sign in\",\n \"subtitle\": \"Enter your email and password to access the panel.\",\n \"emailLabel\": \"Email\",\n \"emailPlaceholder\": \"name@example.com\",\n \"passwordLabel\": \"Password\",\n \"passwordPlaceholder\": \"••••••••\",\n \"showPassword\": \"Show password\",\n \"hidePassword\": \"Hide password\",\n \"submit\": \"Sign in\",\n \"submitting\": \"Signing in…\",\n \"forgot\": \"Forgot password?\",\n \"errorGeneric\": \"Error\",\n \"errorLogin\": \"Sign-in failed\"\n },\n \"forgot\": {\n \"back\": \"← Back\",\n \"title\": \"Forgot password\",\n \"subtitle\": \"Enter the account email. We will send a link to set a new password.\",\n \"submit\": \"Send link\",\n \"submitting\": \"Sending…\",\n \"sentTitle\": \"Check your inbox\",\n \"sentBody\": \"We sent a link to set a new password.\",\n \"backToSignIn\": \"Back to sign in\"\n },\n \"setPassword\": {\n \"invalidLink\": \"Invalid link.\",\n \"invalidLinkHint\": \"Request a new one from the sign-in page.\",\n \"titleCreate\": \"Set password\",\n \"titleReset\": \"New password\",\n \"subtitleCreate\": \"Enter your name and choose a password to access the panel.\",\n \"subtitleReset\": \"Enter a new password for your panel.\",\n \"nameLabel\": \"Name\",\n \"namePlaceholder\": \"Your name\",\n \"emailLabel\": \"Email\",\n \"emailPlaceholder\": \"name@example.com\",\n \"passwordLabel\": \"Password\",\n \"passwordPlaceholder\": \"At least 8 characters\",\n \"confirmLabel\": \"Confirm password\",\n \"confirmPlaceholder\": \"Repeat the password\",\n \"show\": \"Show\",\n \"hide\": \"Hide\",\n \"submitCreate\": \"Create account →\",\n \"submitReset\": \"Change password →\",\n \"submittingCreate\": \"Creating…\",\n \"submittingReset\": \"Saving…\",\n \"mismatch\": \"Passwords do not match.\",\n \"doneCreate\": \"Account created!\",\n \"doneReset\": \"Password changed!\",\n \"doneRedirect\": \"Signing you in…\",\n \"haveAccount\": \"Already have an account?\",\n \"signInLink\": \"Sign in\",\n \"errorGeneric\": \"Error\"\n }\n },\n \"common\": {\n \"days\": {\n \"monday\": \"Monday\",\n \"tuesday\": \"Tuesday\",\n \"wednesday\": \"Wednesday\",\n \"thursday\": \"Thursday\",\n \"friday\": \"Friday\",\n \"saturday\": \"Saturday\",\n \"sunday\": \"Sunday\"\n }\n },\n \"adminDashboard\": {\n \"navigation\": \"Navigation\",\n \"tabs\": {\n \"site\": \"Website\",\n \"images\": \"Site images\",\n \"specialist\": \"Owner profile\",\n \"staff\": \"Team\",\n \"services\": \"Booking services\",\n \"offers\": \"Offers\",\n \"brands\": \"Brands\",\n \"blog\": \"Blog\",\n \"hours\": \"Working hours\",\n \"bookings\": \"Booking\",\n \"clients\": \"Clients\",\n \"domain\": \"Custom domain\",\n \"payments\": \"Payments\",\n \"integrations\": \"Integrations\",\n \"marketing\": \"Marketing\",\n \"legal\": \"Legal\",\n \"account\": \"Account\"\n },\n \"groups\": {\n \"navigation\": \"Navigation\",\n \"content\": \"Content\",\n \"team\": \"Team\",\n \"settings\": \"Settings\",\n \"site\": \"Site\",\n \"engine\": \"Booking engine\",\n \"publicSite\": \"Public site\",\n \"delivery\": \"Delivery\",\n \"account\": \"Account\"\n },\n \"actions\": {\n \"save\": \"Save\",\n \"copyLink\": \"Copy link\",\n \"qrCode\": \"QR code\",\n \"closeMenu\": \"Close menu\"\n },\n \"notices\": {\n \"siteSaved\": \"Information saved.\",\n \"profileSaved\": \"Profile saved.\",\n \"imagesSaved\": \"Images saved.\",\n \"imagesUploadNeedsSave\": \"The images were uploaded, but we could not save them. Press \\\"Save\\\".\",\n \"servicesSaved\": \"Services saved.\",\n \"hoursSaved\": \"Working hours saved.\",\n \"linkCopied\": \"Link copied!\"\n },\n \"siteTab\": {\n \"sections\": {\n \"basics\": \"Contacts\",\n \"address\": \"WWW.\",\n \"addressMobile\": \"Address / WWW\",\n \"about\": \"About\",\n \"faq\": \"FAQ\",\n \"amenities\": \"Additional\",\n \"amenitiesMobile\": \"More info\"\n },\n \"fields\": {\n \"salonName\": \"Salon name\",\n \"category\": \"Category\",\n \"phone\": \"Phone\",\n \"email\": \"Email\",\n \"city\": \"City\",\n \"language\": \"Language\",\n \"address\": \"Address\"\n },\n \"languageOptions\": {\n \"bg\": \"Bulgarian\",\n \"en\": \"English\"\n },\n \"locationFallback\": \"Location\",\n \"viewAppleMaps\": \"View in Apple Maps\",\n \"socialPlaceholder\": \"salonexample\",\n \"connectedDomain\": \"Connected domain\",\n \"manage\": \"Manage\",\n \"connectOwnDomain\": \"Connect your own domain\",\n \"connectOwnDomainHint\": \"Enter a domain you already bought and point it to the site.\"\n }\n }\n}\n","import bg from '@/locales/bg.json';\nimport en from '@/locales/en.json';\n\nexport type Locale = 'bg' | 'en';\n\nexport type TFunc = (key: string, vars?: Record<string, string | number>) => string;\n\nconst dict: Record<Locale, typeof bg> = { bg, en: en as typeof bg };\n\nfunction resolve(obj: unknown, keys: string[]): string | undefined {\n let cur: unknown = obj;\n for (const k of keys) {\n if (cur == null || typeof cur !== 'object') return undefined;\n cur = (cur as Record<string, unknown>)[k];\n }\n return typeof cur === 'string' ? cur : undefined;\n}\n\nfunction interpolate(str: string, vars: Record<string, string | number>): string {\n return str.replace(/\\{(\\w+)\\}/g, (_, k: string) => String(vars[k] ?? `{${k}}`));\n}\n\nexport function normalizeLocale(value: string | null | undefined): Locale {\n const normalized = String(value ?? '').trim().toLowerCase();\n return normalized === 'en' || normalized.startsWith('en-') ? 'en' : 'bg';\n}\n\nexport function getT(locale: Locale): TFunc {\n const translations = dict[locale] ?? dict.bg;\n return function t(key: string, vars?: Record<string, string | number>): string {\n const parts = key.split('.');\n let value = resolve(translations, parts);\n if (value === undefined) {\n value = resolve(dict.bg, parts) ?? key;\n }\n return vars ? interpolate(value, vars) : value;\n };\n}\n","'use client';\n\nimport { createContext, useContext, type ReactNode } from 'react';\nimport { getT, type Locale, type TFunc } from './i18n';\n\nconst I18nContext = createContext<TFunc>(getT('bg'));\n\nexport function I18nProvider({ locale, children }: { locale: Locale; children: ReactNode }) {\n const t = getT(locale);\n return <I18nContext.Provider value={t}>{children}</I18nContext.Provider>;\n}\n\nexport function useT(): TFunc {\n return useContext(I18nContext);\n}\n"]}