@resira/ui 0.3.2 → 0.4.1

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.d.cts CHANGED
@@ -1,746 +1,801 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import React from 'react';
3
- import { Product, WeightedBaseUrl, Resira, RefundRule, TimeSlotAvailability, DurationPrice, PublicResource, ValidatePromoCodeResponse, Reservation, AvailabilityParams, Availability, Dish, PaymentIntentResponse, CreatePaymentIntentRequest, CreateReservationRequest } from '@resira/sdk';
4
- export { ConfirmPaymentRequest, ConfirmPaymentResponse, CreatePaymentIntentRequest, Dish, DishListResponse, DishModel, DishResponse, PaymentIntentResponse, PricingModel, Product, ProductListResponse, PublicResource, ResourceListResponse } from '@resira/sdk';
5
-
6
- type ResiraDomain = "rental" | "restaurant" | "watersport" | "service";
7
- /** Layout direction for the product/service selector. */
8
- type ServiceLayout = "vertical" | "horizontal";
9
- /** Domain-specific configuration. */
10
- interface DomainConfig {
11
- /** Label for the domain (e.g. "Vacation Rental", "Restaurant"). */
12
- label?: string;
13
- /** Default party size. */
14
- defaultPartySize?: number;
15
- /** Minimum party size. */
16
- minPartySize?: number;
17
- /** Maximum party size. */
18
- maxPartySize?: number;
19
- /** Minimum stay in nights (rental only). */
20
- minStay?: number;
21
- /** Default duration in minutes (service/watersport). */
22
- defaultDuration?: number;
23
- /** Available durations in minutes (service/watersport). */
24
- availableDurations?: number[];
25
- /** Allow selecting multiple resources in one booking. */
26
- allowMultiSelect?: boolean;
27
- }
28
- /** Theme color palette — maps to CSS custom properties. */
29
- interface ResiraTheme {
30
- /** Primary brand color. @default "#2563eb" */
31
- primaryColor?: string;
32
- /** Primary color on hover. @default "#1d4ed8" */
33
- primaryHover?: string;
34
- /** Text on primary background. @default "#ffffff" */
35
- primaryForeground?: string;
36
- /** Accent/secondary color. @default "#f0f4ff" */
37
- accentColor?: string;
38
- /** Accent foreground. @default "#1e40af" */
39
- accentForeground?: string;
40
- /** Error color. @default "#dc2626" */
41
- errorColor?: string;
42
- /** Success color. @default "#16a34a" */
43
- successColor?: string;
44
- /** Warning color. @default "#d97706" */
45
- warningColor?: string;
46
- /** Default text color. @default "#0f172a" */
47
- textColor?: string;
48
- /** Muted/secondary text. @default "#64748b" */
49
- mutedColor?: string;
50
- /** Surface / card background. @default "#ffffff" */
51
- surfaceColor?: string;
52
- /** Subtle background (e.g. form inputs). @default "#f8fafc" */
53
- backgroundSubtle?: string;
54
- /** Border color. @default "#e2e8f0" */
55
- borderColor?: string;
56
- /** Card border radius. @default "12px" */
57
- borderRadius?: string;
58
- /** Font family. @default "system-ui, -apple-system, sans-serif" */
59
- fontFamily?: string;
60
- /** Card component radius. @default "14px" */
61
- cardRadius?: string;
62
- /** Button radius. @default "10px" */
63
- buttonRadius?: string;
64
- /** Input radius. @default "10px" */
65
- inputRadius?: string;
66
- /** Chip/pill radius. @default "20px" */
67
- chipRadius?: string;
68
- /** Base spacing unit. @default "16px" */
69
- spacing?: string;
70
- /** Small shadow. */
71
- shadowSm?: string;
72
- /** Medium shadow. */
73
- shadowMd?: string;
74
- /** Large shadow. */
75
- shadowLg?: string;
76
- /** Calendar day cell size. @default "36px" */
77
- calendarDaySize?: string;
78
- /** Minimum width for time slot cells. @default "80px" */
79
- slotMinWidth?: string;
80
- }
81
- /** Internationalization strings. Override any label. */
82
- interface ResiraLocale {
83
- /** @default "Select dates" */
84
- selectDates?: string;
85
- /** @default "Select a time" */
86
- selectTime?: string;
87
- /** @default "Guest details" */
88
- guestDetails?: string;
89
- /** @default "Confirm booking" */
90
- confirmBooking?: string;
91
- /** @default "Booking confirmed" */
92
- bookingConfirmed?: string;
93
- /** @default "Full name" */
94
- fullName?: string;
95
- /** @default "Email" */
96
- email?: string;
97
- /** @default "Phone" */
98
- phone?: string;
99
- /** @default "Party size" */
100
- partySize?: string;
101
- /** @default "Notes" */
102
- notes?: string;
103
- /** @default "Check-in" */
104
- checkIn?: string;
105
- /** @default "Check-out" */
106
- checkOut?: string;
107
- /** @default "Guests" */
108
- guests?: string;
109
- /** @default "per night" */
110
- perNight?: string;
111
- /** @default "total" */
112
- total?: string;
113
- /** @default "Available" */
114
- available?: string;
115
- /** @default "Unavailable" */
116
- unavailable?: string;
117
- /** @default "Loading…" */
118
- loading?: string;
119
- /** @default "Something went wrong" */
120
- errorGeneric?: string;
121
- /** @default "Continue" */
122
- continue?: string;
123
- /** @default "Back" */
124
- back?: string;
125
- /** @default "Book now" */
126
- bookNow?: string;
127
- /** @default "nights" */
128
- nights?: string;
129
- /** @default "Duration" */
130
- duration?: string;
131
- /** @default "minutes" */
132
- minutes?: string;
133
- /** @default "No availability" */
134
- noAvailability?: string;
135
- /** @default "Required" */
136
- required?: string;
137
- /** @default "Invalid email" */
138
- invalidEmail?: string;
139
- /** @default "Choose a service" */
140
- chooseService?: string;
141
- /** @default "per session" */
142
- perSession?: string;
143
- /** @default "per person" */
144
- perPerson?: string;
145
- /** @default "Payment" */
146
- payment?: string;
147
- /** @default "Pay now" */
148
- payNow?: string;
149
- /** @default "Pay at venue" */
150
- payAtVenue?: string;
151
- /** @default "Processing payment…" */
152
- processingPayment?: string;
153
- /** @default "Payment failed" */
154
- paymentFailed?: string;
155
- /** @default "Terms & conditions" */
156
- termsTitle?: string;
157
- /** @default "I accept the terms and conditions" */
158
- termsAccept?: string;
159
- /** @default "I accept the waiver and release of liability" */
160
- waiverAccept?: string;
161
- /** @default "You must accept the terms to continue" */
162
- termsRequired?: string;
163
- /** @default "Discount code" */
164
- discountCode?: string;
165
- /** @default "Enter code" */
166
- discountPlaceholder?: string;
167
- /** @default "Apply" */
168
- discountApply?: string;
169
- /** @default "Code applied!" */
170
- discountApplied?: string;
171
- /** @default "Invalid code" */
172
- discountInvalid?: string;
173
- /** @default "Discount" */
174
- discountLabel?: string;
175
- /** @default "Original" */
176
- originalPrice?: string;
177
- /** @default "Cancellation policy" */
178
- refundPolicyTitle?: string;
179
- /** @default "Close" */
180
- close?: string;
181
- /** @default "Done" */
182
- done?: string;
183
- /** @default "Phone or email required" */
184
- contactRequired?: string;
185
- /** @default "Please provide at least a phone number or email" */
186
- contactHint?: string;
187
- /** @default "Allergies, special requests..." */
188
- restaurantNotesPlaceholder?: string;
189
- /** @default "Reserve a table" */
190
- reserveTable?: string;
191
- /** @default "Reservation for" */
192
- reservationFor?: string;
193
- }
194
- /** Default English locale. */
195
- declare const DEFAULT_LOCALE: Required<ResiraLocale>;
196
- /** CSS class name overrides for deep styling customization. */
197
- interface ResiraClassNames {
198
- /** Root widget wrapper. */
199
- root?: string;
200
- /** Step indicator bar. */
201
- steps?: string;
202
- /** Widget header area. */
203
- header?: string;
204
- /** Widget body area. */
205
- body?: string;
206
- /** Widget footer area. */
207
- footer?: string;
208
- /** Service/product card. */
209
- serviceCard?: string;
210
- /** Service/product card when selected. */
211
- serviceCardSelected?: string;
212
- /** Service list container. */
213
- serviceList?: string;
214
- /** Calendar container. */
215
- calendar?: string;
216
- /** Calendar day cell. */
217
- calendarDay?: string;
218
- /** Time slot button. */
219
- timeSlot?: string;
220
- /** Time slot button when selected. */
221
- timeSlotSelected?: string;
222
- /** Duration option button. */
223
- durationOption?: string;
224
- /** Party size control. */
225
- partySize?: string;
226
- /** Primary action button. */
227
- primaryButton?: string;
228
- /** Secondary action button. */
229
- secondaryButton?: string;
230
- /** Form field wrapper. */
231
- field?: string;
232
- /** Form input. */
233
- fieldInput?: string;
234
- /** Price preview panel. */
235
- pricePreview?: string;
236
- }
237
- /** Configuration passed to ResiraProvider. */
238
- interface ResiraProviderConfig {
239
- /** Theme overrides. */
240
- theme?: ResiraTheme;
241
- /** Locale / label overrides. */
242
- locale?: ResiraLocale;
243
- /** Domain-specific configuration overrides. */
244
- domainConfig?: DomainConfig;
245
- /** CSS class name overrides for full styling control. */
246
- classNames?: ResiraClassNames;
247
- /** Layout direction for services. @default "vertical" */
248
- serviceLayout?: ServiceLayout;
249
- /** Number of services visible before scrolling. @default 4 */
250
- visibleServiceCount?: number;
251
- /** Group services by linked equipment category. @default true */
252
- groupServicesByCategory?: boolean;
253
- /** Custom render function for service cards. Receives product and selected state. */
254
- renderServiceCard?: (product: Product, selected: boolean) => React.ReactNode;
255
- /** API base URL override (defaults to SDK default). */
256
- baseUrl?: string;
257
- /** Weighted API origins for client-side traffic splitting. */
258
- baseUrls?: Array<string | WeightedBaseUrl>;
259
- /** Stripe publishable key for payment processing. */
260
- stripePublishableKey?: string;
261
- /** Custom terms & conditions text or URL. */
262
- termsText?: string;
263
- /** Custom waiver text. */
264
- waiverText?: string;
265
- /** Whether to show the waiver checkbox. */
266
- showWaiver?: boolean;
267
- /** Whether to show the terms checkbox. */
268
- showTerms?: boolean;
269
- /** Whether to show remaining capacity labels in time slots. @default false */
270
- showRemainingSpots?: boolean;
271
- /** Percentage of total to charge upfront (0-100). Default 100. */
272
- depositPercent?: number;
273
- }
274
- /** Props for the ResiraProvider component. */
275
- interface ResiraProviderProps {
276
- /** API key for authentication. */
277
- apiKey: string;
278
- /** Resource ID to book. Optional — omit to enable catalog mode (multi-resource picker). */
279
- resourceId?: string;
280
- /** Booking domain type. */
281
- domain: ResiraDomain;
282
- /** Configuration overrides. */
283
- config?: ResiraProviderConfig;
284
- /** Callback when the modal/widget should close. */
285
- onClose?: () => void;
286
- /** Child components. */
287
- children: React.ReactNode;
288
- }
289
- /** Shape of the Resira context available to all child components. */
290
- interface ResiraContextValue {
291
- /** Instantiated SDK client. */
292
- client: Resira;
293
- /** Initial resource ID (may be undefined in catalog mode). */
294
- resourceId?: string;
295
- /** Currently active resource ID (set after user picks from catalog). */
296
- activeResourceId: string | undefined;
297
- /** Set the active resource ID. */
298
- setActiveResourceId: (id: string) => void;
299
- /** Whether catalog/multi-resource mode is enabled. */
300
- catalogMode: boolean;
301
- /** Whether multiple resources can be selected at once. */
302
- allowMultiSelect: boolean;
303
- /** Domain type. */
304
- domain: ResiraDomain;
305
- /** Resolved theme. */
306
- theme: Required<ResiraTheme>;
307
- /** Resolved locale. */
308
- locale: Required<ResiraLocale>;
309
- /** Resolved domain config. */
310
- domainConfig: DomainConfig;
311
- /** Stripe publishable key. */
312
- stripePublishableKey?: string;
313
- /** Custom terms text. */
314
- termsText?: string;
315
- /** Custom waiver text. */
316
- waiverText?: string;
317
- /** Whether to show the waiver checkbox. */
318
- showWaiver: boolean;
319
- /** Whether to show the terms checkbox. */
320
- showTerms: boolean;
321
- /** Whether to show remaining capacity labels in time slots. */
322
- showRemainingSpots: boolean;
323
- /** Deposit percentage (0-100). */
324
- depositPercent: number;
325
- /** Refund policy rules from property config. */
326
- refundPolicy: RefundRule[];
327
- /** Callback when the modal should close. */
328
- onClose?: () => void;
329
- /** CSS class name overrides. */
330
- classNames: ResiraClassNames;
331
- /** Layout direction for service cards. */
332
- serviceLayout: ServiceLayout;
333
- /** Number of visible service cards before scroll. */
334
- visibleServiceCount: number;
335
- /** Whether services should be grouped by linked equipment category. */
336
- groupServicesByCategory: boolean;
337
- /** Custom render function for service cards. */
338
- renderServiceCard?: (product: Product, selected: boolean) => React.ReactNode;
339
- }
340
- /** Steps in the booking flow. */
341
- type BookingStep = "resource" | "availability" | "details" | "terms" | "payment" | "confirmation";
342
- /** Selection state from the availability step. */
343
- interface BookingSelection {
344
- /** Selected start date (YYYY-MM-DD). */
345
- startDate?: string;
346
- /** Selected end date (YYYY-MM-DD). */
347
- endDate?: string;
348
- /** Selected time slot start (ISO 8601). */
349
- startTime?: string;
350
- /** Selected time slot end (ISO 8601). */
351
- endTime?: string;
352
- /** Party size. */
353
- partySize: number;
354
- /** Duration in minutes (watersport/service). */
355
- duration?: number;
356
- /** Selected product/service ID. */
357
- productId?: string;
358
- /** Discount code (optional, no server validation yet). */
359
- discountCode?: string;
360
- }
361
- /** Guest form values. */
362
- interface GuestFormValues {
363
- guestName: string;
364
- guestEmail: string;
365
- guestPhone: string;
366
- notes: string;
367
- }
368
- /** Validation errors for guest form fields. */
369
- type GuestFormErrors = Partial<Record<keyof GuestFormValues, string>>;
370
-
371
- /** Access the Resira context. Throws if used outside ResiraProvider. */
372
- declare function useResira(): ResiraContextValue;
373
- /**
374
- * ResiraProvider root of the @resira/ui component tree.
375
- *
376
- * Initializes the SDK client and provides domain configuration,
377
- * theme, and locale to all child components.
378
- *
379
- * ```tsx
380
- * <ResiraProvider apiKey="resira_live_…" resourceId="prop-1" domain="rental">
381
- * <ResiraBookingWidget />
382
- * </ResiraProvider>
383
- * ```
384
- */
385
- declare function ResiraProvider({ apiKey, resourceId, domain, config, onClose, children, }: ResiraProviderProps): react_jsx_runtime.JSX.Element;
386
-
387
- declare function ResiraBookingWidget(): react_jsx_runtime.JSX.Element;
388
-
389
- interface BookingModalProps {
390
- /** API key for authentication. */
391
- apiKey: string;
392
- /** Booking domain type. */
393
- domain: ResiraDomain;
394
- /** Optional resource ID (omit for catalog mode). */
395
- resourceId?: string;
396
- /** Configuration overrides. */
397
- config?: ResiraProviderConfig;
398
- /** Custom trigger button — if omitted, uses the default "Book Now" button. */
399
- trigger?: React.ReactNode;
400
- /** Custom button label. @default "Book Now" */
401
- buttonLabel?: string;
402
- /** Custom button className. */
403
- buttonClassName?: string;
404
- /** Custom button style. */
405
- buttonStyle?: React.CSSProperties;
406
- }
407
- declare function BookingModal({ apiKey, domain, resourceId, config, trigger, buttonLabel, buttonClassName, buttonStyle, }: BookingModalProps): react_jsx_runtime.JSX.Element;
408
-
409
- interface BookingCalendarProps {
410
- /** Set of blocked/unavailable dates (YYYY-MM-DD). */
411
- blockedDates?: Set<string>;
412
- /** Currently selected start date. */
413
- startDate?: string;
414
- /** Currently selected end date. */
415
- endDate?: string;
416
- /** Called when the user selects dates. */
417
- onSelect: (start: string, end: string | undefined) => void;
418
- /** Minimum stay in nights. */
419
- minStay?: number;
420
- }
421
- declare function BookingCalendar({ blockedDates, startDate, endDate, onSelect, minStay, }: BookingCalendarProps): react_jsx_runtime.JSX.Element;
422
-
423
- interface TimeSlotPickerProps {
424
- timeSlots: TimeSlotAvailability[];
425
- selectedDate: string;
426
- onDateChange: (date: string) => void;
427
- selectedSlot?: string;
428
- onSlotSelect: (start: string, end: string) => void;
429
- partySize: number;
430
- onPartySizeChange: (size: number) => void;
431
- showPartySize?: boolean;
432
- showDuration?: boolean;
433
- selectedDuration?: number;
434
- onDurationChange?: (minutes: number) => void;
435
- maxPartySizeOverride?: number;
436
- durationPricing?: DurationPrice[];
437
- currency?: string;
438
- /** Set of dates (YYYY-MM-DD) that are fully booked. */
439
- fullyBookedDates?: Set<string>;
440
- /** Whether to show remaining-capacity labels under available slots. */
441
- showRemainingSpots?: boolean;
442
- }
443
- declare function TimeSlotPicker({ timeSlots, selectedDate, onDateChange, selectedSlot, onSlotSelect, partySize, onPartySizeChange, showPartySize, showDuration, selectedDuration, onDurationChange, maxPartySizeOverride, durationPricing, currency, fullyBookedDates, showRemainingSpots, }: TimeSlotPickerProps): react_jsx_runtime.JSX.Element;
444
-
445
- interface ResourcePickerProps {
446
- /** List of resources to display. */
447
- resources: PublicResource[];
448
- /** Currently selected resource ID(s). */
449
- selectedIds: string[];
450
- /** Callback when a resource is selected. */
451
- onSelect: (resourceId: string) => void;
452
- /** Whether the user can select multiple resources at once. */
453
- allowMultiSelect?: boolean;
454
- /** Whether the list is loading. */
455
- loading?: boolean;
456
- /** Error message if loading failed. */
457
- error?: string | null;
458
- }
459
- declare function ResourcePicker({ resources, selectedIds, onSelect, allowMultiSelect, loading, error, }: ResourcePickerProps): react_jsx_runtime.JSX.Element;
460
-
461
- interface ProductSelectorProps {
462
- products: Product[];
463
- resources?: PublicResource[];
464
- selectedId?: string;
465
- onSelect: (product: Product) => void;
466
- loading?: boolean;
467
- error?: string | null;
468
- /** Override layout from provider. */
469
- layout?: ServiceLayout;
470
- /** Override visible count from provider. */
471
- visibleCount?: number;
472
- /** Override category grouping from provider. @default true */
473
- groupByCategory?: boolean;
474
- }
475
- declare function ProductSelector({ products, resources, selectedId, onSelect, loading, error, layout: layoutProp, visibleCount: visibleCountProp, groupByCategory: groupByCategoryProp, }: ProductSelectorProps): react_jsx_runtime.JSX.Element;
476
-
477
- /**
478
- * Validate the guest form. Returns an errors object (empty = valid).
479
- *
480
- * When `contactMode` is `"either"` (restaurant), at least one of
481
- * phone or email must be provided but neither is individually required.
482
- */
483
- declare function validateGuestForm(values: GuestFormValues, labels: {
484
- required: string;
485
- invalidEmail: string;
486
- contactRequired?: string;
487
- }, contactMode?: "email-required" | "either"): GuestFormErrors;
488
- interface GuestFormProps {
489
- values: GuestFormValues;
490
- onChange: (values: GuestFormValues) => void;
491
- errors?: GuestFormErrors;
492
- }
493
- declare function GuestForm({ values, onChange, errors }: GuestFormProps): react_jsx_runtime.JSX.Element;
494
-
495
- interface WaiverConsentProps {
496
- termsAccepted: boolean;
497
- onTermsChange: (accepted: boolean) => void;
498
- waiverAccepted: boolean;
499
- onWaiverChange: (accepted: boolean) => void;
500
- discountCode: string;
501
- onDiscountCodeChange: (code: string) => void;
502
- onPromoValidated?: (result: ValidatePromoCodeResponse) => void;
503
- error?: string;
504
- }
505
- declare function WaiverConsent({ termsAccepted, onTermsChange, waiverAccepted, onWaiverChange, discountCode, onDiscountCodeChange, onPromoValidated, error, }: WaiverConsentProps): react_jsx_runtime.JSX.Element;
506
-
507
- interface PaymentFormProps {
508
- /** Stripe client secret from the payment intent. */
509
- clientSecret: string;
510
- /** Amount to charge now (cents). */
511
- amountNow: number;
512
- /** Amount to charge at venue (cents). */
513
- amountAtVenue: number;
514
- /** Total amount (cents). */
515
- totalAmount: number;
516
- /** Currency code. */
517
- currency: string;
518
- /** Called when payment succeeds. Receives the paymentIntent ID. */
519
- onSuccess: (paymentIntentId: string) => void;
520
- /** Called when payment fails. */
521
- onError: (message: string) => void;
522
- /** Whether the form is in a processing state. */
523
- processing?: boolean;
524
- /** Discount amount in cents (if a promo code was applied). */
525
- discountAmount?: number;
526
- /** Original price before discount (cents). */
527
- originalPrice?: number;
528
- /** The promo code that was applied. */
529
- promoCodeApplied?: string;
530
- /** Hide the built-in submit button so navigation can be driven externally. */
531
- hideSubmitButton?: boolean;
532
- /** Increment to request a submit from an external footer action. */
533
- submitRequestId?: number;
534
- /** Called when the payment element becomes ready or not ready. */
535
- onReadyChange?: (ready: boolean) => void;
536
- /** Called when the form starts or stops processing a submission. */
537
- onSubmittingChange?: (submitting: boolean) => void;
538
- }
539
- declare function PaymentForm({ clientSecret, amountNow, amountAtVenue, totalAmount, currency, onSuccess, onError, processing, discountAmount, originalPrice, promoCodeApplied, hideSubmitButton, submitRequestId, onReadyChange, onSubmittingChange, }: PaymentFormProps): react_jsx_runtime.JSX.Element;
540
-
541
- interface SummaryPreviewProps {
542
- selection: BookingSelection;
543
- guest: GuestFormValues;
544
- totalPrice?: number;
545
- currency?: string;
546
- }
547
- declare function SummaryPreview({ selection, guest, totalPrice, currency, }: SummaryPreviewProps): react_jsx_runtime.JSX.Element;
548
- interface ConfirmationViewProps {
549
- reservation: Reservation;
550
- }
551
- declare function ConfirmationView({ reservation }: ConfirmationViewProps): react_jsx_runtime.JSX.Element;
552
-
553
- interface DishShowcaseProps {
554
- /** Single dish ID — when set, opens directly to that dish. */
555
- dishId?: string;
556
- /** Show all dishes in a browsable grid (ignored when dishId is set). */
557
- showAll?: boolean;
558
- /** Filter dishes by category (e.g. "Starter", "Main"). */
559
- category?: string;
560
- /** Custom CSS class for the trigger button. */
561
- className?: string;
562
- /** Custom inline styles for the trigger button. */
563
- style?: React.CSSProperties;
564
- /** Button content / label. */
565
- children: React.ReactNode;
566
- }
567
- declare function DishShowcase({ dishId, showAll, category, className, style, children, }: DishShowcaseProps): react_jsx_runtime.JSX.Element;
568
-
569
- interface UseAvailabilityReturn {
570
- /** Current availability data. */
571
- data: Availability | null;
572
- /** Whether the request is in flight. */
573
- loading: boolean;
574
- /** Error message if the request failed. */
575
- error: string | null;
576
- /** Re-fetch availability with optional new params. */
577
- refetch: (params?: AvailabilityParams) => Promise<void>;
578
- }
579
- /**
580
- * Fetch and cache availability data for a resource or product.
581
- *
582
- * Automatically re-fetches when `params` change (shallow compare).
583
- *
584
- * When `productId` is provided, uses the product-level availability
585
- * endpoint which aggregates capacity across all linked equipment.
586
- *
587
- * ```tsx
588
- * const { data, loading, error } = useAvailability({
589
- * date: "2026-07-01",
590
- * durationMinutes: 30,
591
- * }, "product-uuid");
592
- * ```
593
- */
594
- declare function useAvailability(params?: AvailabilityParams, productId?: string): UseAvailabilityReturn;
595
- interface UseReservationReturn {
596
- /** The created reservation (after successful submit). */
597
- reservation: Reservation | null;
598
- /** Whether the submission is in flight. */
599
- submitting: boolean;
600
- /** Error message if submission failed. */
601
- error: string | null;
602
- /** Submit a reservation. Returns the created reservation on success. */
603
- submit: (data: CreateReservationRequest) => Promise<Reservation | null>;
604
- /** Reset the hook state. */
605
- reset: () => void;
606
- }
607
- /**
608
- * Create a reservation via the SDK.
609
- *
610
- * ```tsx
611
- * const { submit, submitting, reservation, error } = useReservation();
612
- *
613
- * const handleSubmit = async () => {
614
- * await submit({
615
- * guestName: "Jane",
616
- * guestEmail: "jane@example.com",
617
- * startDate: "2026-07-01",
618
- * endDate: "2026-07-07",
619
- * });
620
- * };
621
- * ```
622
- */
623
- declare function useReservation(): UseReservationReturn;
624
- interface UseResourcesReturn {
625
- /** List of resources belonging to the organisation. */
626
- resources: PublicResource[];
627
- /** Whether the request is in flight. */
628
- loading: boolean;
629
- /** Error message if fetch failed. */
630
- error: string | null;
631
- }
632
- /**
633
- * Fetch the resource catalogue for the current organisation via the SDK.
634
- *
635
- * The hook fires automatically on mount (no parameters required).
636
- */
637
- declare function useResources(): UseResourcesReturn;
638
- interface UseProductsReturn {
639
- /** List of products/services belonging to the organisation. */
640
- products: Product[];
641
- /** Whether the request is in flight. */
642
- loading: boolean;
643
- /** Error message if fetch failed. */
644
- error: string | null;
645
- }
646
- /**
647
- * Fetch the product/service catalogue for the current organisation via the SDK.
648
- *
649
- * Calls `GET /v1/public/products` using the API key. Returns real products
650
- * with pricing, duration, and linked equipment as created in the admin dashboard.
651
- *
652
- * The hook fires automatically on mount (no parameters required).
653
- */
654
- declare function useProducts(): UseProductsReturn;
655
- interface UsePaymentIntentReturn {
656
- /** The payment intent response after creation. */
657
- paymentIntent: PaymentIntentResponse | null;
658
- /** Whether the payment intent is being created. */
659
- creating: boolean;
660
- /** Error message if creation failed. */
661
- error: string | null;
662
- /** Create a new payment intent. */
663
- create: (data: CreatePaymentIntentRequest) => Promise<PaymentIntentResponse | null>;
664
- /** Confirm payment was completed. */
665
- confirm: (paymentIntentId: string, reservationId: string) => Promise<boolean>;
666
- /** Whether confirmation is in progress. */
667
- confirming: boolean;
668
- /** Reset the hook state. */
669
- reset: () => void;
670
- }
671
- /**
672
- * Create and manage Stripe payment intents via the SDK.
673
- */
674
- declare function usePaymentIntent(): UsePaymentIntentReturn;
675
- interface UseDishReturn {
676
- /** The fetched dish. */
677
- dish: Dish | null;
678
- /** Whether the request is in flight. */
679
- loading: boolean;
680
- /** Error message if fetch failed. */
681
- error: string | null;
682
- }
683
- /**
684
- * Fetch a single dish by ID via the SDK.
685
- *
686
- * ```tsx
687
- * const { dish, loading, error } = useDish("dish-uuid");
688
- * ```
689
- */
690
- declare function useDish(dishId: string | undefined): UseDishReturn;
691
- interface UseDishesReturn {
692
- /** List of dishes. */
693
- dishes: Dish[];
694
- /** Whether the request is in flight. */
695
- loading: boolean;
696
- /** Error message if fetch failed. */
697
- error: string | null;
698
- }
699
- /**
700
- * Fetch all dishes for the organisation via the SDK.
701
- *
702
- * ```tsx
703
- * const { dishes, loading, error } = useDishes();
704
- * ```
705
- */
706
- declare function useDishes(enabled?: boolean): UseDishesReturn;
707
-
708
- /** Default theme values. */
709
- declare const DEFAULT_THEME: Required<ResiraTheme>;
710
- /**
711
- * Merge user-supplied theme with defaults, producing a complete theme.
712
- */
713
- declare function resolveTheme(overrides?: ResiraTheme): Required<ResiraTheme>;
714
- /**
715
- * Generate CSS custom properties from a theme object.
716
- * Returns a CSSProperties-compatible object.
717
- */
718
- declare function themeToCSS(theme: Required<ResiraTheme>): Record<string, string>;
719
-
720
- interface IconProps {
721
- size?: number;
722
- className?: string;
723
- }
724
- declare function CalendarIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
725
- declare function ClockIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
726
- declare function UserIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
727
- declare function UsersIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
728
- declare function CheckIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
729
- declare function CheckCircleIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
730
- declare function ChevronLeftIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
731
- declare function ChevronRightIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
732
- declare function AlertCircleIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
733
- declare function MinusIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
734
- declare function PlusIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
735
- declare function MailIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
736
- declare function PhoneIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
737
- declare function NoteIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
738
- declare function XIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
739
- declare function LockIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
740
- declare function CreditCardIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
741
- declare function ShieldIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
742
- declare function TagIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
743
- declare function CubeIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
744
- declare function ViewfinderIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
745
-
746
- export { AlertCircleIcon, BookingCalendar, BookingModal, type BookingSelection, type BookingStep, CalendarIcon, CheckCircleIcon, CheckIcon, ChevronLeftIcon, ChevronRightIcon, ClockIcon, ConfirmationView, CreditCardIcon, CubeIcon, DEFAULT_LOCALE, DEFAULT_THEME, DishShowcase, type DishShowcaseProps, type DomainConfig, GuestForm, type GuestFormErrors, type GuestFormValues, LockIcon, MailIcon, MinusIcon, NoteIcon, PaymentForm, PhoneIcon, PlusIcon, ProductSelector, ResiraBookingWidget, type ResiraClassNames, type ResiraContextValue, type ResiraDomain, type ResiraLocale, ResiraProvider, type ResiraProviderConfig, type ResiraProviderProps, type ResiraTheme, ResourcePicker, type ServiceLayout, ShieldIcon, SummaryPreview, TagIcon, TimeSlotPicker, UserIcon, UsersIcon, ViewfinderIcon, WaiverConsent, XIcon, resolveTheme, themeToCSS, useAvailability, useDish, useDishes, usePaymentIntent, useProducts, useReservation, useResira, useResources, validateGuestForm };
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
3
+ import { Product, WeightedBaseUrl, Resira, RefundRule, TimeSlotAvailability, DurationPrice, PublicResource, ValidatePromoCodeResponse, Reservation, AvailabilityParams, Availability, Dish, PaymentIntentResponse, CreatePaymentIntentRequest, CreateReservationRequest } from '@resira/sdk';
4
+ export { ConfirmPaymentRequest, ConfirmPaymentResponse, CreatePaymentIntentRequest, Dish, DishListResponse, DishModel, DishResponse, PaymentIntentResponse, PricingModel, Product, ProductListResponse, PublicResource, ResourceListResponse } from '@resira/sdk';
5
+
6
+ type ResiraDomain = "rental" | "restaurant" | "watersport" | "service";
7
+ /** Layout direction for the product/service selector. */
8
+ type ServiceLayout = "vertical" | "horizontal";
9
+ /** Domain-specific configuration. */
10
+ interface DomainConfig {
11
+ /** Label for the domain (e.g. "Vacation Rental", "Restaurant"). */
12
+ label?: string;
13
+ /** Default party size. */
14
+ defaultPartySize?: number;
15
+ /** Minimum party size. */
16
+ minPartySize?: number;
17
+ /** Maximum party size. */
18
+ maxPartySize?: number;
19
+ /** Minimum stay in nights (rental only). */
20
+ minStay?: number;
21
+ /** Default duration in minutes (service/watersport). */
22
+ defaultDuration?: number;
23
+ /** Available durations in minutes (service/watersport). */
24
+ availableDurations?: number[];
25
+ /** Allow selecting multiple resources in one booking. */
26
+ allowMultiSelect?: boolean;
27
+ }
28
+ /** Theme color palette — maps to CSS custom properties. */
29
+ interface ResiraTheme {
30
+ /** Primary brand color. @default "#2563eb" */
31
+ primaryColor?: string;
32
+ /** Primary color on hover. @default "#1d4ed8" */
33
+ primaryHover?: string;
34
+ /** Text on primary background. @default "#ffffff" */
35
+ primaryForeground?: string;
36
+ /** Accent/secondary color. @default "#f0f4ff" */
37
+ accentColor?: string;
38
+ /** Accent foreground. @default "#1e40af" */
39
+ accentForeground?: string;
40
+ /** Error color. @default "#dc2626" */
41
+ errorColor?: string;
42
+ /** Success color. @default "#16a34a" */
43
+ successColor?: string;
44
+ /** Warning color. @default "#d97706" */
45
+ warningColor?: string;
46
+ /** Default text color. @default "#0f172a" */
47
+ textColor?: string;
48
+ /** Muted/secondary text. @default "#64748b" */
49
+ mutedColor?: string;
50
+ /** Surface / card background. @default "#ffffff" */
51
+ surfaceColor?: string;
52
+ /** Subtle background (e.g. form inputs). @default "#f8fafc" */
53
+ backgroundSubtle?: string;
54
+ /** Border color. @default "#e2e8f0" */
55
+ borderColor?: string;
56
+ /** Card border radius. @default "12px" */
57
+ borderRadius?: string;
58
+ /** Font family. @default "system-ui, -apple-system, sans-serif" */
59
+ fontFamily?: string;
60
+ /** Card component radius. @default "14px" */
61
+ cardRadius?: string;
62
+ /** Button radius. @default "10px" */
63
+ buttonRadius?: string;
64
+ /** Input radius. @default "10px" */
65
+ inputRadius?: string;
66
+ /** Chip/pill radius. @default "20px" */
67
+ chipRadius?: string;
68
+ /** Base spacing unit. @default "16px" */
69
+ spacing?: string;
70
+ /** Small shadow. */
71
+ shadowSm?: string;
72
+ /** Medium shadow. */
73
+ shadowMd?: string;
74
+ /** Large shadow. */
75
+ shadowLg?: string;
76
+ /** Calendar day cell size. @default "36px" */
77
+ calendarDaySize?: string;
78
+ /** Minimum width for time slot cells. @default "80px" */
79
+ slotMinWidth?: string;
80
+ }
81
+ /** Internationalization strings. Override any label. */
82
+ interface ResiraLocale {
83
+ /** @default "Select dates" */
84
+ selectDates?: string;
85
+ /** @default "Select a time" */
86
+ selectTime?: string;
87
+ /** @default "Guest details" */
88
+ guestDetails?: string;
89
+ /** @default "Confirm booking" */
90
+ confirmBooking?: string;
91
+ /** @default "Booking confirmed" */
92
+ bookingConfirmed?: string;
93
+ /** @default "Full name" */
94
+ fullName?: string;
95
+ /** @default "Email" */
96
+ email?: string;
97
+ /** @default "Phone" */
98
+ phone?: string;
99
+ /** @default "Party size" */
100
+ partySize?: string;
101
+ /** @default "Notes" */
102
+ notes?: string;
103
+ /** @default "Check-in" */
104
+ checkIn?: string;
105
+ /** @default "Check-out" */
106
+ checkOut?: string;
107
+ /** @default "Guests" */
108
+ guests?: string;
109
+ /** @default "per night" */
110
+ perNight?: string;
111
+ /** @default "total" */
112
+ total?: string;
113
+ /** @default "Available" */
114
+ available?: string;
115
+ /** @default "Unavailable" */
116
+ unavailable?: string;
117
+ /** @default "Loading…" */
118
+ loading?: string;
119
+ /** @default "Something went wrong" */
120
+ errorGeneric?: string;
121
+ /** @default "Continue" */
122
+ continue?: string;
123
+ /** @default "Back" */
124
+ back?: string;
125
+ /** @default "Book now" */
126
+ bookNow?: string;
127
+ /** @default "nights" */
128
+ nights?: string;
129
+ /** @default "Duration" */
130
+ duration?: string;
131
+ /** @default "minutes" */
132
+ minutes?: string;
133
+ /** @default "No availability" */
134
+ noAvailability?: string;
135
+ /** @default "Required" */
136
+ required?: string;
137
+ /** @default "Invalid email" */
138
+ invalidEmail?: string;
139
+ /** @default "Choose a service" */
140
+ chooseService?: string;
141
+ /** @default "per session" */
142
+ perSession?: string;
143
+ /** @default "per person" */
144
+ perPerson?: string;
145
+ /** @default "Payment" */
146
+ payment?: string;
147
+ /** @default "Pay now" */
148
+ payNow?: string;
149
+ /** @default "Pay at venue" */
150
+ payAtVenue?: string;
151
+ /** @default "Processing payment…" */
152
+ processingPayment?: string;
153
+ /** @default "Payment failed" */
154
+ paymentFailed?: string;
155
+ /** @default "Terms & conditions" */
156
+ termsTitle?: string;
157
+ /** @default "I accept the terms and conditions" */
158
+ termsAccept?: string;
159
+ /** @default "I accept the waiver and release of liability" */
160
+ waiverAccept?: string;
161
+ /** @default "You must accept the terms to continue" */
162
+ termsRequired?: string;
163
+ /** @default "Discount code" */
164
+ discountCode?: string;
165
+ /** @default "Enter code" */
166
+ discountPlaceholder?: string;
167
+ /** @default "Apply" */
168
+ discountApply?: string;
169
+ /** @default "Code applied!" */
170
+ discountApplied?: string;
171
+ /** @default "Invalid code" */
172
+ discountInvalid?: string;
173
+ /** @default "Discount" */
174
+ discountLabel?: string;
175
+ /** @default "Original" */
176
+ originalPrice?: string;
177
+ /** @default "Cancellation policy" */
178
+ refundPolicyTitle?: string;
179
+ /** @default "Close" */
180
+ close?: string;
181
+ /** @default "Done" */
182
+ done?: string;
183
+ /** @default "Phone or email required" */
184
+ contactRequired?: string;
185
+ /** @default "Please provide at least a phone number or email" */
186
+ contactHint?: string;
187
+ /** @default "Allergies, special requests..." */
188
+ restaurantNotesPlaceholder?: string;
189
+ /** @default "Reserve a table" */
190
+ reserveTable?: string;
191
+ /** @default "Reservation for" */
192
+ reservationFor?: string;
193
+ }
194
+ /** Default English locale. */
195
+ declare const DEFAULT_LOCALE: Required<ResiraLocale>;
196
+ /** CSS class name overrides for deep styling customization. */
197
+ interface ResiraClassNames {
198
+ /** Root widget wrapper. */
199
+ root?: string;
200
+ /** Step indicator bar. */
201
+ steps?: string;
202
+ /** Widget header area. */
203
+ header?: string;
204
+ /** Widget body area. */
205
+ body?: string;
206
+ /** Widget footer area. */
207
+ footer?: string;
208
+ /** Service/product card. */
209
+ serviceCard?: string;
210
+ /** Service/product card when selected. */
211
+ serviceCardSelected?: string;
212
+ /** Service list container. */
213
+ serviceList?: string;
214
+ /** Calendar container. */
215
+ calendar?: string;
216
+ /** Calendar day cell. */
217
+ calendarDay?: string;
218
+ /** Time slot button. */
219
+ timeSlot?: string;
220
+ /** Time slot button when selected. */
221
+ timeSlotSelected?: string;
222
+ /** Duration option button. */
223
+ durationOption?: string;
224
+ /** Party size control. */
225
+ partySize?: string;
226
+ /** Primary action button. */
227
+ primaryButton?: string;
228
+ /** Secondary action button. */
229
+ secondaryButton?: string;
230
+ /** Form field wrapper. */
231
+ field?: string;
232
+ /** Form input. */
233
+ fieldInput?: string;
234
+ /** Price preview panel. */
235
+ pricePreview?: string;
236
+ }
237
+ /** Pre-filled selection data for deeplink integration. */
238
+ interface DeeplinkSelection {
239
+ /** Pre-selected product/service ID. */
240
+ productId?: string;
241
+ /** Pre-selected date (YYYY-MM-DD). */
242
+ date?: string;
243
+ /** Pre-selected party size. */
244
+ partySize?: number;
245
+ /** Pre-selected duration in minutes. */
246
+ duration?: number;
247
+ }
248
+ /** Pre-filled guest data for deeplink integration. */
249
+ interface DeeplinkGuest {
250
+ /** Guest name. */
251
+ name?: string;
252
+ /** Guest email. */
253
+ email?: string;
254
+ /** Guest phone. */
255
+ phone?: string;
256
+ /** Notes. */
257
+ notes?: string;
258
+ }
259
+ /** Configuration passed to ResiraProvider. */
260
+ interface ResiraProviderConfig {
261
+ /** Theme overrides. */
262
+ theme?: ResiraTheme;
263
+ /** Locale / label overrides. */
264
+ locale?: ResiraLocale;
265
+ /** Domain-specific configuration overrides. */
266
+ domainConfig?: DomainConfig;
267
+ /** CSS class name overrides for full styling control. */
268
+ classNames?: ResiraClassNames;
269
+ /** Layout direction for services. @default "vertical" */
270
+ serviceLayout?: ServiceLayout;
271
+ /** Number of services visible before scrolling. @default 4 */
272
+ visibleServiceCount?: number;
273
+ /** Group services by linked equipment category. @default true */
274
+ groupServicesByCategory?: boolean;
275
+ /** Custom render function for service cards. Receives product and selected state. */
276
+ renderServiceCard?: (product: Product, selected: boolean) => React.ReactNode;
277
+ /** API base URL override (defaults to SDK default). */
278
+ baseUrl?: string;
279
+ /** Weighted API origins for client-side traffic splitting. */
280
+ baseUrls?: Array<string | WeightedBaseUrl>;
281
+ /** Stripe publishable key for payment processing. */
282
+ stripePublishableKey?: string;
283
+ /** Custom terms & conditions text or URL. */
284
+ termsText?: string;
285
+ /** Custom waiver text. */
286
+ waiverText?: string;
287
+ /** Whether to show the waiver checkbox. */
288
+ showWaiver?: boolean;
289
+ /** Whether to show the terms checkbox. */
290
+ showTerms?: boolean;
291
+ /** Whether to show remaining capacity labels in time slots. @default false */
292
+ showRemainingSpots?: boolean;
293
+ /** Percentage of total to charge upfront (0-100). Default 100. */
294
+ depositPercent?: number;
295
+ /** Whether to show the step indicator bar. @default true */
296
+ showStepIndicator?: boolean;
297
+ /** Pre-fill booking data for deeplink integration. */
298
+ deeplink?: DeeplinkSelection;
299
+ /** Pre-fill guest information. */
300
+ deeplinkGuest?: DeeplinkGuest;
301
+ /** Called when the booking step changes. */
302
+ onStepChange?: (step: BookingStep) => void;
303
+ /** Called when a booking is successfully completed. */
304
+ onBookingComplete?: (data: {
305
+ reservationId?: string;
306
+ product?: Product;
307
+ selection: BookingSelection;
308
+ guest: GuestFormValues;
309
+ }) => void;
310
+ /** Called when an error occurs during the booking flow. */
311
+ onError?: (code: string, message: string) => void;
312
+ }
313
+ /** Props for the ResiraProvider component. */
314
+ interface ResiraProviderProps {
315
+ /** API key for authentication. */
316
+ apiKey: string;
317
+ /** Resource ID to book. Optional omit to enable catalog mode (multi-resource picker). */
318
+ resourceId?: string;
319
+ /** Booking domain type. */
320
+ domain: ResiraDomain;
321
+ /** Configuration overrides. */
322
+ config?: ResiraProviderConfig;
323
+ /** Callback when the modal/widget should close. */
324
+ onClose?: () => void;
325
+ /** Child components. */
326
+ children: React.ReactNode;
327
+ }
328
+ /** Shape of the Resira context available to all child components. */
329
+ interface ResiraContextValue {
330
+ /** Instantiated SDK client. */
331
+ client: Resira;
332
+ /** Initial resource ID (may be undefined in catalog mode). */
333
+ resourceId?: string;
334
+ /** Currently active resource ID (set after user picks from catalog). */
335
+ activeResourceId: string | undefined;
336
+ /** Set the active resource ID. */
337
+ setActiveResourceId: (id: string) => void;
338
+ /** Whether catalog/multi-resource mode is enabled. */
339
+ catalogMode: boolean;
340
+ /** Whether multiple resources can be selected at once. */
341
+ allowMultiSelect: boolean;
342
+ /** Domain type. */
343
+ domain: ResiraDomain;
344
+ /** Resolved theme. */
345
+ theme: Required<ResiraTheme>;
346
+ /** Resolved locale. */
347
+ locale: Required<ResiraLocale>;
348
+ /** Resolved domain config. */
349
+ domainConfig: DomainConfig;
350
+ /** Stripe publishable key. */
351
+ stripePublishableKey?: string;
352
+ /** Custom terms text. */
353
+ termsText?: string;
354
+ /** Custom waiver text. */
355
+ waiverText?: string;
356
+ /** Whether to show the waiver checkbox. */
357
+ showWaiver: boolean;
358
+ /** Whether to show the terms checkbox. */
359
+ showTerms: boolean;
360
+ /** Whether to show remaining capacity labels in time slots. */
361
+ showRemainingSpots: boolean;
362
+ /** Deposit percentage (0-100). */
363
+ depositPercent: number;
364
+ /** Refund policy rules from property config. */
365
+ refundPolicy: RefundRule[];
366
+ /** Callback when the modal should close. */
367
+ onClose?: () => void;
368
+ /** CSS class name overrides. */
369
+ classNames: ResiraClassNames;
370
+ /** Layout direction for service cards. */
371
+ serviceLayout: ServiceLayout;
372
+ /** Number of visible service cards before scroll. */
373
+ visibleServiceCount: number;
374
+ /** Whether services should be grouped by linked equipment category. */
375
+ groupServicesByCategory: boolean;
376
+ /** Custom render function for service cards. */
377
+ renderServiceCard?: (product: Product, selected: boolean) => React.ReactNode;
378
+ /** Whether the step indicator bar is visible. */
379
+ showStepIndicator: boolean;
380
+ /** Pre-fill booking data for deeplink integration. */
381
+ deeplink?: DeeplinkSelection;
382
+ /** Pre-fill guest information. */
383
+ deeplinkGuest?: DeeplinkGuest;
384
+ /** Called when the booking step changes. */
385
+ onStepChange?: (step: BookingStep) => void;
386
+ /** Called when a booking is successfully completed. */
387
+ onBookingComplete?: (data: {
388
+ reservationId?: string;
389
+ product?: Product;
390
+ selection: BookingSelection;
391
+ guest: GuestFormValues;
392
+ }) => void;
393
+ /** Called when an error occurs during the booking flow. */
394
+ onError?: (code: string, message: string) => void;
395
+ }
396
+ /** Steps in the booking flow. */
397
+ type BookingStep = "resource" | "availability" | "details" | "terms" | "payment" | "confirmation";
398
+ /** Selection state from the availability step. */
399
+ interface BookingSelection {
400
+ /** Selected start date (YYYY-MM-DD). */
401
+ startDate?: string;
402
+ /** Selected end date (YYYY-MM-DD). */
403
+ endDate?: string;
404
+ /** Selected time slot start (ISO 8601). */
405
+ startTime?: string;
406
+ /** Selected time slot end (ISO 8601). */
407
+ endTime?: string;
408
+ /** Party size. */
409
+ partySize: number;
410
+ /** Duration in minutes (watersport/service). */
411
+ duration?: number;
412
+ /** Selected product/service ID. */
413
+ productId?: string;
414
+ /** Discount code (optional, no server validation yet). */
415
+ discountCode?: string;
416
+ }
417
+ /** Guest form values. */
418
+ interface GuestFormValues {
419
+ guestName: string;
420
+ guestEmail: string;
421
+ guestPhone: string;
422
+ notes: string;
423
+ }
424
+ /** Validation errors for guest form fields. */
425
+ type GuestFormErrors = Partial<Record<keyof GuestFormValues, string>>;
426
+
427
+ /** Access the Resira context. Throws if used outside ResiraProvider. */
428
+ declare function useResira(): ResiraContextValue;
429
+ /**
430
+ * ResiraProvider root of the @resira/ui component tree.
431
+ *
432
+ * Initializes the SDK client and provides domain configuration,
433
+ * theme, and locale to all child components.
434
+ *
435
+ * ```tsx
436
+ * <ResiraProvider apiKey="resira_live_…" resourceId="prop-1" domain="rental">
437
+ * <ResiraBookingWidget />
438
+ * </ResiraProvider>
439
+ * ```
440
+ */
441
+ declare function ResiraProvider({ apiKey, resourceId, domain, config, onClose, children, }: ResiraProviderProps): react_jsx_runtime.JSX.Element;
442
+
443
+ declare function ResiraBookingWidget(): react_jsx_runtime.JSX.Element;
444
+
445
+ interface BookingModalProps {
446
+ /** API key for authentication. */
447
+ apiKey: string;
448
+ /** Booking domain type. */
449
+ domain: ResiraDomain;
450
+ /** Optional resource ID (omit for catalog mode). */
451
+ resourceId?: string;
452
+ /** Configuration overrides. */
453
+ config?: ResiraProviderConfig;
454
+ /** Custom trigger button — if omitted, uses the default "Book Now" button. */
455
+ trigger?: React.ReactNode;
456
+ /** Custom button label. @default "Book Now" */
457
+ buttonLabel?: string;
458
+ /** Custom button className. */
459
+ buttonClassName?: string;
460
+ /** Custom button style. */
461
+ buttonStyle?: React.CSSProperties;
462
+ }
463
+ declare function BookingModal({ apiKey, domain, resourceId, config, trigger, buttonLabel, buttonClassName, buttonStyle, }: BookingModalProps): react_jsx_runtime.JSX.Element;
464
+
465
+ interface BookingCalendarProps {
466
+ /** Set of blocked/unavailable dates (YYYY-MM-DD). */
467
+ blockedDates?: Set<string>;
468
+ /** Currently selected start date. */
469
+ startDate?: string;
470
+ /** Currently selected end date. */
471
+ endDate?: string;
472
+ /** Called when the user selects dates. */
473
+ onSelect: (start: string, end: string | undefined) => void;
474
+ /** Minimum stay in nights. */
475
+ minStay?: number;
476
+ }
477
+ declare function BookingCalendar({ blockedDates, startDate, endDate, onSelect, minStay, }: BookingCalendarProps): react_jsx_runtime.JSX.Element;
478
+
479
+ interface TimeSlotPickerProps {
480
+ timeSlots: TimeSlotAvailability[];
481
+ selectedDate: string;
482
+ onDateChange: (date: string) => void;
483
+ selectedSlot?: string;
484
+ onSlotSelect: (start: string, end: string) => void;
485
+ partySize: number;
486
+ onPartySizeChange: (size: number) => void;
487
+ showPartySize?: boolean;
488
+ showDuration?: boolean;
489
+ selectedDuration?: number;
490
+ onDurationChange?: (minutes: number) => void;
491
+ maxPartySizeOverride?: number;
492
+ durationPricing?: DurationPrice[];
493
+ currency?: string;
494
+ /** Set of dates (YYYY-MM-DD) that are fully booked. */
495
+ fullyBookedDates?: Set<string>;
496
+ /** Whether to show remaining-capacity labels under available slots. */
497
+ showRemainingSpots?: boolean;
498
+ }
499
+ declare function TimeSlotPicker({ timeSlots, selectedDate, onDateChange, selectedSlot, onSlotSelect, partySize, onPartySizeChange, showPartySize, showDuration, selectedDuration, onDurationChange, maxPartySizeOverride, durationPricing, currency, fullyBookedDates, showRemainingSpots, }: TimeSlotPickerProps): react_jsx_runtime.JSX.Element;
500
+
501
+ interface ResourcePickerProps {
502
+ /** List of resources to display. */
503
+ resources: PublicResource[];
504
+ /** Currently selected resource ID(s). */
505
+ selectedIds: string[];
506
+ /** Callback when a resource is selected. */
507
+ onSelect: (resourceId: string) => void;
508
+ /** Whether the user can select multiple resources at once. */
509
+ allowMultiSelect?: boolean;
510
+ /** Whether the list is loading. */
511
+ loading?: boolean;
512
+ /** Error message if loading failed. */
513
+ error?: string | null;
514
+ }
515
+ declare function ResourcePicker({ resources, selectedIds, onSelect, allowMultiSelect, loading, error, }: ResourcePickerProps): react_jsx_runtime.JSX.Element;
516
+
517
+ interface ProductSelectorProps {
518
+ products: Product[];
519
+ resources?: PublicResource[];
520
+ selectedId?: string;
521
+ onSelect: (product: Product) => void;
522
+ loading?: boolean;
523
+ error?: string | null;
524
+ layout?: ServiceLayout;
525
+ visibleCount?: number;
526
+ groupByCategory?: boolean;
527
+ /** Pre-select a specific category to show (skip category tiles). */
528
+ initialCategory?: string;
529
+ }
530
+ declare function ProductSelector({ products, resources, selectedId, onSelect, loading, error, layout: layoutProp, visibleCount: visibleCountProp, groupByCategory: groupByCategoryProp, initialCategory, }: ProductSelectorProps): react_jsx_runtime.JSX.Element;
531
+
532
+ /**
533
+ * Validate the guest form. Returns an errors object (empty = valid).
534
+ *
535
+ * When `contactMode` is `"either"` (restaurant), at least one of
536
+ * phone or email must be provided but neither is individually required.
537
+ */
538
+ declare function validateGuestForm(values: GuestFormValues, labels: {
539
+ required: string;
540
+ invalidEmail: string;
541
+ contactRequired?: string;
542
+ }, contactMode?: "email-required" | "either"): GuestFormErrors;
543
+ interface GuestFormProps {
544
+ values: GuestFormValues;
545
+ onChange: (values: GuestFormValues) => void;
546
+ errors?: GuestFormErrors;
547
+ }
548
+ declare function GuestForm({ values, onChange, errors }: GuestFormProps): react_jsx_runtime.JSX.Element;
549
+
550
+ interface WaiverConsentProps {
551
+ termsAccepted: boolean;
552
+ onTermsChange: (accepted: boolean) => void;
553
+ waiverAccepted: boolean;
554
+ onWaiverChange: (accepted: boolean) => void;
555
+ discountCode: string;
556
+ onDiscountCodeChange: (code: string) => void;
557
+ onPromoValidated?: (result: ValidatePromoCodeResponse) => void;
558
+ error?: string;
559
+ }
560
+ declare function WaiverConsent({ termsAccepted, onTermsChange, waiverAccepted, onWaiverChange, discountCode, onDiscountCodeChange, onPromoValidated, error, }: WaiverConsentProps): react_jsx_runtime.JSX.Element;
561
+
562
+ interface PaymentFormProps {
563
+ /** Stripe client secret from the payment intent. */
564
+ clientSecret: string;
565
+ /** Amount to charge now (cents). */
566
+ amountNow: number;
567
+ /** Amount to charge at venue (cents). */
568
+ amountAtVenue: number;
569
+ /** Total amount (cents). */
570
+ totalAmount: number;
571
+ /** Currency code. */
572
+ currency: string;
573
+ /** Called when payment succeeds. Receives the paymentIntent ID. */
574
+ onSuccess: (paymentIntentId: string) => void;
575
+ /** Called when payment fails. */
576
+ onError: (message: string) => void;
577
+ /** Whether the form is in a processing state. */
578
+ processing?: boolean;
579
+ /** Discount amount in cents (if a promo code was applied). */
580
+ discountAmount?: number;
581
+ /** Original price before discount (cents). */
582
+ originalPrice?: number;
583
+ /** The promo code that was applied. */
584
+ promoCodeApplied?: string;
585
+ /** Hide the built-in submit button so navigation can be driven externally. */
586
+ hideSubmitButton?: boolean;
587
+ /** Increment to request a submit from an external footer action. */
588
+ submitRequestId?: number;
589
+ /** Called when the payment element becomes ready or not ready. */
590
+ onReadyChange?: (ready: boolean) => void;
591
+ /** Called when the form starts or stops processing a submission. */
592
+ onSubmittingChange?: (submitting: boolean) => void;
593
+ }
594
+ declare function PaymentForm({ clientSecret, amountNow, amountAtVenue, totalAmount, currency, onSuccess, onError, processing, discountAmount, originalPrice, promoCodeApplied, hideSubmitButton, submitRequestId, onReadyChange, onSubmittingChange, }: PaymentFormProps): react_jsx_runtime.JSX.Element;
595
+
596
+ interface SummaryPreviewProps {
597
+ selection: BookingSelection;
598
+ guest: GuestFormValues;
599
+ totalPrice?: number;
600
+ currency?: string;
601
+ }
602
+ declare function SummaryPreview({ selection, guest, totalPrice, currency, }: SummaryPreviewProps): react_jsx_runtime.JSX.Element;
603
+ interface ConfirmationViewProps {
604
+ reservation: Reservation;
605
+ }
606
+ declare function ConfirmationView({ reservation }: ConfirmationViewProps): react_jsx_runtime.JSX.Element;
607
+
608
+ interface DishShowcaseProps {
609
+ /** Single dish ID — when set, opens directly to that dish. */
610
+ dishId?: string;
611
+ /** Show all dishes in a browsable grid (ignored when dishId is set). */
612
+ showAll?: boolean;
613
+ /** Filter dishes by category (e.g. "Starter", "Main"). */
614
+ category?: string;
615
+ /** Custom CSS class for the trigger button. */
616
+ className?: string;
617
+ /** Custom inline styles for the trigger button. */
618
+ style?: React.CSSProperties;
619
+ /** Button content / label. */
620
+ children: React.ReactNode;
621
+ }
622
+ declare function DishShowcase({ dishId, showAll, category, className, style, children, }: DishShowcaseProps): react_jsx_runtime.JSX.Element;
623
+
624
+ interface UseAvailabilityReturn {
625
+ /** Current availability data. */
626
+ data: Availability | null;
627
+ /** Whether the request is in flight. */
628
+ loading: boolean;
629
+ /** Error message if the request failed. */
630
+ error: string | null;
631
+ /** Re-fetch availability with optional new params. */
632
+ refetch: (params?: AvailabilityParams) => Promise<void>;
633
+ }
634
+ /**
635
+ * Fetch and cache availability data for a resource or product.
636
+ *
637
+ * Automatically re-fetches when `params` change (shallow compare).
638
+ *
639
+ * When `productId` is provided, uses the product-level availability
640
+ * endpoint which aggregates capacity across all linked equipment.
641
+ *
642
+ * ```tsx
643
+ * const { data, loading, error } = useAvailability({
644
+ * date: "2026-07-01",
645
+ * durationMinutes: 30,
646
+ * }, "product-uuid");
647
+ * ```
648
+ */
649
+ declare function useAvailability(params?: AvailabilityParams, productId?: string): UseAvailabilityReturn;
650
+ interface UseReservationReturn {
651
+ /** The created reservation (after successful submit). */
652
+ reservation: Reservation | null;
653
+ /** Whether the submission is in flight. */
654
+ submitting: boolean;
655
+ /** Error message if submission failed. */
656
+ error: string | null;
657
+ /** Submit a reservation. Returns the created reservation on success. */
658
+ submit: (data: CreateReservationRequest) => Promise<Reservation | null>;
659
+ /** Reset the hook state. */
660
+ reset: () => void;
661
+ }
662
+ /**
663
+ * Create a reservation via the SDK.
664
+ *
665
+ * ```tsx
666
+ * const { submit, submitting, reservation, error } = useReservation();
667
+ *
668
+ * const handleSubmit = async () => {
669
+ * await submit({
670
+ * guestName: "Jane",
671
+ * guestEmail: "jane@example.com",
672
+ * startDate: "2026-07-01",
673
+ * endDate: "2026-07-07",
674
+ * });
675
+ * };
676
+ * ```
677
+ */
678
+ declare function useReservation(): UseReservationReturn;
679
+ interface UseResourcesReturn {
680
+ /** List of resources belonging to the organisation. */
681
+ resources: PublicResource[];
682
+ /** Whether the request is in flight. */
683
+ loading: boolean;
684
+ /** Error message if fetch failed. */
685
+ error: string | null;
686
+ }
687
+ /**
688
+ * Fetch the resource catalogue for the current organisation via the SDK.
689
+ *
690
+ * The hook fires automatically on mount (no parameters required).
691
+ */
692
+ declare function useResources(): UseResourcesReturn;
693
+ interface UseProductsReturn {
694
+ /** List of products/services belonging to the organisation. */
695
+ products: Product[];
696
+ /** Whether the request is in flight. */
697
+ loading: boolean;
698
+ /** Error message if fetch failed. */
699
+ error: string | null;
700
+ }
701
+ /**
702
+ * Fetch the product/service catalogue for the current organisation via the SDK.
703
+ *
704
+ * Calls `GET /v1/public/products` using the API key. Returns real products
705
+ * with pricing, duration, and linked equipment as created in the admin dashboard.
706
+ *
707
+ * The hook fires automatically on mount (no parameters required).
708
+ */
709
+ declare function useProducts(): UseProductsReturn;
710
+ interface UsePaymentIntentReturn {
711
+ /** The payment intent response after creation. */
712
+ paymentIntent: PaymentIntentResponse | null;
713
+ /** Whether the payment intent is being created. */
714
+ creating: boolean;
715
+ /** Error message if creation failed. */
716
+ error: string | null;
717
+ /** Create a new payment intent. */
718
+ create: (data: CreatePaymentIntentRequest) => Promise<PaymentIntentResponse | null>;
719
+ /** Confirm payment was completed. */
720
+ confirm: (paymentIntentId: string, reservationId: string) => Promise<boolean>;
721
+ /** Whether confirmation is in progress. */
722
+ confirming: boolean;
723
+ /** Reset the hook state. */
724
+ reset: () => void;
725
+ }
726
+ /**
727
+ * Create and manage Stripe payment intents via the SDK.
728
+ */
729
+ declare function usePaymentIntent(): UsePaymentIntentReturn;
730
+ interface UseDishReturn {
731
+ /** The fetched dish. */
732
+ dish: Dish | null;
733
+ /** Whether the request is in flight. */
734
+ loading: boolean;
735
+ /** Error message if fetch failed. */
736
+ error: string | null;
737
+ }
738
+ /**
739
+ * Fetch a single dish by ID via the SDK.
740
+ *
741
+ * ```tsx
742
+ * const { dish, loading, error } = useDish("dish-uuid");
743
+ * ```
744
+ */
745
+ declare function useDish(dishId: string | undefined): UseDishReturn;
746
+ interface UseDishesReturn {
747
+ /** List of dishes. */
748
+ dishes: Dish[];
749
+ /** Whether the request is in flight. */
750
+ loading: boolean;
751
+ /** Error message if fetch failed. */
752
+ error: string | null;
753
+ }
754
+ /**
755
+ * Fetch all dishes for the organisation via the SDK.
756
+ *
757
+ * ```tsx
758
+ * const { dishes, loading, error } = useDishes();
759
+ * ```
760
+ */
761
+ declare function useDishes(enabled?: boolean): UseDishesReturn;
762
+
763
+ /** Default theme values. */
764
+ declare const DEFAULT_THEME: Required<ResiraTheme>;
765
+ /**
766
+ * Merge user-supplied theme with defaults, producing a complete theme.
767
+ */
768
+ declare function resolveTheme(overrides?: ResiraTheme): Required<ResiraTheme>;
769
+ /**
770
+ * Generate CSS custom properties from a theme object.
771
+ * Returns a CSSProperties-compatible object.
772
+ */
773
+ declare function themeToCSS(theme: Required<ResiraTheme>): Record<string, string>;
774
+
775
+ interface IconProps {
776
+ size?: number;
777
+ className?: string;
778
+ }
779
+ declare function CalendarIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
780
+ declare function ClockIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
781
+ declare function UserIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
782
+ declare function UsersIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
783
+ declare function CheckIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
784
+ declare function CheckCircleIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
785
+ declare function ChevronLeftIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
786
+ declare function ChevronRightIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
787
+ declare function AlertCircleIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
788
+ declare function MinusIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
789
+ declare function PlusIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
790
+ declare function MailIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
791
+ declare function PhoneIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
792
+ declare function NoteIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
793
+ declare function XIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
794
+ declare function LockIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
795
+ declare function CreditCardIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
796
+ declare function ShieldIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
797
+ declare function TagIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
798
+ declare function CubeIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
799
+ declare function ViewfinderIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
800
+
801
+ export { AlertCircleIcon, BookingCalendar, BookingModal, type BookingSelection, type BookingStep, CalendarIcon, CheckCircleIcon, CheckIcon, ChevronLeftIcon, ChevronRightIcon, ClockIcon, ConfirmationView, CreditCardIcon, CubeIcon, DEFAULT_LOCALE, DEFAULT_THEME, type DeeplinkGuest, type DeeplinkSelection, DishShowcase, type DishShowcaseProps, type DomainConfig, GuestForm, type GuestFormErrors, type GuestFormValues, LockIcon, MailIcon, MinusIcon, NoteIcon, PaymentForm, PhoneIcon, PlusIcon, ProductSelector, ResiraBookingWidget, type ResiraClassNames, type ResiraContextValue, type ResiraDomain, type ResiraLocale, ResiraProvider, type ResiraProviderConfig, type ResiraProviderProps, type ResiraTheme, ResourcePicker, type ServiceLayout, ShieldIcon, SummaryPreview, TagIcon, TimeSlotPicker, UserIcon, UsersIcon, ViewfinderIcon, WaiverConsent, XIcon, resolveTheme, themeToCSS, useAvailability, useDish, useDishes, usePaymentIntent, useProducts, useReservation, useResira, useResources, validateGuestForm };