import type { BookingOperator, BookingService, BookingSlot, BookingSpecialty, BookingValue, ConfirmationChannel, InsuranceType } from './booking-types'; /** * Sentinel for the operator filter's "All operators" pseudo-option. Mirrors * `OPERATORS_ALL = '0'` in the legacy `useBookingState.js`, but the kit * uses `'all'` as the well-known string so consumers can't accidentally * collide with a real operator id of `'0'`. */ export declare const OPERATORS_ALL: "all"; export interface CascadePolicy { /** ISO 3166-1 alpha-2 country code. Currently only `'de'` toggles a gate. */ country?: string; useSpecialties?: boolean; allowOperatorSelection?: boolean; /** When set, locks step 4 to this operator id and hides the picker. */ lockedOperatorId?: string; /** Defaults to `false`. When true, single-service lists auto-pre-fill. */ autoSelectSingleService?: boolean; /** * Defaults to `false`. When true, the operators offered come from the * chosen service (`appointmentBookingReasonIds`) even when specialties are * on; the specialty only groups services. Added in 1.40.0. */ operatorsByService?: boolean; } export interface CascadeInputs extends CascadePolicy { specialties: BookingSpecialty[]; services: BookingService[]; operators: BookingOperator[]; availableDates: string[]; availableSlots: Record; value: BookingValue; } export interface CascadeGates { insurance: boolean; specialty: boolean; service: boolean; operator: boolean; date: boolean; slot: boolean; details: boolean; /** True when a service is picked but no eligible operators can perform it. */ onboardingIncomplete: boolean; } export interface CascadeFiltered { specialties: BookingSpecialty[]; services: BookingService[]; /** * Eligible operators for the active specialty (when `useSpecialties=true`) * OR the active service. Excludes the "All operators" sentinel — that's * always prepended in the UI layer. */ operators: BookingOperator[]; } /** Step number — 1-indexed, matches the docs / a11y order. */ export type CascadeStep = 1 | 2 | 3 | 4 | 5 | 6 | 7; export interface CascadeOutputs { gates: CascadeGates; filtered: CascadeFiltered; /** Current step: the first visible step that has an unfulfilled requirement. */ currentStep: CascadeStep; /** Total visible steps (1..7 minus any auto-skipped). */ totalSteps: number; /** Ordered list of the visible step indices, used by variants that show a stepper. */ visibleSteps: CascadeStep[]; /** Whether every required step is satisfied — the submit button is gated on this. */ isReadyToSubmit: boolean; /** Selected service's duration, if any — needed for slot fetching. */ durationMin?: number; /** Selected slot resolved from `value.date` + `value.slotKey`. */ selectedSlot?: BookingSlot; } /** * Whether `step` holds an answer the cascade can move past. The one check * shared by `deriveStep` and every variant body, so the two cannot drift. */ export declare function stepIsFulfilled(step: CascadeStep, value: BookingValue): boolean; export declare function deriveCascade(inputs: CascadeInputs): CascadeOutputs; export declare function resetOnInsuranceChange(value: BookingValue, next: InsuranceType | undefined): BookingValue; export declare function resetOnSpecialtyChange(value: BookingValue, next: string | undefined): BookingValue; /** * Multi-select counterpart to `resetOnSpecialtyChange`. Writes the * `specialtyIds` array form and clears any single-form `specialtyId` * so the cascade reads the array. Added in 0.34.0. */ export declare function resetOnSpecialtyIdsChange(value: BookingValue, next: string[] | undefined): BookingValue; export declare function resetOnServiceChange(value: BookingValue, next: string | undefined): BookingValue; /** Multi-select counterpart to `resetOnServiceChange`. Added in 0.34.0. */ export declare function resetOnServiceIdsChange(value: BookingValue, next: string[] | undefined): BookingValue; export declare function resetOnOperatorChange(value: BookingValue, next: string | undefined): BookingValue; /** Multi-select counterpart to `resetOnOperatorChange`. Added in 0.34.0. */ export declare function resetOnOperatorIdsChange(value: BookingValue, next: string[] | undefined): BookingValue; /** Returns the effective specialty selection as an array. Empty when nothing picked. */ export declare function resolveSpecialtyIds(value: BookingValue): string[]; /** Returns the effective service selection as an array. Empty when nothing picked. */ export declare function resolveServiceIds(value: BookingValue): string[]; /** Returns the effective operator selection as an array. Empty when nothing picked. */ export declare function resolveOperatorIds(value: BookingValue): string[]; export declare function resetOnDateChange(value: BookingValue, next: string | undefined): BookingValue; export declare function resetOnSlotChange(value: BookingValue, next: string | undefined): BookingValue; export declare function applyAutoSelects(value: BookingValue, inputs: CascadePolicy & { specialties: BookingSpecialty[]; services: BookingService[]; }): BookingValue; /** Resolve the active operator id, treating the `'all'` sentinel as `undefined`. */ export declare function resolveOperatorId(value: BookingValue): string | undefined; /** * Resolve the effective list of enabled channels. Falls back to `['email']` * when the consumer omits the prop, preserving the pre-amendment behaviour. */ export declare function resolveConfirmationChannels(enabled: ConfirmationChannel[] | undefined): ConfirmationChannel[]; /** Use the selection when present, otherwise the sole enabled channel or email. * `enabled` must be resolved with `resolveConfirmationChannels` first. */ export declare function resolveEffectiveConfirmationChannels(enabled: ConfirmationChannel[], selection: ConfirmationChannel[] | undefined): ConfirmationChannel[]; /** * Compute the channels to pre-check. Result is intersected with `enabled` * for safety so a channel the practice didn't enable never gets ticked. * * Rules (per spec): * 1. Always include 'email'. * 2. Include 'whatsapp' if enabled AND mobile looks plausible. * 3. Include 'sms' ONLY when whatsapp is NOT in `enabled`. * 4. If the consumer passes `override`, honour it verbatim (still * intersected with `enabled` for safety). */ export declare function defaultConfirmationSelection(enabled: ConfirmationChannel[] | undefined, mobile: string | undefined, override?: ConfirmationChannel[]): ConfirmationChannel[]; //# sourceMappingURL=cascade.d.ts.map