@spotsdev/sdk 1.0.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.
- package/dist/api/client.d.ts +12 -0
- package/dist/api/client.js +68 -0
- package/dist/api/mutations/clubs.d.ts +47 -0
- package/dist/api/mutations/clubs.js +95 -0
- package/dist/api/mutations/conversations.d.ts +45 -0
- package/dist/api/mutations/conversations.js +110 -0
- package/dist/api/mutations/index.d.ts +13 -0
- package/dist/api/mutations/index.js +38 -0
- package/dist/api/mutations/notifications.d.ts +38 -0
- package/dist/api/mutations/notifications.js +64 -0
- package/dist/api/mutations/orders.d.ts +73 -0
- package/dist/api/mutations/orders.js +116 -0
- package/dist/api/mutations/posts.d.ts +123 -0
- package/dist/api/mutations/posts.js +229 -0
- package/dist/api/mutations/products.d.ts +81 -0
- package/dist/api/mutations/products.js +102 -0
- package/dist/api/mutations/spots.d.ts +59 -0
- package/dist/api/mutations/spots.js +129 -0
- package/dist/api/mutations/users.d.ts +71 -0
- package/dist/api/mutations/users.js +173 -0
- package/dist/api/queries/auth.d.ts +37 -0
- package/dist/api/queries/auth.js +61 -0
- package/dist/api/queries/clubs.d.ts +52 -0
- package/dist/api/queries/clubs.js +116 -0
- package/dist/api/queries/conversations.d.ts +52 -0
- package/dist/api/queries/conversations.js +83 -0
- package/dist/api/queries/index.d.ts +26 -0
- package/dist/api/queries/index.js +65 -0
- package/dist/api/queries/misc.d.ts +54 -0
- package/dist/api/queries/misc.js +129 -0
- package/dist/api/queries/notifications.d.ts +34 -0
- package/dist/api/queries/notifications.js +62 -0
- package/dist/api/queries/orders.d.ts +45 -0
- package/dist/api/queries/orders.js +93 -0
- package/dist/api/queries/posts.d.ts +55 -0
- package/dist/api/queries/posts.js +130 -0
- package/dist/api/queries/products.d.ts +52 -0
- package/dist/api/queries/products.js +89 -0
- package/dist/api/queries/spots.d.ts +78 -0
- package/dist/api/queries/spots.js +168 -0
- package/dist/api/queries/templates.d.ts +42 -0
- package/dist/api/queries/templates.js +86 -0
- package/dist/api/queries/users.d.ts +90 -0
- package/dist/api/queries/users.js +187 -0
- package/dist/api/services/index.d.ts +2 -0
- package/dist/api/services/index.js +8 -0
- package/dist/api/services/marketplace.d.ts +129 -0
- package/dist/api/services/marketplace.js +168 -0
- package/dist/api/types.d.ts +54 -0
- package/dist/api/types.js +34 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +73 -0
- package/package.json +57 -0
- package/src/api/client.ts +78 -0
- package/src/api/mutations/clubs.ts +107 -0
- package/src/api/mutations/conversations.ts +124 -0
- package/src/api/mutations/index.ts +29 -0
- package/src/api/mutations/notifications.ts +70 -0
- package/src/api/mutations/orders.ts +174 -0
- package/src/api/mutations/posts.ts +278 -0
- package/src/api/mutations/products.ts +160 -0
- package/src/api/mutations/spots.ts +146 -0
- package/src/api/mutations/users.ts +197 -0
- package/src/api/queries/auth.ts +67 -0
- package/src/api/queries/clubs.ts +135 -0
- package/src/api/queries/conversations.ts +94 -0
- package/src/api/queries/index.ts +48 -0
- package/src/api/queries/misc.ts +140 -0
- package/src/api/queries/notifications.ts +66 -0
- package/src/api/queries/orders.ts +119 -0
- package/src/api/queries/posts.ts +142 -0
- package/src/api/queries/products.ts +123 -0
- package/src/api/queries/spots.ts +201 -0
- package/src/api/queries/templates.ts +95 -0
- package/src/api/queries/users.ts +206 -0
- package/src/api/services/index.ts +6 -0
- package/src/api/services/marketplace.ts +265 -0
- package/src/api/types.ts +144 -0
- package/src/index.ts +63 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spots Mutation Hooks
|
|
3
|
+
*
|
|
4
|
+
* TanStack Query hooks for spot mutation operations.
|
|
5
|
+
*/
|
|
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';
|
|
12
|
+
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// MUTATION HOOKS
|
|
15
|
+
// ============================================================================
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create a new spot
|
|
19
|
+
*
|
|
20
|
+
* @endpoint POST /api/v1/spots
|
|
21
|
+
*/
|
|
22
|
+
export function useCreateSpot(
|
|
23
|
+
options?: Omit<UseMutationOptions<Spot, Error, Partial<Spot>>, 'mutationFn'>
|
|
24
|
+
): UseMutationResult<Spot, Error, Partial<Spot>> {
|
|
25
|
+
const queryClient = useQueryClient();
|
|
26
|
+
|
|
27
|
+
return useMutation({
|
|
28
|
+
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;
|
|
32
|
+
},
|
|
33
|
+
onSuccess: () => {
|
|
34
|
+
queryClient.invalidateQueries({ queryKey: spotKeys.lists() });
|
|
35
|
+
},
|
|
36
|
+
...options,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Update a spot
|
|
42
|
+
*
|
|
43
|
+
* @endpoint PUT /api/v1/spots/{spotId}
|
|
44
|
+
*/
|
|
45
|
+
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();
|
|
49
|
+
|
|
50
|
+
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;
|
|
55
|
+
},
|
|
56
|
+
onSuccess: (data, variables) => {
|
|
57
|
+
queryClient.setQueryData(spotKeys.detail(variables.spotId), data);
|
|
58
|
+
},
|
|
59
|
+
...options,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Claim a spot (for business owners)
|
|
65
|
+
*
|
|
66
|
+
* @endpoint POST /api/v1/spots/{spotId}/claim
|
|
67
|
+
*/
|
|
68
|
+
export function useClaimSpot(
|
|
69
|
+
options?: Omit<UseMutationOptions<{ claimId: string }, Error, { spotId: string } & ClaimSpotRequest>, 'mutationFn'>
|
|
70
|
+
): UseMutationResult<{ claimId: string }, Error, { spotId: string } & ClaimSpotRequest> {
|
|
71
|
+
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;
|
|
76
|
+
},
|
|
77
|
+
...options,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Subscribe to a spot
|
|
83
|
+
*
|
|
84
|
+
* @endpoint POST /api/v1/spots/{spotId}/subscribe
|
|
85
|
+
*/
|
|
86
|
+
export function useSubscribeToSpot(
|
|
87
|
+
options?: Omit<UseMutationOptions<void, Error, string>, 'mutationFn'>
|
|
88
|
+
): UseMutationResult<void, Error, string> {
|
|
89
|
+
const queryClient = useQueryClient();
|
|
90
|
+
|
|
91
|
+
return useMutation({
|
|
92
|
+
mutationFn: async (spotId: string): Promise<void> => {
|
|
93
|
+
const client = getApiClient();
|
|
94
|
+
await client.post(`/api/v1/spots/${spotId}/subscribe`);
|
|
95
|
+
},
|
|
96
|
+
onSuccess: () => {
|
|
97
|
+
queryClient.invalidateQueries({ queryKey: userKeys.subscriptions() });
|
|
98
|
+
},
|
|
99
|
+
...options,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Unsubscribe from a spot
|
|
105
|
+
*
|
|
106
|
+
* @endpoint DELETE /api/v1/spots/{spotId}/subscribe
|
|
107
|
+
*/
|
|
108
|
+
export function useUnsubscribeFromSpot(
|
|
109
|
+
options?: Omit<UseMutationOptions<void, Error, string>, 'mutationFn'>
|
|
110
|
+
): UseMutationResult<void, Error, string> {
|
|
111
|
+
const queryClient = useQueryClient();
|
|
112
|
+
|
|
113
|
+
return useMutation({
|
|
114
|
+
mutationFn: async (spotId: string): Promise<void> => {
|
|
115
|
+
const client = getApiClient();
|
|
116
|
+
await client.delete(`/api/v1/spots/${spotId}/subscribe`);
|
|
117
|
+
},
|
|
118
|
+
onSuccess: () => {
|
|
119
|
+
queryClient.invalidateQueries({ queryKey: userKeys.subscriptions() });
|
|
120
|
+
},
|
|
121
|
+
...options,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Toggle favorite status on a spot
|
|
127
|
+
*
|
|
128
|
+
* @endpoint POST /api/v1/spots/{spotId}/favorite
|
|
129
|
+
*/
|
|
130
|
+
export function useFavoriteSpot(
|
|
131
|
+
options?: Omit<UseMutationOptions<{ isFavorite: boolean }, Error, string>, 'mutationFn'>
|
|
132
|
+
): UseMutationResult<{ isFavorite: boolean }, Error, string> {
|
|
133
|
+
const queryClient = useQueryClient();
|
|
134
|
+
|
|
135
|
+
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;
|
|
140
|
+
},
|
|
141
|
+
onSuccess: () => {
|
|
142
|
+
queryClient.invalidateQueries({ queryKey: userKeys.favorites() });
|
|
143
|
+
},
|
|
144
|
+
...options,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Users Mutation Hooks
|
|
3
|
+
*
|
|
4
|
+
* TanStack Query hooks for user mutation operations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useMutation, useQueryClient, UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
|
|
8
|
+
import { getApiClient } from '../client';
|
|
9
|
+
import { userKeys } from '../queries/users';
|
|
10
|
+
import type { User, UpdateProfileRequest, ApiResponse } from '../types';
|
|
11
|
+
|
|
12
|
+
// ============================================================================
|
|
13
|
+
// MUTATION HOOKS
|
|
14
|
+
// ============================================================================
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Update current user's profile
|
|
18
|
+
*
|
|
19
|
+
* @endpoint PUT /api/v1/users/me
|
|
20
|
+
*/
|
|
21
|
+
export function useUpdateProfile(
|
|
22
|
+
options?: Omit<UseMutationOptions<User, Error, UpdateProfileRequest>, 'mutationFn'>
|
|
23
|
+
): UseMutationResult<User, Error, UpdateProfileRequest> {
|
|
24
|
+
const queryClient = useQueryClient();
|
|
25
|
+
|
|
26
|
+
return useMutation({
|
|
27
|
+
mutationFn: async (data: UpdateProfileRequest): Promise<User> => {
|
|
28
|
+
const client = getApiClient();
|
|
29
|
+
const response = await client.put<ApiResponse<User>>('/api/v1/users/me', data);
|
|
30
|
+
return response.data.data;
|
|
31
|
+
},
|
|
32
|
+
onSuccess: (data) => {
|
|
33
|
+
queryClient.setQueryData(userKeys.me(), data);
|
|
34
|
+
},
|
|
35
|
+
...options,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Upload avatar
|
|
41
|
+
*
|
|
42
|
+
* @endpoint POST /api/v1/users/me/avatar
|
|
43
|
+
*/
|
|
44
|
+
export function useUploadAvatar(
|
|
45
|
+
options?: Omit<UseMutationOptions<{ avatarUrl: string }, Error, FormData>, 'mutationFn'>
|
|
46
|
+
): UseMutationResult<{ avatarUrl: string }, Error, FormData> {
|
|
47
|
+
const queryClient = useQueryClient();
|
|
48
|
+
|
|
49
|
+
return useMutation({
|
|
50
|
+
mutationFn: async (formData: FormData): Promise<{ avatarUrl: string }> => {
|
|
51
|
+
const client = getApiClient();
|
|
52
|
+
const response = await client.post<ApiResponse<{ avatarUrl: string }>>('/api/v1/users/me/avatar', formData, {
|
|
53
|
+
headers: { 'Content-Type': 'multipart/form-data' },
|
|
54
|
+
});
|
|
55
|
+
return response.data.data;
|
|
56
|
+
},
|
|
57
|
+
onSuccess: () => {
|
|
58
|
+
queryClient.invalidateQueries({ queryKey: userKeys.me() });
|
|
59
|
+
},
|
|
60
|
+
...options,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Delete current user's account
|
|
66
|
+
*
|
|
67
|
+
* @endpoint DELETE /api/v1/users/me
|
|
68
|
+
*/
|
|
69
|
+
export function useDeleteAccount(
|
|
70
|
+
options?: Omit<UseMutationOptions<void, Error, void>, 'mutationFn'>
|
|
71
|
+
): UseMutationResult<void, Error, void> {
|
|
72
|
+
const queryClient = useQueryClient();
|
|
73
|
+
|
|
74
|
+
return useMutation({
|
|
75
|
+
mutationFn: async (): Promise<void> => {
|
|
76
|
+
const client = getApiClient();
|
|
77
|
+
await client.delete('/api/v1/users/me');
|
|
78
|
+
},
|
|
79
|
+
onSuccess: () => {
|
|
80
|
+
queryClient.clear();
|
|
81
|
+
},
|
|
82
|
+
...options,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Update user vibes
|
|
88
|
+
*
|
|
89
|
+
* @endpoint PUT /api/v1/user/me/vibes
|
|
90
|
+
*/
|
|
91
|
+
export function useUpdateVibes(
|
|
92
|
+
options?: Omit<UseMutationOptions<User, Error, { vibes: string[] }>, 'mutationFn'>
|
|
93
|
+
): UseMutationResult<User, Error, { vibes: string[] }> {
|
|
94
|
+
const queryClient = useQueryClient();
|
|
95
|
+
|
|
96
|
+
return useMutation({
|
|
97
|
+
mutationFn: async (data: { vibes: string[] }): Promise<User> => {
|
|
98
|
+
const client = getApiClient();
|
|
99
|
+
const response = await client.put<ApiResponse<User>>('/api/v1/user/me/vibes', data);
|
|
100
|
+
return response.data.data;
|
|
101
|
+
},
|
|
102
|
+
onSuccess: () => {
|
|
103
|
+
queryClient.invalidateQueries({ queryKey: userKeys.me() });
|
|
104
|
+
},
|
|
105
|
+
...options,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Update user interests
|
|
111
|
+
*
|
|
112
|
+
* @endpoint PUT /api/v1/user/me/interests
|
|
113
|
+
*/
|
|
114
|
+
export function useUpdateInterests(
|
|
115
|
+
options?: Omit<UseMutationOptions<User, Error, { interests: string[] }>, 'mutationFn'>
|
|
116
|
+
): UseMutationResult<User, Error, { interests: string[] }> {
|
|
117
|
+
const queryClient = useQueryClient();
|
|
118
|
+
|
|
119
|
+
return useMutation({
|
|
120
|
+
mutationFn: async (data: { interests: string[] }): Promise<User> => {
|
|
121
|
+
const client = getApiClient();
|
|
122
|
+
const response = await client.put<ApiResponse<User>>('/api/v1/user/me/interests', data);
|
|
123
|
+
return response.data.data;
|
|
124
|
+
},
|
|
125
|
+
onSuccess: () => {
|
|
126
|
+
queryClient.invalidateQueries({ queryKey: userKeys.me() });
|
|
127
|
+
},
|
|
128
|
+
...options,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Complete onboarding step
|
|
134
|
+
*
|
|
135
|
+
* @endpoint POST /api/v1/user/me/onboarding-step
|
|
136
|
+
*/
|
|
137
|
+
export function useCompleteOnboardingStep(
|
|
138
|
+
options?: Omit<UseMutationOptions<User, Error, { step: number }>, 'mutationFn'>
|
|
139
|
+
): UseMutationResult<User, Error, { step: number }> {
|
|
140
|
+
const queryClient = useQueryClient();
|
|
141
|
+
|
|
142
|
+
return useMutation({
|
|
143
|
+
mutationFn: async (data: { step: number }): Promise<User> => {
|
|
144
|
+
const client = getApiClient();
|
|
145
|
+
const response = await client.post<ApiResponse<User>>('/api/v1/user/me/onboarding-step', data);
|
|
146
|
+
return response.data.data;
|
|
147
|
+
},
|
|
148
|
+
onSuccess: () => {
|
|
149
|
+
queryClient.invalidateQueries({ queryKey: userKeys.me() });
|
|
150
|
+
},
|
|
151
|
+
...options,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Block a user
|
|
157
|
+
*
|
|
158
|
+
* @endpoint POST /api/v1/users/{id}/block
|
|
159
|
+
*/
|
|
160
|
+
export function useBlockUser(
|
|
161
|
+
options?: Omit<UseMutationOptions<void, Error, string>, 'mutationFn'>
|
|
162
|
+
): UseMutationResult<void, Error, string> {
|
|
163
|
+
const queryClient = useQueryClient();
|
|
164
|
+
|
|
165
|
+
return useMutation({
|
|
166
|
+
mutationFn: async (userId: string): Promise<void> => {
|
|
167
|
+
const client = getApiClient();
|
|
168
|
+
await client.post(`/api/v1/users/${userId}/block`);
|
|
169
|
+
},
|
|
170
|
+
onSuccess: () => {
|
|
171
|
+
queryClient.invalidateQueries({ queryKey: userKeys.blocked() });
|
|
172
|
+
},
|
|
173
|
+
...options,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Unblock a user
|
|
179
|
+
*
|
|
180
|
+
* @endpoint DELETE /api/v1/users/{id}/block
|
|
181
|
+
*/
|
|
182
|
+
export function useUnblockUser(
|
|
183
|
+
options?: Omit<UseMutationOptions<void, Error, string>, 'mutationFn'>
|
|
184
|
+
): UseMutationResult<void, Error, string> {
|
|
185
|
+
const queryClient = useQueryClient();
|
|
186
|
+
|
|
187
|
+
return useMutation({
|
|
188
|
+
mutationFn: async (userId: string): Promise<void> => {
|
|
189
|
+
const client = getApiClient();
|
|
190
|
+
await client.delete(`/api/v1/users/${userId}/block`);
|
|
191
|
+
},
|
|
192
|
+
onSuccess: () => {
|
|
193
|
+
queryClient.invalidateQueries({ queryKey: userKeys.blocked() });
|
|
194
|
+
},
|
|
195
|
+
...options,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Mutation Hooks
|
|
3
|
+
*
|
|
4
|
+
* TanStack Query hooks for authentication operations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useMutation, UseMutationOptions, UseMutationResult } from '@tanstack/react-query';
|
|
8
|
+
import { getApiClient } from '../client';
|
|
9
|
+
import type { SendOtpRequest, VerifyOtpRequest, AuthResponse, ApiResponse } from '../types';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// MUTATION HOOKS
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Send OTP to phone number
|
|
17
|
+
*
|
|
18
|
+
* @endpoint POST /api/v1/auth/send-otp
|
|
19
|
+
*/
|
|
20
|
+
export function useSendOtp(
|
|
21
|
+
options?: Omit<UseMutationOptions<ApiResponse<{ sent: boolean }>, Error, SendOtpRequest>, 'mutationFn'>
|
|
22
|
+
): UseMutationResult<ApiResponse<{ sent: boolean }>, Error, SendOtpRequest> {
|
|
23
|
+
return useMutation({
|
|
24
|
+
mutationFn: async (data: SendOtpRequest) => {
|
|
25
|
+
const client = getApiClient();
|
|
26
|
+
const response = await client.post<ApiResponse<{ sent: boolean }>>('/api/v1/auth/send-otp', data);
|
|
27
|
+
return response.data;
|
|
28
|
+
},
|
|
29
|
+
...options,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Verify OTP and authenticate
|
|
35
|
+
*
|
|
36
|
+
* @endpoint POST /api/v1/auth/verify-otp
|
|
37
|
+
*/
|
|
38
|
+
export function useVerifyOtp(
|
|
39
|
+
options?: Omit<UseMutationOptions<AuthResponse, Error, VerifyOtpRequest>, 'mutationFn'>
|
|
40
|
+
): UseMutationResult<AuthResponse, Error, VerifyOtpRequest> {
|
|
41
|
+
return useMutation({
|
|
42
|
+
mutationFn: async (data: VerifyOtpRequest) => {
|
|
43
|
+
const client = getApiClient();
|
|
44
|
+
const response = await client.post<AuthResponse>('/api/v1/auth/verify-otp', data);
|
|
45
|
+
return response.data;
|
|
46
|
+
},
|
|
47
|
+
...options,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Refresh access token
|
|
53
|
+
*
|
|
54
|
+
* @endpoint POST /api/v1/auth/refresh
|
|
55
|
+
*/
|
|
56
|
+
export function useRefreshToken(
|
|
57
|
+
options?: Omit<UseMutationOptions<{ accessToken: string }, Error, { refreshToken: string }>, 'mutationFn'>
|
|
58
|
+
): UseMutationResult<{ accessToken: string }, Error, { refreshToken: string }> {
|
|
59
|
+
return useMutation({
|
|
60
|
+
mutationFn: async (data: { refreshToken: string }) => {
|
|
61
|
+
const client = getApiClient();
|
|
62
|
+
const response = await client.post<{ accessToken: string }>('/api/v1/auth/refresh', data);
|
|
63
|
+
return response.data;
|
|
64
|
+
},
|
|
65
|
+
...options,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clubs Query Hooks
|
|
3
|
+
*
|
|
4
|
+
* TanStack Query hooks for club operations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useQuery, UseQueryOptions, UseQueryResult } from '@tanstack/react-query';
|
|
8
|
+
import { getApiClient } from '../client';
|
|
9
|
+
import type { Club, ApiResponse } from '../types';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// QUERY KEYS
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
export const clubKeys = {
|
|
16
|
+
all: ['clubs'] as const,
|
|
17
|
+
bySpot: (spotId: string) => [...clubKeys.all, 'spot', spotId] as const,
|
|
18
|
+
details: () => [...clubKeys.all, 'detail'] as const,
|
|
19
|
+
detail: (id: string) => [...clubKeys.details(), id] as const,
|
|
20
|
+
bySlug: (slug: string) => [...clubKeys.all, 'slug', slug] as const,
|
|
21
|
+
byUser: (userId: string) => [...clubKeys.all, 'user', userId] as const,
|
|
22
|
+
membership: (clubId: string, userId: string) => [...clubKeys.detail(clubId), 'membership', userId] as const,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// QUERY HOOKS
|
|
27
|
+
// ============================================================================
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get clubs for a spot
|
|
31
|
+
*
|
|
32
|
+
* @endpoint GET /api/v1/clubs/spot/{spotId}
|
|
33
|
+
*/
|
|
34
|
+
export function useClubsBySpot(
|
|
35
|
+
spotId: string,
|
|
36
|
+
options?: Omit<UseQueryOptions<Club[]>, 'queryKey' | 'queryFn'>
|
|
37
|
+
): UseQueryResult<Club[]> {
|
|
38
|
+
return useQuery({
|
|
39
|
+
queryKey: clubKeys.bySpot(spotId),
|
|
40
|
+
queryFn: async (): Promise<Club[]> => {
|
|
41
|
+
const client = getApiClient();
|
|
42
|
+
const response = await client.get<ApiResponse<Club[]>>(`/api/v1/clubs/spot/${spotId}`);
|
|
43
|
+
return response.data.data;
|
|
44
|
+
},
|
|
45
|
+
enabled: !!spotId,
|
|
46
|
+
...options,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get a club by ID
|
|
52
|
+
*
|
|
53
|
+
* @endpoint GET /api/v1/clubs/{id}
|
|
54
|
+
*/
|
|
55
|
+
export function useClub(
|
|
56
|
+
clubId: string,
|
|
57
|
+
options?: Omit<UseQueryOptions<Club>, 'queryKey' | 'queryFn'>
|
|
58
|
+
): UseQueryResult<Club> {
|
|
59
|
+
return useQuery({
|
|
60
|
+
queryKey: clubKeys.detail(clubId),
|
|
61
|
+
queryFn: async (): Promise<Club> => {
|
|
62
|
+
const client = getApiClient();
|
|
63
|
+
const response = await client.get<ApiResponse<Club>>(`/api/v1/clubs/${clubId}`);
|
|
64
|
+
return response.data.data;
|
|
65
|
+
},
|
|
66
|
+
enabled: !!clubId,
|
|
67
|
+
...options,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get a club by slug
|
|
73
|
+
*
|
|
74
|
+
* @endpoint GET /api/v1/clubs/slug/{slug}
|
|
75
|
+
*/
|
|
76
|
+
export function useClubBySlug(
|
|
77
|
+
slug: string,
|
|
78
|
+
options?: Omit<UseQueryOptions<Club>, 'queryKey' | 'queryFn'>
|
|
79
|
+
): UseQueryResult<Club> {
|
|
80
|
+
return useQuery({
|
|
81
|
+
queryKey: clubKeys.bySlug(slug),
|
|
82
|
+
queryFn: async (): Promise<Club> => {
|
|
83
|
+
const client = getApiClient();
|
|
84
|
+
const response = await client.get<ApiResponse<Club>>(`/api/v1/clubs/slug/${slug}`);
|
|
85
|
+
return response.data.data;
|
|
86
|
+
},
|
|
87
|
+
enabled: !!slug,
|
|
88
|
+
...options,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get clubs for a user
|
|
94
|
+
*
|
|
95
|
+
* @endpoint GET /api/v1/clubs/user/{userId}
|
|
96
|
+
*/
|
|
97
|
+
export function useClubsByUser(
|
|
98
|
+
userId: string,
|
|
99
|
+
options?: Omit<UseQueryOptions<Club[]>, 'queryKey' | 'queryFn'>
|
|
100
|
+
): UseQueryResult<Club[]> {
|
|
101
|
+
return useQuery({
|
|
102
|
+
queryKey: clubKeys.byUser(userId),
|
|
103
|
+
queryFn: async (): Promise<Club[]> => {
|
|
104
|
+
const client = getApiClient();
|
|
105
|
+
const response = await client.get<ApiResponse<Club[]>>(`/api/v1/clubs/user/${userId}`);
|
|
106
|
+
return response.data.data;
|
|
107
|
+
},
|
|
108
|
+
enabled: !!userId,
|
|
109
|
+
...options,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get membership status for a user in a club
|
|
115
|
+
*
|
|
116
|
+
* @endpoint GET /api/v1/clubs/{id}/membership/{userId}
|
|
117
|
+
*/
|
|
118
|
+
export function useClubMembership(
|
|
119
|
+
clubId: string,
|
|
120
|
+
userId: string,
|
|
121
|
+
options?: Omit<UseQueryOptions<{ isMember: boolean; role?: string }>, 'queryKey' | 'queryFn'>
|
|
122
|
+
): UseQueryResult<{ isMember: boolean; role?: string }> {
|
|
123
|
+
return useQuery({
|
|
124
|
+
queryKey: clubKeys.membership(clubId, userId),
|
|
125
|
+
queryFn: async () => {
|
|
126
|
+
const client = getApiClient();
|
|
127
|
+
const response = await client.get<ApiResponse<{ isMember: boolean; role?: string }>>(
|
|
128
|
+
`/api/v1/clubs/${clubId}/membership/${userId}`
|
|
129
|
+
);
|
|
130
|
+
return response.data.data;
|
|
131
|
+
},
|
|
132
|
+
enabled: !!clubId && !!userId,
|
|
133
|
+
...options,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversations Query Hooks
|
|
3
|
+
*
|
|
4
|
+
* TanStack Query hooks for conversation/messaging operations.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useQuery, UseQueryOptions, UseQueryResult } from '@tanstack/react-query';
|
|
8
|
+
import { getApiClient } from '../client';
|
|
9
|
+
import type { Conversation, Message, ApiResponse } from '../types';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// QUERY KEYS
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
export const conversationKeys = {
|
|
16
|
+
all: ['conversations'] as const,
|
|
17
|
+
lists: () => [...conversationKeys.all, 'list'] as const,
|
|
18
|
+
list: () => [...conversationKeys.lists()] as const,
|
|
19
|
+
details: () => [...conversationKeys.all, 'detail'] as const,
|
|
20
|
+
detail: (id: string) => [...conversationKeys.details(), id] as const,
|
|
21
|
+
messages: (conversationId: string, params?: { before?: string }) =>
|
|
22
|
+
[...conversationKeys.detail(conversationId), 'messages', params] as const,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// QUERY HOOKS
|
|
27
|
+
// ============================================================================
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get all conversations for current user
|
|
31
|
+
*
|
|
32
|
+
* @endpoint GET /api/v1/conversations
|
|
33
|
+
*/
|
|
34
|
+
export function useConversations(
|
|
35
|
+
options?: Omit<UseQueryOptions<Conversation[]>, 'queryKey' | 'queryFn'>
|
|
36
|
+
): UseQueryResult<Conversation[]> {
|
|
37
|
+
return useQuery({
|
|
38
|
+
queryKey: conversationKeys.list(),
|
|
39
|
+
queryFn: async (): Promise<Conversation[]> => {
|
|
40
|
+
const client = getApiClient();
|
|
41
|
+
const response = await client.get<ApiResponse<Conversation[]>>('/api/v1/conversations');
|
|
42
|
+
return response.data.data;
|
|
43
|
+
},
|
|
44
|
+
...options,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Get a single conversation with details
|
|
50
|
+
*
|
|
51
|
+
* @endpoint GET /api/v1/conversations/{id}
|
|
52
|
+
*/
|
|
53
|
+
export function useConversation(
|
|
54
|
+
conversationId: string,
|
|
55
|
+
options?: Omit<UseQueryOptions<Conversation>, 'queryKey' | 'queryFn'>
|
|
56
|
+
): UseQueryResult<Conversation> {
|
|
57
|
+
return useQuery({
|
|
58
|
+
queryKey: conversationKeys.detail(conversationId),
|
|
59
|
+
queryFn: async (): Promise<Conversation> => {
|
|
60
|
+
const client = getApiClient();
|
|
61
|
+
const response = await client.get<ApiResponse<Conversation>>(`/api/v1/conversations/${conversationId}`);
|
|
62
|
+
return response.data.data;
|
|
63
|
+
},
|
|
64
|
+
enabled: !!conversationId,
|
|
65
|
+
...options,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get messages for a conversation
|
|
71
|
+
*
|
|
72
|
+
* @endpoint GET /api/v1/conversations/{id}/messages
|
|
73
|
+
*/
|
|
74
|
+
export function useConversationMessages(
|
|
75
|
+
conversationId: string,
|
|
76
|
+
params?: { limit?: number; before?: string },
|
|
77
|
+
options?: Omit<UseQueryOptions<{ data: Message[]; meta: { hasMore: boolean; oldestMessageAt: string | null } }>, 'queryKey' | 'queryFn'>
|
|
78
|
+
): UseQueryResult<{ data: Message[]; meta: { hasMore: boolean; oldestMessageAt: string | null } }> {
|
|
79
|
+
return useQuery({
|
|
80
|
+
queryKey: conversationKeys.messages(conversationId, params),
|
|
81
|
+
queryFn: async () => {
|
|
82
|
+
const client = getApiClient();
|
|
83
|
+
const queryParams = new URLSearchParams();
|
|
84
|
+
if (params?.limit) queryParams.set('limit', String(params.limit));
|
|
85
|
+
if (params?.before) queryParams.set('before', params.before);
|
|
86
|
+
const response = await client.get<{ data: Message[]; meta: { hasMore: boolean; oldestMessageAt: string | null } }>(
|
|
87
|
+
`/api/v1/conversations/${conversationId}/messages?${queryParams}`
|
|
88
|
+
);
|
|
89
|
+
return response.data;
|
|
90
|
+
},
|
|
91
|
+
enabled: !!conversationId,
|
|
92
|
+
...options,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spots SDK Query Hooks Index
|
|
3
|
+
*
|
|
4
|
+
* Re-exports all query hooks and keys.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Auth (mutations, but grouped with queries for convenience)
|
|
8
|
+
export * from './auth';
|
|
9
|
+
|
|
10
|
+
// Users
|
|
11
|
+
export * from './users';
|
|
12
|
+
export { userKeys } from './users';
|
|
13
|
+
|
|
14
|
+
// Spots
|
|
15
|
+
export * from './spots';
|
|
16
|
+
export { spotKeys } from './spots';
|
|
17
|
+
|
|
18
|
+
// Posts
|
|
19
|
+
export * from './posts';
|
|
20
|
+
export { postKeys } from './posts';
|
|
21
|
+
|
|
22
|
+
// Conversations
|
|
23
|
+
export * from './conversations';
|
|
24
|
+
export { conversationKeys } from './conversations';
|
|
25
|
+
|
|
26
|
+
// Clubs
|
|
27
|
+
export * from './clubs';
|
|
28
|
+
export { clubKeys } from './clubs';
|
|
29
|
+
|
|
30
|
+
// Templates
|
|
31
|
+
export * from './templates';
|
|
32
|
+
export { templateKeys } from './templates';
|
|
33
|
+
|
|
34
|
+
// Notifications
|
|
35
|
+
export * from './notifications';
|
|
36
|
+
export { notificationKeys } from './notifications';
|
|
37
|
+
|
|
38
|
+
// Misc (cities, vibes, events)
|
|
39
|
+
export * from './misc';
|
|
40
|
+
export { miscKeys } from './misc';
|
|
41
|
+
|
|
42
|
+
// Products (marketplace)
|
|
43
|
+
export * from './products';
|
|
44
|
+
export { productKeys } from './products';
|
|
45
|
+
|
|
46
|
+
// Orders (marketplace)
|
|
47
|
+
export * from './orders';
|
|
48
|
+
export { orderKeys } from './orders';
|