@idkwebsites/components 0.1.7 → 0.1.8
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.cjs +792 -206
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +78 -8
- package/dist/index.d.ts +78 -8
- package/dist/index.js +780 -194
- package/dist/index.js.map +1 -1
- package/dist/styles.css +275 -0
- package/dist/styles.css.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/core/PlatformProvider.tsx","../src/core/context.ts","../src/core/hooks/useTenant.ts","../src/core/api-client.ts","../src/core/hooks/useServices.ts","../src/core/hooks/useTeam.ts","../src/core/hooks/useAvailability.ts","../src/core/hooks/useBooking.ts","../src/components/ServiceCard.tsx","../src/components/ServicesList.tsx","../src/components/TeamMember.tsx","../src/components/TeamGrid.tsx","../src/components/ContactForm.tsx","../src/components/BookingWidget.tsx","../src/components/AvailabilityPicker.tsx","../src/components/ServicePicker.tsx","../src/components/StaffPicker.tsx","../src/components/DatePicker.tsx","../src/components/TimePicker.tsx"],"sourcesContent":["'use client'\n\n// This package is client-first. Re-exported entrypoints must be marked\n// as client components so Next can import them from app/server files.\n\nexport { PlatformProvider } from './core/PlatformProvider'\nexport { useTenant } from './core/hooks/useTenant'\nexport { useServices } from './core/hooks/useServices'\nexport { useTeam } from './core/hooks/useTeam'\nexport { useAvailability } from './core/hooks/useAvailability'\nexport { useCreateBooking, useCancelBooking, useBookingLookup } from './core/hooks/useBooking'\n\nexport { ServicesList } from './components/ServicesList'\nexport { ServiceCard } from './components/ServiceCard'\nexport { TeamGrid } from './components/TeamGrid'\nexport { TeamMember } from './components/TeamMember'\nexport { ContactForm } from './components/ContactForm'\nexport { BookingWidget } from './components/BookingWidget'\nexport { AvailabilityPicker } from './components/AvailabilityPicker'\n\nexport { ServicePicker } from './components/ServicePicker'\nexport { StaffPicker } from './components/StaffPicker'\nexport { DatePicker } from './components/DatePicker'\nexport { TimePicker } from './components/TimePicker'\n\nexport type {\n TenantInfo,\n Service,\n StaffMember,\n AvailabilityResult,\n BookingCreateInput,\n BookingCancelInput,\n BookingLookup,\n ContactSubmissionInput,\n} from './types'\n","/**\n * PlatformProvider\n * Provides API configuration + React Query client for all components.\n */\n'use client'\n\nimport { useState, type ReactNode } from 'react'\nimport {\n QueryClient,\n QueryClientProvider,\n HydrationBoundary,\n type DehydratedState,\n type DefaultOptions,\n} from '@tanstack/react-query'\nimport { PlatformContext } from './context'\n\ninterface PlatformProviderProps {\n apiKey: string\n apiUrl?: string\n children: ReactNode\n dehydratedState?: DehydratedState\n queryOptions?: DefaultOptions\n queryClient?: QueryClient\n}\n\nconst DEFAULT_API_URL =\n process.env.NEXT_PUBLIC_IDK_API_URL ||\n process.env.NEXT_PUBLIC_PLATFORM_API_URL ||\n 'https://app.idkwebsites.com/api/v1'\n\nexport function PlatformProvider({\n apiKey,\n apiUrl = DEFAULT_API_URL,\n children,\n dehydratedState,\n queryOptions,\n queryClient,\n}: PlatformProviderProps) {\n const [client] = useState(\n () =>\n queryClient ||\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 30_000,\n retry: 1,\n ...queryOptions?.queries,\n },\n mutations: {\n ...queryOptions?.mutations,\n },\n },\n })\n )\n\n return (\n <PlatformContext.Provider value={{ apiKey, apiUrl }}>\n <QueryClientProvider client={client}>\n <HydrationBoundary state={dehydratedState}>{children}</HydrationBoundary>\n </QueryClientProvider>\n </PlatformContext.Provider>\n )\n}\n","import { createContext, useContext } from 'react'\n\nexport interface PlatformConfig {\n apiKey: string\n apiUrl: string\n}\n\nconst PlatformContext = createContext<PlatformConfig | null>(null)\n\nexport function usePlatformConfig(): PlatformConfig {\n const context = useContext(PlatformContext)\n if (!context) {\n throw new Error('PlatformProvider is missing in the component tree.')\n }\n return context\n}\n\nexport { PlatformContext }\n","import { useQuery } from '@tanstack/react-query'\nimport { apiRequest } from '../api-client'\nimport { usePlatformConfig } from '../context'\nimport type { TenantInfo } from '../../types'\n\nexport function useTenant() {\n const config = usePlatformConfig()\n\n return useQuery({\n queryKey: ['idk', 'tenant'],\n queryFn: () => apiRequest<TenantInfo>(config, '/tenant'),\n })\n}\n","export class ApiError extends Error {\n status: number\n code: string\n\n constructor(message: string, status: number, code: string) {\n super(message)\n this.name = 'ApiError'\n this.status = status\n this.code = code\n }\n}\n\nexport interface ApiClientConfig {\n apiKey: string\n apiUrl: string\n}\n\nfunction normalizeBaseUrl(apiUrl: string): string {\n return apiUrl.replace(/\\/+$/, '')\n}\n\nexport async function apiRequest<T>(\n config: ApiClientConfig,\n path: string,\n options: RequestInit = {}\n): Promise<T> {\n const url = `${normalizeBaseUrl(config.apiUrl)}${path.startsWith('/') ? path : `/${path}`}`\n\n const headers = new Headers(options.headers)\n headers.set('X-API-Key', config.apiKey)\n if (!headers.has('Content-Type') && options.body) {\n headers.set('Content-Type', 'application/json')\n }\n\n const response = await fetch(url, {\n ...options,\n headers,\n })\n\n const payload = await response.json().catch(() => null)\n\n if (!response.ok) {\n const errorCode = payload?.error?.code || 'REQUEST_FAILED'\n const errorMessage = payload?.error?.message || response.statusText\n throw new ApiError(errorMessage, response.status, errorCode)\n }\n\n if (payload?.error) {\n throw new ApiError(payload.error.message || 'Request failed', payload.error.status || 400, payload.error.code || 'REQUEST_FAILED')\n }\n\n return payload?.data as T\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { apiRequest } from '../api-client'\nimport { usePlatformConfig } from '../context'\nimport type { Service } from '../../types'\n\ninterface ServicesResponse {\n services: Service[]\n total: number\n}\n\nexport function useServices() {\n const config = usePlatformConfig()\n\n return useQuery({\n queryKey: ['idk', 'services'],\n queryFn: () => apiRequest<ServicesResponse>(config, '/services'),\n })\n}\n","import { useQuery } from '@tanstack/react-query'\nimport { apiRequest } from '../api-client'\nimport { usePlatformConfig } from '../context'\nimport type { StaffMember } from '../../types'\n\ninterface TeamResponse {\n team: StaffMember[]\n total: number\n}\n\nexport function useTeam() {\n const config = usePlatformConfig()\n\n return useQuery({\n queryKey: ['idk', 'team'],\n queryFn: () => apiRequest<TeamResponse>(config, '/team'),\n })\n}\n","import { useMemo } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { apiRequest } from '../api-client'\nimport { usePlatformConfig } from '../context'\nimport type { AvailabilityResult } from '../../types'\n\nexport interface AvailabilityParams {\n serviceId: string\n staffId?: string\n date?: string\n days?: number\n startDate?: string\n endDate?: string\n enabled?: boolean\n}\n\nfunction buildQuery(params: AvailabilityParams): string {\n const searchParams = new URLSearchParams()\n searchParams.set('serviceId', params.serviceId)\n if (params.staffId) searchParams.set('staffId', params.staffId)\n if (params.startDate) searchParams.set('startDate', params.startDate)\n if (params.endDate) searchParams.set('endDate', params.endDate)\n if (params.date) searchParams.set('date', params.date)\n if (params.days) searchParams.set('days', String(params.days))\n return searchParams.toString()\n}\n\nexport function useAvailability(params: AvailabilityParams) {\n const config = usePlatformConfig()\n const queryString = useMemo(\n () => buildQuery(params),\n [params.serviceId, params.staffId, params.startDate, params.endDate, params.date, params.days]\n )\n const enabled = params.enabled ?? Boolean(params.serviceId)\n\n return useQuery({\n queryKey: ['idk', 'availability', queryString],\n queryFn: () => apiRequest<AvailabilityResult>(config, `/availability?${queryString}`),\n enabled,\n })\n}\n","import { useMutation, useQuery } from '@tanstack/react-query'\nimport { apiRequest } from '../api-client'\nimport { usePlatformConfig } from '../context'\nimport type { BookingCreateInput, BookingCancelInput, BookingLookup } from '../../types'\n\nexport function useCreateBooking() {\n const config = usePlatformConfig()\n\n return useMutation({\n mutationFn: (input: BookingCreateInput) =>\n apiRequest<{ booking: unknown }>(config, '/bookings', {\n method: 'POST',\n body: JSON.stringify(input),\n }),\n })\n}\n\nexport function useCancelBooking() {\n const config = usePlatformConfig()\n\n return useMutation({\n mutationFn: (input: BookingCancelInput) =>\n apiRequest<{ booking: unknown }>(config, `/bookings/${input.uid}/cancel`, {\n method: 'POST',\n body: JSON.stringify({\n reason: input.reason,\n cancelledBy: input.cancelledBy || 'customer',\n }),\n }),\n })\n}\n\nexport function useBookingLookup(uid?: string, enabled = true) {\n const config = usePlatformConfig()\n\n return useQuery({\n queryKey: ['idk', 'booking', uid],\n queryFn: () => apiRequest<BookingLookup>(config, `/bookings/${uid}`),\n enabled: Boolean(uid) && enabled,\n })\n}\n","'use client'\n\nimport type { Service } from '../types'\n\ninterface ServiceCardProps {\n service: Service\n className?: string\n showDescription?: boolean\n showPrice?: boolean\n onSelect?: (service: Service) => void\n}\n\nexport function ServiceCard({\n service,\n className,\n showDescription = true,\n showPrice = true,\n onSelect,\n}: ServiceCardProps) {\n const handleClick = () => {\n if (onSelect) onSelect(service)\n }\n\n return (\n <div\n className={['idk-card', onSelect ? 'idk-card--clickable' : '', className]\n .filter(Boolean)\n .join(' ')}\n onClick={onSelect ? handleClick : undefined}\n role={onSelect ? 'button' : undefined}\n tabIndex={onSelect ? 0 : undefined}\n >\n <div className=\"idk-card__header\">\n <h3 className=\"idk-card__title\">{service.name}</h3>\n {showPrice && typeof service.price === 'number' && service.price > 0 ? (\n <span className=\"idk-card__price\">${(service.price / 100).toFixed(2)}</span>\n ) : null}\n </div>\n {showDescription && service.description ? (\n <p className=\"idk-card__description\">{service.description}</p>\n ) : null}\n <div className=\"idk-card__meta\">\n <span>{service.duration} min</span>\n {service.category ? <span>{service.category}</span> : null}\n </div>\n </div>\n )\n}\n","'use client'\n\nimport { ServiceCard } from './ServiceCard'\nimport { useServices } from '../core/hooks/useServices'\nimport type { Service } from '../types'\n\ninterface ServicesListProps {\n layout?: 'grid' | 'list'\n columns?: number\n className?: string\n showDescription?: boolean\n showPrice?: boolean\n onSelect?: (service: Service) => void\n}\n\nexport function ServicesList({\n layout = 'grid',\n columns = 3,\n className,\n showDescription,\n showPrice,\n onSelect,\n}: ServicesListProps) {\n const { data, isLoading, error } = useServices()\n\n if (isLoading) {\n return <div className=\"idk-state\">Loading services...</div>\n }\n\n if (error || !data?.services?.length) {\n return <div className=\"idk-state\">No services available.</div>\n }\n\n const gridStyle = layout === 'grid'\n ? { gridTemplateColumns: `repeat(${Math.max(1, columns)}, minmax(0, 1fr))` }\n : undefined\n\n return (\n <div\n className={[\n 'idk-services',\n layout === 'grid' ? 'idk-services--grid' : 'idk-services--list',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={gridStyle}\n >\n {data.services.map((service) => (\n <ServiceCard\n key={service.id}\n service={service}\n showDescription={showDescription}\n showPrice={showPrice}\n onSelect={onSelect}\n />\n ))}\n </div>\n )\n}\n","'use client'\n\nimport type { StaffMember } from '../types'\n\ninterface TeamMemberProps {\n member: StaffMember\n className?: string\n showRole?: boolean\n showEmail?: boolean\n}\n\nexport function TeamMember({\n member,\n className,\n showRole = true,\n showEmail = false,\n}: TeamMemberProps) {\n const initials = member.name\n ?.split(' ')\n .map((part) => part[0])\n .slice(0, 2)\n .join('')\n .toUpperCase()\n\n return (\n <div className={['idk-card', className].filter(Boolean).join(' ')}>\n <div className=\"idk-team__avatar\">\n {member.photo?.url ? (\n <img src={member.photo.url} alt={member.name} />\n ) : (\n <span>{initials}</span>\n )}\n </div>\n <div className=\"idk-team__info\">\n <h3 className=\"idk-card__title\">{member.name}</h3>\n {showRole ? (\n <p className=\"idk-card__description\">{member.role || 'Staff'}</p>\n ) : null}\n {showEmail ? (\n <p className=\"idk-card__meta\">{member.email}</p>\n ) : null}\n </div>\n </div>\n )\n}\n","'use client'\n\nimport { useTeam } from '../core/hooks/useTeam'\nimport { TeamMember } from './TeamMember'\n\ninterface TeamGridProps {\n columns?: number\n className?: string\n showRole?: boolean\n showEmail?: boolean\n}\n\nexport function TeamGrid({\n columns = 3,\n className,\n showRole,\n showEmail,\n}: TeamGridProps) {\n const { data, isLoading, error } = useTeam()\n\n if (isLoading) {\n return <div className=\"idk-state\">Loading team...</div>\n }\n\n if (error || !data?.team?.length) {\n return <div className=\"idk-state\">No team members available.</div>\n }\n\n const gridStyle = { gridTemplateColumns: `repeat(${Math.max(1, columns)}, minmax(0, 1fr))` }\n\n return (\n <div\n className={['idk-team', className].filter(Boolean).join(' ')}\n style={gridStyle}\n >\n {data.team.map((member) => (\n <TeamMember\n key={member.id}\n member={member}\n showRole={showRole}\n showEmail={showEmail}\n />\n ))}\n </div>\n )\n}\n","'use client'\n\nimport { useState } from 'react'\nimport { useMutation } from '@tanstack/react-query'\nimport { apiRequest } from '../core/api-client'\nimport { usePlatformConfig } from '../core/context'\nimport type { ContactSubmissionInput } from '../types'\n\ntype ContactField = 'name' | 'email' | 'phone' | 'subject' | 'message'\n\ninterface ContactFormProps {\n fields?: ContactField[]\n formType?: ContactSubmissionInput['formType']\n submitLabel?: string\n className?: string\n onSuccess?: () => void\n onError?: (message: string) => void\n}\n\nconst DEFAULT_FIELDS: ContactField[] = ['name', 'email', 'phone', 'message']\n\nexport function ContactForm({\n fields = DEFAULT_FIELDS,\n formType = 'contact',\n submitLabel = 'Send Message',\n className,\n onSuccess,\n onError,\n}: ContactFormProps) {\n const config = usePlatformConfig()\n const [formState, setFormState] = useState<Record<ContactField, string>>({\n name: '',\n email: '',\n phone: '',\n subject: '',\n message: '',\n })\n\n const mutation = useMutation({\n mutationFn: (payload: ContactSubmissionInput) =>\n apiRequest<{ submissionId: string | number }>(config, '/contact', {\n method: 'POST',\n body: JSON.stringify(payload),\n }),\n onSuccess: () => {\n setFormState({ name: '', email: '', phone: '', subject: '', message: '' })\n onSuccess?.()\n },\n onError: (error) => {\n const message = error instanceof Error ? error.message : 'Failed to submit form'\n onError?.(message)\n },\n })\n\n const handleChange = (field: ContactField, value: string) => {\n setFormState((prev) => ({ ...prev, [field]: value }))\n }\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n\n mutation.mutate({\n name: formState.name,\n email: formState.email,\n phone: formState.phone || undefined,\n subject: formState.subject || undefined,\n message: formState.message,\n formType,\n })\n }\n\n return (\n <form className={['idk-form', className].filter(Boolean).join(' ')} onSubmit={handleSubmit}>\n {fields.includes('name') && (\n <label className=\"idk-form__field\">\n <span>Name</span>\n <input\n value={formState.name}\n onChange={(event) => handleChange('name', event.target.value)}\n required\n />\n </label>\n )}\n {fields.includes('email') && (\n <label className=\"idk-form__field\">\n <span>Email</span>\n <input\n type=\"email\"\n value={formState.email}\n onChange={(event) => handleChange('email', event.target.value)}\n required\n />\n </label>\n )}\n {fields.includes('phone') && (\n <label className=\"idk-form__field\">\n <span>Phone</span>\n <input\n value={formState.phone}\n onChange={(event) => handleChange('phone', event.target.value)}\n />\n </label>\n )}\n {fields.includes('subject') && (\n <label className=\"idk-form__field\">\n <span>Subject</span>\n <input\n value={formState.subject}\n onChange={(event) => handleChange('subject', event.target.value)}\n />\n </label>\n )}\n {fields.includes('message') && (\n <label className=\"idk-form__field\">\n <span>Message</span>\n <textarea\n value={formState.message}\n onChange={(event) => handleChange('message', event.target.value)}\n rows={5}\n required\n />\n </label>\n )}\n <button type=\"submit\" className=\"idk-button\" disabled={mutation.isPending}>\n {mutation.isPending ? 'Sending...' : submitLabel}\n </button>\n {mutation.isError ? (\n <p className=\"idk-form__error\">Something went wrong. Please try again.</p>\n ) : null}\n {mutation.isSuccess ? (\n <p className=\"idk-form__success\">Thanks! We'll be in touch soon.</p>\n ) : null}\n </form>\n )\n}\n","\"use client\"\n\nimport { useMemo, useState } from \"react\"\nimport { useServices } from \"../core/hooks/useServices\"\nimport { useTeam } from \"../core/hooks/useTeam\"\nimport { useAvailability } from \"../core/hooks/useAvailability\"\nimport { useCreateBooking } from \"../core/hooks/useBooking\"\nimport type { Service, StaffMember } from \"../types\"\n\ninterface BookingWidgetProps {\n className?: string\n showStaffSelection?: boolean\n onSuccess?: (booking: unknown) => void\n}\n\ntype Step = \"service\" | \"staff\" | \"time\" | \"details\" | \"done\"\n\nexport function BookingWidget({\n className,\n showStaffSelection = true,\n onSuccess,\n}: BookingWidgetProps) {\n const { data: servicesData, isLoading: servicesLoading } = useServices()\n const { data: teamData } = useTeam()\n const createBooking = useCreateBooking()\n\n const [step, setStep] = useState<Step>(\"service\")\n const [selectedService, setSelectedService] = useState<Service | null>(null)\n const [selectedStaff, setSelectedStaff] = useState<StaffMember | null>(null)\n const [selectedDate, setSelectedDate] = useState<string | null>(null)\n const [selectedTime, setSelectedTime] = useState<string | null>(null)\n const [selectedEndTime, setSelectedEndTime] = useState<string | null>(null)\n const [details, setDetails] = useState({\n name: \"\",\n email: \"\",\n phone: \"\",\n notes: \"\",\n })\n\n const staffOptions = useMemo(() => {\n if (!selectedService) return []\n if (selectedService.assignedStaff && selectedService.assignedStaff.length > 0) {\n return selectedService.assignedStaff\n }\n return teamData?.team || []\n }, [selectedService, teamData])\n\n const availability = useAvailability({\n serviceId: selectedService?.id || \"\",\n staffId: selectedStaff?.id,\n days: 7,\n enabled: Boolean(selectedService),\n })\n\n const requiresStaff =\n showStaffSelection ||\n selectedService?.requiresStaffSelection ||\n selectedService?.schedulingType === \"customer-choice\"\n\n const handleSubmit = async (event: React.FormEvent) => {\n event.preventDefault()\n if (!selectedService || !selectedDate || !selectedTime || !selectedEndTime) return\n\n const start = new Date(`${selectedDate}T${selectedTime}:00`)\n const end = new Date(`${selectedDate}T${selectedEndTime}:00`)\n\n const result = await createBooking.mutateAsync({\n serviceId: selectedService.id,\n staffId: selectedStaff?.id,\n startTime: start.toISOString(),\n endTime: end.toISOString(),\n customerName: details.name,\n customerEmail: details.email,\n customerPhone: details.phone || undefined,\n customerNotes: details.notes || undefined,\n })\n\n setStep(\"done\")\n onSuccess?.(result?.booking)\n }\n\n if (servicesLoading) {\n return <div className=\"idk-state\">Loading booking options...</div>\n }\n\n if (!servicesData?.services?.length) {\n return <div className=\"idk-state\">No services available.</div>\n }\n\n return (\n <div className={[\"idk-booking\", className].filter(Boolean).join(\" \")}>\n {step === \"service\" && (\n <div className=\"idk-booking__step\">\n <h3>Select a service</h3>\n <div className=\"idk-services idk-services--list\">\n {servicesData.services.map((service) => (\n <button\n key={service.id}\n type=\"button\"\n className=\"idk-card idk-card--clickable\"\n onClick={() => {\n setSelectedService(service)\n if (requiresStaff) {\n setStep(\"staff\")\n } else {\n setStep(\"time\")\n }\n }}\n >\n <div className=\"idk-card__header\">\n <span className=\"idk-card__title\">{service.name}</span>\n {typeof service.price === \"number\" && service.price > 0 ? (\n <span className=\"idk-card__price\">\n ${(service.price / 100).toFixed(2)}\n </span>\n ) : null}\n </div>\n <div className=\"idk-card__meta\">{service.duration} min</div>\n </button>\n ))}\n </div>\n </div>\n )}\n\n {step === \"staff\" && (\n <div className=\"idk-booking__step\">\n <h3>Select a team member</h3>\n <div className=\"idk-team\">\n {staffOptions.map((staff) => (\n <button\n key={staff.id}\n type=\"button\"\n className=\"idk-card idk-card--clickable\"\n onClick={() => {\n setSelectedStaff(staff)\n setStep(\"time\")\n }}\n >\n <span className=\"idk-card__title\">{staff.name}</span>\n <span className=\"idk-card__meta\">{staff.role || \"Staff\"}</span>\n </button>\n ))}\n </div>\n <button\n type=\"button\"\n className=\"idk-link\"\n onClick={() => {\n setSelectedStaff(null)\n setStep(\"time\")\n }}\n >\n Continue without selecting\n </button>\n </div>\n )}\n\n {step === \"time\" && (\n <div className=\"idk-booking__step\">\n <h3>Select a time</h3>\n {availability.isLoading ? (\n <div className=\"idk-state\">Loading availability...</div>\n ) : availability.data ? (\n <div className=\"idk-availability\">\n <div className=\"idk-availability__dates\">\n {availability.data.dates.map((entry) => (\n <button\n key={entry.date}\n type=\"button\"\n className={entry.date === selectedDate ? \"is-active\" : undefined}\n onClick={() => {\n setSelectedDate(entry.date)\n setSelectedTime(null)\n setSelectedEndTime(null)\n }}\n >\n {entry.date}\n </button>\n ))}\n </div>\n <div className=\"idk-availability__slots\">\n {(availability.data.dates.find((entry) => entry.date === selectedDate)?.slots ||\n availability.data.dates[0]?.slots ||\n [])\n .filter((slot) => slot.available)\n .map((slot) => (\n <button\n key={`${slot.time}-${slot.endTime}`}\n type=\"button\"\n className={slot.time === selectedTime ? \"is-active\" : undefined}\n onClick={() => {\n const date = selectedDate || availability.data?.dates[0]?.date\n setSelectedDate(date || null)\n setSelectedTime(slot.time)\n setSelectedEndTime(slot.endTime)\n setStep(\"details\")\n }}\n >\n {slot.time}\n </button>\n ))}\n </div>\n </div>\n ) : (\n <div className=\"idk-state\">No availability found.</div>\n )}\n </div>\n )}\n\n {step === \"details\" && (\n <form className=\"idk-form\" onSubmit={handleSubmit}>\n <h3>Your details</h3>\n <label className=\"idk-form__field\">\n <span>Name</span>\n <input\n value={details.name}\n onChange={(event) => setDetails((prev) => ({ ...prev, name: event.target.value }))}\n required\n />\n </label>\n <label className=\"idk-form__field\">\n <span>Email</span>\n <input\n type=\"email\"\n value={details.email}\n onChange={(event) => setDetails((prev) => ({ ...prev, email: event.target.value }))}\n required\n />\n </label>\n <label className=\"idk-form__field\">\n <span>Phone</span>\n <input\n value={details.phone}\n onChange={(event) => setDetails((prev) => ({ ...prev, phone: event.target.value }))}\n />\n </label>\n <label className=\"idk-form__field\">\n <span>Notes</span>\n <textarea\n rows={4}\n value={details.notes}\n onChange={(event) => setDetails((prev) => ({ ...prev, notes: event.target.value }))}\n />\n </label>\n <button type=\"submit\" className=\"idk-button\" disabled={createBooking.isPending}>\n {createBooking.isPending ? \"Booking...\" : \"Confirm booking\"}\n </button>\n </form>\n )}\n\n {step === \"done\" && (\n <div className=\"idk-state\">\n Booking confirmed. You'll receive a confirmation email shortly.\n </div>\n )}\n </div>\n )\n}\n","'use client'\n\nimport { useState } from 'react'\nimport { useAvailability } from '../core/hooks/useAvailability'\n\ninterface AvailabilityPickerProps {\n serviceId: string\n staffId?: string\n date?: string\n days?: number\n className?: string\n onSelect?: (params: { date: string; time: string; endTime: string }) => void\n}\n\nexport function AvailabilityPicker({\n serviceId,\n staffId,\n date,\n days = 7,\n className,\n onSelect,\n}: AvailabilityPickerProps) {\n const [selectedDate, setSelectedDate] = useState<string | null>(date || null)\n const [selectedTime, setSelectedTime] = useState<string | null>(null)\n\n const { data, isLoading } = useAvailability({\n serviceId,\n staffId,\n date,\n days,\n })\n\n if (isLoading) {\n return <div className=\"idk-state\">Loading availability...</div>\n }\n\n if (!data?.dates?.length) {\n return <div className=\"idk-state\">No availability found.</div>\n }\n\n const activeDate = selectedDate || data.dates[0]?.date\n const activeSlots = data.dates.find((entry) => entry.date === activeDate)?.slots || []\n\n return (\n <div className={['idk-availability', className].filter(Boolean).join(' ')}>\n <div className=\"idk-availability__dates\">\n {data.dates.map((entry) => (\n <button\n key={entry.date}\n type=\"button\"\n className={entry.date === activeDate ? 'is-active' : undefined}\n onClick={() => {\n setSelectedDate(entry.date)\n setSelectedTime(null)\n }}\n >\n {entry.date}\n </button>\n ))}\n </div>\n <div className=\"idk-availability__slots\">\n {activeSlots.filter((slot) => slot.available).length === 0 ? (\n <div className=\"idk-state\">No slots available.</div>\n ) : (\n activeSlots\n .filter((slot) => slot.available)\n .map((slot) => (\n <button\n key={`${activeDate}-${slot.time}`}\n type=\"button\"\n className={selectedTime === slot.time ? 'is-active' : undefined}\n onClick={() => {\n setSelectedTime(slot.time)\n if (onSelect && activeDate) {\n onSelect({\n date: activeDate,\n time: slot.time,\n endTime: slot.endTime,\n })\n }\n }}\n >\n {slot.time}\n </button>\n ))\n )}\n </div>\n </div>\n )\n}\n","\"use client\"\n\nimport type { Service } from \"../types\"\n\ninterface ServicePickerProps {\n services: Service[]\n selectedId?: string | null\n onSelect?: (service: Service) => void\n className?: string\n}\n\nexport function ServicePicker({\n services,\n selectedId,\n onSelect,\n className,\n}: ServicePickerProps) {\n return (\n <div className={[\"idk-picker\", className].filter(Boolean).join(\" \")}>\n {services.map((service) => (\n <button\n key={service.id}\n type=\"button\"\n className={selectedId === service.id ? \"is-active\" : undefined}\n onClick={() => onSelect?.(service)}\n >\n <span>{service.name}</span>\n <small>{service.duration} min</small>\n </button>\n ))}\n </div>\n )\n}\n","\"use client\"\n\nimport type { StaffMember } from \"../types\"\n\ninterface StaffPickerProps {\n staff: StaffMember[]\n selectedId?: string | null\n onSelect?: (member: StaffMember) => void\n className?: string\n}\n\nexport function StaffPicker({\n staff,\n selectedId,\n onSelect,\n className,\n}: StaffPickerProps) {\n return (\n <div className={[\"idk-picker\", className].filter(Boolean).join(\" \")}>\n {staff.map((member) => (\n <button\n key={member.id}\n type=\"button\"\n className={selectedId === member.id ? \"is-active\" : undefined}\n onClick={() => onSelect?.(member)}\n >\n <span>{member.name}</span>\n <small>{member.role || \"Staff\"}</small>\n </button>\n ))}\n </div>\n )\n}\n","\"use client\"\n\ninterface DatePickerProps {\n dates: string[]\n selectedDate?: string | null\n onSelect?: (date: string) => void\n className?: string\n}\n\nexport function DatePicker({\n dates,\n selectedDate,\n onSelect,\n className,\n}: DatePickerProps) {\n return (\n <div className={[\"idk-picker\", className].filter(Boolean).join(\" \")}>\n {dates.map((date) => (\n <button\n key={date}\n type=\"button\"\n className={selectedDate === date ? \"is-active\" : undefined}\n onClick={() => onSelect?.(date)}\n >\n {date}\n </button>\n ))}\n </div>\n )\n}\n","\"use client\"\n\nimport type { AvailabilitySlot } from \"../types\"\n\ninterface TimePickerProps {\n slots: AvailabilitySlot[]\n selectedTime?: string | null\n onSelect?: (slot: AvailabilitySlot) => void\n className?: string\n}\n\nexport function TimePicker({\n slots,\n selectedTime,\n onSelect,\n className,\n}: TimePickerProps) {\n return (\n <div className={[\"idk-picker\", className].filter(Boolean).join(\" \")}>\n {slots.map((slot) => (\n <button\n key={`${slot.time}-${slot.endTime}`}\n type=\"button\"\n className={selectedTime === slot.time ? \"is-active\" : undefined}\n disabled={!slot.available}\n onClick={() => onSelect?.(slot)}\n >\n {slot.time}\n </button>\n ))}\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACMA,IAAAA,gBAAyC;AACzC,yBAMO;;;ACbP,mBAA0C;AAO1C,IAAM,sBAAkB,4BAAqC,IAAI;AAE1D,SAAS,oBAAoC;AAClD,QAAM,cAAU,yBAAW,eAAe;AAC1C,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AACA,SAAO;AACT;;;AD2CQ;AAjCR,IAAM,kBACJ,QAAQ,IAAI,2BACZ,QAAQ,IAAI,gCACZ;AAEK,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA0B;AACxB,QAAM,CAAC,MAAM,QAAI;AAAA,IACf,MACE,eACA,IAAI,+BAAY;AAAA,MACd,gBAAgB;AAAA,QACd,SAAS;AAAA,UACP,WAAW;AAAA,UACX,OAAO;AAAA,UACP,GAAG,cAAc;AAAA,QACnB;AAAA,QACA,WAAW;AAAA,UACT,GAAG,cAAc;AAAA,QACnB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACL;AAEA,SACE,4CAAC,gBAAgB,UAAhB,EAAyB,OAAO,EAAE,QAAQ,OAAO,GAChD,sDAAC,0CAAoB,QACnB,sDAAC,wCAAkB,OAAO,iBAAkB,UAAS,GACvD,GACF;AAEJ;;;AE9DA,IAAAC,sBAAyB;;;ACAlB,IAAM,WAAN,cAAuB,MAAM;AAAA,EAClC;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,QAAgB,MAAc;AACzD,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EACd;AACF;AAOA,SAAS,iBAAiB,QAAwB;AAChD,SAAO,OAAO,QAAQ,QAAQ,EAAE;AAClC;AAEA,eAAsB,WACpB,QACA,MACA,UAAuB,CAAC,GACZ;AACZ,QAAM,MAAM,GAAG,iBAAiB,OAAO,MAAM,CAAC,GAAG,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI,EAAE;AAEzF,QAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAC3C,UAAQ,IAAI,aAAa,OAAO,MAAM;AACtC,MAAI,CAAC,QAAQ,IAAI,cAAc,KAAK,QAAQ,MAAM;AAChD,YAAQ,IAAI,gBAAgB,kBAAkB;AAAA,EAChD;AAEA,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,GAAG;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,UAAU,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,IAAI;AAEtD,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,YAAY,SAAS,OAAO,QAAQ;AAC1C,UAAM,eAAe,SAAS,OAAO,WAAW,SAAS;AACzD,UAAM,IAAI,SAAS,cAAc,SAAS,QAAQ,SAAS;AAAA,EAC7D;AAEA,MAAI,SAAS,OAAO;AAClB,UAAM,IAAI,SAAS,QAAQ,MAAM,WAAW,kBAAkB,QAAQ,MAAM,UAAU,KAAK,QAAQ,MAAM,QAAQ,gBAAgB;AAAA,EACnI;AAEA,SAAO,SAAS;AAClB;;;AD/CO,SAAS,YAAY;AAC1B,QAAM,SAAS,kBAAkB;AAEjC,aAAO,8BAAS;AAAA,IACd,UAAU,CAAC,OAAO,QAAQ;AAAA,IAC1B,SAAS,MAAM,WAAuB,QAAQ,SAAS;AAAA,EACzD,CAAC;AACH;;;AEZA,IAAAC,sBAAyB;AAUlB,SAAS,cAAc;AAC5B,QAAM,SAAS,kBAAkB;AAEjC,aAAO,8BAAS;AAAA,IACd,UAAU,CAAC,OAAO,UAAU;AAAA,IAC5B,SAAS,MAAM,WAA6B,QAAQ,WAAW;AAAA,EACjE,CAAC;AACH;;;ACjBA,IAAAC,sBAAyB;AAUlB,SAAS,UAAU;AACxB,QAAM,SAAS,kBAAkB;AAEjC,aAAO,8BAAS;AAAA,IACd,UAAU,CAAC,OAAO,MAAM;AAAA,IACxB,SAAS,MAAM,WAAyB,QAAQ,OAAO;AAAA,EACzD,CAAC;AACH;;;ACjBA,IAAAC,gBAAwB;AACxB,IAAAC,sBAAyB;AAezB,SAAS,WAAW,QAAoC;AACtD,QAAM,eAAe,IAAI,gBAAgB;AACzC,eAAa,IAAI,aAAa,OAAO,SAAS;AAC9C,MAAI,OAAO,QAAS,cAAa,IAAI,WAAW,OAAO,OAAO;AAC9D,MAAI,OAAO,UAAW,cAAa,IAAI,aAAa,OAAO,SAAS;AACpE,MAAI,OAAO,QAAS,cAAa,IAAI,WAAW,OAAO,OAAO;AAC9D,MAAI,OAAO,KAAM,cAAa,IAAI,QAAQ,OAAO,IAAI;AACrD,MAAI,OAAO,KAAM,cAAa,IAAI,QAAQ,OAAO,OAAO,IAAI,CAAC;AAC7D,SAAO,aAAa,SAAS;AAC/B;AAEO,SAAS,gBAAgB,QAA4B;AAC1D,QAAM,SAAS,kBAAkB;AACjC,QAAM,kBAAc;AAAA,IAClB,MAAM,WAAW,MAAM;AAAA,IACvB,CAAC,OAAO,WAAW,OAAO,SAAS,OAAO,WAAW,OAAO,SAAS,OAAO,MAAM,OAAO,IAAI;AAAA,EAC/F;AACA,QAAM,UAAU,OAAO,WAAW,QAAQ,OAAO,SAAS;AAE1D,aAAO,8BAAS;AAAA,IACd,UAAU,CAAC,OAAO,gBAAgB,WAAW;AAAA,IAC7C,SAAS,MAAM,WAA+B,QAAQ,iBAAiB,WAAW,EAAE;AAAA,IACpF;AAAA,EACF,CAAC;AACH;;;ACxCA,IAAAC,sBAAsC;AAK/B,SAAS,mBAAmB;AACjC,QAAM,SAAS,kBAAkB;AAEjC,aAAO,iCAAY;AAAA,IACjB,YAAY,CAAC,UACX,WAAiC,QAAQ,aAAa;AAAA,MACpD,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,KAAK;AAAA,IAC5B,CAAC;AAAA,EACL,CAAC;AACH;AAEO,SAAS,mBAAmB;AACjC,QAAM,SAAS,kBAAkB;AAEjC,aAAO,iCAAY;AAAA,IACjB,YAAY,CAAC,UACX,WAAiC,QAAQ,aAAa,MAAM,GAAG,WAAW;AAAA,MACxE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU;AAAA,QACnB,QAAQ,MAAM;AAAA,QACd,aAAa,MAAM,eAAe;AAAA,MACpC,CAAC;AAAA,IACH,CAAC;AAAA,EACL,CAAC;AACH;AAEO,SAAS,iBAAiB,KAAc,UAAU,MAAM;AAC7D,QAAM,SAAS,kBAAkB;AAEjC,aAAO,8BAAS;AAAA,IACd,UAAU,CAAC,OAAO,WAAW,GAAG;AAAA,IAChC,SAAS,MAAM,WAA0B,QAAQ,aAAa,GAAG,EAAE;AAAA,IACnE,SAAS,QAAQ,GAAG,KAAK;AAAA,EAC3B,CAAC;AACH;;;ACPQ,IAAAC,sBAAA;AArBD,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,YAAY;AAAA,EACZ;AACF,GAAqB;AACnB,QAAM,cAAc,MAAM;AACxB,QAAI,SAAU,UAAS,OAAO;AAAA,EAChC;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,CAAC,YAAY,WAAW,wBAAwB,IAAI,SAAS,EACrE,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACX,SAAS,WAAW,cAAc;AAAA,MAClC,MAAM,WAAW,WAAW;AAAA,MAC5B,UAAU,WAAW,IAAI;AAAA,MAEzB;AAAA,sDAAC,SAAI,WAAU,oBACb;AAAA,uDAAC,QAAG,WAAU,mBAAmB,kBAAQ,MAAK;AAAA,UAC7C,aAAa,OAAO,QAAQ,UAAU,YAAY,QAAQ,QAAQ,IACjE,8CAAC,UAAK,WAAU,mBAAkB;AAAA;AAAA,aAAG,QAAQ,QAAQ,KAAK,QAAQ,CAAC;AAAA,aAAE,IACnE;AAAA,WACN;AAAA,QACC,mBAAmB,QAAQ,cAC1B,6CAAC,OAAE,WAAU,yBAAyB,kBAAQ,aAAY,IACxD;AAAA,QACJ,8CAAC,SAAI,WAAU,kBACb;AAAA,wDAAC,UAAM;AAAA,oBAAQ;AAAA,YAAS;AAAA,aAAI;AAAA,UAC3B,QAAQ,WAAW,6CAAC,UAAM,kBAAQ,UAAS,IAAU;AAAA,WACxD;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACrBW,IAAAC,sBAAA;AAXJ,SAAS,aAAa;AAAA,EAC3B,SAAS;AAAA,EACT,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,EAAE,MAAM,WAAW,MAAM,IAAI,YAAY;AAE/C,MAAI,WAAW;AACb,WAAO,6CAAC,SAAI,WAAU,aAAY,iCAAmB;AAAA,EACvD;AAEA,MAAI,SAAS,CAAC,MAAM,UAAU,QAAQ;AACpC,WAAO,6CAAC,SAAI,WAAU,aAAY,oCAAsB;AAAA,EAC1D;AAEA,QAAM,YAAY,WAAW,SACzB,EAAE,qBAAqB,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,oBAAoB,IACzE;AAEJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,WAAW,SAAS,uBAAuB;AAAA,QAC3C;AAAA,MACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,MACX,OAAO;AAAA,MAEN,eAAK,SAAS,IAAI,CAAC,YAClB;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAJK,QAAQ;AAAA,MAKf,CACD;AAAA;AAAA,EACH;AAEJ;;;AC/BU,IAAAC,sBAAA;AAjBH,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,YAAY;AACd,GAAoB;AAClB,QAAM,WAAW,OAAO,MACpB,MAAM,GAAG,EACV,IAAI,CAAC,SAAS,KAAK,CAAC,CAAC,EACrB,MAAM,GAAG,CAAC,EACV,KAAK,EAAE,EACP,YAAY;AAEf,SACE,8CAAC,SAAI,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC9D;AAAA,iDAAC,SAAI,WAAU,oBACZ,iBAAO,OAAO,MACb,6CAAC,SAAI,KAAK,OAAO,MAAM,KAAK,KAAK,OAAO,MAAM,IAE9C,6CAAC,UAAM,oBAAS,GAEpB;AAAA,IACA,8CAAC,SAAI,WAAU,kBACb;AAAA,mDAAC,QAAG,WAAU,mBAAmB,iBAAO,MAAK;AAAA,MAC5C,WACC,6CAAC,OAAE,WAAU,yBAAyB,iBAAO,QAAQ,SAAQ,IAC3D;AAAA,MACH,YACC,6CAAC,OAAE,WAAU,kBAAkB,iBAAO,OAAM,IAC1C;AAAA,OACN;AAAA,KACF;AAEJ;;;ACvBW,IAAAC,sBAAA;AATJ,SAAS,SAAS;AAAA,EACvB,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AACF,GAAkB;AAChB,QAAM,EAAE,MAAM,WAAW,MAAM,IAAI,QAAQ;AAE3C,MAAI,WAAW;AACb,WAAO,6CAAC,SAAI,WAAU,aAAY,6BAAe;AAAA,EACnD;AAEA,MAAI,SAAS,CAAC,MAAM,MAAM,QAAQ;AAChC,WAAO,6CAAC,SAAI,WAAU,aAAY,wCAA0B;AAAA,EAC9D;AAEA,QAAM,YAAY,EAAE,qBAAqB,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC,oBAAoB;AAE3F,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAC3D,OAAO;AAAA,MAEN,eAAK,KAAK,IAAI,CAAC,WACd;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA;AAAA,UACA;AAAA;AAAA,QAHK,OAAO;AAAA,MAId,CACD;AAAA;AAAA,EACH;AAEJ;;;AC3CA,IAAAC,gBAAyB;AACzB,IAAAC,sBAA4B;AAuEpB,IAAAC,sBAAA;AAvDR,IAAM,iBAAiC,CAAC,QAAQ,SAAS,SAAS,SAAS;AAEpE,SAAS,YAAY;AAAA,EAC1B,SAAS;AAAA,EACT,WAAW;AAAA,EACX,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,QAAM,SAAS,kBAAkB;AACjC,QAAM,CAAC,WAAW,YAAY,QAAI,wBAAuC;AAAA,IACvE,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC;AAED,QAAM,eAAW,iCAAY;AAAA,IAC3B,YAAY,CAAC,YACX,WAA8C,QAAQ,YAAY;AAAA,MAChE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,OAAO;AAAA,IAC9B,CAAC;AAAA,IACH,WAAW,MAAM;AACf,mBAAa,EAAE,MAAM,IAAI,OAAO,IAAI,OAAO,IAAI,SAAS,IAAI,SAAS,GAAG,CAAC;AACzE,kBAAY;AAAA,IACd;AAAA,IACA,SAAS,CAAC,UAAU;AAClB,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,gBAAU,OAAO;AAAA,IACnB;AAAA,EACF,CAAC;AAED,QAAM,eAAe,CAAC,OAAqB,UAAkB;AAC3D,iBAAa,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,KAAK,GAAG,MAAM,EAAE;AAAA,EACtD;AAEA,QAAM,eAAe,CAAC,UAA4C;AAChE,UAAM,eAAe;AAErB,aAAS,OAAO;AAAA,MACd,MAAM,UAAU;AAAA,MAChB,OAAO,UAAU;AAAA,MACjB,OAAO,UAAU,SAAS;AAAA,MAC1B,SAAS,UAAU,WAAW;AAAA,MAC9B,SAAS,UAAU;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SACE,8CAAC,UAAK,WAAW,CAAC,YAAY,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAAG,UAAU,cAC3E;AAAA,WAAO,SAAS,MAAM,KACrB,8CAAC,WAAM,WAAU,mBACf;AAAA,mDAAC,UAAK,kBAAI;AAAA,MACV;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,UAAU;AAAA,UACjB,UAAU,CAAC,UAAU,aAAa,QAAQ,MAAM,OAAO,KAAK;AAAA,UAC5D,UAAQ;AAAA;AAAA,MACV;AAAA,OACF;AAAA,IAED,OAAO,SAAS,OAAO,KACtB,8CAAC,WAAM,WAAU,mBACf;AAAA,mDAAC,UAAK,mBAAK;AAAA,MACX;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,OAAO,UAAU;AAAA,UACjB,UAAU,CAAC,UAAU,aAAa,SAAS,MAAM,OAAO,KAAK;AAAA,UAC7D,UAAQ;AAAA;AAAA,MACV;AAAA,OACF;AAAA,IAED,OAAO,SAAS,OAAO,KACtB,8CAAC,WAAM,WAAU,mBACf;AAAA,mDAAC,UAAK,mBAAK;AAAA,MACX;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,UAAU;AAAA,UACjB,UAAU,CAAC,UAAU,aAAa,SAAS,MAAM,OAAO,KAAK;AAAA;AAAA,MAC/D;AAAA,OACF;AAAA,IAED,OAAO,SAAS,SAAS,KACxB,8CAAC,WAAM,WAAU,mBACf;AAAA,mDAAC,UAAK,qBAAO;AAAA,MACb;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,UAAU;AAAA,UACjB,UAAU,CAAC,UAAU,aAAa,WAAW,MAAM,OAAO,KAAK;AAAA;AAAA,MACjE;AAAA,OACF;AAAA,IAED,OAAO,SAAS,SAAS,KACxB,8CAAC,WAAM,WAAU,mBACf;AAAA,mDAAC,UAAK,qBAAO;AAAA,MACb;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,UAAU;AAAA,UACjB,UAAU,CAAC,UAAU,aAAa,WAAW,MAAM,OAAO,KAAK;AAAA,UAC/D,MAAM;AAAA,UACN,UAAQ;AAAA;AAAA,MACV;AAAA,OACF;AAAA,IAEF,6CAAC,YAAO,MAAK,UAAS,WAAU,cAAa,UAAU,SAAS,WAC7D,mBAAS,YAAY,eAAe,aACvC;AAAA,IACC,SAAS,UACR,6CAAC,OAAE,WAAU,mBAAkB,qDAAuC,IACpE;AAAA,IACH,SAAS,YACR,6CAAC,OAAE,WAAU,qBAAoB,6CAAoC,IACnE;AAAA,KACN;AAEJ;;;ACpIA,IAAAC,gBAAkC;AAgFvB,IAAAC,sBAAA;AAjEJ,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,qBAAqB;AAAA,EACrB;AACF,GAAuB;AACrB,QAAM,EAAE,MAAM,cAAc,WAAW,gBAAgB,IAAI,YAAY;AACvE,QAAM,EAAE,MAAM,SAAS,IAAI,QAAQ;AACnC,QAAM,gBAAgB,iBAAiB;AAEvC,QAAM,CAAC,MAAM,OAAO,QAAI,wBAAe,SAAS;AAChD,QAAM,CAAC,iBAAiB,kBAAkB,QAAI,wBAAyB,IAAI;AAC3E,QAAM,CAAC,eAAe,gBAAgB,QAAI,wBAA6B,IAAI;AAC3E,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAwB,IAAI;AACpE,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAwB,IAAI;AACpE,QAAM,CAAC,iBAAiB,kBAAkB,QAAI,wBAAwB,IAAI;AAC1E,QAAM,CAAC,SAAS,UAAU,QAAI,wBAAS;AAAA,IACrC,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,EACT,CAAC;AAED,QAAM,mBAAe,uBAAQ,MAAM;AACjC,QAAI,CAAC,gBAAiB,QAAO,CAAC;AAC9B,QAAI,gBAAgB,iBAAiB,gBAAgB,cAAc,SAAS,GAAG;AAC7E,aAAO,gBAAgB;AAAA,IACzB;AACA,WAAO,UAAU,QAAQ,CAAC;AAAA,EAC5B,GAAG,CAAC,iBAAiB,QAAQ,CAAC;AAE9B,QAAM,eAAe,gBAAgB;AAAA,IACnC,WAAW,iBAAiB,MAAM;AAAA,IAClC,SAAS,eAAe;AAAA,IACxB,MAAM;AAAA,IACN,SAAS,QAAQ,eAAe;AAAA,EAClC,CAAC;AAED,QAAM,gBACJ,sBACA,iBAAiB,0BACjB,iBAAiB,mBAAmB;AAEtC,QAAM,eAAe,OAAO,UAA2B;AACrD,UAAM,eAAe;AACrB,QAAI,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,gBAAiB;AAE5E,UAAM,QAAQ,oBAAI,KAAK,GAAG,YAAY,IAAI,YAAY,KAAK;AAC3D,UAAM,MAAM,oBAAI,KAAK,GAAG,YAAY,IAAI,eAAe,KAAK;AAE5D,UAAM,SAAS,MAAM,cAAc,YAAY;AAAA,MAC7C,WAAW,gBAAgB;AAAA,MAC3B,SAAS,eAAe;AAAA,MACxB,WAAW,MAAM,YAAY;AAAA,MAC7B,SAAS,IAAI,YAAY;AAAA,MACzB,cAAc,QAAQ;AAAA,MACtB,eAAe,QAAQ;AAAA,MACvB,eAAe,QAAQ,SAAS;AAAA,MAChC,eAAe,QAAQ,SAAS;AAAA,IAClC,CAAC;AAED,YAAQ,MAAM;AACd,gBAAY,QAAQ,OAAO;AAAA,EAC7B;AAEA,MAAI,iBAAiB;AACnB,WAAO,6CAAC,SAAI,WAAU,aAAY,wCAA0B;AAAA,EAC9D;AAEA,MAAI,CAAC,cAAc,UAAU,QAAQ;AACnC,WAAO,6CAAC,SAAI,WAAU,aAAY,oCAAsB;AAAA,EAC1D;AAEA,SACE,8CAAC,SAAI,WAAW,CAAC,eAAe,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAChE;AAAA,aAAS,aACR,8CAAC,SAAI,WAAU,qBACb;AAAA,mDAAC,QAAG,8BAAgB;AAAA,MACpB,6CAAC,SAAI,WAAU,mCACZ,uBAAa,SAAS,IAAI,CAAC,YAC1B;AAAA,QAAC;AAAA;AAAA,UAEC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM;AACb,+BAAmB,OAAO;AAC1B,gBAAI,eAAe;AACjB,sBAAQ,OAAO;AAAA,YACjB,OAAO;AACL,sBAAQ,MAAM;AAAA,YAChB;AAAA,UACF;AAAA,UAEA;AAAA,0DAAC,SAAI,WAAU,oBACb;AAAA,2DAAC,UAAK,WAAU,mBAAmB,kBAAQ,MAAK;AAAA,cAC/C,OAAO,QAAQ,UAAU,YAAY,QAAQ,QAAQ,IACpD,8CAAC,UAAK,WAAU,mBAAkB;AAAA;AAAA,iBAC7B,QAAQ,QAAQ,KAAK,QAAQ,CAAC;AAAA,iBACnC,IACE;AAAA,eACN;AAAA,YACA,8CAAC,SAAI,WAAU,kBAAkB;AAAA,sBAAQ;AAAA,cAAS;AAAA,eAAI;AAAA;AAAA;AAAA,QApBjD,QAAQ;AAAA,MAqBf,CACD,GACH;AAAA,OACF;AAAA,IAGD,SAAS,WACR,8CAAC,SAAI,WAAU,qBACb;AAAA,mDAAC,QAAG,kCAAoB;AAAA,MACxB,6CAAC,SAAI,WAAU,YACZ,uBAAa,IAAI,CAAC,UACjB;AAAA,QAAC;AAAA;AAAA,UAEC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM;AACb,6BAAiB,KAAK;AACtB,oBAAQ,MAAM;AAAA,UAChB;AAAA,UAEA;AAAA,yDAAC,UAAK,WAAU,mBAAmB,gBAAM,MAAK;AAAA,YAC9C,6CAAC,UAAK,WAAU,kBAAkB,gBAAM,QAAQ,SAAQ;AAAA;AAAA;AAAA,QATnD,MAAM;AAAA,MAUb,CACD,GACH;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM;AACb,6BAAiB,IAAI;AACrB,oBAAQ,MAAM;AAAA,UAChB;AAAA,UACD;AAAA;AAAA,MAED;AAAA,OACF;AAAA,IAGD,SAAS,UACR,8CAAC,SAAI,WAAU,qBACb;AAAA,mDAAC,QAAG,2BAAa;AAAA,MAChB,aAAa,YACZ,6CAAC,SAAI,WAAU,aAAY,qCAAuB,IAChD,aAAa,OACf,8CAAC,SAAI,WAAU,oBACb;AAAA,qDAAC,SAAI,WAAU,2BACZ,uBAAa,KAAK,MAAM,IAAI,CAAC,UAC5B;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,WAAW,MAAM,SAAS,eAAe,cAAc;AAAA,YACvD,SAAS,MAAM;AACb,8BAAgB,MAAM,IAAI;AAC1B,8BAAgB,IAAI;AACpB,iCAAmB,IAAI;AAAA,YACzB;AAAA,YAEC,gBAAM;AAAA;AAAA,UATF,MAAM;AAAA,QAUb,CACD,GACH;AAAA,QACA,6CAAC,SAAI,WAAU,2BACX,wBAAa,KAAK,MAAM,KAAK,CAAC,UAAU,MAAM,SAAS,YAAY,GAAG,SACtE,aAAa,KAAK,MAAM,CAAC,GAAG,SAC5B,CAAC,GACA,OAAO,CAAC,SAAS,KAAK,SAAS,EAC/B,IAAI,CAAC,SACJ;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,WAAW,KAAK,SAAS,eAAe,cAAc;AAAA,YACtD,SAAS,MAAM;AACb,oBAAM,OAAO,gBAAgB,aAAa,MAAM,MAAM,CAAC,GAAG;AAC1D,8BAAgB,QAAQ,IAAI;AAC5B,8BAAgB,KAAK,IAAI;AACzB,iCAAmB,KAAK,OAAO;AAC/B,sBAAQ,SAAS;AAAA,YACnB;AAAA,YAEC,eAAK;AAAA;AAAA,UAXD,GAAG,KAAK,IAAI,IAAI,KAAK,OAAO;AAAA,QAYnC,CACD,GACL;AAAA,SACF,IAEA,6CAAC,SAAI,WAAU,aAAY,oCAAsB;AAAA,OAErD;AAAA,IAGD,SAAS,aACR,8CAAC,UAAK,WAAU,YAAW,UAAU,cACnC;AAAA,mDAAC,QAAG,0BAAY;AAAA,MAChB,8CAAC,WAAM,WAAU,mBACf;AAAA,qDAAC,UAAK,kBAAI;AAAA,QACV;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,QAAQ;AAAA,YACf,UAAU,CAAC,UAAU,WAAW,CAAC,UAAU,EAAE,GAAG,MAAM,MAAM,MAAM,OAAO,MAAM,EAAE;AAAA,YACjF,UAAQ;AAAA;AAAA,QACV;AAAA,SACF;AAAA,MACA,8CAAC,WAAM,WAAU,mBACf;AAAA,qDAAC,UAAK,mBAAK;AAAA,QACX;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAO,QAAQ;AAAA,YACf,UAAU,CAAC,UAAU,WAAW,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,MAAM,OAAO,MAAM,EAAE;AAAA,YAClF,UAAQ;AAAA;AAAA,QACV;AAAA,SACF;AAAA,MACA,8CAAC,WAAM,WAAU,mBACf;AAAA,qDAAC,UAAK,mBAAK;AAAA,QACX;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,QAAQ;AAAA,YACf,UAAU,CAAC,UAAU,WAAW,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,MAAM,OAAO,MAAM,EAAE;AAAA;AAAA,QACpF;AAAA,SACF;AAAA,MACA,8CAAC,WAAM,WAAU,mBACf;AAAA,qDAAC,UAAK,mBAAK;AAAA,QACX;AAAA,UAAC;AAAA;AAAA,YACC,MAAM;AAAA,YACN,OAAO,QAAQ;AAAA,YACf,UAAU,CAAC,UAAU,WAAW,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,MAAM,OAAO,MAAM,EAAE;AAAA;AAAA,QACpF;AAAA,SACF;AAAA,MACA,6CAAC,YAAO,MAAK,UAAS,WAAU,cAAa,UAAU,cAAc,WAClE,wBAAc,YAAY,eAAe,mBAC5C;AAAA,OACF;AAAA,IAGD,SAAS,UACR,6CAAC,SAAI,WAAU,aAAY,6EAE3B;AAAA,KAEJ;AAEJ;;;AC9PA,IAAAC,gBAAyB;AA+Bd,IAAAC,sBAAA;AAnBJ,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAwB,QAAQ,IAAI;AAC5E,QAAM,CAAC,cAAc,eAAe,QAAI,wBAAwB,IAAI;AAEpE,QAAM,EAAE,MAAM,UAAU,IAAI,gBAAgB;AAAA,IAC1C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,WAAW;AACb,WAAO,6CAAC,SAAI,WAAU,aAAY,qCAAuB;AAAA,EAC3D;AAEA,MAAI,CAAC,MAAM,OAAO,QAAQ;AACxB,WAAO,6CAAC,SAAI,WAAU,aAAY,oCAAsB;AAAA,EAC1D;AAEA,QAAM,aAAa,gBAAgB,KAAK,MAAM,CAAC,GAAG;AAClD,QAAM,cAAc,KAAK,MAAM,KAAK,CAAC,UAAU,MAAM,SAAS,UAAU,GAAG,SAAS,CAAC;AAErF,SACE,8CAAC,SAAI,WAAW,CAAC,oBAAoB,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GACtE;AAAA,iDAAC,SAAI,WAAU,2BACZ,eAAK,MAAM,IAAI,CAAC,UACf;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QACL,WAAW,MAAM,SAAS,aAAa,cAAc;AAAA,QACrD,SAAS,MAAM;AACb,0BAAgB,MAAM,IAAI;AAC1B,0BAAgB,IAAI;AAAA,QACtB;AAAA,QAEC,gBAAM;AAAA;AAAA,MARF,MAAM;AAAA,IASb,CACD,GACH;AAAA,IACA,6CAAC,SAAI,WAAU,2BACZ,sBAAY,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,WAAW,IACvD,6CAAC,SAAI,WAAU,aAAY,iCAAmB,IAE9C,YACG,OAAO,CAAC,SAAS,KAAK,SAAS,EAC/B,IAAI,CAAC,SACJ;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QACL,WAAW,iBAAiB,KAAK,OAAO,cAAc;AAAA,QACtD,SAAS,MAAM;AACb,0BAAgB,KAAK,IAAI;AACzB,cAAI,YAAY,YAAY;AAC1B,qBAAS;AAAA,cACP,MAAM;AAAA,cACN,MAAM,KAAK;AAAA,cACX,SAAS,KAAK;AAAA,YAChB,CAAC;AAAA,UACH;AAAA,QACF;AAAA,QAEC,eAAK;AAAA;AAAA,MAdD,GAAG,UAAU,IAAI,KAAK,IAAI;AAAA,IAejC,CACD,GAEP;AAAA,KACF;AAEJ;;;AC/DU,IAAAC,sBAAA;AAfH,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,SACE,6CAAC,SAAI,WAAW,CAAC,cAAc,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC/D,mBAAS,IAAI,CAAC,YACb;AAAA,IAAC;AAAA;AAAA,MAEC,MAAK;AAAA,MACL,WAAW,eAAe,QAAQ,KAAK,cAAc;AAAA,MACrD,SAAS,MAAM,WAAW,OAAO;AAAA,MAEjC;AAAA,qDAAC,UAAM,kBAAQ,MAAK;AAAA,QACpB,8CAAC,WAAO;AAAA,kBAAQ;AAAA,UAAS;AAAA,WAAI;AAAA;AAAA;AAAA,IANxB,QAAQ;AAAA,EAOf,CACD,GACH;AAEJ;;;ACZQ,IAAAC,uBAAA;AATD,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqB;AACnB,SACE,8CAAC,SAAI,WAAW,CAAC,cAAc,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC/D,gBAAM,IAAI,CAAC,WACV;AAAA,IAAC;AAAA;AAAA,MAEC,MAAK;AAAA,MACL,WAAW,eAAe,OAAO,KAAK,cAAc;AAAA,MACpD,SAAS,MAAM,WAAW,MAAM;AAAA,MAEhC;AAAA,sDAAC,UAAM,iBAAO,MAAK;AAAA,QACnB,8CAAC,WAAO,iBAAO,QAAQ,SAAQ;AAAA;AAAA;AAAA,IAN1B,OAAO;AAAA,EAOd,CACD,GACH;AAEJ;;;ACdQ,IAAAC,uBAAA;AATD,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,SACE,8CAAC,SAAI,WAAW,CAAC,cAAc,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC/D,gBAAM,IAAI,CAAC,SACV;AAAA,IAAC;AAAA;AAAA,MAEC,MAAK;AAAA,MACL,WAAW,iBAAiB,OAAO,cAAc;AAAA,MACjD,SAAS,MAAM,WAAW,IAAI;AAAA,MAE7B;AAAA;AAAA,IALI;AAAA,EAMP,CACD,GACH;AAEJ;;;ACTQ,IAAAC,uBAAA;AATD,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,SACE,8CAAC,SAAI,WAAW,CAAC,cAAc,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,GAC/D,gBAAM,IAAI,CAAC,SACV;AAAA,IAAC;AAAA;AAAA,MAEC,MAAK;AAAA,MACL,WAAW,iBAAiB,KAAK,OAAO,cAAc;AAAA,MACtD,UAAU,CAAC,KAAK;AAAA,MAChB,SAAS,MAAM,WAAW,IAAI;AAAA,MAE7B,eAAK;AAAA;AAAA,IAND,GAAG,KAAK,IAAI,IAAI,KAAK,OAAO;AAAA,EAOnC,CACD,GACH;AAEJ;","names":["import_react","import_react_query","import_react_query","import_react_query","import_react","import_react_query","import_react_query","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_react_query","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/PlatformProvider.tsx","../src/core/context.ts","../src/core/hooks/useTenant.ts","../src/core/api-client.ts","../src/core/hooks/useServices.ts","../src/core/hooks/useTeam.ts","../src/core/hooks/useAvailability.ts","../src/core/hooks/useBooking.ts","../src/components/ServiceCard.tsx","../src/components/ServicesList.tsx","../src/components/TeamMember.tsx","../src/components/TeamGrid.tsx","../src/components/ContactForm.tsx","../src/components/BookingWidget.tsx","../src/components/AvailabilityPicker.tsx","../src/components/ServicePicker.tsx","../src/components/StaffPicker.tsx","../src/components/DatePicker.tsx","../src/components/TimePicker.tsx"],"sourcesContent":["'use client'\n\n// This package is client-first. Re-exported entrypoints must be marked\n// as client components so Next can import them from app/server files.\n\nexport { PlatformProvider } from './core/PlatformProvider'\nexport { useTenant } from './core/hooks/useTenant'\nexport { useServices } from './core/hooks/useServices'\nexport { useTeam } from './core/hooks/useTeam'\nexport { useAvailability } from './core/hooks/useAvailability'\nexport { useCreateBooking, useCancelBooking, useBookingLookup } from './core/hooks/useBooking'\n\nexport { ServicesList } from './components/ServicesList'\nexport { ServiceCard } from './components/ServiceCard'\nexport { TeamGrid } from './components/TeamGrid'\nexport { TeamMember } from './components/TeamMember'\nexport { ContactForm } from './components/ContactForm'\nexport { BookingWidget } from './components/BookingWidget'\nexport { AvailabilityPicker } from './components/AvailabilityPicker'\n\nexport { ServicePicker } from './components/ServicePicker'\nexport { StaffPicker } from './components/StaffPicker'\nexport { DatePicker } from './components/DatePicker'\nexport { TimePicker } from './components/TimePicker'\n\nexport type {\n TenantInfo,\n Service,\n StaffMember,\n AvailabilityResult,\n BookingCreateInput,\n BookingCancelInput,\n BookingLookup,\n ContactSubmissionInput,\n} from './types'\n\nexport type { ServicesQueryParams } from './core/hooks/useServices'\nexport type { TeamQueryParams } from './core/hooks/useTeam'\n","/**\n * PlatformProvider\n * Provides API configuration + React Query client for all components.\n */\n'use client'\n\nimport { useState, type ReactNode } from 'react'\nimport {\n QueryClient,\n QueryClientProvider,\n HydrationBoundary,\n type DehydratedState,\n type DefaultOptions,\n} from '@tanstack/react-query'\nimport { PlatformContext } from './context'\n\ninterface PlatformProviderProps {\n apiKey: string\n apiUrl?: string\n children: ReactNode\n dehydratedState?: DehydratedState\n queryOptions?: DefaultOptions\n queryClient?: QueryClient\n}\n\nconst DEFAULT_API_URL =\n process.env.NEXT_PUBLIC_IDK_API_URL ||\n process.env.NEXT_PUBLIC_PLATFORM_API_URL ||\n 'https://app.idkwebsites.com/api/v1'\n\nexport function PlatformProvider({\n apiKey,\n apiUrl = DEFAULT_API_URL,\n children,\n dehydratedState,\n queryOptions,\n queryClient,\n}: PlatformProviderProps) {\n const [client] = useState(\n () =>\n queryClient ||\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 30_000,\n retry: 1,\n ...queryOptions?.queries,\n },\n mutations: {\n ...queryOptions?.mutations,\n },\n },\n })\n )\n\n return (\n <PlatformContext.Provider value={{ apiKey, apiUrl }}>\n <QueryClientProvider client={client}>\n <HydrationBoundary state={dehydratedState}>{children}</HydrationBoundary>\n </QueryClientProvider>\n </PlatformContext.Provider>\n )\n}\n","import { createContext, useContext } from 'react'\n\nexport interface PlatformConfig {\n apiKey: string\n apiUrl: string\n}\n\nconst PlatformContext = createContext<PlatformConfig | null>(null)\n\nexport function usePlatformConfig(): PlatformConfig {\n const context = useContext(PlatformContext)\n if (!context) {\n throw new Error('PlatformProvider is missing in the component tree.')\n }\n return context\n}\n\nexport { PlatformContext }\n","import { useQuery } from '@tanstack/react-query'\nimport { apiRequest } from '../api-client'\nimport { usePlatformConfig } from '../context'\nimport type { TenantInfo } from '../../types'\n\nexport function useTenant() {\n const config = usePlatformConfig()\n\n return useQuery({\n queryKey: ['idk', 'tenant'],\n queryFn: () => apiRequest<TenantInfo>(config, '/tenant'),\n })\n}\n","export class ApiError extends Error {\n status: number\n code: string\n\n constructor(message: string, status: number, code: string) {\n super(message)\n this.name = 'ApiError'\n this.status = status\n this.code = code\n }\n}\n\nexport interface ApiClientConfig {\n apiKey: string\n apiUrl: string\n}\n\nfunction normalizeBaseUrl(apiUrl: string): string {\n return apiUrl.replace(/\\/+$/, '')\n}\n\nexport async function apiRequest<T>(\n config: ApiClientConfig,\n path: string,\n options: RequestInit = {}\n): Promise<T> {\n const url = `${normalizeBaseUrl(config.apiUrl)}${path.startsWith('/') ? path : `/${path}`}`\n\n const headers = new Headers(options.headers)\n headers.set('X-API-Key', config.apiKey)\n if (!headers.has('Content-Type') && options.body) {\n headers.set('Content-Type', 'application/json')\n }\n\n const response = await fetch(url, {\n ...options,\n headers,\n })\n\n const payload = await response.json().catch(() => null)\n\n if (!response.ok) {\n const errorCode = payload?.error?.code || 'REQUEST_FAILED'\n const errorMessage = payload?.error?.message || response.statusText\n throw new ApiError(errorMessage, response.status, errorCode)\n }\n\n if (payload?.error) {\n throw new ApiError(payload.error.message || 'Request failed', payload.error.status || 400, payload.error.code || 'REQUEST_FAILED')\n }\n\n return payload?.data as T\n}\n","import { useMemo } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { apiRequest } from '../api-client'\nimport { usePlatformConfig } from '../context'\nimport type { Service } from '../../types'\n\ninterface ServicesResponse {\n services: Service[]\n total: number\n}\n\nexport interface ServicesQueryParams {\n category?: string | string[]\n staffId?: string\n isActive?: boolean\n minPrice?: number\n maxPrice?: number\n search?: string\n ids?: string[]\n limit?: number\n sort?: 'name' | 'price' | 'duration' | 'sortOrder'\n order?: 'asc' | 'desc'\n enabled?: boolean\n}\n\nfunction buildQuery(params?: ServicesQueryParams): string {\n if (!params) return ''\n const searchParams = new URLSearchParams()\n const categories = Array.isArray(params.category)\n ? params.category\n : params.category\n ? [params.category]\n : []\n\n if (categories.length) searchParams.set('category', categories.join(','))\n if (params.staffId) searchParams.set('staffId', params.staffId)\n if (typeof params.isActive === 'boolean') searchParams.set('isActive', String(params.isActive))\n if (typeof params.minPrice === 'number') searchParams.set('minPrice', String(params.minPrice))\n if (typeof params.maxPrice === 'number') searchParams.set('maxPrice', String(params.maxPrice))\n if (params.search) searchParams.set('search', params.search)\n if (params.ids?.length) searchParams.set('ids', params.ids.join(','))\n if (typeof params.limit === 'number') searchParams.set('limit', String(params.limit))\n if (params.sort) searchParams.set('sort', params.sort)\n if (params.order) searchParams.set('order', params.order)\n\n return searchParams.toString()\n}\n\nexport function useServices(params?: ServicesQueryParams) {\n const config = usePlatformConfig()\n const queryString = useMemo(() => buildQuery(params), [\n params?.category,\n params?.staffId,\n params?.isActive,\n params?.minPrice,\n params?.maxPrice,\n params?.search,\n params?.ids,\n params?.limit,\n params?.sort,\n params?.order,\n ])\n\n const enabled = params?.enabled ?? true\n\n return useQuery({\n queryKey: ['idk', 'services', queryString],\n queryFn: () =>\n apiRequest<ServicesResponse>(\n config,\n queryString ? `/services?${queryString}` : '/services'\n ),\n enabled,\n })\n}\n","import { useMemo } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { apiRequest } from '../api-client'\nimport { usePlatformConfig } from '../context'\nimport type { StaffMember } from '../../types'\n\ninterface TeamResponse {\n team: StaffMember[]\n total: number\n}\n\nexport interface TeamQueryParams {\n role?: string | string[]\n isActive?: boolean\n acceptsNewBookings?: boolean\n search?: string\n ids?: string[]\n serviceId?: string\n limit?: number\n sort?: 'name' | 'role' | 'createdAt'\n order?: 'asc' | 'desc'\n enabled?: boolean\n}\n\nfunction buildQuery(params?: TeamQueryParams): string {\n if (!params) return ''\n const searchParams = new URLSearchParams()\n const roles = Array.isArray(params.role)\n ? params.role\n : params.role\n ? [params.role]\n : []\n\n if (roles.length) searchParams.set('role', roles.join(','))\n if (typeof params.isActive === 'boolean') searchParams.set('isActive', String(params.isActive))\n if (typeof params.acceptsNewBookings === 'boolean') {\n searchParams.set('acceptsNewBookings', String(params.acceptsNewBookings))\n }\n if (params.search) searchParams.set('search', params.search)\n if (params.ids?.length) searchParams.set('ids', params.ids.join(','))\n if (params.serviceId) searchParams.set('serviceId', params.serviceId)\n if (typeof params.limit === 'number') searchParams.set('limit', String(params.limit))\n if (params.sort) searchParams.set('sort', params.sort)\n if (params.order) searchParams.set('order', params.order)\n\n return searchParams.toString()\n}\n\nexport function useTeam(params?: TeamQueryParams) {\n const config = usePlatformConfig()\n const queryString = useMemo(() => buildQuery(params), [\n params?.role,\n params?.isActive,\n params?.acceptsNewBookings,\n params?.search,\n params?.ids,\n params?.serviceId,\n params?.limit,\n params?.sort,\n params?.order,\n ])\n\n const enabled = params?.enabled ?? true\n\n return useQuery({\n queryKey: ['idk', 'team', queryString],\n queryFn: () =>\n apiRequest<TeamResponse>(\n config,\n queryString ? `/team?${queryString}` : '/team'\n ),\n enabled,\n })\n}\n","import { useMemo } from 'react'\nimport { useQuery } from '@tanstack/react-query'\nimport { apiRequest } from '../api-client'\nimport { usePlatformConfig } from '../context'\nimport type { AvailabilityResult } from '../../types'\n\nexport interface AvailabilityParams {\n serviceId: string\n staffId?: string\n date?: string\n days?: number\n startDate?: string\n endDate?: string\n enabled?: boolean\n}\n\nfunction buildQuery(params: AvailabilityParams): string {\n const searchParams = new URLSearchParams()\n searchParams.set('serviceId', params.serviceId)\n if (params.staffId) searchParams.set('staffId', params.staffId)\n if (params.startDate) searchParams.set('startDate', params.startDate)\n if (params.endDate) searchParams.set('endDate', params.endDate)\n if (params.date) searchParams.set('date', params.date)\n if (params.days) searchParams.set('days', String(params.days))\n return searchParams.toString()\n}\n\nexport function useAvailability(params: AvailabilityParams) {\n const config = usePlatformConfig()\n const queryString = useMemo(\n () => buildQuery(params),\n [params.serviceId, params.staffId, params.startDate, params.endDate, params.date, params.days]\n )\n const enabled = params.enabled ?? Boolean(params.serviceId)\n\n return useQuery({\n queryKey: ['idk', 'availability', queryString],\n queryFn: () => apiRequest<AvailabilityResult>(config, `/availability?${queryString}`),\n enabled,\n })\n}\n","import { useMutation, useQuery } from '@tanstack/react-query'\nimport { apiRequest } from '../api-client'\nimport { usePlatformConfig } from '../context'\nimport type { BookingCreateInput, BookingCancelInput, BookingLookup } from '../../types'\n\nexport function useCreateBooking() {\n const config = usePlatformConfig()\n\n return useMutation({\n mutationFn: (input: BookingCreateInput) =>\n apiRequest<{ booking: unknown }>(config, '/bookings', {\n method: 'POST',\n body: JSON.stringify(input),\n }),\n })\n}\n\nexport function useCancelBooking() {\n const config = usePlatformConfig()\n\n return useMutation({\n mutationFn: (input: BookingCancelInput) =>\n apiRequest<{ booking: unknown }>(config, `/bookings/${input.uid}/cancel`, {\n method: 'POST',\n body: JSON.stringify({\n reason: input.reason,\n cancelledBy: input.cancelledBy || 'customer',\n }),\n }),\n })\n}\n\nexport function useBookingLookup(uid?: string, enabled = true) {\n const config = usePlatformConfig()\n\n return useQuery({\n queryKey: ['idk', 'booking', uid],\n queryFn: () => apiRequest<BookingLookup>(config, `/bookings/${uid}`),\n enabled: Boolean(uid) && enabled,\n })\n}\n","'use client'\n\nimport type { Service } from '../types'\n\ninterface ServiceCardProps {\n service: Service\n className?: string\n showDescription?: boolean\n showPrice?: boolean\n showImage?: boolean\n onSelect?: (service: Service) => void\n}\n\nexport function ServiceCard({\n service,\n className,\n showDescription = true,\n showPrice = true,\n showImage = false,\n onSelect,\n}: ServiceCardProps) {\n const handleClick = () => {\n if (onSelect) onSelect(service)\n }\n\n return (\n <div\n className={['idk-card', onSelect ? 'idk-card--clickable' : '', className]\n .filter(Boolean)\n .join(' ')}\n onClick={onSelect ? handleClick : undefined}\n role={onSelect ? 'button' : undefined}\n tabIndex={onSelect ? 0 : undefined}\n >\n {showImage && service.image?.url ? (\n <div className=\"idk-card__media\">\n <img src={service.image.url} alt={service.name} />\n </div>\n ) : null}\n <div className=\"idk-card__header\">\n <h3 className=\"idk-card__title\">{service.name}</h3>\n {showPrice && typeof service.price === 'number' && service.price > 0 ? (\n <span className=\"idk-card__price\">${(service.price / 100).toFixed(2)}</span>\n ) : null}\n </div>\n {showDescription && service.description ? (\n <p className=\"idk-card__description\">{service.description}</p>\n ) : null}\n <div className=\"idk-card__meta\">\n <span>{service.duration} min</span>\n {service.category ? <span>{service.category}</span> : null}\n </div>\n </div>\n )\n}\n","'use client'\n\nimport { ServiceCard } from './ServiceCard'\nimport { useServices, type ServicesQueryParams } from '../core/hooks/useServices'\nimport type { Service } from '../types'\n\ninterface ServicesListProps {\n layout?: 'grid' | 'list'\n columns?: number\n className?: string\n showDescription?: boolean\n showPrice?: boolean\n showImage?: boolean\n query?: ServicesQueryParams\n filter?: (service: Service) => boolean\n sort?: (a: Service, b: Service) => number\n limit?: number\n emptyMessage?: string\n loadingMessage?: string\n onSelect?: (service: Service) => void\n}\n\nexport function ServicesList({\n layout = 'grid',\n columns = 3,\n className,\n showDescription,\n showPrice,\n showImage,\n query,\n filter,\n sort,\n limit,\n emptyMessage = 'No services available.',\n loadingMessage = 'Loading services...',\n onSelect,\n}: ServicesListProps) {\n const { data, isLoading, error } = useServices(query)\n\n if (isLoading) {\n return <div className=\"idk-state\">{loadingMessage}</div>\n }\n\n let services = data?.services ? [...data.services] : []\n\n if (filter) {\n services = services.filter(filter)\n }\n\n if (sort) {\n services = services.sort(sort)\n }\n\n if (typeof limit === 'number') {\n services = services.slice(0, Math.max(0, limit))\n }\n\n if (error || services.length === 0) {\n return <div className=\"idk-state\">{emptyMessage}</div>\n }\n\n const gridStyle = layout === 'grid'\n ? { gridTemplateColumns: `repeat(${Math.max(1, columns)}, minmax(0, 1fr))` }\n : undefined\n\n return (\n <div\n className={[\n 'idk-services',\n layout === 'grid' ? 'idk-services--grid' : 'idk-services--list',\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n style={gridStyle}\n >\n {services.map((service) => (\n <ServiceCard\n key={service.id}\n service={service}\n showDescription={showDescription}\n showPrice={showPrice}\n showImage={showImage}\n onSelect={onSelect}\n />\n ))}\n </div>\n )\n}\n","'use client'\n\nimport type { StaffMember } from '../types'\n\ninterface TeamMemberProps {\n member: StaffMember\n className?: string\n showRole?: boolean\n showEmail?: boolean\n showBio?: boolean\n layout?: \"card\" | \"profile\"\n imagePosition?: \"left\" | \"right\"\n}\n\nexport function TeamMember({\n member,\n className,\n showRole = true,\n showEmail = false,\n showBio = false,\n layout = \"card\",\n imagePosition = \"left\",\n}: TeamMemberProps) {\n const initials = member.name\n ?.split(' ')\n .map((part) => part[0])\n .slice(0, 2)\n .join('')\n .toUpperCase()\n\n const avatar = (\n <div className=\"idk-team__avatar\">\n {member.photo?.url ? (\n <img src={member.photo.url} alt={member.name} />\n ) : (\n <span>{initials}</span>\n )}\n </div>\n )\n\n if (layout === \"profile\") {\n return (\n <div className={[\"idk-team__profile\", className].filter(Boolean).join(\" \")}>\n {imagePosition === \"left\" ? avatar : null}\n <div className=\"idk-team__info\">\n <h3 className=\"idk-card__title\">{member.name}</h3>\n {showRole ? (\n <p className=\"idk-card__description\">{member.role || \"Staff\"}</p>\n ) : null}\n {showBio && member.bio ? (\n <p className=\"idk-team__bio\">{member.bio}</p>\n ) : null}\n {showEmail ? (\n <p className=\"idk-card__meta\">{member.email}</p>\n ) : null}\n </div>\n {imagePosition === \"right\" ? avatar : null}\n </div>\n )\n }\n\n return (\n <div className={[\"idk-card\", className].filter(Boolean).join(\" \")}>\n <div className=\"idk-team__avatar\">\n {member.photo?.url ? (\n <img src={member.photo.url} alt={member.name} />\n ) : (\n <span>{initials}</span>\n )}\n </div>\n <div className=\"idk-team__info\">\n <h3 className=\"idk-card__title\">{member.name}</h3>\n {showRole ? (\n <p className=\"idk-card__description\">{member.role || \"Staff\"}</p>\n ) : null}\n {showBio && member.bio ? (\n <p className=\"idk-team__bio\">{member.bio}</p>\n ) : null}\n {showEmail ? (\n <p className=\"idk-card__meta\">{member.email}</p>\n ) : null}\n </div>\n </div>\n )\n}\n","'use client'\n\nimport { useTeam, type TeamQueryParams } from '../core/hooks/useTeam'\nimport { TeamMember } from './TeamMember'\nimport type { StaffMember } from '../types'\n\ninterface TeamGridProps {\n columns?: number\n className?: string\n showRole?: boolean\n showEmail?: boolean\n showBio?: boolean\n layout?: \"card\" | \"profile\"\n imagePosition?: \"left\" | \"right\"\n query?: TeamQueryParams\n filter?: (member: StaffMember) => boolean\n sort?: (a: StaffMember, b: StaffMember) => number\n limit?: number\n emptyMessage?: string\n loadingMessage?: string\n}\n\nexport function TeamGrid({\n columns = 3,\n className,\n showRole,\n showEmail,\n showBio,\n layout = \"card\",\n imagePosition = \"left\",\n query,\n filter,\n sort,\n limit,\n emptyMessage = 'No team members available.',\n loadingMessage = 'Loading team...',\n}: TeamGridProps) {\n const { data, isLoading, error } = useTeam(query)\n\n if (isLoading) {\n return <div className=\"idk-state\">{loadingMessage}</div>\n }\n\n let members = data?.team ? [...data.team] : []\n\n if (filter) {\n members = members.filter(filter)\n }\n\n if (sort) {\n members = members.sort(sort)\n }\n\n if (typeof limit === 'number') {\n members = members.slice(0, Math.max(0, limit))\n }\n\n if (error || members.length === 0) {\n return <div className=\"idk-state\">{emptyMessage}</div>\n }\n\n const gridStyle = { gridTemplateColumns: `repeat(${Math.max(1, columns)}, minmax(0, 1fr))` }\n\n return (\n <div\n className={['idk-team', className].filter(Boolean).join(' ')}\n style={gridStyle}\n >\n {members.map((member) => (\n <TeamMember\n key={member.id}\n member={member}\n showRole={showRole}\n showEmail={showEmail}\n showBio={showBio}\n layout={layout}\n imagePosition={imagePosition}\n />\n ))}\n </div>\n )\n}\n","'use client'\n\nimport { useState } from 'react'\nimport { useMutation } from '@tanstack/react-query'\nimport { apiRequest } from '../core/api-client'\nimport { usePlatformConfig } from '../core/context'\nimport type { ContactSubmissionInput } from '../types'\n\ntype ContactField = 'name' | 'email' | 'phone' | 'subject' | 'message'\n\ninterface ContactFormProps {\n fields?: ContactField[]\n formType?: ContactSubmissionInput['formType']\n submitLabel?: string\n className?: string\n onSuccess?: () => void\n onError?: (message: string) => void\n}\n\nconst DEFAULT_FIELDS: ContactField[] = ['name', 'email', 'phone', 'message']\n\nexport function ContactForm({\n fields = DEFAULT_FIELDS,\n formType = 'contact',\n submitLabel = 'Send Message',\n className,\n onSuccess,\n onError,\n}: ContactFormProps) {\n const config = usePlatformConfig()\n const [formState, setFormState] = useState<Record<ContactField, string>>({\n name: '',\n email: '',\n phone: '',\n subject: '',\n message: '',\n })\n\n const mutation = useMutation({\n mutationFn: (payload: ContactSubmissionInput) =>\n apiRequest<{ submissionId: string | number }>(config, '/contact', {\n method: 'POST',\n body: JSON.stringify(payload),\n }),\n onSuccess: () => {\n setFormState({ name: '', email: '', phone: '', subject: '', message: '' })\n onSuccess?.()\n },\n onError: (error) => {\n const message = error instanceof Error ? error.message : 'Failed to submit form'\n onError?.(message)\n },\n })\n\n const handleChange = (field: ContactField, value: string) => {\n setFormState((prev) => ({ ...prev, [field]: value }))\n }\n\n const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {\n event.preventDefault()\n\n mutation.mutate({\n name: formState.name,\n email: formState.email,\n phone: formState.phone || undefined,\n subject: formState.subject || undefined,\n message: formState.message,\n formType,\n })\n }\n\n return (\n <form className={['idk-form', className].filter(Boolean).join(' ')} onSubmit={handleSubmit}>\n {fields.includes('name') && (\n <label className=\"idk-form__field\">\n <span>Name</span>\n <input\n value={formState.name}\n onChange={(event) => handleChange('name', event.target.value)}\n required\n />\n </label>\n )}\n {fields.includes('email') && (\n <label className=\"idk-form__field\">\n <span>Email</span>\n <input\n type=\"email\"\n value={formState.email}\n onChange={(event) => handleChange('email', event.target.value)}\n required\n />\n </label>\n )}\n {fields.includes('phone') && (\n <label className=\"idk-form__field\">\n <span>Phone</span>\n <input\n value={formState.phone}\n onChange={(event) => handleChange('phone', event.target.value)}\n />\n </label>\n )}\n {fields.includes('subject') && (\n <label className=\"idk-form__field\">\n <span>Subject</span>\n <input\n value={formState.subject}\n onChange={(event) => handleChange('subject', event.target.value)}\n />\n </label>\n )}\n {fields.includes('message') && (\n <label className=\"idk-form__field\">\n <span>Message</span>\n <textarea\n value={formState.message}\n onChange={(event) => handleChange('message', event.target.value)}\n rows={5}\n required\n />\n </label>\n )}\n <button type=\"submit\" className=\"idk-button\" disabled={mutation.isPending}>\n {mutation.isPending ? 'Sending...' : submitLabel}\n </button>\n {mutation.isError ? (\n <p className=\"idk-form__error\">Something went wrong. Please try again.</p>\n ) : null}\n {mutation.isSuccess ? (\n <p className=\"idk-form__success\">Thanks! We'll be in touch soon.</p>\n ) : null}\n </form>\n )\n}\n","\"use client\"\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\"\nimport { useServices, type ServicesQueryParams } from \"../core/hooks/useServices\"\nimport { useTeam, type TeamQueryParams } from \"../core/hooks/useTeam\"\nimport { useAvailability } from \"../core/hooks/useAvailability\"\nimport { useCreateBooking } from \"../core/hooks/useBooking\"\nimport type { Service, StaffMember } from \"../types\"\n\ninterface BookingWidgetProps {\n className?: string\n showStaffSelection?: boolean\n onSuccess?: (booking: unknown) => void\n services?: Service[]\n servicesQuery?: ServicesQueryParams\n teamQuery?: TeamQueryParams\n serviceFilter?: (service: Service) => boolean\n teamFilter?: (member: StaffMember) => boolean\n title?: string\n subtitle?: string\n autoAdvanceOnSelect?: boolean\n scrollToStep?: boolean\n scrollOffset?: number\n enableServiceSearch?: boolean\n serviceSearchPlaceholder?: string\n enableCategoryFilter?: boolean\n categoryLabel?: string\n serviceListMaxHeight?: number | string\n serviceLayout?: \"list\" | \"grid\"\n serviceColumns?: number\n servicePageSize?: number\n showServicePagination?: boolean\n staffLayout?: \"list\" | \"grid\"\n staffColumns?: number\n showAnyStaffOption?: boolean\n timeLayout?: \"stack\" | \"split\"\n}\n\ntype Step = \"service\" | \"staff\" | \"time\" | \"details\" | \"done\"\n\nexport function BookingWidget({\n className,\n showStaffSelection = true,\n onSuccess,\n services,\n servicesQuery,\n teamQuery,\n serviceFilter,\n teamFilter,\n title = \"Book an Appointment\",\n subtitle,\n autoAdvanceOnSelect = false,\n scrollToStep = true,\n scrollOffset = 96,\n enableServiceSearch = true,\n serviceSearchPlaceholder = \"Search services\",\n enableCategoryFilter = false,\n categoryLabel = \"All categories\",\n serviceListMaxHeight,\n serviceLayout = \"list\",\n serviceColumns = 2,\n servicePageSize = 10,\n showServicePagination,\n staffLayout = \"grid\",\n staffColumns = 2,\n showAnyStaffOption = true,\n timeLayout = \"split\",\n}: BookingWidgetProps) {\n const resolvedServicesQuery = useMemo(\n () => (services ? { ...servicesQuery, enabled: false } : servicesQuery),\n [services, servicesQuery]\n )\n const { data: servicesData, isLoading: servicesLoading } = useServices(resolvedServicesQuery)\n const { data: teamData } = useTeam(teamQuery)\n const createBooking = useCreateBooking()\n const widgetRef = useRef<HTMLDivElement | null>(null)\n\n const [step, setStep] = useState<Step>(\"service\")\n const [selectedService, setSelectedService] = useState<Service | null>(null)\n const [selectedStaff, setSelectedStaff] = useState<StaffMember | null>(null)\n const [selectedDate, setSelectedDate] = useState<string | null>(null)\n const [selectedTime, setSelectedTime] = useState<string | null>(null)\n const [selectedEndTime, setSelectedEndTime] = useState<string | null>(null)\n const [serviceSearch, setServiceSearch] = useState(\"\")\n const [categoryFilter, setCategoryFilter] = useState(\"all\")\n const [servicePage, setServicePage] = useState(1)\n const [bookingError, setBookingError] = useState<string | null>(null)\n const [details, setDetails] = useState({\n name: \"\",\n email: \"\",\n phone: \"\",\n notes: \"\",\n })\n\n const servicesList = useMemo(() => {\n const list = services ? [...services] : servicesData?.services ? [...servicesData.services] : []\n return serviceFilter ? list.filter(serviceFilter) : list\n }, [services, servicesData, serviceFilter])\n\n const categories = useMemo(() => {\n const set = new Set<string>()\n servicesList.forEach((service) => {\n if (service.category) {\n set.add(service.category)\n }\n })\n return Array.from(set).sort()\n }, [servicesList])\n\n const filteredServices = useMemo(() => {\n const search = serviceSearch.trim().toLowerCase()\n return servicesList.filter((service) => {\n const matchesSearch = !search\n || service.name.toLowerCase().includes(search)\n || (service.description || \"\").toLowerCase().includes(search)\n || (service.category || \"\").toLowerCase().includes(search)\n const matchesCategory =\n categoryFilter === \"all\" ? true : service.category === categoryFilter\n return matchesSearch && matchesCategory\n })\n }, [servicesList, serviceSearch, categoryFilter])\n\n useEffect(() => {\n setServicePage(1)\n }, [serviceSearch, categoryFilter])\n\n const pagedServices = useMemo(() => {\n const pageSize = Math.max(1, servicePageSize)\n return filteredServices.slice(0, pageSize * servicePage)\n }, [filteredServices, servicePage, servicePageSize])\n\n const hasMoreServices = filteredServices.length > pagedServices.length\n const shouldPaginate = showServicePagination ?? hasMoreServices\n\n const staffOptions = useMemo(() => {\n if (!selectedService) return []\n if (selectedService.assignedStaff && selectedService.assignedStaff.length > 0) {\n const assigned = selectedService.assignedStaff\n return teamFilter ? assigned.filter(teamFilter) : assigned\n }\n const teamList = teamData?.team || []\n return teamFilter ? teamList.filter(teamFilter) : teamList\n }, [selectedService, teamData, teamFilter])\n\n const availability = useAvailability({\n serviceId: selectedService?.id || \"\",\n staffId: selectedStaff?.id,\n days: 7,\n enabled: Boolean(selectedService),\n })\n\n const timeZone = availability.data?.timeZone || \"America/Chicago\"\n\n const safeTimeZone = useMemo(() => {\n if (!timeZone) return undefined\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone }).format(new Date())\n return timeZone\n } catch {\n return undefined\n }\n }, [timeZone])\n\n const timeZoneLabel = useMemo(() => {\n if (timeZone) return timeZone\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone\n } catch {\n return \"Local time\"\n }\n }, [timeZone])\n\n const dateLabelFormatter = useMemo(\n () =>\n new Intl.DateTimeFormat(\"en-US\", {\n weekday: \"short\",\n month: \"short\",\n day: \"numeric\",\n }),\n []\n )\n\n const dateHeadingFormatter = useMemo(\n () =>\n new Intl.DateTimeFormat(\"en-US\", {\n weekday: \"long\",\n month: \"long\",\n day: \"numeric\",\n }),\n []\n )\n\n const timeFormatter = useMemo(\n () =>\n new Intl.DateTimeFormat(\"en-US\", {\n timeZone: safeTimeZone,\n hour: \"numeric\",\n minute: \"2-digit\",\n }),\n [safeTimeZone]\n )\n\n const requiresStaff =\n showStaffSelection ||\n selectedService?.requiresStaffSelection ||\n selectedService?.schedulingType === \"customer-choice\"\n\n const canSkipStaff = !selectedService?.requiresStaffSelection\n const totalSteps = requiresStaff ? 4 : 3\n const stepNumber = (() => {\n if (step === \"service\") return 1\n if (step === \"staff\") return 2\n if (step === \"time\") return requiresStaff ? 3 : 2\n if (step === \"details\") return requiresStaff ? 4 : 3\n return totalSteps\n })()\n\n const scrollToTop = useCallback(() => {\n if (!scrollToStep || !widgetRef.current) return\n const top = widgetRef.current.getBoundingClientRect().top + window.scrollY\n window.scrollTo({\n top: Math.max(0, top - scrollOffset),\n behavior: \"smooth\",\n })\n }, [scrollToStep, scrollOffset])\n\n const resetSelections = () => {\n setSelectedStaff(null)\n setSelectedDate(null)\n setSelectedTime(null)\n setSelectedEndTime(null)\n setBookingError(null)\n }\n\n useEffect(() => {\n if (step !== \"time\") return\n if (!availability.data?.dates?.length) return\n if (selectedDate) return\n setSelectedDate(availability.data.dates[0].date)\n }, [step, availability.data, selectedDate])\n\n const parseDateOnly = (value?: string | null): Date | null => {\n if (!value) return null\n const normalized = value.includes(\"T\") ? value.split(\"T\")[0] : value\n const parsed = new Date(`${normalized}T00:00:00`)\n return Number.isNaN(parsed.getTime()) ? null : parsed\n }\n\n const parseDateTime = (value?: string | null, fallbackDate?: string | null): Date | null => {\n if (!value) return null\n const direct = new Date(value)\n if (!Number.isNaN(direct.getTime())) return direct\n if (fallbackDate) {\n const normalized = fallbackDate.includes(\"T\") ? fallbackDate.split(\"T\")[0] : fallbackDate\n const combined = new Date(`${normalized}T${value}`)\n if (!Number.isNaN(combined.getTime())) return combined\n }\n return null\n }\n\n const formatDateLabel = (date: string): string => {\n const parsed = parseDateOnly(date)\n if (!parsed) return date\n try {\n return dateLabelFormatter.format(parsed)\n } catch {\n return date\n }\n }\n\n const formatDateHeading = (date: string): string => {\n const parsed = parseDateOnly(date)\n if (!parsed) return date\n try {\n return dateHeadingFormatter.format(parsed)\n } catch {\n return date\n }\n }\n\n const formatTimeLabel = (iso: string): string => {\n const parsed = parseDateTime(iso, selectedDate)\n if (!parsed) return iso\n try {\n return timeFormatter.format(parsed)\n } catch {\n return parsed.toLocaleTimeString(\"en-US\", { hour: \"numeric\", minute: \"2-digit\" })\n }\n }\n\n const formatDuration = (minutes: number): string => {\n if (!Number.isFinite(minutes)) return \"\"\n if (minutes < 60) return `${minutes} min`\n const hours = Math.floor(minutes / 60)\n const remaining = minutes % 60\n return remaining === 0 ? `${hours} hr${hours > 1 ? \"s\" : \"\"}` : `${hours} hr ${remaining} min`\n }\n\n const handleBack = () => {\n if (step === \"service\") return\n if (step === \"staff\") {\n setStep(\"service\")\n } else if (step === \"time\") {\n if (requiresStaff) {\n setStep(\"staff\")\n } else {\n setStep(\"service\")\n }\n } else if (step === \"details\") {\n setStep(\"time\")\n } else if (step === \"done\") {\n setStep(\"details\")\n }\n setBookingError(null)\n scrollToTop()\n }\n\n const handleServiceContinue = () => {\n if (!selectedService) return\n if (requiresStaff) {\n setStep(\"staff\")\n } else {\n setStep(\"time\")\n }\n scrollToTop()\n }\n\n const handleStaffContinue = () => {\n if (!canSkipStaff && !selectedStaff) return\n setStep(\"time\")\n scrollToTop()\n }\n\n const handleTimeContinue = () => {\n if (!selectedTime || !selectedEndTime) return\n setStep(\"details\")\n scrollToTop()\n }\n\n const handleSubmit = async (event: React.FormEvent) => {\n event.preventDefault()\n if (!selectedService || !selectedDate || !selectedTime || !selectedEndTime) return\n\n const start = parseDateTime(selectedTime, selectedDate)\n const end = parseDateTime(selectedEndTime, selectedDate)\n\n if (!start || !end) {\n setBookingError(\"Please select a valid time slot.\")\n return\n }\n\n try {\n setBookingError(null)\n const result = await createBooking.mutateAsync({\n serviceId: selectedService.id,\n staffId: selectedStaff?.id,\n startTime: start.toISOString(),\n endTime: end.toISOString(),\n customerName: details.name,\n customerEmail: details.email,\n customerPhone: details.phone || undefined,\n customerNotes: details.notes || undefined,\n })\n\n setStep(\"done\")\n onSuccess?.(result?.booking)\n scrollToTop()\n } catch (error) {\n setBookingError(\n error instanceof Error ? error.message : \"Unable to complete booking. Please try again.\"\n )\n }\n }\n\n const isServicesLoading = services ? false : servicesLoading\n\n if (isServicesLoading) {\n return <div className=\"idk-state\">Loading booking options...</div>\n }\n\n if (!servicesList.length) {\n return <div className=\"idk-state\">No services available.</div>\n }\n\n return (\n <div\n ref={widgetRef}\n className={[\"idk-booking\", className].filter(Boolean).join(\" \")}\n >\n <div className=\"idk-booking__header\">\n <div className=\"idk-booking__title-wrap\">\n <h3 className=\"idk-booking__title\">{title}</h3>\n {subtitle ? <p className=\"idk-booking__subtitle\">{subtitle}</p> : null}\n </div>\n {step !== \"service\" && step !== \"done\" ? (\n <button type=\"button\" className=\"idk-link\" onClick={handleBack}>\n Back\n </button>\n ) : null}\n </div>\n\n {step !== \"done\" ? (\n <div className=\"idk-booking__progress\">\n <span>Step {stepNumber} of {totalSteps}</span>\n <div className=\"idk-booking__bar\">\n <div\n className=\"idk-booking__bar-fill\"\n style={{ width: `${(stepNumber / totalSteps) * 100}%` }}\n />\n </div>\n </div>\n ) : null}\n\n {step === \"service\" && (\n <div className=\"idk-booking__step\">\n <h4>Select a service</h4>\n {(enableServiceSearch || enableCategoryFilter) ? (\n <div className=\"idk-booking__filters\">\n {enableServiceSearch ? (\n <input\n type=\"search\"\n value={serviceSearch}\n onChange={(event) => setServiceSearch(event.target.value)}\n placeholder={serviceSearchPlaceholder}\n />\n ) : null}\n {enableCategoryFilter && categories.length > 0 ? (\n <select\n value={categoryFilter}\n onChange={(event) => setCategoryFilter(event.target.value)}\n >\n <option value=\"all\">{categoryLabel}</option>\n {categories.map((category) => (\n <option key={category} value={category}>{category}</option>\n ))}\n </select>\n ) : null}\n </div>\n ) : null}\n\n {filteredServices.length === 0 ? (\n <div className=\"idk-state\">No services match your filters.</div>\n ) : (\n <div\n className={[\n \"idk-services\",\n serviceLayout === \"grid\" ? \"idk-services--grid\" : \"idk-services--list\",\n ].join(\" \")}\n style={{\n ...(serviceLayout === \"grid\"\n ? { gridTemplateColumns: `repeat(${Math.max(1, serviceColumns)}, minmax(0, 1fr))` }\n : undefined),\n ...(serviceListMaxHeight ? { maxHeight: serviceListMaxHeight, overflow: \"auto\" } : undefined),\n }}\n >\n {pagedServices.map((service) => {\n const isSelected = selectedService?.id === service.id\n return (\n <button\n key={service.id}\n type=\"button\"\n className={[\"idk-card\", \"idk-card--clickable\", isSelected ? \"is-active\" : \"\"].join(\" \")}\n onClick={() => {\n setSelectedService(service)\n resetSelections()\n if (autoAdvanceOnSelect) {\n if (requiresStaff) {\n setStep(\"staff\")\n } else {\n setStep(\"time\")\n }\n scrollToTop()\n }\n }}\n >\n <div className=\"idk-card__header\">\n <span className=\"idk-card__title\">{service.name}</span>\n <span className=\"idk-card__aside\">\n {isSelected ? <span className=\"idk-card__check\">✓</span> : null}\n {typeof service.price === \"number\" && service.price > 0 ? (\n <span className=\"idk-card__price\">\n ${(service.price / 100).toFixed(2)}\n </span>\n ) : null}\n </span>\n </div>\n {service.description ? (\n <div className=\"idk-card__description\">{service.description}</div>\n ) : null}\n <div className=\"idk-card__meta\">\n <span>{formatDuration(service.duration)}</span>\n {service.category ? <span className=\"idk-pill\">{service.category}</span> : null}\n </div>\n </button>\n )\n })}\n </div>\n )}\n\n <div className=\"idk-booking__actions\">\n {shouldPaginate ? (\n <button\n type=\"button\"\n className=\"idk-button idk-button--ghost\"\n onClick={() => setServicePage((prev) => prev + 1)}\n disabled={!hasMoreServices}\n >\n {hasMoreServices ? \"Show more services\" : \"All services shown\"}\n </button>\n ) : null}\n {selectedService && !autoAdvanceOnSelect ? (\n <button type=\"button\" className=\"idk-button\" onClick={handleServiceContinue}>\n Continue\n </button>\n ) : null}\n </div>\n </div>\n )}\n\n {step === \"staff\" && (\n <div className=\"idk-booking__step\">\n <h4>Select a team member</h4>\n {staffOptions.length === 0 ? (\n <div className=\"idk-state\">No team members available.</div>\n ) : (\n <div\n className={[\n \"idk-team\",\n staffLayout === \"grid\" ? \"idk-team--grid\" : \"idk-team--list\",\n ].join(\" \")}\n style={\n staffLayout === \"grid\"\n ? { gridTemplateColumns: `repeat(${Math.max(1, staffColumns)}, minmax(0, 1fr))` }\n : undefined\n }\n >\n {showAnyStaffOption && canSkipStaff ? (\n <button\n key=\"any-staff\"\n type=\"button\"\n className={[\"idk-card\", \"idk-card--clickable\", !selectedStaff ? \"is-active\" : \"\"].join(\" \")}\n onClick={() => {\n setSelectedStaff(null)\n setSelectedDate(null)\n setSelectedTime(null)\n setSelectedEndTime(null)\n if (autoAdvanceOnSelect) {\n setStep(\"time\")\n scrollToTop()\n }\n }}\n >\n <div className=\"idk-card__header\">\n <span className=\"idk-card__title\">Any Available</span>\n <span className=\"idk-card__badge\">Recommended</span>\n </div>\n <p className=\"idk-card__description\">\n We'll match you with the first available stylist.\n </p>\n </button>\n ) : null}\n {staffOptions.map((staff) => (\n <button\n key={staff.id}\n type=\"button\"\n className={[\"idk-card\", \"idk-card--clickable\", selectedStaff?.id === staff.id ? \"is-active\" : \"\"].join(\" \")}\n onClick={() => {\n setSelectedStaff(staff)\n setSelectedDate(null)\n setSelectedTime(null)\n setSelectedEndTime(null)\n setBookingError(null)\n if (autoAdvanceOnSelect) {\n setStep(\"time\")\n scrollToTop()\n }\n }}\n >\n <div className=\"idk-team__card\">\n <div className=\"idk-team__avatar\">\n {staff.photo?.url ? (\n <img src={staff.photo.url} alt={staff.name} />\n ) : (\n <span>{staff.name.split(\" \").map((part) => part[0]).slice(0, 2).join(\"\").toUpperCase()}</span>\n )}\n </div>\n <div>\n <span className=\"idk-card__title\">{staff.name}</span>\n <span className=\"idk-card__meta\">{staff.role || \"Staff\"}</span>\n {staff.bio ? <p className=\"idk-card__description\">{staff.bio}</p> : null}\n </div>\n </div>\n </button>\n ))}\n </div>\n )}\n <div className=\"idk-booking__actions\">\n {canSkipStaff ? (\n <button\n type=\"button\"\n className=\"idk-link\"\n onClick={() => {\n setSelectedStaff(null)\n setStep(\"time\")\n scrollToTop()\n }}\n >\n Continue without selecting\n </button>\n ) : null}\n {!autoAdvanceOnSelect ? (\n <button\n type=\"button\"\n className=\"idk-button\"\n onClick={handleStaffContinue}\n disabled={!canSkipStaff && !selectedStaff}\n >\n Continue\n </button>\n ) : null}\n </div>\n </div>\n )}\n\n {step === \"time\" && (\n <div className=\"idk-booking__step\">\n <h4>Select a time</h4>\n {availability.isLoading ? (\n <div className=\"idk-state\">Loading availability...</div>\n ) : availability.data ? (\n <div className={[\"idk-availability\", timeLayout === \"split\" ? \"idk-availability--split\" : \"\"].join(\" \")}>\n <div className=\"idk-availability__dates\">\n {availability.data.dates.map((entry) => (\n <button\n key={entry.date}\n type=\"button\"\n className={entry.date === selectedDate ? \"is-active\" : undefined}\n onClick={() => {\n setSelectedDate(entry.date)\n setSelectedTime(null)\n setSelectedEndTime(null)\n setBookingError(null)\n }}\n >\n <span className=\"idk-date-chip__day\">{formatDateLabel(entry.date)}</span>\n </button>\n ))}\n </div>\n <div className=\"idk-availability__panel\">\n <div className=\"idk-availability__panel-header\">\n <div>\n <div className=\"idk-availability__panel-title\">\n {selectedDate\n ? formatDateHeading(selectedDate)\n : availability.data.dates[0]?.date\n ? formatDateHeading(availability.data.dates[0].date)\n : \"Select a date\"}\n </div>\n <div className=\"idk-availability__panel-subtitle\">{timeZoneLabel}</div>\n </div>\n </div>\n <div className=\"idk-availability__slots\">\n {(() => {\n const activeEntry =\n availability.data.dates.find((entry) => entry.date === selectedDate) ||\n availability.data.dates[0]\n if (!activeEntry) return <div className=\"idk-state\">Select a date to see times.</div>\n const slots = (activeEntry.slots || []).filter((slot) => slot.available)\n if (slots.length === 0) {\n return <div className=\"idk-state\">No available times for this date.</div>\n }\n return slots.map((slot) => (\n <button\n key={`${slot.time}-${slot.endTime}`}\n type=\"button\"\n className={slot.time === selectedTime ? \"is-active\" : undefined}\n onClick={() => {\n const date = selectedDate || activeEntry.date\n setSelectedDate(date || null)\n setSelectedTime(slot.time)\n setSelectedEndTime(slot.endTime)\n setBookingError(null)\n if (autoAdvanceOnSelect) {\n setStep(\"details\")\n scrollToTop()\n }\n }}\n >\n {formatTimeLabel(slot.time)}\n </button>\n ))\n })()}\n </div>\n </div>\n </div>\n ) : (\n <div className=\"idk-state\">No availability found.</div>\n )}\n {!autoAdvanceOnSelect ? (\n <div className=\"idk-booking__actions\">\n <button\n type=\"button\"\n className=\"idk-button\"\n onClick={handleTimeContinue}\n disabled={!selectedTime || !selectedEndTime}\n >\n Continue\n </button>\n </div>\n ) : null}\n </div>\n )}\n\n {step === \"details\" && (\n <form className=\"idk-form\" onSubmit={handleSubmit}>\n <h4>Your details</h4>\n {bookingError ? <div className=\"idk-booking__error\">{bookingError}</div> : null}\n {selectedService && selectedTime ? (\n <div className=\"idk-booking__summary\">\n <div>\n <span className=\"idk-booking__summary-label\">Service</span>\n <p>{selectedService.name}</p>\n </div>\n {selectedStaff ? (\n <div>\n <span className=\"idk-booking__summary-label\">Staff</span>\n <p>{selectedStaff.name}</p>\n </div>\n ) : null}\n <div>\n <span className=\"idk-booking__summary-label\">When</span>\n <p>{formatDateHeading(selectedDate || \"\")} · {formatTimeLabel(selectedTime)}</p>\n </div>\n {selectedService.price ? (\n <div>\n <span className=\"idk-booking__summary-label\">Price</span>\n <p>${(selectedService.price / 100).toFixed(2)}</p>\n </div>\n ) : null}\n </div>\n ) : null}\n <label className=\"idk-form__field\">\n <span>Name</span>\n <input\n value={details.name}\n onChange={(event) => setDetails((prev) => ({ ...prev, name: event.target.value }))}\n required\n />\n </label>\n <label className=\"idk-form__field\">\n <span>Email</span>\n <input\n type=\"email\"\n value={details.email}\n onChange={(event) => setDetails((prev) => ({ ...prev, email: event.target.value }))}\n required\n />\n </label>\n <label className=\"idk-form__field\">\n <span>Phone</span>\n <input\n value={details.phone}\n onChange={(event) => setDetails((prev) => ({ ...prev, phone: event.target.value }))}\n />\n </label>\n <label className=\"idk-form__field\">\n <span>Notes</span>\n <textarea\n rows={4}\n value={details.notes}\n onChange={(event) => setDetails((prev) => ({ ...prev, notes: event.target.value }))}\n />\n </label>\n <button type=\"submit\" className=\"idk-button\" disabled={createBooking.isPending}>\n {createBooking.isPending ? \"Booking...\" : \"Confirm booking\"}\n </button>\n </form>\n )}\n\n {step === \"done\" && (\n <div className=\"idk-booking__done\">\n <div className=\"idk-booking__done-title\">Booking confirmed!</div>\n <p className=\"idk-booking__done-text\">\n We'll send a confirmation email shortly with your appointment details.\n </p>\n <button\n type=\"button\"\n className=\"idk-link\"\n onClick={() => {\n setStep(\"service\")\n setSelectedService(null)\n resetSelections()\n setDetails({ name: \"\", email: \"\", phone: \"\", notes: \"\" })\n scrollToTop()\n }}\n >\n Book another appointment\n </button>\n </div>\n )}\n </div>\n )\n}\n","'use client'\n\nimport { useState } from 'react'\nimport { useAvailability } from '../core/hooks/useAvailability'\n\ninterface AvailabilityPickerProps {\n serviceId: string\n staffId?: string\n date?: string\n days?: number\n className?: string\n onSelect?: (params: { date: string; time: string; endTime: string }) => void\n}\n\nexport function AvailabilityPicker({\n serviceId,\n staffId,\n date,\n days = 7,\n className,\n onSelect,\n}: AvailabilityPickerProps) {\n const [selectedDate, setSelectedDate] = useState<string | null>(date || null)\n const [selectedTime, setSelectedTime] = useState<string | null>(null)\n\n const { data, isLoading } = useAvailability({\n serviceId,\n staffId,\n date,\n days,\n })\n\n if (isLoading) {\n return <div className=\"idk-state\">Loading availability...</div>\n }\n\n if (!data?.dates?.length) {\n return <div className=\"idk-state\">No availability found.</div>\n }\n\n const activeDate = selectedDate || data.dates[0]?.date\n const activeSlots = data.dates.find((entry) => entry.date === activeDate)?.slots || []\n\n return (\n <div className={['idk-availability', className].filter(Boolean).join(' ')}>\n <div className=\"idk-availability__dates\">\n {data.dates.map((entry) => (\n <button\n key={entry.date}\n type=\"button\"\n className={entry.date === activeDate ? 'is-active' : undefined}\n onClick={() => {\n setSelectedDate(entry.date)\n setSelectedTime(null)\n }}\n >\n {entry.date}\n </button>\n ))}\n </div>\n <div className=\"idk-availability__slots\">\n {activeSlots.filter((slot) => slot.available).length === 0 ? (\n <div className=\"idk-state\">No slots available.</div>\n ) : (\n activeSlots\n .filter((slot) => slot.available)\n .map((slot) => (\n <button\n key={`${activeDate}-${slot.time}`}\n type=\"button\"\n className={selectedTime === slot.time ? 'is-active' : undefined}\n onClick={() => {\n setSelectedTime(slot.time)\n if (onSelect && activeDate) {\n onSelect({\n date: activeDate,\n time: slot.time,\n endTime: slot.endTime,\n })\n }\n }}\n >\n {slot.time}\n </button>\n ))\n )}\n </div>\n </div>\n )\n}\n","\"use client\"\n\nimport type { Service } from \"../types\"\n\ninterface ServicePickerProps {\n services: Service[]\n selectedId?: string | null\n onSelect?: (service: Service) => void\n className?: string\n}\n\nexport function ServicePicker({\n services,\n selectedId,\n onSelect,\n className,\n}: ServicePickerProps) {\n return (\n <div className={[\"idk-picker\", className].filter(Boolean).join(\" \")}>\n {services.map((service) => (\n <button\n key={service.id}\n type=\"button\"\n className={selectedId === service.id ? \"is-active\" : undefined}\n onClick={() => onSelect?.(service)}\n >\n <span>{service.name}</span>\n <small>{service.duration} min</small>\n </button>\n ))}\n </div>\n )\n}\n","\"use client\"\n\nimport type { StaffMember } from \"../types\"\n\ninterface StaffPickerProps {\n staff: StaffMember[]\n selectedId?: string | null\n onSelect?: (member: StaffMember) => void\n className?: string\n}\n\nexport function StaffPicker({\n staff,\n selectedId,\n onSelect,\n className,\n}: StaffPickerProps) {\n return (\n <div className={[\"idk-picker\", className].filter(Boolean).join(\" \")}>\n {staff.map((member) => (\n <button\n key={member.id}\n type=\"button\"\n className={selectedId === member.id ? \"is-active\" : undefined}\n onClick={() => onSelect?.(member)}\n >\n <span>{member.name}</span>\n <small>{member.role || \"Staff\"}</small>\n </button>\n ))}\n </div>\n )\n}\n","\"use client\"\n\ninterface DatePickerProps {\n dates: string[]\n selectedDate?: string | null\n onSelect?: (date: string) => void\n className?: string\n}\n\nexport function DatePicker({\n dates,\n selectedDate,\n onSelect,\n className,\n}: DatePickerProps) {\n return (\n <div className={[\"idk-picker\", className].filter(Boolean).join(\" \")}>\n {dates.map((date) => (\n <button\n key={date}\n type=\"button\"\n className={selectedDate === date ? \"is-active\" : undefined}\n onClick={() => onSelect?.(date)}\n >\n {date}\n </button>\n ))}\n </div>\n )\n}\n","\"use client\"\n\nimport type { AvailabilitySlot } from \"../types\"\n\ninterface TimePickerProps {\n slots: AvailabilitySlot[]\n selectedTime?: string | null\n onSelect?: (slot: AvailabilitySlot) => void\n className?: string\n}\n\nexport function TimePicker({\n slots,\n selectedTime,\n onSelect,\n className,\n}: TimePickerProps) {\n return (\n <div className={[\"idk-picker\", className].filter(Boolean).join(\" \")}>\n {slots.map((slot) => (\n <button\n key={`${slot.time}-${slot.endTime}`}\n type=\"button\"\n className={selectedTime === slot.time ? \"is-active\" : undefined}\n disabled={!slot.available}\n onClick={() => onSelect?.(slot)}\n >\n {slot.time}\n </button>\n ))}\n </div>\n )\n}\n"],"mappings":"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","names":["import_react","import_react_query","import_react","import_react_query","import_react","import_react_query","buildQuery","import_react","import_react_query","buildQuery","import_react_query","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_react","import_react_query","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -51,6 +51,7 @@ interface StaffMember {
|
|
|
51
51
|
email: string;
|
|
52
52
|
aliasEmail?: string;
|
|
53
53
|
phone?: string;
|
|
54
|
+
bio?: string;
|
|
54
55
|
role?: 'owner' | 'manager' | 'staff';
|
|
55
56
|
timeZone?: string;
|
|
56
57
|
isActive?: boolean;
|
|
@@ -61,6 +62,7 @@ interface Service {
|
|
|
61
62
|
id: string;
|
|
62
63
|
name: string;
|
|
63
64
|
description?: string;
|
|
65
|
+
image?: MediaRef | null;
|
|
64
66
|
duration: number;
|
|
65
67
|
price?: number;
|
|
66
68
|
category?: string;
|
|
@@ -147,13 +149,38 @@ interface ServicesResponse {
|
|
|
147
149
|
services: Service[];
|
|
148
150
|
total: number;
|
|
149
151
|
}
|
|
150
|
-
|
|
152
|
+
interface ServicesQueryParams {
|
|
153
|
+
category?: string | string[];
|
|
154
|
+
staffId?: string;
|
|
155
|
+
isActive?: boolean;
|
|
156
|
+
minPrice?: number;
|
|
157
|
+
maxPrice?: number;
|
|
158
|
+
search?: string;
|
|
159
|
+
ids?: string[];
|
|
160
|
+
limit?: number;
|
|
161
|
+
sort?: 'name' | 'price' | 'duration' | 'sortOrder';
|
|
162
|
+
order?: 'asc' | 'desc';
|
|
163
|
+
enabled?: boolean;
|
|
164
|
+
}
|
|
165
|
+
declare function useServices(params?: ServicesQueryParams): _tanstack_react_query.UseQueryResult<ServicesResponse, Error>;
|
|
151
166
|
|
|
152
167
|
interface TeamResponse {
|
|
153
168
|
team: StaffMember[];
|
|
154
169
|
total: number;
|
|
155
170
|
}
|
|
156
|
-
|
|
171
|
+
interface TeamQueryParams {
|
|
172
|
+
role?: string | string[];
|
|
173
|
+
isActive?: boolean;
|
|
174
|
+
acceptsNewBookings?: boolean;
|
|
175
|
+
search?: string;
|
|
176
|
+
ids?: string[];
|
|
177
|
+
serviceId?: string;
|
|
178
|
+
limit?: number;
|
|
179
|
+
sort?: 'name' | 'role' | 'createdAt';
|
|
180
|
+
order?: 'asc' | 'desc';
|
|
181
|
+
enabled?: boolean;
|
|
182
|
+
}
|
|
183
|
+
declare function useTeam(params?: TeamQueryParams): _tanstack_react_query.UseQueryResult<TeamResponse, Error>;
|
|
157
184
|
|
|
158
185
|
interface AvailabilityParams {
|
|
159
186
|
serviceId: string;
|
|
@@ -180,34 +207,54 @@ interface ServicesListProps {
|
|
|
180
207
|
className?: string;
|
|
181
208
|
showDescription?: boolean;
|
|
182
209
|
showPrice?: boolean;
|
|
210
|
+
showImage?: boolean;
|
|
211
|
+
query?: ServicesQueryParams;
|
|
212
|
+
filter?: (service: Service) => boolean;
|
|
213
|
+
sort?: (a: Service, b: Service) => number;
|
|
214
|
+
limit?: number;
|
|
215
|
+
emptyMessage?: string;
|
|
216
|
+
loadingMessage?: string;
|
|
183
217
|
onSelect?: (service: Service) => void;
|
|
184
218
|
}
|
|
185
|
-
declare function ServicesList({ layout, columns, className, showDescription, showPrice, onSelect, }: ServicesListProps): react_jsx_runtime.JSX.Element;
|
|
219
|
+
declare function ServicesList({ layout, columns, className, showDescription, showPrice, showImage, query, filter, sort, limit, emptyMessage, loadingMessage, onSelect, }: ServicesListProps): react_jsx_runtime.JSX.Element;
|
|
186
220
|
|
|
187
221
|
interface ServiceCardProps {
|
|
188
222
|
service: Service;
|
|
189
223
|
className?: string;
|
|
190
224
|
showDescription?: boolean;
|
|
191
225
|
showPrice?: boolean;
|
|
226
|
+
showImage?: boolean;
|
|
192
227
|
onSelect?: (service: Service) => void;
|
|
193
228
|
}
|
|
194
|
-
declare function ServiceCard({ service, className, showDescription, showPrice, onSelect, }: ServiceCardProps): react_jsx_runtime.JSX.Element;
|
|
229
|
+
declare function ServiceCard({ service, className, showDescription, showPrice, showImage, onSelect, }: ServiceCardProps): react_jsx_runtime.JSX.Element;
|
|
195
230
|
|
|
196
231
|
interface TeamGridProps {
|
|
197
232
|
columns?: number;
|
|
198
233
|
className?: string;
|
|
199
234
|
showRole?: boolean;
|
|
200
235
|
showEmail?: boolean;
|
|
236
|
+
showBio?: boolean;
|
|
237
|
+
layout?: "card" | "profile";
|
|
238
|
+
imagePosition?: "left" | "right";
|
|
239
|
+
query?: TeamQueryParams;
|
|
240
|
+
filter?: (member: StaffMember) => boolean;
|
|
241
|
+
sort?: (a: StaffMember, b: StaffMember) => number;
|
|
242
|
+
limit?: number;
|
|
243
|
+
emptyMessage?: string;
|
|
244
|
+
loadingMessage?: string;
|
|
201
245
|
}
|
|
202
|
-
declare function TeamGrid({ columns, className, showRole, showEmail, }: TeamGridProps): react_jsx_runtime.JSX.Element;
|
|
246
|
+
declare function TeamGrid({ columns, className, showRole, showEmail, showBio, layout, imagePosition, query, filter, sort, limit, emptyMessage, loadingMessage, }: TeamGridProps): react_jsx_runtime.JSX.Element;
|
|
203
247
|
|
|
204
248
|
interface TeamMemberProps {
|
|
205
249
|
member: StaffMember;
|
|
206
250
|
className?: string;
|
|
207
251
|
showRole?: boolean;
|
|
208
252
|
showEmail?: boolean;
|
|
253
|
+
showBio?: boolean;
|
|
254
|
+
layout?: "card" | "profile";
|
|
255
|
+
imagePosition?: "left" | "right";
|
|
209
256
|
}
|
|
210
|
-
declare function TeamMember({ member, className, showRole, showEmail, }: TeamMemberProps): react_jsx_runtime.JSX.Element;
|
|
257
|
+
declare function TeamMember({ member, className, showRole, showEmail, showBio, layout, imagePosition, }: TeamMemberProps): react_jsx_runtime.JSX.Element;
|
|
211
258
|
|
|
212
259
|
type ContactField = 'name' | 'email' | 'phone' | 'subject' | 'message';
|
|
213
260
|
interface ContactFormProps {
|
|
@@ -224,8 +271,31 @@ interface BookingWidgetProps {
|
|
|
224
271
|
className?: string;
|
|
225
272
|
showStaffSelection?: boolean;
|
|
226
273
|
onSuccess?: (booking: unknown) => void;
|
|
274
|
+
services?: Service[];
|
|
275
|
+
servicesQuery?: ServicesQueryParams;
|
|
276
|
+
teamQuery?: TeamQueryParams;
|
|
277
|
+
serviceFilter?: (service: Service) => boolean;
|
|
278
|
+
teamFilter?: (member: StaffMember) => boolean;
|
|
279
|
+
title?: string;
|
|
280
|
+
subtitle?: string;
|
|
281
|
+
autoAdvanceOnSelect?: boolean;
|
|
282
|
+
scrollToStep?: boolean;
|
|
283
|
+
scrollOffset?: number;
|
|
284
|
+
enableServiceSearch?: boolean;
|
|
285
|
+
serviceSearchPlaceholder?: string;
|
|
286
|
+
enableCategoryFilter?: boolean;
|
|
287
|
+
categoryLabel?: string;
|
|
288
|
+
serviceListMaxHeight?: number | string;
|
|
289
|
+
serviceLayout?: "list" | "grid";
|
|
290
|
+
serviceColumns?: number;
|
|
291
|
+
servicePageSize?: number;
|
|
292
|
+
showServicePagination?: boolean;
|
|
293
|
+
staffLayout?: "list" | "grid";
|
|
294
|
+
staffColumns?: number;
|
|
295
|
+
showAnyStaffOption?: boolean;
|
|
296
|
+
timeLayout?: "stack" | "split";
|
|
227
297
|
}
|
|
228
|
-
declare function BookingWidget({ className, showStaffSelection, onSuccess, }: BookingWidgetProps): react_jsx_runtime.JSX.Element;
|
|
298
|
+
declare function BookingWidget({ className, showStaffSelection, onSuccess, services, servicesQuery, teamQuery, serviceFilter, teamFilter, title, subtitle, autoAdvanceOnSelect, scrollToStep, scrollOffset, enableServiceSearch, serviceSearchPlaceholder, enableCategoryFilter, categoryLabel, serviceListMaxHeight, serviceLayout, serviceColumns, servicePageSize, showServicePagination, staffLayout, staffColumns, showAnyStaffOption, timeLayout, }: BookingWidgetProps): react_jsx_runtime.JSX.Element;
|
|
229
299
|
|
|
230
300
|
interface AvailabilityPickerProps {
|
|
231
301
|
serviceId: string;
|
|
@@ -273,4 +343,4 @@ interface TimePickerProps {
|
|
|
273
343
|
}
|
|
274
344
|
declare function TimePicker({ slots, selectedTime, onSelect, className, }: TimePickerProps): react_jsx_runtime.JSX.Element;
|
|
275
345
|
|
|
276
|
-
export { AvailabilityPicker, type AvailabilityResult, type BookingCancelInput, type BookingCreateInput, type BookingLookup, BookingWidget, ContactForm, type ContactSubmissionInput, DatePicker, PlatformProvider, type Service, ServiceCard, ServicePicker, ServicesList, type StaffMember, StaffPicker, TeamGrid, TeamMember, type TenantInfo, TimePicker, useAvailability, useBookingLookup, useCancelBooking, useCreateBooking, useServices, useTeam, useTenant };
|
|
346
|
+
export { AvailabilityPicker, type AvailabilityResult, type BookingCancelInput, type BookingCreateInput, type BookingLookup, BookingWidget, ContactForm, type ContactSubmissionInput, DatePicker, PlatformProvider, type Service, ServiceCard, ServicePicker, ServicesList, type ServicesQueryParams, type StaffMember, StaffPicker, TeamGrid, TeamMember, type TeamQueryParams, type TenantInfo, TimePicker, useAvailability, useBookingLookup, useCancelBooking, useCreateBooking, useServices, useTeam, useTenant };
|