@spotsdev/sdk 1.0.0 → 1.2.0

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 (74) hide show
  1. package/dist/api/client.d.ts +1 -1
  2. package/dist/api/client.js +7 -3
  3. package/dist/api/entities.d.ts +318 -0
  4. package/dist/api/entities.js +9 -0
  5. package/dist/api/mutations/clubs.d.ts +6 -6
  6. package/dist/api/mutations/clubs.js +12 -10
  7. package/dist/api/mutations/conversations.d.ts +7 -7
  8. package/dist/api/mutations/conversations.js +17 -13
  9. package/dist/api/mutations/index.js +1 -1
  10. package/dist/api/mutations/notifications.d.ts +4 -4
  11. package/dist/api/mutations/notifications.js +7 -7
  12. package/dist/api/mutations/orders.d.ts +7 -7
  13. package/dist/api/mutations/orders.js +11 -13
  14. package/dist/api/mutations/posts.d.ts +13 -13
  15. package/dist/api/mutations/posts.js +41 -29
  16. package/dist/api/mutations/products.d.ts +5 -5
  17. package/dist/api/mutations/products.js +9 -13
  18. package/dist/api/mutations/spots.d.ts +42 -8
  19. package/dist/api/mutations/spots.js +51 -13
  20. package/dist/api/mutations/users.d.ts +12 -10
  21. package/dist/api/mutations/users.js +20 -18
  22. package/dist/api/queries/auth.d.ts +5 -5
  23. package/dist/api/queries/auth.js +7 -7
  24. package/dist/api/queries/clubs.d.ts +7 -7
  25. package/dist/api/queries/clubs.js +11 -11
  26. package/dist/api/queries/conversations.d.ts +5 -5
  27. package/dist/api/queries/conversations.js +7 -7
  28. package/dist/api/queries/index.js +1 -1
  29. package/dist/api/queries/misc.d.ts +8 -32
  30. package/dist/api/queries/misc.js +28 -66
  31. package/dist/api/queries/notifications.d.ts +4 -4
  32. package/dist/api/queries/notifications.js +5 -5
  33. package/dist/api/queries/orders.d.ts +4 -4
  34. package/dist/api/queries/orders.js +7 -7
  35. package/dist/api/queries/posts.d.ts +44 -7
  36. package/dist/api/queries/posts.js +118 -15
  37. package/dist/api/queries/products.d.ts +6 -10
  38. package/dist/api/queries/products.js +7 -9
  39. package/dist/api/queries/spots.d.ts +31 -16
  40. package/dist/api/queries/spots.js +113 -31
  41. package/dist/api/queries/templates.d.ts +6 -9
  42. package/dist/api/queries/templates.js +8 -13
  43. package/dist/api/queries/users.d.ts +25 -11
  44. package/dist/api/queries/users.js +75 -27
  45. package/dist/api/types.d.ts +36 -33
  46. package/dist/api/types.js +6 -7
  47. package/dist/index.d.ts +1 -2
  48. package/dist/index.js +1 -8
  49. package/package.json +6 -21
  50. package/src/api/client.ts +45 -30
  51. package/src/api/entities.ts +424 -0
  52. package/src/api/mutations/clubs.ts +73 -40
  53. package/src/api/mutations/conversations.ts +91 -47
  54. package/src/api/mutations/index.ts +8 -8
  55. package/src/api/mutations/notifications.ts +48 -25
  56. package/src/api/mutations/orders.ts +101 -70
  57. package/src/api/mutations/posts.ts +229 -118
  58. package/src/api/mutations/products.ts +120 -81
  59. package/src/api/mutations/spots.ts +167 -55
  60. package/src/api/mutations/users.ts +109 -76
  61. package/src/api/queries/auth.ts +49 -24
  62. package/src/api/queries/clubs.ts +53 -38
  63. package/src/api/queries/conversations.ts +48 -30
  64. package/src/api/queries/index.ts +21 -21
  65. package/src/api/queries/misc.ts +53 -82
  66. package/src/api/queries/notifications.ts +32 -21
  67. package/src/api/queries/orders.ts +59 -42
  68. package/src/api/queries/posts.ts +203 -48
  69. package/src/api/queries/products.ts +51 -44
  70. package/src/api/queries/spots.ts +216 -85
  71. package/src/api/queries/templates.ts +39 -32
  72. package/src/api/queries/users.ts +157 -64
  73. package/src/api/types.ts +72 -118
  74. package/src/index.ts +5 -11
@@ -4,9 +4,62 @@
4
4
  * TanStack Query hooks for spot-related operations.
5
5
  */
6
6
 
7
- import { useQuery, useInfiniteQuery, UseQueryOptions, UseQueryResult, UseInfiniteQueryOptions, UseInfiniteQueryResult } from '@tanstack/react-query';
8
- import { getApiClient } from '../client';
9
- import type { Spot, SpotImage, ApiResponse, PaginatedResponse } from '../types';
7
+ import {
8
+ useQuery,
9
+ useInfiniteQuery,
10
+ type UseQueryOptions,
11
+ type UseQueryResult,
12
+ type UseInfiniteQueryOptions,
13
+ type UseInfiniteQueryResult,
14
+ } from '@tanstack/react-query'
15
+
16
+ import {getApiClient} from '../client'
17
+ import {type ApiResponse, type PaginatedResponse, type Spot, type SpotImage} from '../types'
18
+
19
+ // ============================================================================
20
+ // HELPER FUNCTIONS
21
+ // ============================================================================
22
+
23
+ /**
24
+ * Extract array data from API response
25
+ * API returns { success, data: { data: [...], meta: {...} } } or { success, data: [...] }
26
+ */
27
+ function extractArrayData<T>(data: unknown): T[] {
28
+ if (Array.isArray(data)) {
29
+ return data
30
+ }
31
+ if (data && typeof data === 'object' && 'data' in data) {
32
+ const nested = (data as {data: unknown}).data
33
+ if (Array.isArray(nested)) {
34
+ return nested
35
+ }
36
+ }
37
+ return []
38
+ }
39
+
40
+ /**
41
+ * Extract single object data from API response
42
+ */
43
+ function extractObjectData<T>(data: unknown): T {
44
+ if (
45
+ data &&
46
+ typeof data === 'object' &&
47
+ 'data' in data &&
48
+ !Array.isArray(data)
49
+ ) {
50
+ const nested = (data as {data: unknown}).data
51
+ if (
52
+ nested &&
53
+ typeof nested === 'object' &&
54
+ 'data' in nested &&
55
+ !Array.isArray(nested)
56
+ ) {
57
+ return (nested as {data: T}).data
58
+ }
59
+ return nested as T
60
+ }
61
+ return data as T
62
+ }
10
63
 
11
64
  // ============================================================================
12
65
  // QUERY KEYS
@@ -15,187 +68,265 @@ import type { Spot, SpotImage, ApiResponse, PaginatedResponse } from '../types';
15
68
  export const spotKeys = {
16
69
  all: ['spots'] as const,
17
70
  lists: () => [...spotKeys.all, 'list'] as const,
18
- list: (filters?: Record<string, unknown>) => [...spotKeys.lists(), filters] as const,
71
+ list: (filters?: Record<string, unknown>) =>
72
+ [...spotKeys.lists(), filters] as const,
19
73
  details: () => [...spotKeys.all, 'detail'] as const,
20
74
  detail: (id: string) => [...spotKeys.details(), id] as const,
21
75
  bySlug: (slug: string) => [...spotKeys.all, 'slug', slug] as const,
22
76
  byQR: (qrCode: string) => [...spotKeys.all, 'qr', qrCode] as const,
23
77
  images: (spotId: string) => [...spotKeys.detail(spotId), 'images'] as const,
24
- };
78
+ }
25
79
 
26
80
  // ============================================================================
27
81
  // QUERY HOOKS
28
82
  // ============================================================================
29
83
 
30
84
  /**
31
- * Get all spots (paginated)
85
+ * Get all spots
32
86
  *
33
- * @endpoint GET /api/v1/spots
34
- * @returns PaginatedResponse with spots array and meta
87
+ * @endpoint GET /spots
35
88
  */
36
89
  export function useSpots(
37
90
  params?: {
38
- limit?: number;
39
- page?: number;
40
- city?: string;
41
- type?: string;
42
- templateSlugs?: string[];
43
- vibeIds?: string[];
44
- search?: string;
91
+ limit?: number
92
+ city?: string
93
+ type?: string
94
+ lat?: number
95
+ lng?: number
96
+ radius?: number
97
+ search?: string
98
+ vibes?: string
99
+ cityId?: string
100
+ page?: number
45
101
  },
46
- options?: Omit<UseQueryOptions<PaginatedResponse<Spot>>, 'queryKey' | 'queryFn'>
47
- ): UseQueryResult<PaginatedResponse<Spot>> {
102
+ options?: Omit<UseQueryOptions<Spot[]>, 'queryKey' | 'queryFn'>,
103
+ ): UseQueryResult<Spot[]> {
48
104
  return useQuery({
49
105
  queryKey: spotKeys.list(params),
50
- queryFn: async (): Promise<PaginatedResponse<Spot>> => {
51
- const client = getApiClient();
52
- const queryParams = new URLSearchParams();
53
- if (params?.limit) queryParams.set('limit', String(params.limit));
54
- if (params?.page) queryParams.set('page', String(params.page));
55
- if (params?.city) queryParams.set('city', params.city);
56
- if (params?.type) queryParams.set('type', params.type);
57
- if (params?.search) queryParams.set('search', params.search);
58
- if (params?.templateSlugs) {
59
- params.templateSlugs.forEach(slug => queryParams.append('templateSlugs', slug));
60
- }
61
- if (params?.vibeIds) {
62
- params.vibeIds.forEach(id => queryParams.append('vibeIds', id));
63
- }
64
- const response = await client.get<ApiResponse<PaginatedResponse<Spot>>>(`/api/v1/spots?${queryParams}`);
65
- return response.data.data;
106
+ queryFn: async (): Promise<Spot[]> => {
107
+ const client = getApiClient()
108
+ const queryParams = new URLSearchParams()
109
+ if (params?.limit) queryParams.set('limit', String(params.limit))
110
+ if (params?.city) queryParams.set('city', params.city)
111
+ if (params?.type) queryParams.set('type', params.type)
112
+ if (params?.lat) queryParams.set('lat', String(params.lat))
113
+ if (params?.lng) queryParams.set('lng', String(params.lng))
114
+ if (params?.radius) queryParams.set('radius', String(params.radius))
115
+ if (params?.search) queryParams.set('search', params.search)
116
+ if (params?.vibes) queryParams.set('vibeIds', params.vibes)
117
+ if (params?.cityId) queryParams.set('cityId', params.cityId)
118
+ if (params?.page) queryParams.set('page', String(params.page))
119
+ const response = await client.get<ApiResponse<unknown>>(
120
+ `/spots?${queryParams}`,
121
+ )
122
+ return extractArrayData<Spot>(response.data.data)
66
123
  },
67
124
  ...options,
68
- });
125
+ })
69
126
  }
70
127
 
71
128
  /**
72
129
  * Get a spot by ID
73
130
  *
74
- * @endpoint GET /api/v1/spots/{spotId}
131
+ * @endpoint GET /spots/{spotId}
75
132
  */
76
133
  export function useSpot(
77
134
  spotId: string,
78
- options?: Omit<UseQueryOptions<Spot>, 'queryKey' | 'queryFn'>
135
+ options?: Omit<UseQueryOptions<Spot>, 'queryKey' | 'queryFn'>,
79
136
  ): UseQueryResult<Spot> {
80
137
  return useQuery({
81
138
  queryKey: spotKeys.detail(spotId),
82
139
  queryFn: async (): Promise<Spot> => {
83
- const client = getApiClient();
84
- const response = await client.get<ApiResponse<Spot>>(`/api/v1/spots/${spotId}`);
85
- return response.data.data;
140
+ const client = getApiClient()
141
+ const response = await client.get<ApiResponse<unknown>>(
142
+ `/spots/${spotId}`,
143
+ )
144
+ return extractObjectData<Spot>(response.data.data)
86
145
  },
87
146
  enabled: !!spotId,
88
147
  ...options,
89
- });
148
+ })
90
149
  }
91
150
 
92
151
  /**
93
152
  * Get a spot by slug
94
153
  *
95
- * @endpoint GET /api/v1/spots/slug/{slug}
154
+ * @endpoint GET /spots/slug/{slug}
96
155
  */
97
156
  export function useSpotBySlug(
98
157
  slug: string,
99
- options?: Omit<UseQueryOptions<Spot>, 'queryKey' | 'queryFn'>
158
+ options?: Omit<UseQueryOptions<Spot>, 'queryKey' | 'queryFn'>,
100
159
  ): UseQueryResult<Spot> {
101
160
  return useQuery({
102
161
  queryKey: spotKeys.bySlug(slug),
103
162
  queryFn: async (): Promise<Spot> => {
104
- const client = getApiClient();
105
- const response = await client.get<ApiResponse<Spot>>(`/api/v1/spots/slug/${slug}`);
106
- return response.data.data;
163
+ const client = getApiClient()
164
+ const response = await client.get<ApiResponse<unknown>>(
165
+ `/spots/slug/${slug}`,
166
+ )
167
+ return extractObjectData<Spot>(response.data.data)
107
168
  },
108
169
  enabled: !!slug,
109
170
  ...options,
110
- });
171
+ })
111
172
  }
112
173
 
113
174
  /**
114
175
  * Get a spot by QR code
115
176
  *
116
- * @endpoint GET /api/v1/spots/qr/{qrCode}
177
+ * @endpoint GET /spots/qr/{qrCode}
117
178
  */
118
179
  export function useSpotByQR(
119
180
  qrCode: string,
120
- options?: Omit<UseQueryOptions<Spot>, 'queryKey' | 'queryFn'>
181
+ options?: Omit<UseQueryOptions<Spot>, 'queryKey' | 'queryFn'>,
121
182
  ): UseQueryResult<Spot> {
122
183
  return useQuery({
123
184
  queryKey: spotKeys.byQR(qrCode),
124
185
  queryFn: async (): Promise<Spot> => {
125
- const client = getApiClient();
126
- const response = await client.get<ApiResponse<Spot>>(`/api/v1/spots/qr/${qrCode}`);
127
- return response.data.data;
186
+ const client = getApiClient()
187
+ const response = await client.get<ApiResponse<unknown>>(
188
+ `/spots/qr/${qrCode}`,
189
+ )
190
+ return extractObjectData<Spot>(response.data.data)
128
191
  },
129
192
  enabled: !!qrCode,
130
193
  ...options,
131
- });
194
+ })
132
195
  }
133
196
 
134
197
  /**
135
198
  * Get images for a spot
136
199
  *
137
- * @endpoint GET /api/v1/spots/{spotId}/images
200
+ * @endpoint GET /spots/{spotId}/images
138
201
  */
139
202
  export function useSpotImages(
140
203
  spotId: string,
141
- options?: Omit<UseQueryOptions<SpotImage[]>, 'queryKey' | 'queryFn'>
204
+ options?: Omit<UseQueryOptions<SpotImage[]>, 'queryKey' | 'queryFn'>,
142
205
  ): UseQueryResult<SpotImage[]> {
143
206
  return useQuery({
144
207
  queryKey: spotKeys.images(spotId),
145
208
  queryFn: async (): Promise<SpotImage[]> => {
146
- const client = getApiClient();
147
- const response = await client.get<ApiResponse<SpotImage[]>>(`/api/v1/spots/${spotId}/images`);
148
- return response.data.data;
209
+ const client = getApiClient()
210
+ const response = await client.get<ApiResponse<unknown>>(
211
+ `/spots/${spotId}/images`,
212
+ )
213
+ return extractArrayData<SpotImage>(response.data.data)
149
214
  },
150
215
  enabled: !!spotId,
151
216
  ...options,
152
- });
217
+ })
153
218
  }
154
219
 
155
220
  /**
156
- * Infinite scroll query for spots
221
+ * Check if a spot is favorited by the current user
157
222
  *
158
- * @endpoint GET /api/v1/spots (paginated)
159
- * @returns Infinite query with pages of spots
223
+ * @endpoint GET /spots/{spotId}/favorite
224
+ */
225
+ export function useSpotFavoriteStatus(
226
+ spotId: string,
227
+ options?: Omit<
228
+ UseQueryOptions<{isFavorite: boolean}>,
229
+ 'queryKey' | 'queryFn'
230
+ >,
231
+ ): UseQueryResult<{isFavorite: boolean}> {
232
+ return useQuery({
233
+ queryKey: [...spotKeys.detail(spotId), 'favorite'] as const,
234
+ queryFn: async (): Promise<{isFavorite: boolean}> => {
235
+ const client = getApiClient()
236
+ const response = await client.get<ApiResponse<{isFavorite: boolean}>>(
237
+ `/spots/${spotId}/favorite`,
238
+ )
239
+ return extractObjectData<{isFavorite: boolean}>(response.data.data)
240
+ },
241
+ enabled: !!spotId,
242
+ ...options,
243
+ })
244
+ }
245
+
246
+ // ============================================================================
247
+ // INFINITE QUERY HOOKS
248
+ // ============================================================================
249
+
250
+ /**
251
+ * Params for infinite spots query
160
252
  */
161
253
  export interface InfiniteSpotsParams {
162
- limit?: number;
163
- city?: string;
164
- cityId?: string;
165
- type?: string;
166
- templateSlugs?: string[];
167
- vibeIds?: string[];
168
- search?: string;
254
+ limit?: number
255
+ city?: string
256
+ cityId?: string
257
+ type?: string
258
+ templateSlugs?: string[]
259
+ vibeIds?: string[]
260
+ search?: string
169
261
  }
170
262
 
263
+ /**
264
+ * Infinite scroll query for spots
265
+ *
266
+ * @endpoint GET /spots (paginated)
267
+ * @returns Infinite query with pages of spots
268
+ */
171
269
  export function useInfiniteSpots(
172
270
  params?: InfiniteSpotsParams,
173
- options?: Omit<UseInfiniteQueryOptions<PaginatedResponse<Spot>, Error, { pages: PaginatedResponse<Spot>[]; pageParams: number[] }>, 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'>
174
- ): UseInfiniteQueryResult<{ pages: PaginatedResponse<Spot>[]; pageParams: number[] }, Error> {
271
+ options?: Omit<
272
+ UseInfiniteQueryOptions<
273
+ PaginatedResponse<Spot>,
274
+ Error,
275
+ {pages: PaginatedResponse<Spot>[]; pageParams: number[]}
276
+ >,
277
+ 'queryKey' | 'queryFn' | 'getNextPageParam' | 'initialPageParam'
278
+ >,
279
+ ): UseInfiniteQueryResult<
280
+ {pages: PaginatedResponse<Spot>[]; pageParams: number[]},
281
+ Error
282
+ > {
175
283
  return useInfiniteQuery({
176
284
  queryKey: [...spotKeys.lists(), 'infinite', params] as const,
177
- queryFn: async ({ pageParam }): Promise<PaginatedResponse<Spot>> => {
178
- const client = getApiClient();
179
- const queryParams = new URLSearchParams();
180
- queryParams.set('page', String(pageParam));
181
- if (params?.limit) queryParams.set('limit', String(params.limit));
182
- if (params?.city) queryParams.set('city', params.city);
183
- if (params?.cityId) queryParams.set('cityId', params.cityId);
184
- if (params?.type && params.type !== 'All') queryParams.set('type', params.type);
185
- if (params?.search?.trim()) queryParams.set('search', params.search.trim());
285
+ queryFn: async ({pageParam = 1}): Promise<PaginatedResponse<Spot>> => {
286
+ const client = getApiClient()
287
+ const queryParams = new URLSearchParams()
288
+ queryParams.set('page', String(pageParam))
289
+ if (params?.limit) queryParams.set('limit', String(params.limit))
290
+ if (params?.city) queryParams.set('city', params.city)
291
+ if (params?.cityId) queryParams.set('cityId', params.cityId)
292
+ if (params?.type && params.type !== 'All')
293
+ queryParams.set('type', params.type)
294
+ if (params?.search?.trim())
295
+ queryParams.set('search', params.search.trim())
186
296
  if (params?.templateSlugs) {
187
- params.templateSlugs.forEach(slug => queryParams.append('templateSlugs', slug));
297
+ params.templateSlugs.forEach((slug) =>
298
+ queryParams.append('templateSlugs', slug),
299
+ )
188
300
  }
189
301
  if (params?.vibeIds) {
190
- params.vibeIds.forEach(id => queryParams.append('vibeIds', id));
302
+ params.vibeIds.forEach((id) => queryParams.append('vibeIds', id))
303
+ }
304
+ const response = await client.get<ApiResponse<PaginatedResponse<Spot>>>(
305
+ `/spots?${queryParams}`,
306
+ )
307
+ // Handle nested response structure
308
+ const data = response.data.data
309
+ if (data && typeof data === 'object' && 'data' in data) {
310
+ return data as PaginatedResponse<Spot>
311
+ }
312
+ // Fallback for array response
313
+ const page = pageParam as number
314
+ return {
315
+ data: extractArrayData<Spot>(data),
316
+ meta: {
317
+ total: 0,
318
+ page,
319
+ limit: params?.limit || 20,
320
+ totalPages: 1,
321
+ hasNextPage: false,
322
+ hasPreviousPage: page > 1,
323
+ },
191
324
  }
192
- const response = await client.get<ApiResponse<PaginatedResponse<Spot>>>(`/api/v1/spots?${queryParams}`);
193
- return response.data.data;
194
325
  },
195
326
  initialPageParam: 1,
196
327
  getNextPageParam: (lastPage) => {
197
- return lastPage.meta.hasNextPage ? lastPage.meta.page + 1 : undefined;
328
+ return lastPage.meta.hasNextPage ? lastPage.meta.page + 1 : undefined
198
329
  },
199
330
  ...options,
200
- });
331
+ })
201
332
  }
@@ -2,13 +2,16 @@
2
2
  * Templates Query Hooks
3
3
  *
4
4
  * TanStack Query hooks for post template operations.
5
- *
6
- * Templates are reference data (flat array), not paginated.
7
5
  */
8
6
 
9
- import { useQuery, UseQueryOptions, UseQueryResult } from '@tanstack/react-query';
10
- import { getApiClient } from '../client';
11
- import type { Template, ApiResponse } from '../types';
7
+ import {
8
+ useQuery,
9
+ type UseQueryOptions,
10
+ type UseQueryResult,
11
+ } from '@tanstack/react-query'
12
+
13
+ import {getApiClient} from '../client'
14
+ import {type ApiResponse, type Template} from '../types'
12
15
 
13
16
  // ============================================================================
14
17
  // QUERY KEYS
@@ -17,79 +20,83 @@ import type { Template, ApiResponse } from '../types';
17
20
  export const templateKeys = {
18
21
  all: ['templates'] as const,
19
22
  lists: () => [...templateKeys.all, 'list'] as const,
20
- list: (filters?: { spotType?: string }) => [...templateKeys.lists(), filters] as const,
23
+ list: (filters?: {spotType?: string}) =>
24
+ [...templateKeys.lists(), filters] as const,
21
25
  details: () => [...templateKeys.all, 'detail'] as const,
22
26
  detail: (id: string) => [...templateKeys.details(), id] as const,
23
27
  bySlug: (slug: string) => [...templateKeys.all, 'slug', slug] as const,
24
- };
28
+ }
25
29
 
26
30
  // ============================================================================
27
31
  // QUERY HOOKS
28
32
  // ============================================================================
29
33
 
30
34
  /**
31
- * Get all templates (flat array - reference data)
35
+ * Get all templates
32
36
  *
33
- * @endpoint GET /api/v1/templates
34
- * @returns Flat array of templates (not paginated)
37
+ * @endpoint GET /templates
35
38
  */
36
39
  export function useTemplates(
37
- params?: { spotType?: string },
38
- options?: Omit<UseQueryOptions<Template[]>, 'queryKey' | 'queryFn'>
40
+ params?: {spotType?: string},
41
+ options?: Omit<UseQueryOptions<Template[]>, 'queryKey' | 'queryFn'>,
39
42
  ): UseQueryResult<Template[]> {
40
43
  return useQuery({
41
44
  queryKey: templateKeys.list(params),
42
45
  queryFn: async (): Promise<Template[]> => {
43
- const client = getApiClient();
44
- const queryParams = new URLSearchParams();
45
- if (params?.spotType) queryParams.set('spotType', params.spotType);
46
- const response = await client.get<ApiResponse<Template[]>>(`/api/v1/templates?${queryParams}`);
47
- // Templates endpoint returns flat array: { data: [] }
48
- return response.data.data;
46
+ const client = getApiClient()
47
+ const queryParams = new URLSearchParams()
48
+ if (params?.spotType) queryParams.set('spotType', params.spotType)
49
+ const response = await client.get<ApiResponse<Template[]>>(
50
+ `/templates?${queryParams}`,
51
+ )
52
+ return response.data.data
49
53
  },
50
- staleTime: 1000 * 60 * 60, // Cache for 1 hour (reference data)
51
54
  ...options,
52
- });
55
+ })
53
56
  }
54
57
 
55
58
  /**
56
59
  * Get a template by ID
57
60
  *
58
- * @endpoint GET /api/v1/templates/{templateId}
61
+ * @endpoint GET /templates/{templateId}
59
62
  */
60
63
  export function useTemplate(
61
64
  templateId: string,
62
- options?: Omit<UseQueryOptions<Template>, 'queryKey' | 'queryFn'>
65
+ options?: Omit<UseQueryOptions<Template>, 'queryKey' | 'queryFn'>,
63
66
  ): UseQueryResult<Template> {
64
67
  return useQuery({
65
68
  queryKey: templateKeys.detail(templateId),
66
69
  queryFn: async (): Promise<Template> => {
67
- const client = getApiClient();
68
- const response = await client.get<ApiResponse<Template>>(`/api/v1/templates/${templateId}`);
69
- return response.data.data;
70
+ const client = getApiClient()
71
+ const response = await client.get<ApiResponse<Template>>(
72
+ `/templates/${templateId}`,
73
+ )
74
+ return response.data.data
70
75
  },
71
76
  enabled: !!templateId,
72
77
  ...options,
73
- });
78
+ })
74
79
  }
75
80
 
76
81
  /**
77
82
  * Get a template by slug
78
83
  *
79
- * @endpoint GET /api/v1/templates/slug/{slug}
84
+ * @endpoint GET /templates/slug/{slug}
80
85
  */
81
86
  export function useTemplateBySlug(
82
87
  slug: string,
83
- options?: Omit<UseQueryOptions<Template>, 'queryKey' | 'queryFn'>
88
+ options?: Omit<UseQueryOptions<Template>, 'queryKey' | 'queryFn'>,
84
89
  ): UseQueryResult<Template> {
85
90
  return useQuery({
86
91
  queryKey: templateKeys.bySlug(slug),
87
92
  queryFn: async (): Promise<Template> => {
88
- const client = getApiClient();
89
- const response = await client.get<ApiResponse<Template>>(`/api/v1/templates/slug/${slug}`);
90
- return response.data.data;
93
+ const client = getApiClient()
94
+ const response = await client.get<ApiResponse<Template>>(
95
+ `/templates/slug/${slug}`,
96
+ )
97
+ return response.data.data
91
98
  },
92
99
  enabled: !!slug,
93
100
  ...options,
94
- });
101
+ })
95
102
  }