@spotsdev/sdk 1.0.0 → 1.1.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 +316 -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 +420 -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,49 +4,54 @@
4
4
  * TanStack Query hooks for product mutation operations.
5
5
  */
6
6
 
7
- import { useMutation, useQueryClient, UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
8
- import { getApiClient } from '../client';
9
- import { productKeys } from '../queries/products';
10
- import type { Product, ProductType, ProductStatus, ApiResponse } from '../types';
7
+ import {
8
+ useMutation,
9
+ useQueryClient,
10
+ type UseMutationOptions,
11
+ type UseMutationResult,
12
+ } from '@tanstack/react-query'
13
+ import {getApiClient} from '../client'
14
+ import {productKeys} from '../queries/products'
15
+ import type {Product, ProductType, ProductStatus, ApiResponse} from '../types'
11
16
 
12
17
  // ============================================================================
13
18
  // TYPES
14
19
  // ============================================================================
15
20
 
16
21
  export interface CreateProductRequest {
17
- spotId: string;
18
- name: string;
19
- description?: string;
20
- type: ProductType;
21
- price: number;
22
- currency?: string;
23
- stockQuantity?: number;
24
- lowStockThreshold?: number;
25
- validFrom?: string;
26
- validUntil?: string;
27
- deliveryRadiusKm?: number;
28
- prepTimeMinutes?: number;
29
- maxCapacity?: number;
30
- eventDate?: string;
31
- imageUrl?: string;
32
- metadata?: Record<string, unknown>;
22
+ spotId: string
23
+ name: string
24
+ description?: string
25
+ type: ProductType
26
+ price: number
27
+ currency?: string
28
+ stockQuantity?: number
29
+ lowStockThreshold?: number
30
+ validFrom?: string
31
+ validUntil?: string
32
+ deliveryRadiusKm?: number
33
+ prepTimeMinutes?: number
34
+ maxCapacity?: number
35
+ eventDate?: string
36
+ imageUrl?: string
37
+ metadata?: Record<string, unknown>
33
38
  }
34
39
 
35
40
  export interface UpdateProductRequest {
36
- name?: string;
37
- description?: string;
38
- price?: number;
39
- stockQuantity?: number;
40
- lowStockThreshold?: number;
41
- status?: ProductStatus;
42
- validFrom?: string;
43
- validUntil?: string;
44
- deliveryRadiusKm?: number;
45
- prepTimeMinutes?: number;
46
- maxCapacity?: number;
47
- eventDate?: string;
48
- imageUrl?: string;
49
- metadata?: Record<string, unknown>;
41
+ name?: string
42
+ description?: string
43
+ price?: number
44
+ stockQuantity?: number
45
+ lowStockThreshold?: number
46
+ status?: ProductStatus
47
+ validFrom?: string
48
+ validUntil?: string
49
+ deliveryRadiusKm?: number
50
+ prepTimeMinutes?: number
51
+ maxCapacity?: number
52
+ eventDate?: string
53
+ imageUrl?: string
54
+ metadata?: Record<string, unknown>
50
55
  }
51
56
 
52
57
  // ============================================================================
@@ -56,105 +61,139 @@ export interface UpdateProductRequest {
56
61
  /**
57
62
  * Create a new product
58
63
  *
59
- * @endpoint POST /api/v1/spots/{spotId}/products
64
+ * @endpoint POST /spots/{spotId}/products
60
65
  */
61
66
  export function useCreateProduct(
62
- options?: Omit<UseMutationOptions<Product, Error, CreateProductRequest>, 'mutationFn'>
67
+ options?: Omit<
68
+ UseMutationOptions<Product, Error, CreateProductRequest>,
69
+ 'mutationFn'
70
+ >,
63
71
  ): UseMutationResult<Product, Error, CreateProductRequest> {
64
- const queryClient = useQueryClient();
72
+ const queryClient = useQueryClient()
65
73
 
66
74
  return useMutation({
67
75
  mutationFn: async (data: CreateProductRequest): Promise<Product> => {
68
- const client = getApiClient();
69
- const { spotId, ...productData } = data;
76
+ const client = getApiClient()
77
+ const {spotId, ...productData} = data
70
78
  const response = await client.post<ApiResponse<Product>>(
71
- `/api/v1/spots/${spotId}/products`,
72
- productData
73
- );
74
- return response.data.data;
79
+ `/spots/${spotId}/products`,
80
+ productData,
81
+ )
82
+ return response.data.data
75
83
  },
76
84
  onSuccess: (_, variables) => {
77
- queryClient.invalidateQueries({ queryKey: productKeys.bySpot(variables.spotId) });
78
- queryClient.invalidateQueries({ queryKey: productKeys.list({ my: true }) });
85
+ queryClient.invalidateQueries({queryKey: productKeys.bySpot(variables.spotId)})
86
+ queryClient.invalidateQueries({queryKey: productKeys.list({my: true})})
79
87
  },
80
88
  ...options,
81
- });
89
+ })
82
90
  }
83
91
 
84
92
  /**
85
93
  * Update a product
86
94
  *
87
- * @endpoint PUT /api/v1/products/{productId}
95
+ * @endpoint PUT /products/{productId}
88
96
  */
89
97
  export function useUpdateProduct(
90
- options?: Omit<UseMutationOptions<Product, Error, { productId: string; data: UpdateProductRequest }>, 'mutationFn'>
91
- ): UseMutationResult<Product, Error, { productId: string; data: UpdateProductRequest }> {
92
- const queryClient = useQueryClient();
98
+ options?: Omit<
99
+ UseMutationOptions<
100
+ Product,
101
+ Error,
102
+ {productId: string; data: UpdateProductRequest}
103
+ >,
104
+ 'mutationFn'
105
+ >,
106
+ ): UseMutationResult<
107
+ Product,
108
+ Error,
109
+ {productId: string; data: UpdateProductRequest}
110
+ > {
111
+ const queryClient = useQueryClient()
93
112
 
94
113
  return useMutation({
95
- mutationFn: async ({ productId, data }): Promise<Product> => {
96
- const client = getApiClient();
97
- const response = await client.put<ApiResponse<Product>>(`/api/v1/products/${productId}`, data);
98
- return response.data.data;
114
+ mutationFn: async ({productId, data}): Promise<Product> => {
115
+ const client = getApiClient()
116
+ const response = await client.put<ApiResponse<Product>>(
117
+ `/products/${productId}`,
118
+ data,
119
+ )
120
+ return response.data.data
99
121
  },
100
122
  onSuccess: (data) => {
101
- queryClient.setQueryData(productKeys.detail(data.id), data);
102
- queryClient.invalidateQueries({ queryKey: productKeys.bySpot(data.spotId) });
103
- queryClient.invalidateQueries({ queryKey: productKeys.list({ my: true }) });
123
+ queryClient.setQueryData(productKeys.detail(data.id), data)
124
+ queryClient.invalidateQueries({queryKey: productKeys.bySpot(data.spotId)})
125
+ queryClient.invalidateQueries({queryKey: productKeys.list({my: true})})
104
126
  },
105
127
  ...options,
106
- });
128
+ })
107
129
  }
108
130
 
109
131
  /**
110
132
  * Delete a product
111
133
  *
112
- * @endpoint DELETE /api/v1/products/{productId}
134
+ * @endpoint DELETE /products/{productId}
113
135
  */
114
136
  export function useDeleteProduct(
115
- options?: Omit<UseMutationOptions<void, Error, string>, 'mutationFn'>
137
+ options?: Omit<UseMutationOptions<void, Error, string>, 'mutationFn'>,
116
138
  ): UseMutationResult<void, Error, string> {
117
- const queryClient = useQueryClient();
139
+ const queryClient = useQueryClient()
118
140
 
119
141
  return useMutation({
120
142
  mutationFn: async (productId: string): Promise<void> => {
121
- const client = getApiClient();
122
- await client.delete(`/api/v1/products/${productId}`);
143
+ const client = getApiClient()
144
+ await client.delete(`/products/${productId}`)
123
145
  },
124
146
  onSuccess: () => {
125
- queryClient.invalidateQueries({ queryKey: productKeys.all });
147
+ queryClient.invalidateQueries({queryKey: productKeys.all})
126
148
  },
127
149
  ...options,
128
- });
150
+ })
129
151
  }
130
152
 
131
153
  /**
132
154
  * Adjust product stock
133
155
  *
134
- * @endpoint POST /api/v1/products/{productId}/stock
156
+ * @endpoint POST /products/{productId}/stock
135
157
  */
136
158
  export function useAdjustStock(
137
159
  options?: Omit<
138
- UseMutationOptions<Product, Error, { productId: string; quantity: number; reason: 'RESTOCK' | 'ADJUSTMENT'; notes?: string }>,
160
+ UseMutationOptions<
161
+ Product,
162
+ Error,
163
+ {
164
+ productId: string
165
+ quantity: number
166
+ reason: 'RESTOCK' | 'ADJUSTMENT'
167
+ notes?: string
168
+ }
169
+ >,
139
170
  'mutationFn'
140
- >
141
- ): UseMutationResult<Product, Error, { productId: string; quantity: number; reason: 'RESTOCK' | 'ADJUSTMENT'; notes?: string }> {
142
- const queryClient = useQueryClient();
171
+ >,
172
+ ): UseMutationResult<
173
+ Product,
174
+ Error,
175
+ {
176
+ productId: string
177
+ quantity: number
178
+ reason: 'RESTOCK' | 'ADJUSTMENT'
179
+ notes?: string
180
+ }
181
+ > {
182
+ const queryClient = useQueryClient()
143
183
 
144
184
  return useMutation({
145
- mutationFn: async ({ productId, quantity, reason, notes }): Promise<Product> => {
146
- const client = getApiClient();
147
- const response = await client.post<ApiResponse<Product>>(`/api/v1/products/${productId}/stock`, {
148
- quantity,
149
- reason,
150
- notes,
151
- });
152
- return response.data.data;
185
+ mutationFn: async ({productId, quantity, reason, notes}): Promise<Product> => {
186
+ const client = getApiClient()
187
+ const response = await client.post<ApiResponse<Product>>(
188
+ `/products/${productId}/stock`,
189
+ {quantity, reason, notes},
190
+ )
191
+ return response.data.data
153
192
  },
154
193
  onSuccess: (data) => {
155
- queryClient.setQueryData(productKeys.detail(data.id), data);
156
- queryClient.invalidateQueries({ queryKey: productKeys.bySpot(data.spotId) });
194
+ queryClient.setQueryData(productKeys.detail(data.id), data)
195
+ queryClient.invalidateQueries({queryKey: productKeys.bySpot(data.spotId)})
157
196
  },
158
197
  ...options,
159
- });
198
+ })
160
199
  }
@@ -4,11 +4,17 @@
4
4
  * TanStack Query hooks for spot mutation operations.
5
5
  */
6
6
 
7
- import { useMutation, useQueryClient, UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
8
- import { getApiClient } from '../client';
9
- import { spotKeys } from '../queries/spots';
10
- import { userKeys } from '../queries/users';
11
- import type { Spot, ClaimSpotRequest, ApiResponse } from '../types';
7
+ import {
8
+ useMutation,
9
+ type UseMutationOptions,
10
+ type UseMutationResult,
11
+ useQueryClient,
12
+ } from '@tanstack/react-query'
13
+
14
+ import {getApiClient} from '../client'
15
+ import {spotKeys} from '../queries/spots'
16
+ import {userKeys} from '../queries/users'
17
+ import {type ApiResponse, type ClaimSpotRequest, type Spot} from '../types'
12
18
 
13
19
  // ============================================================================
14
20
  // MUTATION HOOKS
@@ -17,130 +23,236 @@ import type { Spot, ClaimSpotRequest, ApiResponse } from '../types';
17
23
  /**
18
24
  * Create a new spot
19
25
  *
20
- * @endpoint POST /api/v1/spots
26
+ * @endpoint POST /spots
21
27
  */
22
28
  export function useCreateSpot(
23
- options?: Omit<UseMutationOptions<Spot, Error, Partial<Spot>>, 'mutationFn'>
29
+ options?: Omit<UseMutationOptions<Spot, Error, Partial<Spot>>, 'mutationFn'>,
24
30
  ): UseMutationResult<Spot, Error, Partial<Spot>> {
25
- const queryClient = useQueryClient();
31
+ const queryClient = useQueryClient()
26
32
 
27
33
  return useMutation({
28
34
  mutationFn: async (data: Partial<Spot>): Promise<Spot> => {
29
- const client = getApiClient();
30
- const response = await client.post<ApiResponse<Spot>>('/api/v1/spots', data);
31
- return response.data.data;
35
+ const client = getApiClient()
36
+ const response = await client.post<ApiResponse<Spot>>('/spots', data)
37
+ return response.data.data
32
38
  },
33
39
  onSuccess: () => {
34
- queryClient.invalidateQueries({ queryKey: spotKeys.lists() });
40
+ queryClient.invalidateQueries({queryKey: spotKeys.lists()})
35
41
  },
36
42
  ...options,
37
- });
43
+ })
38
44
  }
39
45
 
40
46
  /**
41
47
  * Update a spot
42
48
  *
43
- * @endpoint PUT /api/v1/spots/{spotId}
49
+ * @endpoint PUT /spots/{spotId}
44
50
  */
45
51
  export function useUpdateSpot(
46
- options?: Omit<UseMutationOptions<Spot, Error, { spotId: string } & Partial<Spot>>, 'mutationFn'>
47
- ): UseMutationResult<Spot, Error, { spotId: string } & Partial<Spot>> {
48
- const queryClient = useQueryClient();
52
+ options?: Omit<
53
+ UseMutationOptions<Spot, Error, {spotId: string} & Partial<Spot>>,
54
+ 'mutationFn'
55
+ >,
56
+ ): UseMutationResult<Spot, Error, {spotId: string} & Partial<Spot>> {
57
+ const queryClient = useQueryClient()
49
58
 
50
59
  return useMutation({
51
- mutationFn: async ({ spotId, ...data }): Promise<Spot> => {
52
- const client = getApiClient();
53
- const response = await client.put<ApiResponse<Spot>>(`/api/v1/spots/${spotId}`, data);
54
- return response.data.data;
60
+ mutationFn: async ({spotId, ...data}): Promise<Spot> => {
61
+ const client = getApiClient()
62
+ const response = await client.put<ApiResponse<Spot>>(
63
+ `/spots/${spotId}`,
64
+ data,
65
+ )
66
+ return response.data.data
55
67
  },
56
68
  onSuccess: (data, variables) => {
57
- queryClient.setQueryData(spotKeys.detail(variables.spotId), data);
69
+ queryClient.setQueryData(spotKeys.detail(variables.spotId), data)
58
70
  },
59
71
  ...options,
60
- });
72
+ })
61
73
  }
62
74
 
63
75
  /**
64
76
  * Claim a spot (for business owners)
65
77
  *
66
- * @endpoint POST /api/v1/spots/{spotId}/claim
78
+ * @endpoint POST /spots/{spotId}/claim
67
79
  */
68
80
  export function useClaimSpot(
69
- options?: Omit<UseMutationOptions<{ claimId: string }, Error, { spotId: string } & ClaimSpotRequest>, 'mutationFn'>
70
- ): UseMutationResult<{ claimId: string }, Error, { spotId: string } & ClaimSpotRequest> {
81
+ options?: Omit<
82
+ UseMutationOptions<
83
+ {claimId: string},
84
+ Error,
85
+ {spotId: string} & ClaimSpotRequest
86
+ >,
87
+ 'mutationFn'
88
+ >,
89
+ ): UseMutationResult<
90
+ {claimId: string},
91
+ Error,
92
+ {spotId: string} & ClaimSpotRequest
93
+ > {
71
94
  return useMutation({
72
- mutationFn: async ({ spotId, ...data }): Promise<{ claimId: string }> => {
73
- const client = getApiClient();
74
- const response = await client.post<ApiResponse<{ claimId: string }>>(`/api/v1/spots/${spotId}/claim`, data);
75
- return response.data.data;
95
+ mutationFn: async ({spotId, ...data}): Promise<{claimId: string}> => {
96
+ const client = getApiClient()
97
+ const response = await client.post<ApiResponse<{claimId: string}>>(
98
+ `/spots/${spotId}/claim`,
99
+ data,
100
+ )
101
+ return response.data.data
76
102
  },
77
103
  ...options,
78
- });
104
+ })
79
105
  }
80
106
 
81
107
  /**
82
108
  * Subscribe to a spot
83
109
  *
84
- * @endpoint POST /api/v1/spots/{spotId}/subscribe
110
+ * @endpoint POST /spots/{spotId}/subscribe
85
111
  */
86
112
  export function useSubscribeToSpot(
87
- options?: Omit<UseMutationOptions<void, Error, string>, 'mutationFn'>
113
+ options?: Omit<UseMutationOptions<void, Error, string>, 'mutationFn'>,
88
114
  ): UseMutationResult<void, Error, string> {
89
- const queryClient = useQueryClient();
115
+ const queryClient = useQueryClient()
90
116
 
91
117
  return useMutation({
92
118
  mutationFn: async (spotId: string): Promise<void> => {
93
- const client = getApiClient();
94
- await client.post(`/api/v1/spots/${spotId}/subscribe`);
119
+ const client = getApiClient()
120
+ await client.post(`/spots/${spotId}/subscribe`)
95
121
  },
96
122
  onSuccess: () => {
97
- queryClient.invalidateQueries({ queryKey: userKeys.subscriptions() });
123
+ queryClient.invalidateQueries({queryKey: userKeys.subscriptions()})
98
124
  },
99
125
  ...options,
100
- });
126
+ })
101
127
  }
102
128
 
103
129
  /**
104
130
  * Unsubscribe from a spot
105
131
  *
106
- * @endpoint DELETE /api/v1/spots/{spotId}/subscribe
132
+ * @endpoint DELETE /spots/{spotId}/subscribe
107
133
  */
108
134
  export function useUnsubscribeFromSpot(
109
- options?: Omit<UseMutationOptions<void, Error, string>, 'mutationFn'>
135
+ options?: Omit<UseMutationOptions<void, Error, string>, 'mutationFn'>,
110
136
  ): UseMutationResult<void, Error, string> {
111
- const queryClient = useQueryClient();
137
+ const queryClient = useQueryClient()
112
138
 
113
139
  return useMutation({
114
140
  mutationFn: async (spotId: string): Promise<void> => {
115
- const client = getApiClient();
116
- await client.delete(`/api/v1/spots/${spotId}/subscribe`);
141
+ const client = getApiClient()
142
+ await client.delete(`/spots/${spotId}/subscribe`)
117
143
  },
118
144
  onSuccess: () => {
119
- queryClient.invalidateQueries({ queryKey: userKeys.subscriptions() });
145
+ queryClient.invalidateQueries({queryKey: userKeys.subscriptions()})
120
146
  },
121
147
  ...options,
122
- });
148
+ })
123
149
  }
124
150
 
125
151
  /**
126
152
  * Toggle favorite status on a spot
127
153
  *
128
- * @endpoint POST /api/v1/spots/{spotId}/favorite
154
+ * @endpoint POST /spots/{spotId}/favorite
129
155
  */
130
156
  export function useFavoriteSpot(
131
- options?: Omit<UseMutationOptions<{ isFavorite: boolean }, Error, string>, 'mutationFn'>
132
- ): UseMutationResult<{ isFavorite: boolean }, Error, string> {
133
- const queryClient = useQueryClient();
157
+ options?: Omit<
158
+ UseMutationOptions<{isFavorite: boolean}, Error, string>,
159
+ 'mutationFn'
160
+ >,
161
+ ): UseMutationResult<{isFavorite: boolean}, Error, string> {
162
+ const queryClient = useQueryClient()
134
163
 
135
164
  return useMutation({
136
- mutationFn: async (spotId: string): Promise<{ isFavorite: boolean }> => {
137
- const client = getApiClient();
138
- const response = await client.post<ApiResponse<{ isFavorite: boolean }>>(`/api/v1/spots/${spotId}/favorite`);
139
- return response.data.data;
165
+ mutationFn: async (spotId: string): Promise<{isFavorite: boolean}> => {
166
+ const client = getApiClient()
167
+ const response = await client.post<ApiResponse<{isFavorite: boolean}>>(
168
+ `/spots/${spotId}/favorite`,
169
+ )
170
+ return response.data.data
140
171
  },
141
172
  onSuccess: () => {
142
- queryClient.invalidateQueries({ queryKey: userKeys.favorites() });
173
+ queryClient.invalidateQueries({queryKey: userKeys.favorites()})
174
+ },
175
+ ...options,
176
+ })
177
+ }
178
+
179
+ /**
180
+ * Rate a spot
181
+ *
182
+ * @endpoint POST /spots/{spotId}/rate
183
+ */
184
+ export function useRateSpot(
185
+ options?: Omit<
186
+ UseMutationOptions<
187
+ {rating: number},
188
+ Error,
189
+ {spotId: string; rating: number}
190
+ >,
191
+ 'mutationFn'
192
+ >,
193
+ ): UseMutationResult<
194
+ {rating: number},
195
+ Error,
196
+ {spotId: string; rating: number}
197
+ > {
198
+ const queryClient = useQueryClient()
199
+
200
+ return useMutation({
201
+ mutationFn: async ({
202
+ spotId,
203
+ rating,
204
+ }: {
205
+ spotId: string
206
+ rating: number
207
+ }): Promise<{rating: number}> => {
208
+ const client = getApiClient()
209
+ const response = await client.post<ApiResponse<{rating: number}>>(
210
+ `/spots/${spotId}/rate`,
211
+ {rating},
212
+ )
213
+ return response.data.data
214
+ },
215
+ onSuccess: (_, variables) => {
216
+ queryClient.invalidateQueries({
217
+ queryKey: spotKeys.detail(variables.spotId),
218
+ })
219
+ },
220
+ ...options,
221
+ })
222
+ }
223
+
224
+ /**
225
+ * Report a spot
226
+ *
227
+ * @endpoint POST /spots/{spotId}/report
228
+ */
229
+ export function useReportSpot(
230
+ options?: Omit<
231
+ UseMutationOptions<
232
+ {success: boolean},
233
+ Error,
234
+ {spotId: string; reason: string; details?: string}
235
+ >,
236
+ 'mutationFn'
237
+ >,
238
+ ): UseMutationResult<
239
+ {success: boolean},
240
+ Error,
241
+ {spotId: string; reason: string; details?: string}
242
+ > {
243
+ return useMutation({
244
+ mutationFn: async ({
245
+ spotId,
246
+ reason,
247
+ details,
248
+ }): Promise<{success: boolean}> => {
249
+ const client = getApiClient()
250
+ const response = await client.post<ApiResponse<{success: boolean}>>(
251
+ `/spots/${spotId}/report`,
252
+ {reason, details},
253
+ )
254
+ return response.data.data
143
255
  },
144
256
  ...options,
145
- });
257
+ })
146
258
  }