@growsober/sdk 1.0.22 → 1.0.24
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/api/mutations/products.d.ts +3 -150
- package/dist/api/mutations/products.js +1 -124
- package/dist/api/queries/creators.d.ts +32 -0
- package/dist/api/queries/creators.js +39 -1
- package/dist/api/queries/products.d.ts +9 -87
- package/dist/api/queries/products.js +1 -86
- package/package.json +3 -2
- package/src/api/mutations/products.ts +4 -153
- package/src/api/queries/creators.ts +70 -0
- package/src/api/queries/products.ts +11 -88
|
@@ -1,40 +1,14 @@
|
|
|
1
1
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
2
2
|
import { getApiClient } from '../client';
|
|
3
|
-
import { productKeys, CreatorProductResponse, ProductBookingResponse,
|
|
3
|
+
import { productKeys, CreatorProductResponse, ProductBookingResponse, CreateProductDto, UpdateProductDto } from '../queries/products';
|
|
4
4
|
import { creatorKeys } from '../queries/creators';
|
|
5
5
|
|
|
6
6
|
// ============================================================================
|
|
7
|
-
// TYPES
|
|
7
|
+
// TYPES — request types derived from auto-generated OpenAPI DTOs
|
|
8
8
|
// ============================================================================
|
|
9
9
|
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
description?: string;
|
|
13
|
-
imageUrl?: string;
|
|
14
|
-
type?: ProductType;
|
|
15
|
-
price: number;
|
|
16
|
-
currency?: string;
|
|
17
|
-
durationMinutes?: number;
|
|
18
|
-
maxParticipants?: number;
|
|
19
|
-
deliveryMethod?: DeliveryMethod;
|
|
20
|
-
locationDetails?: string;
|
|
21
|
-
slug?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface UpdateProductRequest {
|
|
25
|
-
title?: string;
|
|
26
|
-
description?: string;
|
|
27
|
-
imageUrl?: string;
|
|
28
|
-
type?: ProductType;
|
|
29
|
-
price?: number;
|
|
30
|
-
currency?: string;
|
|
31
|
-
durationMinutes?: number;
|
|
32
|
-
maxParticipants?: number;
|
|
33
|
-
deliveryMethod?: DeliveryMethod;
|
|
34
|
-
locationDetails?: string;
|
|
35
|
-
isActive?: boolean;
|
|
36
|
-
isFeatured?: boolean;
|
|
37
|
-
}
|
|
10
|
+
export type CreateProductRequest = CreateProductDto;
|
|
11
|
+
export type UpdateProductRequest = UpdateProductDto;
|
|
38
12
|
|
|
39
13
|
export interface BookProductRequest {
|
|
40
14
|
scheduledAt: string;
|
|
@@ -57,25 +31,6 @@ export interface CancelBookingRequest {
|
|
|
57
31
|
// MUTATION HOOKS - PRODUCTS
|
|
58
32
|
// ============================================================================
|
|
59
33
|
|
|
60
|
-
/**
|
|
61
|
-
* Create a new product for a creator
|
|
62
|
-
*
|
|
63
|
-
* @example
|
|
64
|
-
* ```tsx
|
|
65
|
-
* const { mutate: createProduct, isLoading } = useCreateProduct();
|
|
66
|
-
*
|
|
67
|
-
* createProduct({
|
|
68
|
-
* creatorId: 'creator-123',
|
|
69
|
-
* data: {
|
|
70
|
-
* title: '1-on-1 Coaching Session',
|
|
71
|
-
* description: 'Personal coaching session',
|
|
72
|
-
* type: 'SESSION_1ON1',
|
|
73
|
-
* price: 5000,
|
|
74
|
-
* durationMinutes: 60,
|
|
75
|
-
* },
|
|
76
|
-
* });
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
34
|
export function useCreateProduct() {
|
|
80
35
|
const queryClient = useQueryClient();
|
|
81
36
|
|
|
@@ -98,23 +53,6 @@ export function useCreateProduct() {
|
|
|
98
53
|
});
|
|
99
54
|
}
|
|
100
55
|
|
|
101
|
-
/**
|
|
102
|
-
* Update an existing product
|
|
103
|
-
*
|
|
104
|
-
* @example
|
|
105
|
-
* ```tsx
|
|
106
|
-
* const { mutate: updateProduct, isLoading } = useUpdateProduct();
|
|
107
|
-
*
|
|
108
|
-
* updateProduct({
|
|
109
|
-
* creatorId: 'creator-123',
|
|
110
|
-
* productId: 'product-456',
|
|
111
|
-
* data: {
|
|
112
|
-
* price: 6000,
|
|
113
|
-
* isActive: true,
|
|
114
|
-
* },
|
|
115
|
-
* });
|
|
116
|
-
* ```
|
|
117
|
-
*/
|
|
118
56
|
export function useUpdateProduct() {
|
|
119
57
|
const queryClient = useQueryClient();
|
|
120
58
|
|
|
@@ -143,19 +81,6 @@ export function useUpdateProduct() {
|
|
|
143
81
|
});
|
|
144
82
|
}
|
|
145
83
|
|
|
146
|
-
/**
|
|
147
|
-
* Delete a product
|
|
148
|
-
*
|
|
149
|
-
* @example
|
|
150
|
-
* ```tsx
|
|
151
|
-
* const { mutate: deleteProduct, isLoading } = useDeleteProduct();
|
|
152
|
-
*
|
|
153
|
-
* deleteProduct({
|
|
154
|
-
* creatorId: 'creator-123',
|
|
155
|
-
* productId: 'product-456',
|
|
156
|
-
* });
|
|
157
|
-
* ```
|
|
158
|
-
*/
|
|
159
84
|
export function useDeleteProduct() {
|
|
160
85
|
const queryClient = useQueryClient();
|
|
161
86
|
|
|
@@ -182,23 +107,6 @@ export function useDeleteProduct() {
|
|
|
182
107
|
// MUTATION HOOKS - BOOKINGS
|
|
183
108
|
// ============================================================================
|
|
184
109
|
|
|
185
|
-
/**
|
|
186
|
-
* Book a product/session
|
|
187
|
-
*
|
|
188
|
-
* @example
|
|
189
|
-
* ```tsx
|
|
190
|
-
* const { mutate: bookProduct, isLoading } = useBookProduct();
|
|
191
|
-
*
|
|
192
|
-
* bookProduct({
|
|
193
|
-
* productId: 'product-123',
|
|
194
|
-
* data: {
|
|
195
|
-
* scheduledAt: '2024-03-15T10:00:00Z',
|
|
196
|
-
* timezone: 'Europe/London',
|
|
197
|
-
* clientNotes: 'Looking forward to the session!',
|
|
198
|
-
* },
|
|
199
|
-
* });
|
|
200
|
-
* ```
|
|
201
|
-
*/
|
|
202
110
|
export function useBookProduct() {
|
|
203
111
|
const queryClient = useQueryClient();
|
|
204
112
|
|
|
@@ -220,22 +128,6 @@ export function useBookProduct() {
|
|
|
220
128
|
});
|
|
221
129
|
}
|
|
222
130
|
|
|
223
|
-
/**
|
|
224
|
-
* Update a product booking
|
|
225
|
-
*
|
|
226
|
-
* @example
|
|
227
|
-
* ```tsx
|
|
228
|
-
* const { mutate: updateBooking, isLoading } = useUpdateProductBooking();
|
|
229
|
-
*
|
|
230
|
-
* updateBooking({
|
|
231
|
-
* bookingId: 'booking-123',
|
|
232
|
-
* data: {
|
|
233
|
-
* scheduledAt: '2024-03-16T14:00:00Z',
|
|
234
|
-
* clientNotes: 'Rescheduled due to conflict',
|
|
235
|
-
* },
|
|
236
|
-
* });
|
|
237
|
-
* ```
|
|
238
|
-
*/
|
|
239
131
|
export function useUpdateProductBooking() {
|
|
240
132
|
const queryClient = useQueryClient();
|
|
241
133
|
|
|
@@ -257,25 +149,11 @@ export function useUpdateProductBooking() {
|
|
|
257
149
|
onSuccess: (_, { bookingId }) => {
|
|
258
150
|
queryClient.invalidateQueries({ queryKey: productKeys.bookingDetail(bookingId) });
|
|
259
151
|
queryClient.invalidateQueries({ queryKey: productKeys.myBookings() });
|
|
260
|
-
// Also invalidate creator bookings as they see this
|
|
261
152
|
queryClient.invalidateQueries({ queryKey: productKeys.bookings() });
|
|
262
153
|
},
|
|
263
154
|
});
|
|
264
155
|
}
|
|
265
156
|
|
|
266
|
-
/**
|
|
267
|
-
* Cancel a product booking
|
|
268
|
-
*
|
|
269
|
-
* @example
|
|
270
|
-
* ```tsx
|
|
271
|
-
* const { mutate: cancelBooking, isLoading } = useCancelProductBooking();
|
|
272
|
-
*
|
|
273
|
-
* cancelBooking({
|
|
274
|
-
* bookingId: 'booking-123',
|
|
275
|
-
* data: { reason: 'Schedule conflict' },
|
|
276
|
-
* });
|
|
277
|
-
* ```
|
|
278
|
-
*/
|
|
279
157
|
export function useCancelProductBooking() {
|
|
280
158
|
const queryClient = useQueryClient();
|
|
281
159
|
|
|
@@ -302,16 +180,6 @@ export function useCancelProductBooking() {
|
|
|
302
180
|
});
|
|
303
181
|
}
|
|
304
182
|
|
|
305
|
-
/**
|
|
306
|
-
* Mark a booking as completed (creator only)
|
|
307
|
-
*
|
|
308
|
-
* @example
|
|
309
|
-
* ```tsx
|
|
310
|
-
* const { mutate: completeBooking, isLoading } = useCompleteProductBooking();
|
|
311
|
-
*
|
|
312
|
-
* completeBooking({ bookingId: 'booking-123' });
|
|
313
|
-
* ```
|
|
314
|
-
*/
|
|
315
183
|
export function useCompleteProductBooking() {
|
|
316
184
|
const queryClient = useQueryClient();
|
|
317
185
|
|
|
@@ -344,23 +212,6 @@ export interface PaymentIntentResponse {
|
|
|
344
212
|
paymentIntentId: string;
|
|
345
213
|
}
|
|
346
214
|
|
|
347
|
-
/**
|
|
348
|
-
* Create a payment intent for a product booking
|
|
349
|
-
* Use this with Stripe Elements to process payment
|
|
350
|
-
*
|
|
351
|
-
* @example
|
|
352
|
-
* ```tsx
|
|
353
|
-
* const { mutate: createPaymentIntent, data, isLoading } = useCreateProductPaymentIntent();
|
|
354
|
-
*
|
|
355
|
-
* // Create payment intent
|
|
356
|
-
* createPaymentIntent({ bookingId: 'booking-123' });
|
|
357
|
-
*
|
|
358
|
-
* // Use clientSecret with Stripe Elements
|
|
359
|
-
* if (data?.clientSecret) {
|
|
360
|
-
* // Pass to Stripe PaymentElement
|
|
361
|
-
* }
|
|
362
|
-
* ```
|
|
363
|
-
*/
|
|
364
215
|
export function useCreateProductPaymentIntent() {
|
|
365
216
|
return useMutation({
|
|
366
217
|
mutationFn: async ({
|
|
@@ -23,6 +23,8 @@ export const creatorKeys = {
|
|
|
23
23
|
byUser: (userId: string) => [...creatorKeys.all, 'user', userId] as const,
|
|
24
24
|
me: () => [...creatorKeys.all, 'me'] as const,
|
|
25
25
|
availability: (creatorId: string) => [...creatorKeys.detail(creatorId), 'availability'] as const,
|
|
26
|
+
availableDates: (creatorId: string, from: string, to: string) => [...creatorKeys.detail(creatorId), 'available-dates', from, to] as const,
|
|
27
|
+
availableSlots: (creatorId: string, date: string, durationMinutes: number) => [...creatorKeys.detail(creatorId), 'available-slots', date, durationMinutes] as const,
|
|
26
28
|
content: (creatorId: string) => [...creatorKeys.detail(creatorId), 'content'] as const,
|
|
27
29
|
allContent: (creatorId: string) => [...creatorKeys.detail(creatorId), 'content', 'all'] as const,
|
|
28
30
|
events: (creatorId: string) => [...creatorKeys.detail(creatorId), 'events'] as const,
|
|
@@ -229,6 +231,74 @@ export function useCreatorAvailability(
|
|
|
229
231
|
});
|
|
230
232
|
}
|
|
231
233
|
|
|
234
|
+
// ============================================================================
|
|
235
|
+
// AVAILABILITY-AWARE SCHEDULING
|
|
236
|
+
// ============================================================================
|
|
237
|
+
|
|
238
|
+
export interface AvailableDateEntry {
|
|
239
|
+
date: string;
|
|
240
|
+
hasAvailability: boolean;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export interface AvailableDatesResponse {
|
|
244
|
+
dates: AvailableDateEntry[];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export interface AvailableSlotEntry {
|
|
248
|
+
startTime: string;
|
|
249
|
+
endTime: string;
|
|
250
|
+
available: boolean;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export interface AvailableSlotsResponse {
|
|
254
|
+
date: string;
|
|
255
|
+
slots: AvailableSlotEntry[];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Get dates with availability for a creator in a date range
|
|
260
|
+
*/
|
|
261
|
+
export function useCreatorAvailableDates(
|
|
262
|
+
creatorId: string,
|
|
263
|
+
params: { from: string; to: string },
|
|
264
|
+
options?: Omit<UseQueryOptions<AvailableDatesResponse>, 'queryKey' | 'queryFn'>
|
|
265
|
+
) {
|
|
266
|
+
return useQuery({
|
|
267
|
+
queryKey: creatorKeys.availableDates(creatorId, params.from, params.to),
|
|
268
|
+
queryFn: async (): Promise<AvailableDatesResponse> => {
|
|
269
|
+
const client = getApiClient();
|
|
270
|
+
const response = await client.get(`/api/v1/creators/${creatorId}/available-dates`, {
|
|
271
|
+
params,
|
|
272
|
+
});
|
|
273
|
+
return response.data;
|
|
274
|
+
},
|
|
275
|
+
enabled: !!creatorId && !!params.from && !!params.to,
|
|
276
|
+
...options,
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Get available time slots for a creator on a specific date
|
|
282
|
+
*/
|
|
283
|
+
export function useCreatorAvailableSlots(
|
|
284
|
+
creatorId: string,
|
|
285
|
+
params: { date: string; durationMinutes?: number },
|
|
286
|
+
options?: Omit<UseQueryOptions<AvailableSlotsResponse>, 'queryKey' | 'queryFn'>
|
|
287
|
+
) {
|
|
288
|
+
return useQuery({
|
|
289
|
+
queryKey: creatorKeys.availableSlots(creatorId, params.date, params.durationMinutes || 60),
|
|
290
|
+
queryFn: async (): Promise<AvailableSlotsResponse> => {
|
|
291
|
+
const client = getApiClient();
|
|
292
|
+
const response = await client.get(`/api/v1/creators/${creatorId}/available-slots`, {
|
|
293
|
+
params,
|
|
294
|
+
});
|
|
295
|
+
return response.data;
|
|
296
|
+
},
|
|
297
|
+
enabled: !!creatorId && !!params.date,
|
|
298
|
+
...options,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
|
|
232
302
|
/**
|
|
233
303
|
* Get a creator's published library content
|
|
234
304
|
*
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { useQuery, UseQueryOptions } from '@tanstack/react-query';
|
|
2
2
|
import { getApiClient } from '../client';
|
|
3
|
+
import type { components } from '@growsober/types';
|
|
3
4
|
|
|
4
5
|
// ============================================================================
|
|
5
|
-
// TYPES
|
|
6
|
+
// TYPES — derived from auto-generated OpenAPI types
|
|
6
7
|
// ============================================================================
|
|
7
8
|
|
|
8
|
-
export type
|
|
9
|
-
export type
|
|
9
|
+
export type CreateProductDto = components['schemas']['CreateProductDto'];
|
|
10
|
+
export type UpdateProductDto = components['schemas']['UpdateProductDto'];
|
|
11
|
+
|
|
12
|
+
export type ProductType = CreateProductDto['type'];
|
|
13
|
+
export type DeliveryMethod = CreateProductDto['deliveryMethod'];
|
|
10
14
|
export type BookingStatus = 'PENDING' | 'CONFIRMED' | 'CANCELLED' | 'COMPLETED';
|
|
11
15
|
export type PaymentStatus = 'PENDING' | 'PAID' | 'REFUNDED' | 'FAILED';
|
|
12
16
|
|
|
@@ -17,6 +21,8 @@ export interface CreatorProductResponse {
|
|
|
17
21
|
slug: string;
|
|
18
22
|
description: string | null;
|
|
19
23
|
imageUrl: string | null;
|
|
24
|
+
category: string | null;
|
|
25
|
+
tags: string[];
|
|
20
26
|
type: ProductType;
|
|
21
27
|
price: number;
|
|
22
28
|
currency: string;
|
|
@@ -26,6 +32,8 @@ export interface CreatorProductResponse {
|
|
|
26
32
|
locationDetails: string | null;
|
|
27
33
|
isActive: boolean;
|
|
28
34
|
isFeatured: boolean;
|
|
35
|
+
stripeProductId?: string | null;
|
|
36
|
+
stripePriceId?: string | null;
|
|
29
37
|
createdAt: string;
|
|
30
38
|
updatedAt: string;
|
|
31
39
|
creator?: {
|
|
@@ -112,21 +120,6 @@ export const productKeys = {
|
|
|
112
120
|
// QUERY HOOKS
|
|
113
121
|
// ============================================================================
|
|
114
122
|
|
|
115
|
-
/**
|
|
116
|
-
* Get paginated list of all active products
|
|
117
|
-
*
|
|
118
|
-
* @param filters - Query parameters for filtering and pagination
|
|
119
|
-
* @param options - TanStack Query options
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* ```tsx
|
|
123
|
-
* const { data, isLoading } = useProducts({
|
|
124
|
-
* page: 1,
|
|
125
|
-
* limit: 20,
|
|
126
|
-
* type: 'SESSION_1ON1',
|
|
127
|
-
* });
|
|
128
|
-
* ```
|
|
129
|
-
*/
|
|
130
123
|
export function useProducts(
|
|
131
124
|
filters?: ProductFilters,
|
|
132
125
|
options?: Omit<UseQueryOptions<PaginatedProductsResponse>, 'queryKey' | 'queryFn'>
|
|
@@ -144,17 +137,6 @@ export function useProducts(
|
|
|
144
137
|
});
|
|
145
138
|
}
|
|
146
139
|
|
|
147
|
-
/**
|
|
148
|
-
* Get a single product by ID
|
|
149
|
-
*
|
|
150
|
-
* @param id - Product ID
|
|
151
|
-
* @param options - TanStack Query options
|
|
152
|
-
*
|
|
153
|
-
* @example
|
|
154
|
-
* ```tsx
|
|
155
|
-
* const { data, isLoading } = useProduct('product-123');
|
|
156
|
-
* ```
|
|
157
|
-
*/
|
|
158
140
|
export function useProduct(
|
|
159
141
|
id: string,
|
|
160
142
|
options?: Omit<UseQueryOptions<CreatorProductResponse>, 'queryKey' | 'queryFn'>
|
|
@@ -171,17 +153,6 @@ export function useProduct(
|
|
|
171
153
|
});
|
|
172
154
|
}
|
|
173
155
|
|
|
174
|
-
/**
|
|
175
|
-
* Get a product by its slug
|
|
176
|
-
*
|
|
177
|
-
* @param slug - Product slug
|
|
178
|
-
* @param options - TanStack Query options
|
|
179
|
-
*
|
|
180
|
-
* @example
|
|
181
|
-
* ```tsx
|
|
182
|
-
* const { data, isLoading } = useProductBySlug('1-on-1-coaching-abc123');
|
|
183
|
-
* ```
|
|
184
|
-
*/
|
|
185
156
|
export function useProductBySlug(
|
|
186
157
|
slug: string,
|
|
187
158
|
options?: Omit<UseQueryOptions<CreatorProductResponse>, 'queryKey' | 'queryFn'>
|
|
@@ -198,21 +169,6 @@ export function useProductBySlug(
|
|
|
198
169
|
});
|
|
199
170
|
}
|
|
200
171
|
|
|
201
|
-
/**
|
|
202
|
-
* Get products for a specific creator
|
|
203
|
-
*
|
|
204
|
-
* @param creatorId - Creator ID
|
|
205
|
-
* @param filters - Query parameters for filtering
|
|
206
|
-
* @param options - TanStack Query options
|
|
207
|
-
*
|
|
208
|
-
* @example
|
|
209
|
-
* ```tsx
|
|
210
|
-
* const { data, isLoading } = useCreatorProducts('creator-123', {
|
|
211
|
-
* type: 'SESSION_1ON1',
|
|
212
|
-
* isActive: true,
|
|
213
|
-
* });
|
|
214
|
-
* ```
|
|
215
|
-
*/
|
|
216
172
|
export function useCreatorProducts(
|
|
217
173
|
creatorId: string,
|
|
218
174
|
filters?: ProductFilters,
|
|
@@ -232,16 +188,6 @@ export function useCreatorProducts(
|
|
|
232
188
|
});
|
|
233
189
|
}
|
|
234
190
|
|
|
235
|
-
/**
|
|
236
|
-
* Get current user's product bookings
|
|
237
|
-
*
|
|
238
|
-
* @param options - TanStack Query options
|
|
239
|
-
*
|
|
240
|
-
* @example
|
|
241
|
-
* ```tsx
|
|
242
|
-
* const { data, isLoading } = useMyProductBookings();
|
|
243
|
-
* ```
|
|
244
|
-
*/
|
|
245
191
|
export function useMyProductBookings(
|
|
246
192
|
options?: Omit<UseQueryOptions<ProductBookingResponse[]>, 'queryKey' | 'queryFn'>
|
|
247
193
|
) {
|
|
@@ -256,17 +202,6 @@ export function useMyProductBookings(
|
|
|
256
202
|
});
|
|
257
203
|
}
|
|
258
204
|
|
|
259
|
-
/**
|
|
260
|
-
* Get a single product booking by ID
|
|
261
|
-
*
|
|
262
|
-
* @param bookingId - Booking ID
|
|
263
|
-
* @param options - TanStack Query options
|
|
264
|
-
*
|
|
265
|
-
* @example
|
|
266
|
-
* ```tsx
|
|
267
|
-
* const { data, isLoading } = useProductBooking('booking-123');
|
|
268
|
-
* ```
|
|
269
|
-
*/
|
|
270
205
|
export function useProductBooking(
|
|
271
206
|
bookingId: string,
|
|
272
207
|
options?: Omit<UseQueryOptions<ProductBookingResponse>, 'queryKey' | 'queryFn'>
|
|
@@ -283,18 +218,6 @@ export function useProductBooking(
|
|
|
283
218
|
});
|
|
284
219
|
}
|
|
285
220
|
|
|
286
|
-
/**
|
|
287
|
-
* Get bookings for a creator's products (creator dashboard)
|
|
288
|
-
*
|
|
289
|
-
* @param creatorId - Creator ID
|
|
290
|
-
* @param options - TanStack Query options
|
|
291
|
-
*
|
|
292
|
-
* @example
|
|
293
|
-
* ```tsx
|
|
294
|
-
* // For creator dashboard - see all bookings for their products
|
|
295
|
-
* const { data, isLoading } = useCreatorBookings('creator-123');
|
|
296
|
-
* ```
|
|
297
|
-
*/
|
|
298
221
|
export function useCreatorBookings(
|
|
299
222
|
creatorId: string,
|
|
300
223
|
options?: Omit<UseQueryOptions<ProductBookingResponse[]>, 'queryKey' | 'queryFn'>
|