@growsober/sdk 1.0.5 → 1.0.8

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.
Files changed (70) hide show
  1. package/dist/__tests__/e2e.test.d.ts +30 -0
  2. package/dist/__tests__/e2e.test.js +959 -63
  3. package/dist/api/mutations/badges.d.ts +116 -0
  4. package/dist/api/mutations/badges.js +177 -0
  5. package/dist/api/mutations/brands.d.ts +251 -0
  6. package/dist/api/mutations/brands.js +242 -0
  7. package/dist/api/mutations/creators.d.ts +131 -0
  8. package/dist/api/mutations/creators.js +129 -0
  9. package/dist/api/mutations/event-chat.d.ts +2 -2
  10. package/dist/api/mutations/event-chat.js +9 -9
  11. package/dist/api/mutations/index.d.ts +4 -0
  12. package/dist/api/mutations/index.js +5 -1
  13. package/dist/api/mutations/jack.d.ts +29 -0
  14. package/dist/api/mutations/jack.js +41 -1
  15. package/dist/api/mutations/products.d.ts +175 -0
  16. package/dist/api/mutations/products.js +226 -0
  17. package/dist/api/mutations/support.d.ts +20 -1
  18. package/dist/api/mutations/support.js +36 -1
  19. package/dist/api/queries/badges.d.ts +221 -0
  20. package/dist/api/queries/badges.js +290 -0
  21. package/dist/api/queries/bookings.d.ts +1 -1
  22. package/dist/api/queries/brands.d.ts +248 -0
  23. package/dist/api/queries/brands.js +226 -0
  24. package/dist/api/queries/businesses.d.ts +61 -1
  25. package/dist/api/queries/businesses.js +27 -1
  26. package/dist/api/queries/creators.d.ts +332 -0
  27. package/dist/api/queries/creators.js +249 -0
  28. package/dist/api/queries/event-chat.d.ts +1 -1
  29. package/dist/api/queries/event-chat.js +4 -4
  30. package/dist/api/queries/events.d.ts +45 -0
  31. package/dist/api/queries/index.d.ts +5 -0
  32. package/dist/api/queries/index.js +6 -1
  33. package/dist/api/queries/jack.d.ts +80 -0
  34. package/dist/api/queries/jack.js +98 -1
  35. package/dist/api/queries/library.d.ts +8 -0
  36. package/dist/api/queries/products.d.ts +185 -0
  37. package/dist/api/queries/products.js +203 -0
  38. package/dist/api/queries/support.d.ts +46 -1
  39. package/dist/api/queries/support.js +48 -1
  40. package/dist/api/queries/venues.d.ts +304 -0
  41. package/dist/api/queries/venues.js +211 -0
  42. package/dist/api/types.d.ts +245 -0
  43. package/dist/api/types.js +6 -1
  44. package/dist/api/utils/eventGrouping.d.ts +104 -0
  45. package/dist/api/utils/eventGrouping.js +155 -0
  46. package/dist/index.d.ts +1 -0
  47. package/dist/index.js +5 -1
  48. package/package.json +5 -2
  49. package/src/__tests__/e2e.test.ts +996 -64
  50. package/src/api/mutations/badges.ts +228 -0
  51. package/src/api/mutations/brands.ts +376 -0
  52. package/src/api/mutations/creators.ts +171 -0
  53. package/src/api/mutations/event-chat.ts +8 -8
  54. package/src/api/mutations/index.ts +4 -0
  55. package/src/api/mutations/jack.ts +50 -1
  56. package/src/api/mutations/products.ts +336 -0
  57. package/src/api/mutations/support.ts +44 -0
  58. package/src/api/queries/badges.ts +385 -0
  59. package/src/api/queries/brands.ts +281 -0
  60. package/src/api/queries/businesses.ts +30 -1
  61. package/src/api/queries/creators.ts +308 -0
  62. package/src/api/queries/event-chat.ts +3 -3
  63. package/src/api/queries/index.ts +5 -0
  64. package/src/api/queries/jack.ts +139 -1
  65. package/src/api/queries/products.ts +312 -0
  66. package/src/api/queries/support.ts +54 -0
  67. package/src/api/queries/venues.ts +271 -0
  68. package/src/api/types.ts +317 -1
  69. package/src/api/utils/eventGrouping.ts +181 -0
  70. package/src/index.ts +6 -0
@@ -0,0 +1,312 @@
1
+ import { useQuery, UseQueryOptions } from '@tanstack/react-query';
2
+ import { getApiClient } from '../client';
3
+
4
+ // ============================================================================
5
+ // TYPES
6
+ // ============================================================================
7
+
8
+ export type ProductType = 'SESSION_1ON1' | 'SESSION_GROUP' | 'PACKAGE' | 'WORKSHOP' | 'CONSULTATION';
9
+ export type DeliveryMethod = 'VIDEO_CALL' | 'PHONE_CALL' | 'IN_PERSON' | 'HYBRID';
10
+ export type BookingStatus = 'PENDING' | 'CONFIRMED' | 'CANCELLED' | 'COMPLETED';
11
+ export type PaymentStatus = 'PENDING' | 'PAID' | 'REFUNDED' | 'FAILED';
12
+
13
+ export interface CreatorProductResponse {
14
+ id: string;
15
+ creatorId: string;
16
+ title: string;
17
+ slug: string;
18
+ description: string | null;
19
+ imageUrl: string | null;
20
+ type: ProductType;
21
+ price: number;
22
+ currency: string;
23
+ durationMinutes: number;
24
+ maxParticipants: number;
25
+ deliveryMethod: DeliveryMethod;
26
+ locationDetails: string | null;
27
+ isActive: boolean;
28
+ isFeatured: boolean;
29
+ createdAt: string;
30
+ updatedAt: string;
31
+ creator?: {
32
+ id: string;
33
+ displayName: string;
34
+ slug: string;
35
+ avatarUrl: string | null;
36
+ specialties?: string[];
37
+ certifications?: string[];
38
+ };
39
+ }
40
+
41
+ export interface ProductBookingResponse {
42
+ id: string;
43
+ productId: string;
44
+ userId: string;
45
+ scheduledAt: string;
46
+ timezone: string;
47
+ status: BookingStatus;
48
+ paymentStatus: PaymentStatus | null;
49
+ stripePaymentIntentId: string | null;
50
+ amountPaid: number | null;
51
+ currency: string;
52
+ clientNotes: string | null;
53
+ creatorNotes: string | null;
54
+ meetingLink: string | null;
55
+ isCompleted: boolean;
56
+ completedAt: string | null;
57
+ isCancelled: boolean;
58
+ cancelledAt: string | null;
59
+ cancelledBy: string | null;
60
+ cancellationReason: string | null;
61
+ createdAt: string;
62
+ updatedAt: string;
63
+ product?: CreatorProductResponse;
64
+ user?: {
65
+ id: string;
66
+ name: string;
67
+ profileImage: string | null;
68
+ email: string;
69
+ };
70
+ }
71
+
72
+ export interface ProductFilters {
73
+ page?: number;
74
+ limit?: number;
75
+ type?: ProductType;
76
+ deliveryMethod?: DeliveryMethod;
77
+ minPrice?: number;
78
+ maxPrice?: number;
79
+ isActive?: boolean;
80
+ }
81
+
82
+ export interface PaginatedProductsResponse {
83
+ products: CreatorProductResponse[];
84
+ meta: {
85
+ total: number;
86
+ page: number;
87
+ limit: number;
88
+ totalPages: number;
89
+ };
90
+ }
91
+
92
+ // ============================================================================
93
+ // QUERY KEY FACTORY
94
+ // ============================================================================
95
+
96
+ export const productKeys = {
97
+ all: ['products'] as const,
98
+ lists: () => [...productKeys.all, 'list'] as const,
99
+ list: (filters?: ProductFilters) => [...productKeys.lists(), filters] as const,
100
+ details: () => [...productKeys.all, 'detail'] as const,
101
+ detail: (id: string) => [...productKeys.details(), id] as const,
102
+ slug: (slug: string) => [...productKeys.all, 'slug', slug] as const,
103
+ byCreator: (creatorId: string, filters?: ProductFilters) =>
104
+ [...productKeys.all, 'creator', creatorId, filters] as const,
105
+ bookings: () => [...productKeys.all, 'bookings'] as const,
106
+ myBookings: () => [...productKeys.bookings(), 'me'] as const,
107
+ creatorBookings: (creatorId: string) => [...productKeys.bookings(), 'creator', creatorId] as const,
108
+ bookingDetail: (bookingId: string) => [...productKeys.bookings(), 'detail', bookingId] as const,
109
+ };
110
+
111
+ // ============================================================================
112
+ // QUERY HOOKS
113
+ // ============================================================================
114
+
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
+ export function useProducts(
131
+ filters?: ProductFilters,
132
+ options?: Omit<UseQueryOptions<PaginatedProductsResponse>, 'queryKey' | 'queryFn'>
133
+ ) {
134
+ return useQuery({
135
+ queryKey: productKeys.list(filters),
136
+ queryFn: async (): Promise<PaginatedProductsResponse> => {
137
+ const client = getApiClient();
138
+ const response = await client.get('/api/v1/products', {
139
+ params: filters,
140
+ });
141
+ return response.data;
142
+ },
143
+ ...options,
144
+ });
145
+ }
146
+
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
+ export function useProduct(
159
+ id: string,
160
+ options?: Omit<UseQueryOptions<CreatorProductResponse>, 'queryKey' | 'queryFn'>
161
+ ) {
162
+ return useQuery({
163
+ queryKey: productKeys.detail(id),
164
+ queryFn: async (): Promise<CreatorProductResponse> => {
165
+ const client = getApiClient();
166
+ const response = await client.get(`/api/v1/products/${id}`);
167
+ return response.data;
168
+ },
169
+ enabled: !!id,
170
+ ...options,
171
+ });
172
+ }
173
+
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
+ export function useProductBySlug(
186
+ slug: string,
187
+ options?: Omit<UseQueryOptions<CreatorProductResponse>, 'queryKey' | 'queryFn'>
188
+ ) {
189
+ return useQuery({
190
+ queryKey: productKeys.slug(slug),
191
+ queryFn: async (): Promise<CreatorProductResponse> => {
192
+ const client = getApiClient();
193
+ const response = await client.get(`/api/v1/products/slug/${slug}`);
194
+ return response.data;
195
+ },
196
+ enabled: !!slug,
197
+ ...options,
198
+ });
199
+ }
200
+
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
+ export function useCreatorProducts(
217
+ creatorId: string,
218
+ filters?: ProductFilters,
219
+ options?: Omit<UseQueryOptions<PaginatedProductsResponse>, 'queryKey' | 'queryFn'>
220
+ ) {
221
+ return useQuery({
222
+ queryKey: productKeys.byCreator(creatorId, filters),
223
+ queryFn: async (): Promise<PaginatedProductsResponse> => {
224
+ const client = getApiClient();
225
+ const response = await client.get(`/api/v1/creators/${creatorId}/products`, {
226
+ params: filters,
227
+ });
228
+ return response.data;
229
+ },
230
+ enabled: !!creatorId,
231
+ ...options,
232
+ });
233
+ }
234
+
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
+ export function useMyProductBookings(
246
+ options?: Omit<UseQueryOptions<ProductBookingResponse[]>, 'queryKey' | 'queryFn'>
247
+ ) {
248
+ return useQuery({
249
+ queryKey: productKeys.myBookings(),
250
+ queryFn: async (): Promise<ProductBookingResponse[]> => {
251
+ const client = getApiClient();
252
+ const response = await client.get('/api/v1/users/me/product-bookings');
253
+ return response.data;
254
+ },
255
+ ...options,
256
+ });
257
+ }
258
+
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
+ export function useProductBooking(
271
+ bookingId: string,
272
+ options?: Omit<UseQueryOptions<ProductBookingResponse>, 'queryKey' | 'queryFn'>
273
+ ) {
274
+ return useQuery({
275
+ queryKey: productKeys.bookingDetail(bookingId),
276
+ queryFn: async (): Promise<ProductBookingResponse> => {
277
+ const client = getApiClient();
278
+ const response = await client.get(`/api/v1/users/me/product-bookings/${bookingId}`);
279
+ return response.data;
280
+ },
281
+ enabled: !!bookingId,
282
+ ...options,
283
+ });
284
+ }
285
+
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
+ export function useCreatorBookings(
299
+ creatorId: string,
300
+ options?: Omit<UseQueryOptions<ProductBookingResponse[]>, 'queryKey' | 'queryFn'>
301
+ ) {
302
+ return useQuery({
303
+ queryKey: productKeys.creatorBookings(creatorId),
304
+ queryFn: async (): Promise<ProductBookingResponse[]> => {
305
+ const client = getApiClient();
306
+ const response = await client.get(`/api/v1/creators/${creatorId}/products/bookings`);
307
+ return response.data;
308
+ },
309
+ enabled: !!creatorId,
310
+ ...options,
311
+ });
312
+ }
@@ -7,6 +7,8 @@ import type {
7
7
  WinResponse,
8
8
  HabitResponse,
9
9
  ReflectionResponse,
10
+ CravingLogResponse,
11
+ CravingStatsResponse,
10
12
  } from '../types';
11
13
 
12
14
  // ============================================================================
@@ -19,6 +21,8 @@ export const supportKeys = {
19
21
  checkInToday: () => [...supportKeys.checkIns(), 'today'] as const,
20
22
  checkInStreak: () => [...supportKeys.checkIns(), 'streak'] as const,
21
23
  moodLogs: () => [...supportKeys.all, 'mood'] as const,
24
+ cravings: () => [...supportKeys.all, 'cravings'] as const,
25
+ cravingStats: (days?: number) => [...supportKeys.cravings(), 'stats', days] as const,
22
26
  wins: () => [...supportKeys.all, 'wins'] as const,
23
27
  winsByCategory: () => [...supportKeys.wins(), 'by-category'] as const,
24
28
  habits: () => [...supportKeys.all, 'habits'] as const,
@@ -233,3 +237,53 @@ export function useReflections(
233
237
  ...options,
234
238
  });
235
239
  }
240
+
241
+ /**
242
+ * Get user's craving logs
243
+ *
244
+ * @param options - TanStack Query options
245
+ *
246
+ * @example
247
+ * ```tsx
248
+ * const { data, isLoading } = useCravings();
249
+ * ```
250
+ */
251
+ export function useCravings(
252
+ options?: Omit<UseQueryOptions<CravingLogResponse[]>, 'queryKey' | 'queryFn'>
253
+ ) {
254
+ return useQuery({
255
+ queryKey: supportKeys.cravings(),
256
+ queryFn: async (): Promise<CravingLogResponse[]> => {
257
+ const client = getApiClient();
258
+ const response = await client.get('/api/v1/support/cravings');
259
+ return response.data;
260
+ },
261
+ ...options,
262
+ });
263
+ }
264
+
265
+ /**
266
+ * Get craving statistics for a given period
267
+ *
268
+ * @param days - Number of days to include (default: 30)
269
+ * @param options - TanStack Query options
270
+ *
271
+ * @example
272
+ * ```tsx
273
+ * const { data, isLoading } = useCravingStats(30);
274
+ * ```
275
+ */
276
+ export function useCravingStats(
277
+ days: number = 30,
278
+ options?: Omit<UseQueryOptions<CravingStatsResponse>, 'queryKey' | 'queryFn'>
279
+ ) {
280
+ return useQuery({
281
+ queryKey: supportKeys.cravingStats(days),
282
+ queryFn: async (): Promise<CravingStatsResponse> => {
283
+ const client = getApiClient();
284
+ const response = await client.get(`/api/v1/support/cravings/stats?days=${days}`);
285
+ return response.data;
286
+ },
287
+ ...options,
288
+ });
289
+ }
@@ -0,0 +1,271 @@
1
+ import { useQuery, UseQueryOptions } from '@tanstack/react-query';
2
+ import { getApiClient } from '../client';
3
+ import type { VenueResponse, VenueOwnerResponse, EventResponse, OfferResponse } from '../types';
4
+
5
+ // ============================================================================
6
+ // QUERY KEY FACTORY
7
+ // ============================================================================
8
+
9
+ export const venueKeys = {
10
+ all: ['venues'] as const,
11
+ lists: () => [...venueKeys.all, 'list'] as const,
12
+ list: (filters?: VenueFilters) => [...venueKeys.lists(), filters] as const,
13
+ details: () => [...venueKeys.all, 'detail'] as const,
14
+ detail: (id: string) => [...venueKeys.details(), id] as const,
15
+ featured: () => [...venueKeys.all, 'featured'] as const,
16
+ nearby: (params?: NearbyVenueParams) => [...venueKeys.all, 'nearby', params] as const,
17
+ owners: (venueId: string) => [...venueKeys.detail(venueId), 'owners'] as const,
18
+ events: (venueId: string) => [...venueKeys.detail(venueId), 'events'] as const,
19
+ offers: (venueId: string) => [...venueKeys.detail(venueId), 'offers'] as const,
20
+ rewards: (venueId: string) => [...venueKeys.detail(venueId), 'rewards'] as const,
21
+ };
22
+
23
+ // ============================================================================
24
+ // TYPES
25
+ // ============================================================================
26
+
27
+ export interface VenueFilters {
28
+ page?: number;
29
+ limit?: number;
30
+ search?: string;
31
+ cityId?: string;
32
+ type?: string;
33
+ hasAfDrinks?: boolean;
34
+ isAfVenue?: boolean;
35
+ isFeatured?: boolean;
36
+ isFoundingPartner?: boolean;
37
+ lat?: number;
38
+ long?: number;
39
+ radius?: number;
40
+ sortBy?: string;
41
+ sortOrder?: 'asc' | 'desc';
42
+ }
43
+
44
+ export interface NearbyVenueParams {
45
+ lat: number;
46
+ long: number;
47
+ radius?: number;
48
+ limit?: number;
49
+ }
50
+
51
+ export interface PaginatedVenuesResponse {
52
+ venues: VenueResponse[];
53
+ meta: {
54
+ total: number;
55
+ page: number;
56
+ limit: number;
57
+ totalPages: number;
58
+ };
59
+ }
60
+
61
+ // ============================================================================
62
+ // QUERY HOOKS
63
+ // ============================================================================
64
+
65
+ /**
66
+ * Get paginated list of venues with optional filters
67
+ *
68
+ * @param filters - Query parameters for filtering and pagination
69
+ * @param options - TanStack Query options
70
+ *
71
+ * @example
72
+ * ```tsx
73
+ * const { data, isLoading } = useVenues({
74
+ * page: 1,
75
+ * limit: 20,
76
+ * cityId: 'city-123',
77
+ * hasAfDrinks: true,
78
+ * });
79
+ * ```
80
+ */
81
+ export function useVenues(
82
+ filters?: VenueFilters,
83
+ options?: Omit<UseQueryOptions<PaginatedVenuesResponse>, 'queryKey' | 'queryFn'>
84
+ ) {
85
+ return useQuery({
86
+ queryKey: venueKeys.list(filters),
87
+ queryFn: async (): Promise<PaginatedVenuesResponse> => {
88
+ const client = getApiClient();
89
+ const response = await client.get('/api/v1/venues', {
90
+ params: filters,
91
+ });
92
+ return response.data;
93
+ },
94
+ ...options,
95
+ });
96
+ }
97
+
98
+ /**
99
+ * Get featured venues
100
+ *
101
+ * @param limit - Maximum number of venues to return
102
+ * @param options - TanStack Query options
103
+ *
104
+ * @example
105
+ * ```tsx
106
+ * const { data, isLoading } = useFeaturedVenues(10);
107
+ * ```
108
+ */
109
+ export function useFeaturedVenues(
110
+ limit?: number,
111
+ options?: Omit<UseQueryOptions<VenueResponse[]>, 'queryKey' | 'queryFn'>
112
+ ) {
113
+ return useQuery({
114
+ queryKey: venueKeys.featured(),
115
+ queryFn: async (): Promise<VenueResponse[]> => {
116
+ const client = getApiClient();
117
+ const response = await client.get('/api/v1/venues/featured', {
118
+ params: { limit },
119
+ });
120
+ return response.data;
121
+ },
122
+ ...options,
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Get nearby venues based on location
128
+ *
129
+ * @param params - Location parameters (latitude, longitude, radius)
130
+ * @param options - TanStack Query options
131
+ *
132
+ * @example
133
+ * ```tsx
134
+ * const { data, isLoading } = useNearbyVenues({
135
+ * lat: 51.5074,
136
+ * long: -0.1278,
137
+ * radius: 5, // 5km radius
138
+ * limit: 20,
139
+ * });
140
+ * ```
141
+ */
142
+ export function useNearbyVenues(
143
+ params: NearbyVenueParams,
144
+ options?: Omit<UseQueryOptions<VenueResponse[]>, 'queryKey' | 'queryFn'>
145
+ ) {
146
+ return useQuery({
147
+ queryKey: venueKeys.nearby(params),
148
+ queryFn: async (): Promise<VenueResponse[]> => {
149
+ const client = getApiClient();
150
+ const response = await client.get('/api/v1/venues/nearby', {
151
+ params,
152
+ });
153
+ return response.data;
154
+ },
155
+ enabled: !!params.lat && !!params.long,
156
+ ...options,
157
+ });
158
+ }
159
+
160
+ /**
161
+ * Get a single venue by ID
162
+ *
163
+ * @param id - Venue ID
164
+ * @param options - TanStack Query options
165
+ *
166
+ * @example
167
+ * ```tsx
168
+ * const { data, isLoading } = useVenue('venue-123');
169
+ * ```
170
+ */
171
+ export function useVenue(
172
+ id: string,
173
+ options?: Omit<UseQueryOptions<VenueResponse>, 'queryKey' | 'queryFn'>
174
+ ) {
175
+ return useQuery({
176
+ queryKey: venueKeys.detail(id),
177
+ queryFn: async (): Promise<VenueResponse> => {
178
+ const client = getApiClient();
179
+ const response = await client.get(`/api/v1/venues/${id}`);
180
+ return response.data;
181
+ },
182
+ enabled: !!id,
183
+ ...options,
184
+ });
185
+ }
186
+
187
+ /**
188
+ * Get venue owners
189
+ *
190
+ * @param venueId - Venue ID
191
+ * @param options - TanStack Query options
192
+ *
193
+ * @example
194
+ * ```tsx
195
+ * const { data, isLoading } = useVenueOwners('venue-123');
196
+ * ```
197
+ */
198
+ export function useVenueOwners(
199
+ venueId: string,
200
+ options?: Omit<UseQueryOptions<VenueOwnerResponse[]>, 'queryKey' | 'queryFn'>
201
+ ) {
202
+ return useQuery({
203
+ queryKey: venueKeys.owners(venueId),
204
+ queryFn: async (): Promise<VenueOwnerResponse[]> => {
205
+ const client = getApiClient();
206
+ const response = await client.get(`/api/v1/venues/${venueId}/owners`);
207
+ return response.data;
208
+ },
209
+ enabled: !!venueId,
210
+ ...options,
211
+ });
212
+ }
213
+
214
+ /**
215
+ * Get upcoming events at a venue
216
+ *
217
+ * @param venueId - Venue ID
218
+ * @param limit - Maximum number of events to return
219
+ * @param options - TanStack Query options
220
+ *
221
+ * @example
222
+ * ```tsx
223
+ * const { data, isLoading } = useVenueEvents('venue-123', 20);
224
+ * ```
225
+ */
226
+ export function useVenueEvents(
227
+ venueId: string,
228
+ limit?: number,
229
+ options?: Omit<UseQueryOptions<EventResponse[]>, 'queryKey' | 'queryFn'>
230
+ ) {
231
+ return useQuery({
232
+ queryKey: venueKeys.events(venueId),
233
+ queryFn: async (): Promise<EventResponse[]> => {
234
+ const client = getApiClient();
235
+ const response = await client.get(`/api/v1/venues/${venueId}/events`, {
236
+ params: { limit },
237
+ });
238
+ return response.data?.data || response.data || [];
239
+ },
240
+ enabled: !!venueId,
241
+ ...options,
242
+ });
243
+ }
244
+
245
+ /**
246
+ * Get offers for a venue (from legacy Business model)
247
+ *
248
+ * @param venueId - Venue ID
249
+ * @param options - TanStack Query options
250
+ *
251
+ * @example
252
+ * ```tsx
253
+ * const { data, isLoading } = useVenueOffers('venue-123');
254
+ * ```
255
+ */
256
+ export function useVenueOffers(
257
+ venueId: string,
258
+ options?: Omit<UseQueryOptions<OfferResponse[]>, 'queryKey' | 'queryFn'>
259
+ ) {
260
+ return useQuery({
261
+ queryKey: venueKeys.offers(venueId),
262
+ queryFn: async (): Promise<OfferResponse[]> => {
263
+ const client = getApiClient();
264
+ // Use businesses endpoint for offers (legacy)
265
+ const response = await client.get(`/api/v1/businesses/${venueId}/offers`);
266
+ return response.data;
267
+ },
268
+ enabled: !!venueId,
269
+ ...options,
270
+ });
271
+ }