@wix/headless-bookings 0.0.42 → 0.0.44
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/cjs/dist/api/index.d.ts +1 -0
- package/cjs/dist/api/index.js +1 -0
- package/cjs/dist/api/query-locations/index.d.ts +38 -0
- package/cjs/dist/api/query-locations/index.js +30 -0
- package/cjs/dist/react/core/location/Location.d.ts +113 -14
- package/cjs/dist/react/core/location/Location.js +189 -30
- package/cjs/dist/react/core/location-list/LocationList.d.ts +102 -0
- package/cjs/dist/react/core/location-list/LocationList.js +71 -0
- package/cjs/dist/react/index.d.ts +1 -0
- package/cjs/dist/react/index.js +1 -0
- package/cjs/dist/react/location/Location.d.ts +211 -41
- package/cjs/dist/react/location/Location.js +219 -46
- package/cjs/dist/react/location/LocationList.d.ts +98 -0
- package/cjs/dist/react/location/LocationList.js +120 -0
- package/cjs/dist/react/service/Service.d.ts +70 -27
- package/cjs/dist/react/service/Service.js +48 -38
- package/cjs/dist/services/index.d.ts +1 -0
- package/cjs/dist/services/index.js +1 -0
- package/cjs/dist/services/location-list/location-list.d.ts +100 -0
- package/cjs/dist/services/location-list/location-list.def.d.ts +62 -0
- package/cjs/dist/services/location-list/location-list.def.js +17 -0
- package/cjs/dist/services/location-list/location-list.js +212 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/query-locations/index.d.ts +38 -0
- package/dist/api/query-locations/index.js +30 -0
- package/dist/react/core/location/Location.d.ts +113 -14
- package/dist/react/core/location/Location.js +189 -30
- package/dist/react/core/location-list/LocationList.d.ts +102 -0
- package/dist/react/core/location-list/LocationList.js +71 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/react/location/Location.d.ts +211 -41
- package/dist/react/location/Location.js +219 -46
- package/dist/react/location/LocationList.d.ts +98 -0
- package/dist/react/location/LocationList.js +120 -0
- package/dist/react/service/Service.d.ts +70 -27
- package/dist/react/service/Service.js +48 -38
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/location-list/location-list.d.ts +100 -0
- package/dist/services/location-list/location-list.def.d.ts +62 -0
- package/dist/services/location-list/location-list.def.js +17 -0
- package/dist/services/location-list/location-list.js +212 -0
- package/package.json +2 -2
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location List Service Implementation
|
|
3
|
+
* Manages location state, auto-detection, and BookingService integration
|
|
4
|
+
*
|
|
5
|
+
* @module Services/LocationList
|
|
6
|
+
*/
|
|
7
|
+
import type { ServiceFactoryConfig } from '@wix/services-definitions';
|
|
8
|
+
import { type LocationData } from './location-list.def.js';
|
|
9
|
+
/**
|
|
10
|
+
* Configuration interface for LocationListService
|
|
11
|
+
*/
|
|
12
|
+
export interface LocationListServiceConfig {
|
|
13
|
+
/** Locations array (can include any type: BUSINESS, CUSTOM, CUSTOMER) */
|
|
14
|
+
locations?: LocationData[];
|
|
15
|
+
/** Explicit flag for custom locations (overrides auto-detection) */
|
|
16
|
+
hasCustomLocations?: boolean;
|
|
17
|
+
/** Explicit flag for customer locations (overrides auto-detection) */
|
|
18
|
+
hasCustomerLocations?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Implementation of the LocationList service
|
|
22
|
+
* Manages location state and integrates with BookingService for selection (optional)
|
|
23
|
+
*/
|
|
24
|
+
export declare const LocationListService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
25
|
+
__api: import("./location-list.def.js").LocationListServiceAPI;
|
|
26
|
+
__config: {};
|
|
27
|
+
isServiceDefinition?: boolean;
|
|
28
|
+
} & import("./location-list.def.js").LocationListServiceAPI, LocationListServiceConfig>;
|
|
29
|
+
/**
|
|
30
|
+
* Result type for SSR loader
|
|
31
|
+
*/
|
|
32
|
+
export type LoadLocationListServiceResult = {
|
|
33
|
+
type: 'success';
|
|
34
|
+
config: LocationListServiceConfig;
|
|
35
|
+
} | {
|
|
36
|
+
type: 'error';
|
|
37
|
+
error: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* SSR Loader: Fetches locations from API for server-side rendering.
|
|
41
|
+
*
|
|
42
|
+
* @param options - Optional configuration
|
|
43
|
+
* @returns Configuration result for LocationListService with pre-fetched locations
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* // Fetch from API
|
|
48
|
+
* const result = await loadLocationListServiceInitialData();
|
|
49
|
+
*
|
|
50
|
+
* if (result.type === 'error') {
|
|
51
|
+
* return Astro.redirect('/500');
|
|
52
|
+
* }
|
|
53
|
+
*
|
|
54
|
+
* const locationListConfig = result.config;
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* // Pass locations directly (e.g., from service.locations)
|
|
60
|
+
* const result = await loadLocationListServiceInitialData({
|
|
61
|
+
* locations: service.locations,
|
|
62
|
+
* // hasCustom/hasCustomer will be auto-detected from array
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export declare function loadLocationListServiceInitialData(options?: {
|
|
67
|
+
/** Pass locations directly instead of fetching */
|
|
68
|
+
locations?: LocationData[];
|
|
69
|
+
/** Explicit flag for custom locations */
|
|
70
|
+
hasCustomLocations?: boolean;
|
|
71
|
+
/** Explicit flag for customer locations */
|
|
72
|
+
hasCustomerLocations?: boolean;
|
|
73
|
+
}): Promise<LoadLocationListServiceResult>;
|
|
74
|
+
/**
|
|
75
|
+
* Service binding helper for LocationListService.
|
|
76
|
+
* Bundles definition, implementation, and config for ServicesManager.
|
|
77
|
+
*
|
|
78
|
+
* @param servicesConfigs - Object containing LocationListServiceDefinition config
|
|
79
|
+
* @returns Tuple of [Definition, Implementation, Config] for addService()
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const servicesManager = createServicesManager(
|
|
84
|
+
* createServicesMap()
|
|
85
|
+
* .addService(...locationListServiceBinding(configs))
|
|
86
|
+
* );
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare const locationListServiceBinding: <T extends {
|
|
90
|
+
[key: string]: LocationListServiceConfig;
|
|
91
|
+
}>(servicesConfigs: T) => readonly [string & {
|
|
92
|
+
__api: import("./location-list.def.js").LocationListServiceAPI;
|
|
93
|
+
__config: {};
|
|
94
|
+
isServiceDefinition?: boolean;
|
|
95
|
+
} & import("./location-list.def.js").LocationListServiceAPI, import("@wix/services-definitions").ServiceFactory<string & {
|
|
96
|
+
__api: import("./location-list.def.js").LocationListServiceAPI;
|
|
97
|
+
__config: {};
|
|
98
|
+
isServiceDefinition?: boolean;
|
|
99
|
+
} & import("./location-list.def.js").LocationListServiceAPI, LocationListServiceConfig>, LocationListServiceConfig];
|
|
100
|
+
export { LocationListServiceDefinition, LocationType, type LocationData, type DisplayLocation, type LocationListActions, type LocationListServiceAPI, } from './location-list.def.js';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location List Service Definition
|
|
3
|
+
* Defines types and service interface for managing location lists
|
|
4
|
+
*
|
|
5
|
+
* @module Services/LocationList/Definition
|
|
6
|
+
*/
|
|
7
|
+
import type { Signal, ReadOnlySignal } from '@wix/services-definitions/core-services/signals';
|
|
8
|
+
import { LocationType, type Service } from '@wix/auto_sdk_bookings_services';
|
|
9
|
+
/**
|
|
10
|
+
* LocationData type - from Service['locations'][number]
|
|
11
|
+
*/
|
|
12
|
+
export type LocationData = NonNullable<Service['locations']>[number];
|
|
13
|
+
/**
|
|
14
|
+
* Display location wrapper - includes metadata for rendering
|
|
15
|
+
*/
|
|
16
|
+
export interface DisplayLocation {
|
|
17
|
+
/** Original location data, null for synthetic entries */
|
|
18
|
+
location: LocationData | null;
|
|
19
|
+
/** Location type */
|
|
20
|
+
type: LocationType;
|
|
21
|
+
/** True if created from flag (not from array) */
|
|
22
|
+
isSynthetic: boolean;
|
|
23
|
+
/** Unique ID for list rendering */
|
|
24
|
+
id: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Actions interface for location list management
|
|
28
|
+
*/
|
|
29
|
+
export interface LocationListActions {
|
|
30
|
+
/** Select a location (updates BookingService.location if available) */
|
|
31
|
+
select: (displayLocation: DisplayLocation) => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* API interface for the LocationList service
|
|
35
|
+
*/
|
|
36
|
+
export interface LocationListServiceAPI {
|
|
37
|
+
/** Reactive signal containing the raw locations array */
|
|
38
|
+
locations: Signal<LocationData[]>;
|
|
39
|
+
/** Reactive signal containing the display locations (processed for UI) */
|
|
40
|
+
displayLocations: ReadOnlySignal<DisplayLocation[]>;
|
|
41
|
+
/** Whether custom locations exist */
|
|
42
|
+
hasCustomLocations: ReadOnlySignal<boolean>;
|
|
43
|
+
/** Whether customer locations exist */
|
|
44
|
+
hasCustomerLocations: ReadOnlySignal<boolean>;
|
|
45
|
+
/** Reactive signal indicating if locations are loading */
|
|
46
|
+
isLoading: Signal<boolean>;
|
|
47
|
+
/** Reactive signal containing any error message */
|
|
48
|
+
error: Signal<string | null>;
|
|
49
|
+
/** Computed signal for selected location (from BookingService, null if standalone) */
|
|
50
|
+
selectedLocation: ReadOnlySignal<LocationData | null>;
|
|
51
|
+
/** Actions for location management */
|
|
52
|
+
actions: LocationListActions;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Service definition for LocationList
|
|
56
|
+
*/
|
|
57
|
+
export declare const LocationListServiceDefinition: string & {
|
|
58
|
+
__api: LocationListServiceAPI;
|
|
59
|
+
__config: {};
|
|
60
|
+
isServiceDefinition?: boolean;
|
|
61
|
+
} & LocationListServiceAPI;
|
|
62
|
+
export { LocationType };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location List Service Definition
|
|
3
|
+
* Defines types and service interface for managing location lists
|
|
4
|
+
*
|
|
5
|
+
* @module Services/LocationList/Definition
|
|
6
|
+
*/
|
|
7
|
+
import { defineService } from '@wix/services-definitions';
|
|
8
|
+
import { LocationType } from '@wix/auto_sdk_bookings_services';
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Service Definition
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Service definition for LocationList
|
|
14
|
+
*/
|
|
15
|
+
export const LocationListServiceDefinition = defineService('location-list');
|
|
16
|
+
// Re-export LocationType for consumers
|
|
17
|
+
export { LocationType };
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Location List Service Implementation
|
|
3
|
+
* Manages location state, auto-detection, and BookingService integration
|
|
4
|
+
*
|
|
5
|
+
* @module Services/LocationList
|
|
6
|
+
*/
|
|
7
|
+
import { implementService } from '@wix/services-definitions';
|
|
8
|
+
import { SignalsServiceDefinition, } from '@wix/services-definitions/core-services/signals';
|
|
9
|
+
import { LocationType } from '@wix/auto_sdk_bookings_services';
|
|
10
|
+
import { LocationListServiceDefinition, } from './location-list.def.js';
|
|
11
|
+
import { BookingServiceDefinition } from '../booking/booking.js';
|
|
12
|
+
import { queryLocations } from '../../api/query-locations/index.js';
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Constants
|
|
15
|
+
// ============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Synthetic location IDs for non-business locations
|
|
18
|
+
*/
|
|
19
|
+
const SYNTHETIC_CUSTOM_ID = '__synthetic_custom__';
|
|
20
|
+
const SYNTHETIC_CUSTOMER_ID = '__synthetic_customer__';
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Helper Functions
|
|
23
|
+
// ============================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Build display locations from raw locations and flags
|
|
26
|
+
*/
|
|
27
|
+
function buildDisplayLocations(locations, hasCustomLocations, hasCustomerLocations) {
|
|
28
|
+
const displayLocations = [];
|
|
29
|
+
// 1. Add all BUSINESS locations
|
|
30
|
+
const businessLocations = locations.filter((loc) => loc.type === LocationType.BUSINESS || loc.type === undefined);
|
|
31
|
+
for (const loc of businessLocations) {
|
|
32
|
+
displayLocations.push({
|
|
33
|
+
location: loc,
|
|
34
|
+
type: LocationType.BUSINESS,
|
|
35
|
+
isSynthetic: false,
|
|
36
|
+
id: loc.business?._id || loc._id || String(displayLocations.length),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
// Check for existing CUSTOM/CUSTOMER in array
|
|
40
|
+
const customFromArray = locations.find((loc) => loc.type === LocationType.CUSTOM);
|
|
41
|
+
const customerFromArray = locations.find((loc) => loc.type === LocationType.CUSTOMER);
|
|
42
|
+
// 2. Add CUSTOM location (from array or synthetic)
|
|
43
|
+
if (customFromArray) {
|
|
44
|
+
displayLocations.push({
|
|
45
|
+
location: customFromArray,
|
|
46
|
+
type: LocationType.CUSTOM,
|
|
47
|
+
isSynthetic: false,
|
|
48
|
+
id: customFromArray.custom?._id || SYNTHETIC_CUSTOM_ID,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
else if (hasCustomLocations) {
|
|
52
|
+
// Synthetic custom location (only from explicit flag, not array)
|
|
53
|
+
displayLocations.push({
|
|
54
|
+
location: null,
|
|
55
|
+
type: LocationType.CUSTOM,
|
|
56
|
+
isSynthetic: true,
|
|
57
|
+
id: SYNTHETIC_CUSTOM_ID,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
// 3. Add CUSTOMER location (always synthetic display, real or flag-based)
|
|
61
|
+
if (customerFromArray || hasCustomerLocations) {
|
|
62
|
+
displayLocations.push({
|
|
63
|
+
location: customerFromArray || null,
|
|
64
|
+
type: LocationType.CUSTOMER,
|
|
65
|
+
isSynthetic: !customerFromArray,
|
|
66
|
+
id: SYNTHETIC_CUSTOMER_ID,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return displayLocations;
|
|
70
|
+
}
|
|
71
|
+
// ============================================================================
|
|
72
|
+
// Service Implementation
|
|
73
|
+
// ============================================================================
|
|
74
|
+
/**
|
|
75
|
+
* Implementation of the LocationList service
|
|
76
|
+
* Manages location state and integrates with BookingService for selection (optional)
|
|
77
|
+
*/
|
|
78
|
+
export const LocationListService = implementService.withConfig()(LocationListServiceDefinition, ({ getService, config }) => {
|
|
79
|
+
const signalsService = getService(SignalsServiceDefinition);
|
|
80
|
+
// Try to get BookingService - it's optional (Location can be standalone)
|
|
81
|
+
let bookingService = null;
|
|
82
|
+
try {
|
|
83
|
+
bookingService = getService(BookingServiceDefinition);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// BookingService not available - Location is used standalone
|
|
87
|
+
bookingService = null;
|
|
88
|
+
}
|
|
89
|
+
// Initialize raw locations signal
|
|
90
|
+
const locationsSignal = signalsService.signal(config.locations || []);
|
|
91
|
+
// Auto-detect from array
|
|
92
|
+
const hasCustomInArray = (config.locations || []).some((loc) => loc.type === LocationType.CUSTOM);
|
|
93
|
+
const hasCustomerInArray = (config.locations || []).some((loc) => loc.type === LocationType.CUSTOMER);
|
|
94
|
+
// Final flags: explicit config OR auto-detected
|
|
95
|
+
const hasCustomLocationsSignal = signalsService.computed(() => config.hasCustomLocations ?? hasCustomInArray);
|
|
96
|
+
const hasCustomerLocationsSignal = signalsService.computed(() => config.hasCustomerLocations ?? hasCustomerInArray);
|
|
97
|
+
// Display locations - computed from raw + flags
|
|
98
|
+
const displayLocationsSignal = signalsService.computed(() => buildDisplayLocations(locationsSignal.get(), hasCustomLocationsSignal.get(), hasCustomerLocationsSignal.get()));
|
|
99
|
+
const isLoadingSignal = signalsService.signal(false);
|
|
100
|
+
const errorSignal = signalsService.signal(null);
|
|
101
|
+
// Selected location from BookingService (null if standalone)
|
|
102
|
+
const selectedLocationSignal = signalsService.computed(() => {
|
|
103
|
+
if (!bookingService)
|
|
104
|
+
return null;
|
|
105
|
+
return bookingService.location.get();
|
|
106
|
+
});
|
|
107
|
+
// Actions - integrate with BookingService if available
|
|
108
|
+
const actions = {
|
|
109
|
+
select: (displayLocation) => {
|
|
110
|
+
if (bookingService) {
|
|
111
|
+
bookingService.actions.setLocation(displayLocation.location);
|
|
112
|
+
}
|
|
113
|
+
// If standalone, selection is handled by consumer via asChild
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
return {
|
|
117
|
+
locations: locationsSignal,
|
|
118
|
+
displayLocations: displayLocationsSignal,
|
|
119
|
+
hasCustomLocations: hasCustomLocationsSignal,
|
|
120
|
+
hasCustomerLocations: hasCustomerLocationsSignal,
|
|
121
|
+
isLoading: isLoadingSignal,
|
|
122
|
+
error: errorSignal,
|
|
123
|
+
selectedLocation: selectedLocationSignal,
|
|
124
|
+
actions,
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
/**
|
|
128
|
+
* SSR Loader: Fetches locations from API for server-side rendering.
|
|
129
|
+
*
|
|
130
|
+
* @param options - Optional configuration
|
|
131
|
+
* @returns Configuration result for LocationListService with pre-fetched locations
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```typescript
|
|
135
|
+
* // Fetch from API
|
|
136
|
+
* const result = await loadLocationListServiceInitialData();
|
|
137
|
+
*
|
|
138
|
+
* if (result.type === 'error') {
|
|
139
|
+
* return Astro.redirect('/500');
|
|
140
|
+
* }
|
|
141
|
+
*
|
|
142
|
+
* const locationListConfig = result.config;
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* // Pass locations directly (e.g., from service.locations)
|
|
148
|
+
* const result = await loadLocationListServiceInitialData({
|
|
149
|
+
* locations: service.locations,
|
|
150
|
+
* // hasCustom/hasCustomer will be auto-detected from array
|
|
151
|
+
* });
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export async function loadLocationListServiceInitialData(options) {
|
|
155
|
+
try {
|
|
156
|
+
// If locations are passed directly, use them (flags auto-detected if not provided)
|
|
157
|
+
if (options?.locations) {
|
|
158
|
+
return {
|
|
159
|
+
type: 'success',
|
|
160
|
+
config: {
|
|
161
|
+
locations: options.locations,
|
|
162
|
+
hasCustomLocations: options.hasCustomLocations,
|
|
163
|
+
hasCustomerLocations: options.hasCustomerLocations,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
// Otherwise, fetch from API
|
|
168
|
+
const result = await queryLocations();
|
|
169
|
+
return {
|
|
170
|
+
type: 'success',
|
|
171
|
+
config: {
|
|
172
|
+
locations: result.locations,
|
|
173
|
+
hasCustomLocations: result.hasCustomLocations,
|
|
174
|
+
hasCustomerLocations: result.hasCustomerLocations,
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
const message = error instanceof Error ? error.message : 'Failed to load locations';
|
|
180
|
+
console.error('loadLocationListServiceInitialData error:', error);
|
|
181
|
+
return { type: 'error', error: message };
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// ============================================================================
|
|
185
|
+
// Service Binding Helper
|
|
186
|
+
// ============================================================================
|
|
187
|
+
/**
|
|
188
|
+
* Service binding helper for LocationListService.
|
|
189
|
+
* Bundles definition, implementation, and config for ServicesManager.
|
|
190
|
+
*
|
|
191
|
+
* @param servicesConfigs - Object containing LocationListServiceDefinition config
|
|
192
|
+
* @returns Tuple of [Definition, Implementation, Config] for addService()
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* const servicesManager = createServicesManager(
|
|
197
|
+
* createServicesMap()
|
|
198
|
+
* .addService(...locationListServiceBinding(configs))
|
|
199
|
+
* );
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
export const locationListServiceBinding = (servicesConfigs) => {
|
|
203
|
+
return [
|
|
204
|
+
LocationListServiceDefinition,
|
|
205
|
+
LocationListService,
|
|
206
|
+
servicesConfigs['location-list'],
|
|
207
|
+
];
|
|
208
|
+
};
|
|
209
|
+
// ============================================================================
|
|
210
|
+
// Re-exports
|
|
211
|
+
// ============================================================================
|
|
212
|
+
export { LocationListServiceDefinition, LocationType, } from './location-list.def.js';
|
package/dist/api/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { getServiceById, getServiceBySlug, queryServices, type PagingMetadata, t
|
|
|
8
8
|
export { fetchAvailability } from './fetch-availability/index.js';
|
|
9
9
|
export { createBooking, type CreateBookingOptions, type Booking, type CreateBookingRequest, type CreateBookingResponse, type ParticipantNotification, type ContactDetails, } from './create-booking/index.js';
|
|
10
10
|
export { createCheckout, ChannelType, type CreateCheckoutRequest, type CreateCheckoutResponse, } from './create-checkout/index.js';
|
|
11
|
+
export { queryLocations, type QueryLocationsResult, type LocationData, } from './query-locations/index.js';
|
|
11
12
|
/**
|
|
12
13
|
* PagingMetadata includes:
|
|
13
14
|
* - limit: Number of items per page
|
package/dist/api/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { getServiceById, getServiceBySlug, queryServices, } from './query-servic
|
|
|
8
8
|
export { fetchAvailability } from './fetch-availability/index.js';
|
|
9
9
|
export { createBooking, } from './create-booking/index.js';
|
|
10
10
|
export { createCheckout, ChannelType, } from './create-checkout/index.js';
|
|
11
|
+
export { queryLocations, } from './query-locations/index.js';
|
|
11
12
|
/**
|
|
12
13
|
* PagingMetadata includes:
|
|
13
14
|
* - limit: Number of items per page
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Locations API
|
|
3
|
+
* Fetches business locations from Wix Bookings Services
|
|
4
|
+
*
|
|
5
|
+
* @module API/QueryLocations
|
|
6
|
+
*/
|
|
7
|
+
import type { Service } from '@wix/auto_sdk_bookings_services';
|
|
8
|
+
/**
|
|
9
|
+
* LocationData type - from Service['locations'][number]
|
|
10
|
+
*/
|
|
11
|
+
export type LocationData = NonNullable<Service['locations']>[number];
|
|
12
|
+
/**
|
|
13
|
+
* Result from querying locations
|
|
14
|
+
*/
|
|
15
|
+
export interface QueryLocationsResult {
|
|
16
|
+
/** Business locations array */
|
|
17
|
+
locations: LocationData[];
|
|
18
|
+
/** Whether custom locations exist for any service */
|
|
19
|
+
hasCustomLocations: boolean;
|
|
20
|
+
/** Whether customer locations (at customer's place) exist for any service */
|
|
21
|
+
hasCustomerLocations: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Query all locations connected to services.
|
|
25
|
+
* Returns business locations array and existence flags for custom/customer locations.
|
|
26
|
+
*
|
|
27
|
+
* @returns Promise resolving to locations and existence flags
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const { locations, hasCustomLocations, hasCustomerLocations } = await queryLocations();
|
|
32
|
+
*
|
|
33
|
+
* // locations contains all business locations
|
|
34
|
+
* // hasCustomLocations indicates if any service uses custom locations
|
|
35
|
+
* // hasCustomerLocations indicates if any service is at customer's place
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function queryLocations(): Promise<QueryLocationsResult>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Locations API
|
|
3
|
+
* Fetches business locations from Wix Bookings Services
|
|
4
|
+
*
|
|
5
|
+
* @module API/QueryLocations
|
|
6
|
+
*/
|
|
7
|
+
import { queryLocations as queryLocationsApi, } from '@wix/auto_sdk_bookings_services';
|
|
8
|
+
/**
|
|
9
|
+
* Query all locations connected to services.
|
|
10
|
+
* Returns business locations array and existence flags for custom/customer locations.
|
|
11
|
+
*
|
|
12
|
+
* @returns Promise resolving to locations and existence flags
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const { locations, hasCustomLocations, hasCustomerLocations } = await queryLocations();
|
|
17
|
+
*
|
|
18
|
+
* // locations contains all business locations
|
|
19
|
+
* // hasCustomLocations indicates if any service uses custom locations
|
|
20
|
+
* // hasCustomerLocations indicates if any service is at customer's place
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export async function queryLocations() {
|
|
24
|
+
const response = await queryLocationsApi();
|
|
25
|
+
return {
|
|
26
|
+
locations: (response.businessLocations?.locations || []),
|
|
27
|
+
hasCustomLocations: response.customLocations?.exists || false,
|
|
28
|
+
hasCustomerLocations: response.customerLocations?.exists || false,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Core Location Component - Parses service location data
|
|
3
3
|
* Handles business, custom, and customer location types
|
|
4
4
|
* Converts location data to Address component format
|
|
5
|
+
*
|
|
6
|
+
* @module Core/Location
|
|
5
7
|
*/
|
|
6
8
|
import React from 'react';
|
|
7
9
|
import { LocationType, type Service } from '@wix/auto_sdk_bookings_services';
|
|
@@ -10,35 +12,132 @@ import type { AddressData as AddressDataType } from '@wix/headless-components/re
|
|
|
10
12
|
* Re-export AddressData type from Address component for convenience
|
|
11
13
|
*/
|
|
12
14
|
export type AddressData = AddressDataType;
|
|
15
|
+
/**
|
|
16
|
+
* Service location type - from Service['locations'][number]
|
|
17
|
+
*/
|
|
18
|
+
export type ServiceLocation = NonNullable<Service['locations']>[number];
|
|
19
|
+
/**
|
|
20
|
+
* Synthetic location - represents a location type without real data
|
|
21
|
+
* Used for CUSTOMER or CUSTOM locations when no real location data exists
|
|
22
|
+
*/
|
|
23
|
+
export interface SyntheticLocation {
|
|
24
|
+
/** Location type */
|
|
25
|
+
locationType: LocationType.CUSTOMER | LocationType.CUSTOM;
|
|
26
|
+
/** Marker to identify synthetic locations */
|
|
27
|
+
synthetic: true;
|
|
28
|
+
/** Optional ID for tracking */
|
|
29
|
+
id?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Union type - location prop accepts Service or Synthetic location
|
|
33
|
+
*/
|
|
34
|
+
export type LocationInput = ServiceLocation | SyntheticLocation;
|
|
13
35
|
/**
|
|
14
36
|
* Location render props passed to children
|
|
15
37
|
*/
|
|
16
38
|
export interface LocationRenderProps {
|
|
39
|
+
/** Location type */
|
|
17
40
|
locationType: LocationType;
|
|
41
|
+
/** Parsed address data compatible with Address.Root, null if not available */
|
|
18
42
|
address: AddressData | null;
|
|
43
|
+
/** Location name (business.name or custom name) */
|
|
44
|
+
name: string | undefined;
|
|
45
|
+
/** Location ID */
|
|
46
|
+
locationId: string | undefined;
|
|
47
|
+
/** Whether this is a customer location */
|
|
48
|
+
isCustomerLocation: boolean;
|
|
49
|
+
/** Whether this is a custom location */
|
|
50
|
+
isCustomLocation: boolean;
|
|
51
|
+
/** Whether this is a synthetic entry (not from array) */
|
|
52
|
+
isSynthetic: boolean;
|
|
53
|
+
/** Phone number (only for BUSINESS ServiceLocations) */
|
|
54
|
+
phone: string | undefined;
|
|
55
|
+
/** Email address (only for BUSINESS ServiceLocations) */
|
|
56
|
+
email: string | undefined;
|
|
57
|
+
/** Raw location object (Service or Synthetic location) */
|
|
58
|
+
rawLocation: LocationInput | null;
|
|
19
59
|
}
|
|
20
60
|
/**
|
|
21
|
-
* Props for the
|
|
61
|
+
* Props for the Core Location Root component
|
|
22
62
|
*/
|
|
23
|
-
export interface
|
|
24
|
-
location
|
|
63
|
+
export interface RootProps {
|
|
64
|
+
/** Raw location data - accepts Service or Synthetic location */
|
|
65
|
+
location?: LocationInput;
|
|
66
|
+
/** Children */
|
|
67
|
+
children: React.ReactNode;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Props for the Core Location Data component
|
|
71
|
+
*/
|
|
72
|
+
export interface DataProps {
|
|
73
|
+
/** Children render prop that receives location data */
|
|
25
74
|
children: (props: LocationRenderProps) => React.ReactNode;
|
|
26
75
|
}
|
|
27
76
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
77
|
+
* Hook to access location context from CoreLocation.Root
|
|
78
|
+
* @throws Error if used outside of CoreLocation.Root
|
|
79
|
+
*/
|
|
80
|
+
export declare function useLocationContext(): LocationRenderProps;
|
|
81
|
+
/**
|
|
82
|
+
* Core Location Root component that provides location context.
|
|
83
|
+
* Parses location data and makes it available to all child components via context.
|
|
84
|
+
*
|
|
85
|
+
* @component
|
|
86
|
+
* @example
|
|
87
|
+
* ```tsx
|
|
88
|
+
* <CoreLocation.Root location={serviceLocation}>
|
|
89
|
+
* <Location.Name />
|
|
90
|
+
* <Location.Address />
|
|
91
|
+
* </CoreLocation.Root>
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export declare function Root(props: RootProps): React.ReactNode;
|
|
95
|
+
/**
|
|
96
|
+
* Core Location Data component that exposes location data via render props.
|
|
97
|
+
* Must be used within a CoreLocation.Root component.
|
|
98
|
+
*
|
|
99
|
+
* @component
|
|
100
|
+
* @example
|
|
101
|
+
* ```tsx
|
|
102
|
+
* <CoreLocation.Root location={serviceLocation}>
|
|
103
|
+
* <CoreLocation.Data>
|
|
104
|
+
* {({ displayName, address }) => (
|
|
105
|
+
* <div>
|
|
106
|
+
* <span>{displayName}</span>
|
|
107
|
+
* {address && <Address.Formatted address={address} />}
|
|
108
|
+
* </div>
|
|
109
|
+
* )}
|
|
110
|
+
* </CoreLocation.Data>
|
|
111
|
+
* </CoreLocation.Root>
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export declare function Data(props: DataProps): React.ReactNode;
|
|
115
|
+
/**
|
|
116
|
+
* Props for Actions render prop component
|
|
117
|
+
*/
|
|
118
|
+
export interface ActionsProps {
|
|
119
|
+
children: (actions: {
|
|
120
|
+
select: () => void;
|
|
121
|
+
rawLocation: LocationInput | null;
|
|
122
|
+
selected: boolean;
|
|
123
|
+
}) => React.ReactNode;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Core component that provides location selection actions via render props.
|
|
127
|
+
* Sets the location in BookingService when select is called.
|
|
30
128
|
*
|
|
31
129
|
* @component
|
|
32
130
|
* @example
|
|
33
131
|
* ```tsx
|
|
34
|
-
* <CoreLocation location={serviceLocation}>
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* <
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
132
|
+
* <CoreLocation.Root location={serviceLocation}>
|
|
133
|
+
* <CoreLocation.Actions>
|
|
134
|
+
* {({ select, selected, rawLocation }) => (
|
|
135
|
+
* <button onClick={select}>
|
|
136
|
+
* {selected ? 'Selected' : 'Select'}
|
|
137
|
+
* </button>
|
|
138
|
+
* )}
|
|
139
|
+
* </CoreLocation.Actions>
|
|
140
|
+
* </CoreLocation.Root>
|
|
42
141
|
* ```
|
|
43
142
|
*/
|
|
44
|
-
export declare function
|
|
143
|
+
export declare function Actions(props: ActionsProps): React.ReactNode;
|