@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.
- package/dist/api/client.d.ts +1 -1
- package/dist/api/client.js +7 -3
- package/dist/api/entities.d.ts +316 -0
- package/dist/api/entities.js +9 -0
- package/dist/api/mutations/clubs.d.ts +6 -6
- package/dist/api/mutations/clubs.js +12 -10
- package/dist/api/mutations/conversations.d.ts +7 -7
- package/dist/api/mutations/conversations.js +17 -13
- package/dist/api/mutations/index.js +1 -1
- package/dist/api/mutations/notifications.d.ts +4 -4
- package/dist/api/mutations/notifications.js +7 -7
- package/dist/api/mutations/orders.d.ts +7 -7
- package/dist/api/mutations/orders.js +11 -13
- package/dist/api/mutations/posts.d.ts +13 -13
- package/dist/api/mutations/posts.js +41 -29
- package/dist/api/mutations/products.d.ts +5 -5
- package/dist/api/mutations/products.js +9 -13
- package/dist/api/mutations/spots.d.ts +42 -8
- package/dist/api/mutations/spots.js +51 -13
- package/dist/api/mutations/users.d.ts +12 -10
- package/dist/api/mutations/users.js +20 -18
- package/dist/api/queries/auth.d.ts +5 -5
- package/dist/api/queries/auth.js +7 -7
- package/dist/api/queries/clubs.d.ts +7 -7
- package/dist/api/queries/clubs.js +11 -11
- package/dist/api/queries/conversations.d.ts +5 -5
- package/dist/api/queries/conversations.js +7 -7
- package/dist/api/queries/index.js +1 -1
- package/dist/api/queries/misc.d.ts +8 -32
- package/dist/api/queries/misc.js +28 -66
- package/dist/api/queries/notifications.d.ts +4 -4
- package/dist/api/queries/notifications.js +5 -5
- package/dist/api/queries/orders.d.ts +4 -4
- package/dist/api/queries/orders.js +7 -7
- package/dist/api/queries/posts.d.ts +44 -7
- package/dist/api/queries/posts.js +118 -15
- package/dist/api/queries/products.d.ts +6 -10
- package/dist/api/queries/products.js +7 -9
- package/dist/api/queries/spots.d.ts +31 -16
- package/dist/api/queries/spots.js +113 -31
- package/dist/api/queries/templates.d.ts +6 -9
- package/dist/api/queries/templates.js +8 -13
- package/dist/api/queries/users.d.ts +25 -11
- package/dist/api/queries/users.js +75 -27
- package/dist/api/types.d.ts +36 -33
- package/dist/api/types.js +6 -7
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -8
- package/package.json +6 -21
- package/src/api/client.ts +45 -30
- package/src/api/entities.ts +420 -0
- package/src/api/mutations/clubs.ts +73 -40
- package/src/api/mutations/conversations.ts +91 -47
- package/src/api/mutations/index.ts +8 -8
- package/src/api/mutations/notifications.ts +48 -25
- package/src/api/mutations/orders.ts +101 -70
- package/src/api/mutations/posts.ts +229 -118
- package/src/api/mutations/products.ts +120 -81
- package/src/api/mutations/spots.ts +167 -55
- package/src/api/mutations/users.ts +109 -76
- package/src/api/queries/auth.ts +49 -24
- package/src/api/queries/clubs.ts +53 -38
- package/src/api/queries/conversations.ts +48 -30
- package/src/api/queries/index.ts +21 -21
- package/src/api/queries/misc.ts +53 -82
- package/src/api/queries/notifications.ts +32 -21
- package/src/api/queries/orders.ts +59 -42
- package/src/api/queries/posts.ts +203 -48
- package/src/api/queries/products.ts +51 -44
- package/src/api/queries/spots.ts +216 -85
- package/src/api/queries/templates.ts +39 -32
- package/src/api/queries/users.ts +157 -64
- package/src/api/types.ts +72 -118
- package/src/index.ts +5 -11
|
@@ -4,9 +4,14 @@
|
|
|
4
4
|
* TanStack Query hooks for conversation/messaging operations.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
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 Conversation, type Message} from '../types'
|
|
10
15
|
|
|
11
16
|
// ============================================================================
|
|
12
17
|
// QUERY KEYS
|
|
@@ -18,9 +23,9 @@ export const conversationKeys = {
|
|
|
18
23
|
list: () => [...conversationKeys.lists()] as const,
|
|
19
24
|
details: () => [...conversationKeys.all, 'detail'] as const,
|
|
20
25
|
detail: (id: string) => [...conversationKeys.details(), id] as const,
|
|
21
|
-
messages: (conversationId: string, params?: {
|
|
26
|
+
messages: (conversationId: string, params?: {before?: string}) =>
|
|
22
27
|
[...conversationKeys.detail(conversationId), 'messages', params] as const,
|
|
23
|
-
}
|
|
28
|
+
}
|
|
24
29
|
|
|
25
30
|
// ============================================================================
|
|
26
31
|
// QUERY HOOKS
|
|
@@ -29,66 +34,79 @@ export const conversationKeys = {
|
|
|
29
34
|
/**
|
|
30
35
|
* Get all conversations for current user
|
|
31
36
|
*
|
|
32
|
-
* @endpoint GET /
|
|
37
|
+
* @endpoint GET /conversations
|
|
33
38
|
*/
|
|
34
39
|
export function useConversations(
|
|
35
|
-
options?: Omit<UseQueryOptions<Conversation[]>, 'queryKey' | 'queryFn'
|
|
40
|
+
options?: Omit<UseQueryOptions<Conversation[]>, 'queryKey' | 'queryFn'>,
|
|
36
41
|
): UseQueryResult<Conversation[]> {
|
|
37
42
|
return useQuery({
|
|
38
43
|
queryKey: conversationKeys.list(),
|
|
39
44
|
queryFn: async (): Promise<Conversation[]> => {
|
|
40
|
-
const client = getApiClient()
|
|
41
|
-
const response =
|
|
42
|
-
|
|
45
|
+
const client = getApiClient()
|
|
46
|
+
const response =
|
|
47
|
+
await client.get<ApiResponse<Conversation[]>>('/conversations')
|
|
48
|
+
return response.data.data
|
|
43
49
|
},
|
|
44
50
|
...options,
|
|
45
|
-
})
|
|
51
|
+
})
|
|
46
52
|
}
|
|
47
53
|
|
|
48
54
|
/**
|
|
49
55
|
* Get a single conversation with details
|
|
50
56
|
*
|
|
51
|
-
* @endpoint GET /
|
|
57
|
+
* @endpoint GET /conversations/{id}
|
|
52
58
|
*/
|
|
53
59
|
export function useConversation(
|
|
54
60
|
conversationId: string,
|
|
55
|
-
options?: Omit<UseQueryOptions<Conversation>, 'queryKey' | 'queryFn'
|
|
61
|
+
options?: Omit<UseQueryOptions<Conversation>, 'queryKey' | 'queryFn'>,
|
|
56
62
|
): UseQueryResult<Conversation> {
|
|
57
63
|
return useQuery({
|
|
58
64
|
queryKey: conversationKeys.detail(conversationId),
|
|
59
65
|
queryFn: async (): Promise<Conversation> => {
|
|
60
|
-
const client = getApiClient()
|
|
61
|
-
const response = await client.get<ApiResponse<Conversation>>(
|
|
62
|
-
|
|
66
|
+
const client = getApiClient()
|
|
67
|
+
const response = await client.get<ApiResponse<Conversation>>(
|
|
68
|
+
`/conversations/${conversationId}`,
|
|
69
|
+
)
|
|
70
|
+
return response.data.data
|
|
63
71
|
},
|
|
64
72
|
enabled: !!conversationId,
|
|
65
73
|
...options,
|
|
66
|
-
})
|
|
74
|
+
})
|
|
67
75
|
}
|
|
68
76
|
|
|
69
77
|
/**
|
|
70
78
|
* Get messages for a conversation
|
|
71
79
|
*
|
|
72
|
-
* @endpoint GET /
|
|
80
|
+
* @endpoint GET /conversations/{id}/messages
|
|
73
81
|
*/
|
|
74
82
|
export function useConversationMessages(
|
|
75
83
|
conversationId: string,
|
|
76
|
-
params?: {
|
|
77
|
-
options?: Omit<
|
|
78
|
-
|
|
84
|
+
params?: {limit?: number; before?: string},
|
|
85
|
+
options?: Omit<
|
|
86
|
+
UseQueryOptions<{
|
|
87
|
+
data: Message[]
|
|
88
|
+
meta: {hasMore: boolean; oldestMessageAt: string | null}
|
|
89
|
+
}>,
|
|
90
|
+
'queryKey' | 'queryFn'
|
|
91
|
+
>,
|
|
92
|
+
): UseQueryResult<{
|
|
93
|
+
data: Message[]
|
|
94
|
+
meta: {hasMore: boolean; oldestMessageAt: string | null}
|
|
95
|
+
}> {
|
|
79
96
|
return useQuery({
|
|
80
97
|
queryKey: conversationKeys.messages(conversationId, params),
|
|
81
98
|
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<{
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
99
|
+
const client = getApiClient()
|
|
100
|
+
const queryParams = new URLSearchParams()
|
|
101
|
+
if (params?.limit) queryParams.set('limit', String(params.limit))
|
|
102
|
+
if (params?.before) queryParams.set('before', params.before)
|
|
103
|
+
const response = await client.get<{
|
|
104
|
+
data: Message[]
|
|
105
|
+
meta: {hasMore: boolean; oldestMessageAt: string | null}
|
|
106
|
+
}>(`/conversations/${conversationId}/messages?${queryParams}`)
|
|
107
|
+
return response.data
|
|
90
108
|
},
|
|
91
109
|
enabled: !!conversationId,
|
|
92
110
|
...options,
|
|
93
|
-
})
|
|
111
|
+
})
|
|
94
112
|
}
|
package/src/api/queries/index.ts
CHANGED
|
@@ -5,44 +5,44 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
// Auth (mutations, but grouped with queries for convenience)
|
|
8
|
-
export * from './auth'
|
|
8
|
+
export * from './auth'
|
|
9
9
|
|
|
10
10
|
// Users
|
|
11
|
-
export * from './users'
|
|
12
|
-
export {
|
|
11
|
+
export * from './users'
|
|
12
|
+
export {userKeys} from './users'
|
|
13
13
|
|
|
14
14
|
// Spots
|
|
15
|
-
export * from './spots'
|
|
16
|
-
export {
|
|
15
|
+
export * from './spots'
|
|
16
|
+
export {spotKeys} from './spots'
|
|
17
17
|
|
|
18
18
|
// Posts
|
|
19
|
-
export * from './posts'
|
|
20
|
-
export {
|
|
19
|
+
export * from './posts'
|
|
20
|
+
export {postKeys} from './posts'
|
|
21
21
|
|
|
22
22
|
// Conversations
|
|
23
|
-
export * from './conversations'
|
|
24
|
-
export {
|
|
23
|
+
export * from './conversations'
|
|
24
|
+
export {conversationKeys} from './conversations'
|
|
25
25
|
|
|
26
26
|
// Clubs
|
|
27
|
-
export * from './clubs'
|
|
28
|
-
export {
|
|
27
|
+
export * from './clubs'
|
|
28
|
+
export {clubKeys} from './clubs'
|
|
29
29
|
|
|
30
30
|
// Templates
|
|
31
|
-
export * from './templates'
|
|
32
|
-
export {
|
|
31
|
+
export * from './templates'
|
|
32
|
+
export {templateKeys} from './templates'
|
|
33
33
|
|
|
34
34
|
// Notifications
|
|
35
|
-
export * from './notifications'
|
|
36
|
-
export {
|
|
35
|
+
export * from './notifications'
|
|
36
|
+
export {notificationKeys} from './notifications'
|
|
37
37
|
|
|
38
38
|
// Misc (cities, vibes, events)
|
|
39
|
-
export * from './misc'
|
|
40
|
-
export {
|
|
39
|
+
export * from './misc'
|
|
40
|
+
export {miscKeys} from './misc'
|
|
41
41
|
|
|
42
42
|
// Products (marketplace)
|
|
43
|
-
export * from './products'
|
|
44
|
-
export {
|
|
43
|
+
export * from './products'
|
|
44
|
+
export {productKeys} from './products'
|
|
45
45
|
|
|
46
46
|
// Orders (marketplace)
|
|
47
|
-
export * from './orders'
|
|
48
|
-
export {
|
|
47
|
+
export * from './orders'
|
|
48
|
+
export {orderKeys} from './orders'
|
package/src/api/queries/misc.ts
CHANGED
|
@@ -2,16 +2,38 @@
|
|
|
2
2
|
* Misc Query Hooks
|
|
3
3
|
*
|
|
4
4
|
* TanStack Query hooks for cities, vibes, and other reference data.
|
|
5
|
-
* All types come from @prisma/client (via ../types re-export).
|
|
6
|
-
*
|
|
7
|
-
* API Response Patterns:
|
|
8
|
-
* - Reference data (vibes, templates, interests): { success, data: T[], timestamp }
|
|
9
|
-
* - Large datasets (cities, spots, posts): { success, data: { data: T[], meta }, timestamp }
|
|
10
5
|
*/
|
|
11
6
|
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
import {
|
|
8
|
+
useQuery,
|
|
9
|
+
type UseQueryOptions,
|
|
10
|
+
type UseQueryResult,
|
|
11
|
+
} from '@tanstack/react-query'
|
|
12
|
+
|
|
13
|
+
import {getApiClient} from '../client'
|
|
14
|
+
import {
|
|
15
|
+
type ApiResponse,
|
|
16
|
+
type City,
|
|
17
|
+
type LifeSituation,
|
|
18
|
+
type Vibe,
|
|
19
|
+
} from '../types'
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// HELPER FUNCTIONS
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
function extractArrayData<T>(data: unknown): T[] {
|
|
26
|
+
if (Array.isArray(data)) {
|
|
27
|
+
return data
|
|
28
|
+
}
|
|
29
|
+
if (data && typeof data === 'object' && 'data' in data) {
|
|
30
|
+
const nested = (data as {data: unknown}).data
|
|
31
|
+
if (Array.isArray(nested)) {
|
|
32
|
+
return nested
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return []
|
|
36
|
+
}
|
|
15
37
|
|
|
16
38
|
// ============================================================================
|
|
17
39
|
// QUERY KEYS
|
|
@@ -21,120 +43,69 @@ export const miscKeys = {
|
|
|
21
43
|
cities: () => ['cities'] as const,
|
|
22
44
|
vibes: () => ['vibes'] as const,
|
|
23
45
|
lifeSituations: () => ['life-situations'] as const,
|
|
24
|
-
|
|
25
|
-
intentions: () => ['intentions'] as const,
|
|
26
|
-
};
|
|
46
|
+
}
|
|
27
47
|
|
|
28
48
|
// ============================================================================
|
|
29
49
|
// QUERY HOOKS
|
|
30
50
|
// ============================================================================
|
|
31
51
|
|
|
32
52
|
/**
|
|
33
|
-
* Get all cities
|
|
53
|
+
* Get all cities
|
|
34
54
|
*
|
|
35
|
-
* @endpoint GET /
|
|
36
|
-
* @returns PaginatedResponse with cities array
|
|
55
|
+
* @endpoint GET /cities
|
|
37
56
|
*/
|
|
38
57
|
export function useCities(
|
|
39
|
-
options?: Omit<UseQueryOptions<City[]>, 'queryKey' | 'queryFn'
|
|
58
|
+
options?: Omit<UseQueryOptions<City[]>, 'queryKey' | 'queryFn'>,
|
|
40
59
|
): UseQueryResult<City[]> {
|
|
41
60
|
return useQuery({
|
|
42
61
|
queryKey: miscKeys.cities(),
|
|
43
62
|
queryFn: async (): Promise<City[]> => {
|
|
44
|
-
const client = getApiClient()
|
|
45
|
-
const response = await client.get<ApiResponse<
|
|
46
|
-
|
|
47
|
-
return response.data.data.data;
|
|
63
|
+
const client = getApiClient()
|
|
64
|
+
const response = await client.get<ApiResponse<unknown>>('/cities')
|
|
65
|
+
return extractArrayData<City>(response.data.data)
|
|
48
66
|
},
|
|
49
67
|
staleTime: 1000 * 60 * 60,
|
|
50
68
|
...options,
|
|
51
|
-
})
|
|
69
|
+
})
|
|
52
70
|
}
|
|
53
71
|
|
|
54
72
|
/**
|
|
55
|
-
* Get all vibes
|
|
73
|
+
* Get all vibes
|
|
56
74
|
*
|
|
57
|
-
* @endpoint GET /
|
|
58
|
-
* @returns Flat array of vibes (not paginated)
|
|
75
|
+
* @endpoint GET /vibes
|
|
59
76
|
*/
|
|
60
77
|
export function useVibes(
|
|
61
|
-
options?: Omit<UseQueryOptions<Vibe[]>, 'queryKey' | 'queryFn'
|
|
78
|
+
options?: Omit<UseQueryOptions<Vibe[]>, 'queryKey' | 'queryFn'>,
|
|
62
79
|
): UseQueryResult<Vibe[]> {
|
|
63
80
|
return useQuery({
|
|
64
81
|
queryKey: miscKeys.vibes(),
|
|
65
82
|
queryFn: async (): Promise<Vibe[]> => {
|
|
66
|
-
const client = getApiClient()
|
|
67
|
-
const response = await client.get<ApiResponse<
|
|
68
|
-
|
|
69
|
-
return response.data.data;
|
|
83
|
+
const client = getApiClient()
|
|
84
|
+
const response = await client.get<ApiResponse<unknown>>('/vibes')
|
|
85
|
+
return extractArrayData<Vibe>(response.data.data)
|
|
70
86
|
},
|
|
71
87
|
staleTime: 1000 * 60 * 60,
|
|
72
88
|
...options,
|
|
73
|
-
})
|
|
89
|
+
})
|
|
74
90
|
}
|
|
75
91
|
|
|
76
92
|
/**
|
|
77
|
-
* Get all life situations (
|
|
93
|
+
* Get all life situations (for onboarding)
|
|
78
94
|
*
|
|
79
|
-
* @endpoint GET /
|
|
80
|
-
* @returns Flat array of life situations (not paginated)
|
|
95
|
+
* @endpoint GET /life-situations
|
|
81
96
|
*/
|
|
82
97
|
export function useLifeSituations(
|
|
83
|
-
options?: Omit<UseQueryOptions<LifeSituation[]>, 'queryKey' | 'queryFn'
|
|
98
|
+
options?: Omit<UseQueryOptions<LifeSituation[]>, 'queryKey' | 'queryFn'>,
|
|
84
99
|
): UseQueryResult<LifeSituation[]> {
|
|
85
100
|
return useQuery({
|
|
86
101
|
queryKey: miscKeys.lifeSituations(),
|
|
87
102
|
queryFn: async (): Promise<LifeSituation[]> => {
|
|
88
|
-
const client = getApiClient()
|
|
89
|
-
const response =
|
|
90
|
-
|
|
91
|
-
return response.data.data
|
|
92
|
-
},
|
|
93
|
-
staleTime: 1000 * 60 * 60,
|
|
94
|
-
...options,
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Get all interests (flat array - reference data)
|
|
100
|
-
*
|
|
101
|
-
* @endpoint GET /api/v1/interests
|
|
102
|
-
* @returns Flat array of interests (not paginated)
|
|
103
|
-
*/
|
|
104
|
-
export function useInterests(
|
|
105
|
-
options?: Omit<UseQueryOptions<Interest[]>, 'queryKey' | 'queryFn'>
|
|
106
|
-
): UseQueryResult<Interest[]> {
|
|
107
|
-
return useQuery({
|
|
108
|
-
queryKey: miscKeys.interests(),
|
|
109
|
-
queryFn: async (): Promise<Interest[]> => {
|
|
110
|
-
const client = getApiClient();
|
|
111
|
-
const response = await client.get<ApiResponse<Interest[]>>('/api/v1/interests');
|
|
112
|
-
// Interests endpoint returns flat array: { data: [] }
|
|
113
|
-
return response.data.data;
|
|
114
|
-
},
|
|
115
|
-
staleTime: 1000 * 60 * 60,
|
|
116
|
-
...options,
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Get all intentions (flat array - reference data)
|
|
122
|
-
*
|
|
123
|
-
* @endpoint GET /api/v1/intentions
|
|
124
|
-
* @returns Flat array of intentions (not paginated)
|
|
125
|
-
*/
|
|
126
|
-
export function useIntentions(
|
|
127
|
-
options?: Omit<UseQueryOptions<Intention[]>, 'queryKey' | 'queryFn'>
|
|
128
|
-
): UseQueryResult<Intention[]> {
|
|
129
|
-
return useQuery({
|
|
130
|
-
queryKey: miscKeys.intentions(),
|
|
131
|
-
queryFn: async (): Promise<Intention[]> => {
|
|
132
|
-
const client = getApiClient();
|
|
133
|
-
const response = await client.get<ApiResponse<Intention[]>>('/api/v1/intentions');
|
|
134
|
-
// Intentions endpoint returns flat array: { data: [] }
|
|
135
|
-
return response.data.data;
|
|
103
|
+
const client = getApiClient()
|
|
104
|
+
const response =
|
|
105
|
+
await client.get<ApiResponse<unknown>>('/life-situations')
|
|
106
|
+
return extractArrayData<LifeSituation>(response.data.data)
|
|
136
107
|
},
|
|
137
108
|
staleTime: 1000 * 60 * 60,
|
|
138
109
|
...options,
|
|
139
|
-
})
|
|
110
|
+
})
|
|
140
111
|
}
|
|
@@ -4,9 +4,14 @@
|
|
|
4
4
|
* TanStack Query hooks for notification operations.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
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 Notification} from '../types'
|
|
10
15
|
|
|
11
16
|
// ============================================================================
|
|
12
17
|
// QUERY KEYS
|
|
@@ -15,9 +20,10 @@ import type { Notification, ApiResponse } from '../types';
|
|
|
15
20
|
export const notificationKeys = {
|
|
16
21
|
all: ['notifications'] as const,
|
|
17
22
|
lists: () => [...notificationKeys.all, 'list'] as const,
|
|
18
|
-
list: (params?: {
|
|
23
|
+
list: (params?: {limit?: number; unreadOnly?: boolean}) =>
|
|
24
|
+
[...notificationKeys.lists(), params] as const,
|
|
19
25
|
unreadCount: () => [...notificationKeys.all, 'unreadCount'] as const,
|
|
20
|
-
}
|
|
26
|
+
}
|
|
21
27
|
|
|
22
28
|
// ============================================================================
|
|
23
29
|
// QUERY HOOKS
|
|
@@ -26,41 +32,46 @@ export const notificationKeys = {
|
|
|
26
32
|
/**
|
|
27
33
|
* Get notifications for current user
|
|
28
34
|
*
|
|
29
|
-
* @endpoint GET /
|
|
35
|
+
* @endpoint GET /notifications
|
|
30
36
|
*/
|
|
31
37
|
export function useNotifications(
|
|
32
|
-
params?: {
|
|
33
|
-
options?: Omit<UseQueryOptions<Notification[]>, 'queryKey' | 'queryFn'
|
|
38
|
+
params?: {limit?: number; unreadOnly?: boolean},
|
|
39
|
+
options?: Omit<UseQueryOptions<Notification[]>, 'queryKey' | 'queryFn'>,
|
|
34
40
|
): UseQueryResult<Notification[]> {
|
|
35
41
|
return useQuery({
|
|
36
42
|
queryKey: notificationKeys.list(params),
|
|
37
43
|
queryFn: async (): Promise<Notification[]> => {
|
|
38
|
-
const client = getApiClient()
|
|
39
|
-
const queryParams = new URLSearchParams()
|
|
40
|
-
if (params?.limit) queryParams.set('limit', String(params.limit))
|
|
41
|
-
if (params?.unreadOnly)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
const client = getApiClient()
|
|
45
|
+
const queryParams = new URLSearchParams()
|
|
46
|
+
if (params?.limit) queryParams.set('limit', String(params.limit))
|
|
47
|
+
if (params?.unreadOnly)
|
|
48
|
+
queryParams.set('unreadOnly', String(params.unreadOnly))
|
|
49
|
+
const response = await client.get<ApiResponse<Notification[]>>(
|
|
50
|
+
`/notifications?${queryParams}`,
|
|
51
|
+
)
|
|
52
|
+
return response.data.data
|
|
44
53
|
},
|
|
45
54
|
...options,
|
|
46
|
-
})
|
|
55
|
+
})
|
|
47
56
|
}
|
|
48
57
|
|
|
49
58
|
/**
|
|
50
59
|
* Get unread notification count
|
|
51
60
|
*
|
|
52
|
-
* @endpoint GET /
|
|
61
|
+
* @endpoint GET /notifications/unread-count
|
|
53
62
|
*/
|
|
54
63
|
export function useUnreadNotificationCount(
|
|
55
|
-
options?: Omit<UseQueryOptions<number>, 'queryKey' | 'queryFn'
|
|
64
|
+
options?: Omit<UseQueryOptions<number>, 'queryKey' | 'queryFn'>,
|
|
56
65
|
): UseQueryResult<number> {
|
|
57
66
|
return useQuery({
|
|
58
67
|
queryKey: notificationKeys.unreadCount(),
|
|
59
68
|
queryFn: async (): Promise<number> => {
|
|
60
|
-
const client = getApiClient()
|
|
61
|
-
const response = await client.get<ApiResponse<{
|
|
62
|
-
|
|
69
|
+
const client = getApiClient()
|
|
70
|
+
const response = await client.get<ApiResponse<{count: number}>>(
|
|
71
|
+
'/notifications/unread-count',
|
|
72
|
+
)
|
|
73
|
+
return response.data.data.count
|
|
63
74
|
},
|
|
64
75
|
...options,
|
|
65
|
-
})
|
|
76
|
+
})
|
|
66
77
|
}
|
|
@@ -4,9 +4,17 @@
|
|
|
4
4
|
* TanStack Query hooks for order-related operations.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import type {
|
|
7
|
+
import {useQuery, type UseQueryOptions, type UseQueryResult} from '@tanstack/react-query'
|
|
8
|
+
import {getApiClient} from '../client'
|
|
9
|
+
import type {
|
|
10
|
+
Order,
|
|
11
|
+
OrderItem,
|
|
12
|
+
Product,
|
|
13
|
+
Spot,
|
|
14
|
+
OrderStatus,
|
|
15
|
+
ApiResponse,
|
|
16
|
+
PaginatedResponse,
|
|
17
|
+
} from '../types'
|
|
10
18
|
|
|
11
19
|
// ============================================================================
|
|
12
20
|
// QUERY KEYS
|
|
@@ -15,12 +23,13 @@ import type { Order, OrderItem, Product, Spot, OrderStatus, ApiResponse, Paginat
|
|
|
15
23
|
export const orderKeys = {
|
|
16
24
|
all: ['orders'] as const,
|
|
17
25
|
lists: () => [...orderKeys.all, 'list'] as const,
|
|
18
|
-
list: (filters?: Record<string, unknown>) =>
|
|
26
|
+
list: (filters?: Record<string, unknown>) =>
|
|
27
|
+
[...orderKeys.lists(), filters] as const,
|
|
19
28
|
details: () => [...orderKeys.all, 'detail'] as const,
|
|
20
29
|
detail: (id: string) => [...orderKeys.details(), id] as const,
|
|
21
30
|
myOrders: () => [...orderKeys.all, 'my'] as const,
|
|
22
31
|
spotOrders: (spotId: string) => [...orderKeys.all, 'spot', spotId] as const,
|
|
23
|
-
}
|
|
32
|
+
}
|
|
24
33
|
|
|
25
34
|
// ============================================================================
|
|
26
35
|
// TYPES
|
|
@@ -28,15 +37,15 @@ export const orderKeys = {
|
|
|
28
37
|
|
|
29
38
|
export interface OrderWithDetails extends Order {
|
|
30
39
|
items: (OrderItem & {
|
|
31
|
-
product: Pick<Product, 'id' | 'name' | 'slug' | 'type' | 'imageUrl'
|
|
32
|
-
})[]
|
|
33
|
-
spot: Pick<Spot, 'id' | 'name' | 'slug'
|
|
40
|
+
product: Pick<Product, 'id' | 'name' | 'slug' | 'type' | 'imageUrl'>
|
|
41
|
+
})[]
|
|
42
|
+
spot: Pick<Spot, 'id' | 'name' | 'slug'>
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
export interface OrderFilters {
|
|
37
|
-
status?: OrderStatus
|
|
38
|
-
limit?: number
|
|
39
|
-
page?: number
|
|
46
|
+
status?: OrderStatus
|
|
47
|
+
limit?: number
|
|
48
|
+
page?: number
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
// ============================================================================
|
|
@@ -46,74 +55,82 @@ export interface OrderFilters {
|
|
|
46
55
|
/**
|
|
47
56
|
* Get current user's orders (purchases)
|
|
48
57
|
*
|
|
49
|
-
* @endpoint GET /
|
|
58
|
+
* @endpoint GET /users/me/orders
|
|
50
59
|
*/
|
|
51
60
|
export function useMyOrders(
|
|
52
61
|
params?: OrderFilters,
|
|
53
|
-
options?: Omit<
|
|
62
|
+
options?: Omit<
|
|
63
|
+
UseQueryOptions<PaginatedResponse<OrderWithDetails>>,
|
|
64
|
+
'queryKey' | 'queryFn'
|
|
65
|
+
>,
|
|
54
66
|
): UseQueryResult<PaginatedResponse<OrderWithDetails>> {
|
|
55
67
|
return useQuery({
|
|
56
|
-
queryKey: orderKeys.list({
|
|
68
|
+
queryKey: orderKeys.list({...params, my: true}),
|
|
57
69
|
queryFn: async (): Promise<PaginatedResponse<OrderWithDetails>> => {
|
|
58
|
-
const client = getApiClient()
|
|
59
|
-
const queryParams = new URLSearchParams()
|
|
60
|
-
if (params?.status) queryParams.set('status', params.status)
|
|
61
|
-
if (params?.limit) queryParams.set('limit', String(params.limit))
|
|
62
|
-
if (params?.page) queryParams.set('page', String(params.page))
|
|
63
|
-
const response = await client.get<
|
|
64
|
-
|
|
65
|
-
)
|
|
66
|
-
return response.data.data
|
|
70
|
+
const client = getApiClient()
|
|
71
|
+
const queryParams = new URLSearchParams()
|
|
72
|
+
if (params?.status) queryParams.set('status', params.status)
|
|
73
|
+
if (params?.limit) queryParams.set('limit', String(params.limit))
|
|
74
|
+
if (params?.page) queryParams.set('page', String(params.page))
|
|
75
|
+
const response = await client.get<
|
|
76
|
+
ApiResponse<PaginatedResponse<OrderWithDetails>>
|
|
77
|
+
>(`/users/me/orders?${queryParams}`)
|
|
78
|
+
return response.data.data
|
|
67
79
|
},
|
|
68
80
|
...options,
|
|
69
|
-
})
|
|
81
|
+
})
|
|
70
82
|
}
|
|
71
83
|
|
|
72
84
|
/**
|
|
73
85
|
* Get a single order by ID
|
|
74
86
|
*
|
|
75
|
-
* @endpoint GET /
|
|
87
|
+
* @endpoint GET /orders/{orderId}
|
|
76
88
|
*/
|
|
77
89
|
export function useOrder(
|
|
78
90
|
orderId: string,
|
|
79
|
-
options?: Omit<UseQueryOptions<OrderWithDetails>, 'queryKey' | 'queryFn'
|
|
91
|
+
options?: Omit<UseQueryOptions<OrderWithDetails>, 'queryKey' | 'queryFn'>,
|
|
80
92
|
): UseQueryResult<OrderWithDetails> {
|
|
81
93
|
return useQuery({
|
|
82
94
|
queryKey: orderKeys.detail(orderId),
|
|
83
95
|
queryFn: async (): Promise<OrderWithDetails> => {
|
|
84
|
-
const client = getApiClient()
|
|
85
|
-
const response = await client.get<ApiResponse<OrderWithDetails>>(
|
|
86
|
-
|
|
96
|
+
const client = getApiClient()
|
|
97
|
+
const response = await client.get<ApiResponse<OrderWithDetails>>(
|
|
98
|
+
`/orders/${orderId}`,
|
|
99
|
+
)
|
|
100
|
+
return response.data.data
|
|
87
101
|
},
|
|
88
102
|
enabled: !!orderId,
|
|
89
103
|
...options,
|
|
90
|
-
})
|
|
104
|
+
})
|
|
91
105
|
}
|
|
92
106
|
|
|
93
107
|
/**
|
|
94
108
|
* Get orders for a spot (seller view)
|
|
95
109
|
*
|
|
96
|
-
* @endpoint GET /
|
|
110
|
+
* @endpoint GET /seller/spots/{spotId}/orders
|
|
97
111
|
*/
|
|
98
112
|
export function useSpotOrders(
|
|
99
113
|
spotId: string,
|
|
100
114
|
params?: OrderFilters,
|
|
101
|
-
options?: Omit<
|
|
115
|
+
options?: Omit<
|
|
116
|
+
UseQueryOptions<PaginatedResponse<OrderWithDetails>>,
|
|
117
|
+
'queryKey' | 'queryFn'
|
|
118
|
+
>,
|
|
102
119
|
): UseQueryResult<PaginatedResponse<OrderWithDetails>> {
|
|
103
120
|
return useQuery({
|
|
104
121
|
queryKey: orderKeys.spotOrders(spotId),
|
|
105
122
|
queryFn: async (): Promise<PaginatedResponse<OrderWithDetails>> => {
|
|
106
|
-
const client = getApiClient()
|
|
107
|
-
const queryParams = new URLSearchParams()
|
|
108
|
-
if (params?.status) queryParams.set('status', params.status)
|
|
109
|
-
if (params?.limit) queryParams.set('limit', String(params.limit))
|
|
110
|
-
if (params?.page) queryParams.set('page', String(params.page))
|
|
111
|
-
const response = await client.get<
|
|
112
|
-
|
|
113
|
-
)
|
|
114
|
-
return response.data.data
|
|
123
|
+
const client = getApiClient()
|
|
124
|
+
const queryParams = new URLSearchParams()
|
|
125
|
+
if (params?.status) queryParams.set('status', params.status)
|
|
126
|
+
if (params?.limit) queryParams.set('limit', String(params.limit))
|
|
127
|
+
if (params?.page) queryParams.set('page', String(params.page))
|
|
128
|
+
const response = await client.get<
|
|
129
|
+
ApiResponse<PaginatedResponse<OrderWithDetails>>
|
|
130
|
+
>(`/seller/spots/${spotId}/orders?${queryParams}`)
|
|
131
|
+
return response.data.data
|
|
115
132
|
},
|
|
116
133
|
enabled: !!spotId,
|
|
117
134
|
...options,
|
|
118
|
-
})
|
|
135
|
+
})
|
|
119
136
|
}
|