@rovela-ai/sdk 0.3.5 → 0.3.7
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/admin/api/categories.d.ts.map +1 -1
- package/dist/admin/api/categories.js +10 -5
- package/dist/admin/api/categories.js.map +1 -1
- package/dist/admin/api/customers.d.ts.map +1 -1
- package/dist/admin/api/customers.js +8 -4
- package/dist/admin/api/customers.js.map +1 -1
- package/dist/admin/api/orders.d.ts +1 -1
- package/dist/admin/api/orders.d.ts.map +1 -1
- package/dist/admin/api/orders.js +12 -6
- package/dist/admin/api/orders.js.map +1 -1
- package/dist/admin/api/products.d.ts.map +1 -1
- package/dist/admin/api/products.js +19 -8
- package/dist/admin/api/products.js.map +1 -1
- package/dist/admin/api/shipping.d.ts.map +1 -1
- package/dist/admin/api/shipping.js +17 -16
- package/dist/admin/api/shipping.js.map +1 -1
- package/dist/admin/api/tax-zones.d.ts.map +1 -1
- package/dist/admin/api/tax-zones.js +10 -5
- package/dist/admin/api/tax-zones.js.map +1 -1
- package/dist/admin/components/CategoryForm.d.ts.map +1 -1
- package/dist/admin/components/CategoryForm.js +54 -65
- package/dist/admin/components/CategoryForm.js.map +1 -1
- package/dist/admin/components/CategorySelect.d.ts.map +1 -1
- package/dist/admin/components/CategorySelect.js +9 -14
- package/dist/admin/components/CategorySelect.js.map +1 -1
- package/dist/admin/components/CustomerDetails.js +3 -3
- package/dist/admin/components/CustomerDetails.js.map +1 -1
- package/dist/admin/components/CustomerTable.js +3 -3
- package/dist/admin/components/CustomerTable.js.map +1 -1
- package/dist/admin/components/LogoUpload.d.ts.map +1 -1
- package/dist/admin/components/LogoUpload.js +49 -67
- package/dist/admin/components/LogoUpload.js.map +1 -1
- package/dist/admin/components/OrderDetails.d.ts.map +1 -1
- package/dist/admin/components/OrderDetails.js +34 -65
- package/dist/admin/components/OrderDetails.js.map +1 -1
- package/dist/admin/components/OrderTable.js +2 -2
- package/dist/admin/components/OrderTable.js.map +1 -1
- package/dist/admin/components/PaymentSettings.d.ts.map +1 -1
- package/dist/admin/components/PaymentSettings.js +28 -51
- package/dist/admin/components/PaymentSettings.js.map +1 -1
- package/dist/admin/components/ProductTable.js +3 -3
- package/dist/admin/components/ProductTable.js.map +1 -1
- package/dist/admin/components/ShippingSettings.d.ts.map +1 -1
- package/dist/admin/components/ShippingSettings.js +177 -244
- package/dist/admin/components/ShippingSettings.js.map +1 -1
- package/dist/admin/components/StoreSettings.d.ts.map +1 -1
- package/dist/admin/components/StoreSettings.js +28 -42
- package/dist/admin/components/StoreSettings.js.map +1 -1
- package/dist/admin/components/TaxSettings.d.ts.map +1 -1
- package/dist/admin/components/TaxSettings.js +49 -81
- package/dist/admin/components/TaxSettings.js.map +1 -1
- package/dist/admin/hooks/fetchAdminApi.d.ts +65 -0
- package/dist/admin/hooks/fetchAdminApi.d.ts.map +1 -0
- package/dist/admin/hooks/fetchAdminApi.js +96 -0
- package/dist/admin/hooks/fetchAdminApi.js.map +1 -0
- package/dist/admin/hooks/useAdminCategories.d.ts +0 -27
- package/dist/admin/hooks/useAdminCategories.d.ts.map +1 -1
- package/dist/admin/hooks/useAdminCategories.js +39 -147
- package/dist/admin/hooks/useAdminCategories.js.map +1 -1
- package/dist/admin/hooks/useAdminCustomers.d.ts +0 -38
- package/dist/admin/hooks/useAdminCustomers.d.ts.map +1 -1
- package/dist/admin/hooks/useAdminCustomers.js +66 -172
- package/dist/admin/hooks/useAdminCustomers.js.map +1 -1
- package/dist/admin/hooks/useAdminMe.d.ts.map +1 -1
- package/dist/admin/hooks/useAdminMe.js +31 -59
- package/dist/admin/hooks/useAdminMe.js.map +1 -1
- package/dist/admin/hooks/useAdminOrders.d.ts +0 -38
- package/dist/admin/hooks/useAdminOrders.d.ts.map +1 -1
- package/dist/admin/hooks/useAdminOrders.js +66 -208
- package/dist/admin/hooks/useAdminOrders.js.map +1 -1
- package/dist/admin/hooks/useAdminProducts.d.ts +0 -36
- package/dist/admin/hooks/useAdminProducts.d.ts.map +1 -1
- package/dist/admin/hooks/useAdminProducts.js +61 -180
- package/dist/admin/hooks/useAdminProducts.js.map +1 -1
- package/dist/admin/hooks/useAdminStats.d.ts.map +1 -1
- package/dist/admin/hooks/useAdminStats.js +26 -38
- package/dist/admin/hooks/useAdminStats.js.map +1 -1
- package/dist/admin/hooks/useAdminUsers.d.ts.map +1 -1
- package/dist/admin/hooks/useAdminUsers.js +82 -145
- package/dist/admin/hooks/useAdminUsers.js.map +1 -1
- package/dist/admin/types.d.ts +4 -4
- package/dist/admin/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -2,204 +2,98 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @rovela/sdk/admin/hooks/useAdminCustomers
|
|
4
4
|
*
|
|
5
|
-
* Customer management hook for admin panel.
|
|
5
|
+
* Customer management hook for admin panel. All HTTP calls go through
|
|
6
|
+
* `fetchAdminApi` — see its file-level comment for the rationale.
|
|
6
7
|
*/
|
|
7
8
|
import { useState, useCallback } from 'react';
|
|
9
|
+
import { fetchAdminApi } from './fetchAdminApi';
|
|
10
|
+
function toIsoString(value) {
|
|
11
|
+
if (!value)
|
|
12
|
+
return null;
|
|
13
|
+
return typeof value === 'string' ? value : value.toISOString();
|
|
14
|
+
}
|
|
15
|
+
function toCustomerListItem(raw) {
|
|
16
|
+
return {
|
|
17
|
+
id: raw.id,
|
|
18
|
+
email: raw.email,
|
|
19
|
+
name: raw.name || undefined,
|
|
20
|
+
emailVerified: toIsoString(raw.emailVerified),
|
|
21
|
+
createdAt: typeof raw.createdAt === 'string'
|
|
22
|
+
? raw.createdAt
|
|
23
|
+
: raw.createdAt.toISOString(),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function toCustomerDetail(raw) {
|
|
27
|
+
return {
|
|
28
|
+
id: raw.id,
|
|
29
|
+
email: raw.email,
|
|
30
|
+
name: raw.name || undefined,
|
|
31
|
+
emailVerified: toIsoString(raw.emailVerified),
|
|
32
|
+
stripeCustomerId: raw.stripeCustomerId || null,
|
|
33
|
+
createdAt: typeof raw.createdAt === 'string'
|
|
34
|
+
? raw.createdAt
|
|
35
|
+
: raw.createdAt.toISOString(),
|
|
36
|
+
orders: raw.orders || [],
|
|
37
|
+
stats: raw.stats,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
8
40
|
// =============================================================================
|
|
9
41
|
// Hook Implementation
|
|
10
42
|
// =============================================================================
|
|
11
|
-
/**
|
|
12
|
-
* Customer management hook for admin panel.
|
|
13
|
-
*
|
|
14
|
-
* @returns Customers data and management methods
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```typescript
|
|
18
|
-
* function CustomersPage() {
|
|
19
|
-
* const {
|
|
20
|
-
* customers,
|
|
21
|
-
* total,
|
|
22
|
-
* page,
|
|
23
|
-
* isLoading,
|
|
24
|
-
* error,
|
|
25
|
-
* fetchCustomers,
|
|
26
|
-
* getCustomer,
|
|
27
|
-
* } = useAdminCustomers()
|
|
28
|
-
*
|
|
29
|
-
* useEffect(() => {
|
|
30
|
-
* fetchCustomers()
|
|
31
|
-
* }, [fetchCustomers])
|
|
32
|
-
*
|
|
33
|
-
* const handleViewCustomer = async (customerId: string) => {
|
|
34
|
-
* const customer = await getCustomer(customerId)
|
|
35
|
-
* if (customer) {
|
|
36
|
-
* console.log('Customer details:', customer)
|
|
37
|
-
* }
|
|
38
|
-
* }
|
|
39
|
-
*
|
|
40
|
-
* return (
|
|
41
|
-
* <CustomerTable
|
|
42
|
-
* customers={customers}
|
|
43
|
-
* onCustomerClick={handleViewCustomer}
|
|
44
|
-
* />
|
|
45
|
-
* )
|
|
46
|
-
* }
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
43
|
export function useAdminCustomers() {
|
|
50
44
|
const [customers, setCustomers] = useState([]);
|
|
51
45
|
const [total, setTotal] = useState(0);
|
|
52
46
|
const [page, setPage] = useState(1);
|
|
53
47
|
const [isLoading, setIsLoading] = useState(false);
|
|
54
48
|
const [error, setError] = useState(null);
|
|
55
|
-
/**
|
|
56
|
-
* Fetch customers with optional filters.
|
|
57
|
-
*/
|
|
58
49
|
const fetchCustomers = useCallback(async (options = {}) => {
|
|
59
50
|
const { search, page: pageNum = 1, limit = 20 } = options;
|
|
60
51
|
setIsLoading(true);
|
|
61
52
|
setError(null);
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
const data = await response.json();
|
|
74
|
-
// Transform dates from API response
|
|
75
|
-
const transformedCustomers = (data.data || []).map((customer) => ({
|
|
76
|
-
id: customer.id,
|
|
77
|
-
email: customer.email,
|
|
78
|
-
name: customer.name || undefined,
|
|
79
|
-
emailVerified: customer.emailVerified
|
|
80
|
-
? typeof customer.emailVerified === 'string'
|
|
81
|
-
? customer.emailVerified
|
|
82
|
-
: customer.emailVerified.toISOString()
|
|
83
|
-
: null,
|
|
84
|
-
createdAt: typeof customer.createdAt === 'string'
|
|
85
|
-
? customer.createdAt
|
|
86
|
-
: customer.createdAt.toISOString(),
|
|
87
|
-
}));
|
|
88
|
-
setCustomers(transformedCustomers);
|
|
89
|
-
setTotal(data.total || 0);
|
|
90
|
-
setPage(data.page || 1);
|
|
91
|
-
}
|
|
92
|
-
catch (err) {
|
|
93
|
-
console.error('[useAdminCustomers] Fetch error:', err);
|
|
94
|
-
setError(err instanceof Error ? err.message : 'Failed to fetch customers');
|
|
95
|
-
}
|
|
96
|
-
finally {
|
|
97
|
-
setIsLoading(false);
|
|
53
|
+
const params = new URLSearchParams();
|
|
54
|
+
if (search)
|
|
55
|
+
params.set('search', search);
|
|
56
|
+
params.set('page', pageNum.toString());
|
|
57
|
+
params.set('limit', limit.toString());
|
|
58
|
+
const res = await fetchAdminApi(`/api/admin/customers?${params.toString()}`);
|
|
59
|
+
setIsLoading(false);
|
|
60
|
+
if (!res.ok) {
|
|
61
|
+
setError(res.error);
|
|
62
|
+
return;
|
|
98
63
|
}
|
|
64
|
+
setCustomers((res.data.data || []).map(toCustomerListItem));
|
|
65
|
+
setTotal(res.data.total || 0);
|
|
66
|
+
setPage(res.data.page || 1);
|
|
99
67
|
}, []);
|
|
100
|
-
/**
|
|
101
|
-
* Get a single customer by ID with order history.
|
|
102
|
-
*/
|
|
103
68
|
const getCustomer = useCallback(async (customerId) => {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const data = await response.json();
|
|
108
|
-
throw new Error(data.error || 'Failed to fetch customer');
|
|
109
|
-
}
|
|
110
|
-
const data = await response.json();
|
|
111
|
-
const customer = data.data;
|
|
112
|
-
// Transform to AdminCustomerDetail
|
|
113
|
-
return {
|
|
114
|
-
id: customer.id,
|
|
115
|
-
email: customer.email,
|
|
116
|
-
name: customer.name || undefined,
|
|
117
|
-
emailVerified: customer.emailVerified
|
|
118
|
-
? typeof customer.emailVerified === 'string'
|
|
119
|
-
? customer.emailVerified
|
|
120
|
-
: customer.emailVerified.toISOString()
|
|
121
|
-
: null,
|
|
122
|
-
stripeCustomerId: customer.stripeCustomerId || null,
|
|
123
|
-
createdAt: typeof customer.createdAt === 'string'
|
|
124
|
-
? customer.createdAt
|
|
125
|
-
: customer.createdAt.toISOString(),
|
|
126
|
-
orders: customer.orders || [],
|
|
127
|
-
stats: customer.stats,
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
catch (err) {
|
|
131
|
-
console.error('[useAdminCustomers] Get customer error:', err);
|
|
132
|
-
setError(err instanceof Error ? err.message : 'Failed to fetch customer');
|
|
69
|
+
const res = await fetchAdminApi(`/api/admin/customers/${customerId}`);
|
|
70
|
+
if (!res.ok) {
|
|
71
|
+
setError(res.error);
|
|
133
72
|
return null;
|
|
134
73
|
}
|
|
74
|
+
return toCustomerDetail(res.data.data);
|
|
135
75
|
}, []);
|
|
136
|
-
/**
|
|
137
|
-
* Update a customer's profile information.
|
|
138
|
-
*/
|
|
139
76
|
const updateCustomer = useCallback(async (customerId, data) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (!response.ok) {
|
|
148
|
-
return {
|
|
149
|
-
success: false,
|
|
150
|
-
error: result.error || 'Failed to update customer',
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
const customer = result.data;
|
|
154
|
-
// Transform to AdminCustomerDetail
|
|
155
|
-
const transformedCustomer = {
|
|
156
|
-
id: customer.id,
|
|
157
|
-
email: customer.email,
|
|
158
|
-
name: customer.name || undefined,
|
|
159
|
-
emailVerified: customer.emailVerified
|
|
160
|
-
? typeof customer.emailVerified === 'string'
|
|
161
|
-
? customer.emailVerified
|
|
162
|
-
: customer.emailVerified.toISOString()
|
|
163
|
-
: null,
|
|
164
|
-
stripeCustomerId: customer.stripeCustomerId || null,
|
|
165
|
-
createdAt: typeof customer.createdAt === 'string'
|
|
166
|
-
? customer.createdAt
|
|
167
|
-
: customer.createdAt.toISOString(),
|
|
168
|
-
};
|
|
169
|
-
return {
|
|
170
|
-
success: true,
|
|
171
|
-
data: transformedCustomer,
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
catch (err) {
|
|
175
|
-
console.error('[useAdminCustomers] Update customer error:', err);
|
|
176
|
-
return {
|
|
177
|
-
success: false,
|
|
178
|
-
error: err instanceof Error ? err.message : 'Failed to update customer',
|
|
179
|
-
};
|
|
77
|
+
const res = await fetchAdminApi(`/api/admin/customers/${customerId}`, {
|
|
78
|
+
method: 'PUT',
|
|
79
|
+
headers: { 'Content-Type': 'application/json' },
|
|
80
|
+
body: JSON.stringify(data),
|
|
81
|
+
});
|
|
82
|
+
if (!res.ok) {
|
|
83
|
+
return { success: false, error: res.error };
|
|
180
84
|
}
|
|
85
|
+
return { success: true, data: toCustomerDetail(res.data.data) };
|
|
181
86
|
}, []);
|
|
182
|
-
/**
|
|
183
|
-
* Delete (anonymize) a customer by ID.
|
|
184
|
-
* This performs a soft delete that anonymizes customer data for GDPR compliance.
|
|
185
|
-
*/
|
|
186
87
|
const deleteCustomer = useCallback(async (customerId) => {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
setError(result.error || 'Failed to delete customer');
|
|
194
|
-
return false;
|
|
195
|
-
}
|
|
196
|
-
return true;
|
|
197
|
-
}
|
|
198
|
-
catch (err) {
|
|
199
|
-
console.error('[useAdminCustomers] Delete customer error:', err);
|
|
200
|
-
setError(err instanceof Error ? err.message : 'Failed to delete customer');
|
|
201
|
-
return false;
|
|
88
|
+
const res = await fetchAdminApi(`/api/admin/customers/${customerId}`, {
|
|
89
|
+
method: 'DELETE',
|
|
90
|
+
});
|
|
91
|
+
if (!res.ok) {
|
|
92
|
+
setError(res.error);
|
|
93
|
+
return { success: false, error: res.error };
|
|
202
94
|
}
|
|
95
|
+
setError(null);
|
|
96
|
+
return { success: true };
|
|
203
97
|
}, []);
|
|
204
98
|
return {
|
|
205
99
|
customers,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAdminCustomers.js","sourceRoot":"","sources":["../../../src/admin/hooks/useAdminCustomers.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ
|
|
1
|
+
{"version":3,"file":"useAdminCustomers.js","sourceRoot":"","sources":["../../../src/admin/hooks/useAdminCustomers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAdminMe.d.ts","sourceRoot":"","sources":["../../../src/admin/hooks/useAdminMe.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useAdminMe.d.ts","sourceRoot":"","sources":["../../../src/admin/hooks/useAdminMe.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,GAAG,IAAI,CAAA;IAClB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,aAAa,EAAE,CAAC,IAAI,EAAE;QACpB,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACnD,cAAc,EAAE,CAAC,IAAI,EAAE;QACrB,eAAe,EAAE,MAAM,CAAA;QACvB,WAAW,EAAE,MAAM,CAAA;KACpB,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACpD;AAMD,wBAAgB,UAAU,IAAI,gBAAgB,CA2E7C"}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* surface errors in form UI.
|
|
16
16
|
*/
|
|
17
17
|
import { useState, useEffect, useCallback } from 'react';
|
|
18
|
+
import { fetchAdminApi } from './fetchAdminApi';
|
|
18
19
|
// =============================================================================
|
|
19
20
|
// Hook
|
|
20
21
|
// =============================================================================
|
|
@@ -25,78 +26,49 @@ export function useAdminMe() {
|
|
|
25
26
|
const refetch = useCallback(async () => {
|
|
26
27
|
setIsLoading(true);
|
|
27
28
|
setError(null);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
throw new Error(data.error || 'Failed to load profile');
|
|
33
|
-
}
|
|
34
|
-
const data = (await res.json());
|
|
35
|
-
setMe(data);
|
|
36
|
-
}
|
|
37
|
-
catch (err) {
|
|
38
|
-
console.error('[useAdminMe] fetch error:', err);
|
|
39
|
-
setError(err instanceof Error ? err.message : 'Failed to load profile');
|
|
29
|
+
const res = await fetchAdminApi('/api/admin/me');
|
|
30
|
+
setIsLoading(false);
|
|
31
|
+
if (!res.ok) {
|
|
32
|
+
setError(res.error);
|
|
40
33
|
setMe(null);
|
|
34
|
+
return;
|
|
41
35
|
}
|
|
42
|
-
|
|
43
|
-
setIsLoading(false);
|
|
44
|
-
}
|
|
36
|
+
setMe(res.data);
|
|
45
37
|
}, []);
|
|
46
38
|
useEffect(() => {
|
|
47
39
|
refetch();
|
|
48
40
|
}, [refetch]);
|
|
49
41
|
const updateProfile = useCallback(async (data) => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (!res.ok || !body.success) {
|
|
58
|
-
return {
|
|
59
|
-
success: false,
|
|
60
|
-
error: body.error || 'Failed to update profile',
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
await refetch();
|
|
64
|
-
return { success: true };
|
|
42
|
+
const res = await fetchAdminApi('/api/admin/me', {
|
|
43
|
+
method: 'PATCH',
|
|
44
|
+
headers: { 'Content-Type': 'application/json' },
|
|
45
|
+
body: JSON.stringify(data),
|
|
46
|
+
});
|
|
47
|
+
if (!res.ok) {
|
|
48
|
+
return { success: false, error: res.error };
|
|
65
49
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
success: false,
|
|
70
|
-
error: err instanceof Error ? err.message : 'Failed to update profile',
|
|
71
|
-
};
|
|
50
|
+
if (!res.data?.success) {
|
|
51
|
+
return { success: false, error: 'Failed to update profile' };
|
|
72
52
|
}
|
|
53
|
+
await refetch();
|
|
54
|
+
return { success: true };
|
|
73
55
|
}, [refetch]);
|
|
74
56
|
const changePassword = useCallback(async (data) => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (!res.ok || !body.success) {
|
|
83
|
-
return {
|
|
84
|
-
success: false,
|
|
85
|
-
error: body.error || 'Failed to change password',
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
// Password change bumps sessionVersion → this session is now
|
|
89
|
-
// invalid on the very next request. We deliberately DON'T refetch
|
|
90
|
-
// here — the UI will catch the 401 and redirect to login.
|
|
91
|
-
return { success: true };
|
|
57
|
+
const res = await fetchAdminApi('/api/admin/me/password', {
|
|
58
|
+
method: 'PATCH',
|
|
59
|
+
headers: { 'Content-Type': 'application/json' },
|
|
60
|
+
body: JSON.stringify(data),
|
|
61
|
+
});
|
|
62
|
+
if (!res.ok) {
|
|
63
|
+
return { success: false, error: res.error };
|
|
92
64
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
success: false,
|
|
97
|
-
error: err instanceof Error ? err.message : 'Failed to change password',
|
|
98
|
-
};
|
|
65
|
+
if (!res.data?.success) {
|
|
66
|
+
return { success: false, error: 'Failed to change password' };
|
|
99
67
|
}
|
|
68
|
+
// Password change bumps sessionVersion → this session is now
|
|
69
|
+
// invalid on the very next request. We deliberately DON'T refetch
|
|
70
|
+
// here — the UI will catch the 401 and redirect to login.
|
|
71
|
+
return { success: true };
|
|
100
72
|
}, []);
|
|
101
73
|
return { me, isLoading, error, refetch, updateProfile, changePassword };
|
|
102
74
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAdminMe.js","sourceRoot":"","sources":["../../../src/admin/hooks/useAdminMe.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AA+
|
|
1
|
+
{"version":3,"file":"useAdminMe.js","sourceRoot":"","sources":["../../../src/admin/hooks/useAdminMe.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,41 +1,3 @@
|
|
|
1
1
|
import type { UseAdminOrdersReturn } from '../types';
|
|
2
|
-
/**
|
|
3
|
-
* Order management hook for admin panel.
|
|
4
|
-
*
|
|
5
|
-
* @returns Orders data and management methods
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```typescript
|
|
9
|
-
* function OrdersPage() {
|
|
10
|
-
* const {
|
|
11
|
-
* orders,
|
|
12
|
-
* total,
|
|
13
|
-
* page,
|
|
14
|
-
* isLoading,
|
|
15
|
-
* error,
|
|
16
|
-
* fetchOrders,
|
|
17
|
-
* updateStatus,
|
|
18
|
-
* processRefund,
|
|
19
|
-
* } = useAdminOrders()
|
|
20
|
-
*
|
|
21
|
-
* useEffect(() => {
|
|
22
|
-
* fetchOrders({ status: 'pending' })
|
|
23
|
-
* }, [fetchOrders])
|
|
24
|
-
*
|
|
25
|
-
* const handleShip = async (orderId: string) => {
|
|
26
|
-
* const success = await updateStatus(orderId, 'shipped', true)
|
|
27
|
-
* if (success) fetchOrders()
|
|
28
|
-
* }
|
|
29
|
-
*
|
|
30
|
-
* return (
|
|
31
|
-
* <OrderTable
|
|
32
|
-
* orders={orders}
|
|
33
|
-
* onShip={handleShip}
|
|
34
|
-
* onRefund={(id, amount) => processRefund(id, amount)}
|
|
35
|
-
* />
|
|
36
|
-
* )
|
|
37
|
-
* }
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
2
|
export declare function useAdminOrders(): UseAdminOrdersReturn;
|
|
41
3
|
//# sourceMappingURL=useAdminOrders.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAdminOrders.d.ts","sourceRoot":"","sources":["../../../src/admin/hooks/useAdminOrders.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useAdminOrders.d.ts","sourceRoot":"","sources":["../../../src/admin/hooks/useAdminOrders.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAIV,oBAAoB,EAIrB,MAAM,UAAU,CAAA;AAMjB,wBAAgB,cAAc,IAAI,oBAAoB,CAqKrD"}
|