@idkwebsites/components 0.1.0

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.
@@ -0,0 +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":["export { 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&apos;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&apos;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":"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","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"]}
@@ -0,0 +1,276 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import * as _tanstack_react_query from '@tanstack/react-query';
4
+ import { DehydratedState, DefaultOptions, QueryClient } from '@tanstack/react-query';
5
+
6
+ interface PlatformProviderProps {
7
+ apiKey: string;
8
+ apiUrl?: string;
9
+ children: ReactNode;
10
+ dehydratedState?: DehydratedState;
11
+ queryOptions?: DefaultOptions;
12
+ queryClient?: QueryClient;
13
+ }
14
+ declare function PlatformProvider({ apiKey, apiUrl, children, dehydratedState, queryOptions, queryClient, }: PlatformProviderProps): react_jsx_runtime.JSX.Element;
15
+
16
+ interface MediaRef {
17
+ url?: string;
18
+ }
19
+ interface TenantInfo {
20
+ id: string | number;
21
+ name?: string;
22
+ domain?: string;
23
+ customDomain?: string | null;
24
+ adminDomain?: string | null;
25
+ customSiteUrl?: string | null;
26
+ siteMode?: 'template' | 'custom';
27
+ tagline?: string | null;
28
+ phone?: string | null;
29
+ email?: string | null;
30
+ address?: string | null;
31
+ businessType?: string | null;
32
+ timezone?: string | null;
33
+ logo?: MediaRef | number | null;
34
+ logoInitials?: string | null;
35
+ primaryColor?: string | null;
36
+ accentStrategy?: string | null;
37
+ accentColor?: string | null;
38
+ fontPairing?: string | null;
39
+ headlineFont?: string | null;
40
+ bodyFont?: string | null;
41
+ animationTheme?: string | null;
42
+ customAnimation?: Record<string, unknown> | null;
43
+ socialLinks?: Array<{
44
+ platform: string;
45
+ url: string;
46
+ }>;
47
+ }
48
+ interface StaffMember {
49
+ id: string;
50
+ name: string;
51
+ email: string;
52
+ aliasEmail?: string;
53
+ phone?: string;
54
+ role?: 'owner' | 'manager' | 'staff';
55
+ timeZone?: string;
56
+ isActive?: boolean;
57
+ acceptsNewBookings?: boolean;
58
+ photo?: MediaRef | null;
59
+ }
60
+ interface Service {
61
+ id: string;
62
+ name: string;
63
+ description?: string;
64
+ duration: number;
65
+ price?: number;
66
+ category?: string;
67
+ slotInterval?: number;
68
+ minimumBookingNotice?: number;
69
+ beforeEventBuffer?: number;
70
+ afterEventBuffer?: number;
71
+ maxBookingsPerSlot?: number;
72
+ schedulingType?: 'customer-choice' | 'round-robin' | 'collective';
73
+ requiresStaffSelection?: boolean;
74
+ requiresConfirmation?: boolean;
75
+ assignedStaff?: StaffMember[];
76
+ isActive?: boolean;
77
+ }
78
+ interface AvailabilitySlot {
79
+ time: string;
80
+ endTime: string;
81
+ available: boolean;
82
+ }
83
+ interface AvailabilityDate {
84
+ date: string;
85
+ slots: AvailabilitySlot[];
86
+ }
87
+ interface AvailabilityResult {
88
+ service?: Service;
89
+ staff?: StaffMember;
90
+ dates: AvailabilityDate[];
91
+ timeZone?: string;
92
+ }
93
+ interface BookingCreateInput {
94
+ serviceId: string;
95
+ staffId?: string;
96
+ startTime: string;
97
+ endTime: string;
98
+ customerName: string;
99
+ customerEmail: string;
100
+ customerPhone?: string;
101
+ customerNotes?: string;
102
+ responses?: Record<string, unknown>;
103
+ }
104
+ interface BookingCancelInput {
105
+ uid: string;
106
+ reason?: string;
107
+ cancelledBy?: 'customer' | 'staff' | 'system';
108
+ }
109
+ interface BookingLookup {
110
+ bookingId: string;
111
+ uid: string;
112
+ status?: string;
113
+ tenantId?: string;
114
+ tenantName?: string;
115
+ service?: {
116
+ id?: string;
117
+ name?: string;
118
+ duration?: number;
119
+ schedulingType?: 'customer-choice' | 'round-robin' | 'collective';
120
+ requiresStaffSelection?: boolean;
121
+ };
122
+ staff?: {
123
+ id?: string;
124
+ name?: string;
125
+ };
126
+ customerName?: string;
127
+ customerEmail?: string;
128
+ startTime?: string;
129
+ endTime?: string;
130
+ timeZone?: string;
131
+ }
132
+ interface ContactSubmissionInput {
133
+ name: string;
134
+ email: string;
135
+ phone?: string;
136
+ subject?: string;
137
+ message: string;
138
+ service?: string;
139
+ page?: string;
140
+ formType?: 'contact' | 'quote' | 'inquiry';
141
+ metadata?: Record<string, unknown>;
142
+ }
143
+
144
+ declare function useTenant(): _tanstack_react_query.UseQueryResult<TenantInfo, Error>;
145
+
146
+ interface ServicesResponse {
147
+ services: Service[];
148
+ total: number;
149
+ }
150
+ declare function useServices(): _tanstack_react_query.UseQueryResult<ServicesResponse, Error>;
151
+
152
+ interface TeamResponse {
153
+ team: StaffMember[];
154
+ total: number;
155
+ }
156
+ declare function useTeam(): _tanstack_react_query.UseQueryResult<TeamResponse, Error>;
157
+
158
+ interface AvailabilityParams {
159
+ serviceId: string;
160
+ staffId?: string;
161
+ date?: string;
162
+ days?: number;
163
+ startDate?: string;
164
+ endDate?: string;
165
+ enabled?: boolean;
166
+ }
167
+ declare function useAvailability(params: AvailabilityParams): _tanstack_react_query.UseQueryResult<AvailabilityResult, Error>;
168
+
169
+ declare function useCreateBooking(): _tanstack_react_query.UseMutationResult<{
170
+ booking: unknown;
171
+ }, Error, BookingCreateInput, unknown>;
172
+ declare function useCancelBooking(): _tanstack_react_query.UseMutationResult<{
173
+ booking: unknown;
174
+ }, Error, BookingCancelInput, unknown>;
175
+ declare function useBookingLookup(uid?: string, enabled?: boolean): _tanstack_react_query.UseQueryResult<BookingLookup, Error>;
176
+
177
+ interface ServicesListProps {
178
+ layout?: 'grid' | 'list';
179
+ columns?: number;
180
+ className?: string;
181
+ showDescription?: boolean;
182
+ showPrice?: boolean;
183
+ onSelect?: (service: Service) => void;
184
+ }
185
+ declare function ServicesList({ layout, columns, className, showDescription, showPrice, onSelect, }: ServicesListProps): react_jsx_runtime.JSX.Element;
186
+
187
+ interface ServiceCardProps {
188
+ service: Service;
189
+ className?: string;
190
+ showDescription?: boolean;
191
+ showPrice?: boolean;
192
+ onSelect?: (service: Service) => void;
193
+ }
194
+ declare function ServiceCard({ service, className, showDescription, showPrice, onSelect, }: ServiceCardProps): react_jsx_runtime.JSX.Element;
195
+
196
+ interface TeamGridProps {
197
+ columns?: number;
198
+ className?: string;
199
+ showRole?: boolean;
200
+ showEmail?: boolean;
201
+ }
202
+ declare function TeamGrid({ columns, className, showRole, showEmail, }: TeamGridProps): react_jsx_runtime.JSX.Element;
203
+
204
+ interface TeamMemberProps {
205
+ member: StaffMember;
206
+ className?: string;
207
+ showRole?: boolean;
208
+ showEmail?: boolean;
209
+ }
210
+ declare function TeamMember({ member, className, showRole, showEmail, }: TeamMemberProps): react_jsx_runtime.JSX.Element;
211
+
212
+ type ContactField = 'name' | 'email' | 'phone' | 'subject' | 'message';
213
+ interface ContactFormProps {
214
+ fields?: ContactField[];
215
+ formType?: ContactSubmissionInput['formType'];
216
+ submitLabel?: string;
217
+ className?: string;
218
+ onSuccess?: () => void;
219
+ onError?: (message: string) => void;
220
+ }
221
+ declare function ContactForm({ fields, formType, submitLabel, className, onSuccess, onError, }: ContactFormProps): react_jsx_runtime.JSX.Element;
222
+
223
+ interface BookingWidgetProps {
224
+ className?: string;
225
+ showStaffSelection?: boolean;
226
+ onSuccess?: (booking: unknown) => void;
227
+ }
228
+ declare function BookingWidget({ className, showStaffSelection, onSuccess, }: BookingWidgetProps): react_jsx_runtime.JSX.Element;
229
+
230
+ interface AvailabilityPickerProps {
231
+ serviceId: string;
232
+ staffId?: string;
233
+ date?: string;
234
+ days?: number;
235
+ className?: string;
236
+ onSelect?: (params: {
237
+ date: string;
238
+ time: string;
239
+ endTime: string;
240
+ }) => void;
241
+ }
242
+ declare function AvailabilityPicker({ serviceId, staffId, date, days, className, onSelect, }: AvailabilityPickerProps): react_jsx_runtime.JSX.Element;
243
+
244
+ interface ServicePickerProps {
245
+ services: Service[];
246
+ selectedId?: string | null;
247
+ onSelect?: (service: Service) => void;
248
+ className?: string;
249
+ }
250
+ declare function ServicePicker({ services, selectedId, onSelect, className, }: ServicePickerProps): react_jsx_runtime.JSX.Element;
251
+
252
+ interface StaffPickerProps {
253
+ staff: StaffMember[];
254
+ selectedId?: string | null;
255
+ onSelect?: (member: StaffMember) => void;
256
+ className?: string;
257
+ }
258
+ declare function StaffPicker({ staff, selectedId, onSelect, className, }: StaffPickerProps): react_jsx_runtime.JSX.Element;
259
+
260
+ interface DatePickerProps {
261
+ dates: string[];
262
+ selectedDate?: string | null;
263
+ onSelect?: (date: string) => void;
264
+ className?: string;
265
+ }
266
+ declare function DatePicker({ dates, selectedDate, onSelect, className, }: DatePickerProps): react_jsx_runtime.JSX.Element;
267
+
268
+ interface TimePickerProps {
269
+ slots: AvailabilitySlot[];
270
+ selectedTime?: string | null;
271
+ onSelect?: (slot: AvailabilitySlot) => void;
272
+ className?: string;
273
+ }
274
+ declare function TimePicker({ slots, selectedTime, onSelect, className, }: TimePickerProps): react_jsx_runtime.JSX.Element;
275
+
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 };
@@ -0,0 +1,276 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import * as _tanstack_react_query from '@tanstack/react-query';
4
+ import { DehydratedState, DefaultOptions, QueryClient } from '@tanstack/react-query';
5
+
6
+ interface PlatformProviderProps {
7
+ apiKey: string;
8
+ apiUrl?: string;
9
+ children: ReactNode;
10
+ dehydratedState?: DehydratedState;
11
+ queryOptions?: DefaultOptions;
12
+ queryClient?: QueryClient;
13
+ }
14
+ declare function PlatformProvider({ apiKey, apiUrl, children, dehydratedState, queryOptions, queryClient, }: PlatformProviderProps): react_jsx_runtime.JSX.Element;
15
+
16
+ interface MediaRef {
17
+ url?: string;
18
+ }
19
+ interface TenantInfo {
20
+ id: string | number;
21
+ name?: string;
22
+ domain?: string;
23
+ customDomain?: string | null;
24
+ adminDomain?: string | null;
25
+ customSiteUrl?: string | null;
26
+ siteMode?: 'template' | 'custom';
27
+ tagline?: string | null;
28
+ phone?: string | null;
29
+ email?: string | null;
30
+ address?: string | null;
31
+ businessType?: string | null;
32
+ timezone?: string | null;
33
+ logo?: MediaRef | number | null;
34
+ logoInitials?: string | null;
35
+ primaryColor?: string | null;
36
+ accentStrategy?: string | null;
37
+ accentColor?: string | null;
38
+ fontPairing?: string | null;
39
+ headlineFont?: string | null;
40
+ bodyFont?: string | null;
41
+ animationTheme?: string | null;
42
+ customAnimation?: Record<string, unknown> | null;
43
+ socialLinks?: Array<{
44
+ platform: string;
45
+ url: string;
46
+ }>;
47
+ }
48
+ interface StaffMember {
49
+ id: string;
50
+ name: string;
51
+ email: string;
52
+ aliasEmail?: string;
53
+ phone?: string;
54
+ role?: 'owner' | 'manager' | 'staff';
55
+ timeZone?: string;
56
+ isActive?: boolean;
57
+ acceptsNewBookings?: boolean;
58
+ photo?: MediaRef | null;
59
+ }
60
+ interface Service {
61
+ id: string;
62
+ name: string;
63
+ description?: string;
64
+ duration: number;
65
+ price?: number;
66
+ category?: string;
67
+ slotInterval?: number;
68
+ minimumBookingNotice?: number;
69
+ beforeEventBuffer?: number;
70
+ afterEventBuffer?: number;
71
+ maxBookingsPerSlot?: number;
72
+ schedulingType?: 'customer-choice' | 'round-robin' | 'collective';
73
+ requiresStaffSelection?: boolean;
74
+ requiresConfirmation?: boolean;
75
+ assignedStaff?: StaffMember[];
76
+ isActive?: boolean;
77
+ }
78
+ interface AvailabilitySlot {
79
+ time: string;
80
+ endTime: string;
81
+ available: boolean;
82
+ }
83
+ interface AvailabilityDate {
84
+ date: string;
85
+ slots: AvailabilitySlot[];
86
+ }
87
+ interface AvailabilityResult {
88
+ service?: Service;
89
+ staff?: StaffMember;
90
+ dates: AvailabilityDate[];
91
+ timeZone?: string;
92
+ }
93
+ interface BookingCreateInput {
94
+ serviceId: string;
95
+ staffId?: string;
96
+ startTime: string;
97
+ endTime: string;
98
+ customerName: string;
99
+ customerEmail: string;
100
+ customerPhone?: string;
101
+ customerNotes?: string;
102
+ responses?: Record<string, unknown>;
103
+ }
104
+ interface BookingCancelInput {
105
+ uid: string;
106
+ reason?: string;
107
+ cancelledBy?: 'customer' | 'staff' | 'system';
108
+ }
109
+ interface BookingLookup {
110
+ bookingId: string;
111
+ uid: string;
112
+ status?: string;
113
+ tenantId?: string;
114
+ tenantName?: string;
115
+ service?: {
116
+ id?: string;
117
+ name?: string;
118
+ duration?: number;
119
+ schedulingType?: 'customer-choice' | 'round-robin' | 'collective';
120
+ requiresStaffSelection?: boolean;
121
+ };
122
+ staff?: {
123
+ id?: string;
124
+ name?: string;
125
+ };
126
+ customerName?: string;
127
+ customerEmail?: string;
128
+ startTime?: string;
129
+ endTime?: string;
130
+ timeZone?: string;
131
+ }
132
+ interface ContactSubmissionInput {
133
+ name: string;
134
+ email: string;
135
+ phone?: string;
136
+ subject?: string;
137
+ message: string;
138
+ service?: string;
139
+ page?: string;
140
+ formType?: 'contact' | 'quote' | 'inquiry';
141
+ metadata?: Record<string, unknown>;
142
+ }
143
+
144
+ declare function useTenant(): _tanstack_react_query.UseQueryResult<TenantInfo, Error>;
145
+
146
+ interface ServicesResponse {
147
+ services: Service[];
148
+ total: number;
149
+ }
150
+ declare function useServices(): _tanstack_react_query.UseQueryResult<ServicesResponse, Error>;
151
+
152
+ interface TeamResponse {
153
+ team: StaffMember[];
154
+ total: number;
155
+ }
156
+ declare function useTeam(): _tanstack_react_query.UseQueryResult<TeamResponse, Error>;
157
+
158
+ interface AvailabilityParams {
159
+ serviceId: string;
160
+ staffId?: string;
161
+ date?: string;
162
+ days?: number;
163
+ startDate?: string;
164
+ endDate?: string;
165
+ enabled?: boolean;
166
+ }
167
+ declare function useAvailability(params: AvailabilityParams): _tanstack_react_query.UseQueryResult<AvailabilityResult, Error>;
168
+
169
+ declare function useCreateBooking(): _tanstack_react_query.UseMutationResult<{
170
+ booking: unknown;
171
+ }, Error, BookingCreateInput, unknown>;
172
+ declare function useCancelBooking(): _tanstack_react_query.UseMutationResult<{
173
+ booking: unknown;
174
+ }, Error, BookingCancelInput, unknown>;
175
+ declare function useBookingLookup(uid?: string, enabled?: boolean): _tanstack_react_query.UseQueryResult<BookingLookup, Error>;
176
+
177
+ interface ServicesListProps {
178
+ layout?: 'grid' | 'list';
179
+ columns?: number;
180
+ className?: string;
181
+ showDescription?: boolean;
182
+ showPrice?: boolean;
183
+ onSelect?: (service: Service) => void;
184
+ }
185
+ declare function ServicesList({ layout, columns, className, showDescription, showPrice, onSelect, }: ServicesListProps): react_jsx_runtime.JSX.Element;
186
+
187
+ interface ServiceCardProps {
188
+ service: Service;
189
+ className?: string;
190
+ showDescription?: boolean;
191
+ showPrice?: boolean;
192
+ onSelect?: (service: Service) => void;
193
+ }
194
+ declare function ServiceCard({ service, className, showDescription, showPrice, onSelect, }: ServiceCardProps): react_jsx_runtime.JSX.Element;
195
+
196
+ interface TeamGridProps {
197
+ columns?: number;
198
+ className?: string;
199
+ showRole?: boolean;
200
+ showEmail?: boolean;
201
+ }
202
+ declare function TeamGrid({ columns, className, showRole, showEmail, }: TeamGridProps): react_jsx_runtime.JSX.Element;
203
+
204
+ interface TeamMemberProps {
205
+ member: StaffMember;
206
+ className?: string;
207
+ showRole?: boolean;
208
+ showEmail?: boolean;
209
+ }
210
+ declare function TeamMember({ member, className, showRole, showEmail, }: TeamMemberProps): react_jsx_runtime.JSX.Element;
211
+
212
+ type ContactField = 'name' | 'email' | 'phone' | 'subject' | 'message';
213
+ interface ContactFormProps {
214
+ fields?: ContactField[];
215
+ formType?: ContactSubmissionInput['formType'];
216
+ submitLabel?: string;
217
+ className?: string;
218
+ onSuccess?: () => void;
219
+ onError?: (message: string) => void;
220
+ }
221
+ declare function ContactForm({ fields, formType, submitLabel, className, onSuccess, onError, }: ContactFormProps): react_jsx_runtime.JSX.Element;
222
+
223
+ interface BookingWidgetProps {
224
+ className?: string;
225
+ showStaffSelection?: boolean;
226
+ onSuccess?: (booking: unknown) => void;
227
+ }
228
+ declare function BookingWidget({ className, showStaffSelection, onSuccess, }: BookingWidgetProps): react_jsx_runtime.JSX.Element;
229
+
230
+ interface AvailabilityPickerProps {
231
+ serviceId: string;
232
+ staffId?: string;
233
+ date?: string;
234
+ days?: number;
235
+ className?: string;
236
+ onSelect?: (params: {
237
+ date: string;
238
+ time: string;
239
+ endTime: string;
240
+ }) => void;
241
+ }
242
+ declare function AvailabilityPicker({ serviceId, staffId, date, days, className, onSelect, }: AvailabilityPickerProps): react_jsx_runtime.JSX.Element;
243
+
244
+ interface ServicePickerProps {
245
+ services: Service[];
246
+ selectedId?: string | null;
247
+ onSelect?: (service: Service) => void;
248
+ className?: string;
249
+ }
250
+ declare function ServicePicker({ services, selectedId, onSelect, className, }: ServicePickerProps): react_jsx_runtime.JSX.Element;
251
+
252
+ interface StaffPickerProps {
253
+ staff: StaffMember[];
254
+ selectedId?: string | null;
255
+ onSelect?: (member: StaffMember) => void;
256
+ className?: string;
257
+ }
258
+ declare function StaffPicker({ staff, selectedId, onSelect, className, }: StaffPickerProps): react_jsx_runtime.JSX.Element;
259
+
260
+ interface DatePickerProps {
261
+ dates: string[];
262
+ selectedDate?: string | null;
263
+ onSelect?: (date: string) => void;
264
+ className?: string;
265
+ }
266
+ declare function DatePicker({ dates, selectedDate, onSelect, className, }: DatePickerProps): react_jsx_runtime.JSX.Element;
267
+
268
+ interface TimePickerProps {
269
+ slots: AvailabilitySlot[];
270
+ selectedTime?: string | null;
271
+ onSelect?: (slot: AvailabilitySlot) => void;
272
+ className?: string;
273
+ }
274
+ declare function TimePicker({ slots, selectedTime, onSelect, className, }: TimePickerProps): react_jsx_runtime.JSX.Element;
275
+
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 };