@diffsome/react 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/index.mjs ADDED
@@ -0,0 +1,2255 @@
1
+ // src/context/DiffsomeContext.tsx
2
+ import { createContext, useContext, useState, useEffect, useMemo } from "react";
3
+ import { Diffsome } from "@diffsome/sdk";
4
+ import { jsx } from "react/jsx-runtime";
5
+ var DiffsomeContext = createContext(null);
6
+ function DiffsomeProvider({ children, config }) {
7
+ const [isReady, setIsReady] = useState(false);
8
+ const client = useMemo(() => {
9
+ return new Diffsome({
10
+ ...config,
11
+ persistToken: config.persistToken ?? true,
12
+ storageType: config.storageType ?? "localStorage"
13
+ });
14
+ }, [config.tenantId, config.baseUrl, config.apiKey]);
15
+ useEffect(() => {
16
+ setIsReady(true);
17
+ }, []);
18
+ const value = useMemo(() => ({
19
+ client,
20
+ isReady
21
+ }), [client, isReady]);
22
+ return /* @__PURE__ */ jsx(DiffsomeContext.Provider, { value, children });
23
+ }
24
+ function useDiffsome() {
25
+ const context = useContext(DiffsomeContext);
26
+ if (!context) {
27
+ throw new Error("useDiffsome must be used within DiffsomeProvider");
28
+ }
29
+ return context;
30
+ }
31
+ function useClient() {
32
+ const { client } = useDiffsome();
33
+ return client;
34
+ }
35
+
36
+ // src/hooks/useAuth.ts
37
+ import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2 } from "react";
38
+ function useAuth() {
39
+ const client = useClient();
40
+ const [user, setUser] = useState2(null);
41
+ const [loading, setLoading] = useState2(true);
42
+ const [error, setError] = useState2(null);
43
+ const isAuthenticated = !!user && client.isAuthenticated();
44
+ const fetchProfile = useCallback2(async () => {
45
+ if (!client.isAuthenticated()) {
46
+ setUser(null);
47
+ setLoading(false);
48
+ return;
49
+ }
50
+ try {
51
+ const profile = await client.auth.me();
52
+ setUser(profile);
53
+ setError(null);
54
+ } catch (err) {
55
+ setUser(null);
56
+ setError(err instanceof Error ? err : new Error("Failed to fetch profile"));
57
+ } finally {
58
+ setLoading(false);
59
+ }
60
+ }, [client]);
61
+ useEffect2(() => {
62
+ fetchProfile();
63
+ }, [fetchProfile]);
64
+ const login = useCallback2(async (credentials) => {
65
+ setLoading(true);
66
+ setError(null);
67
+ try {
68
+ const response = await client.auth.login(credentials);
69
+ setUser(response.user);
70
+ return response;
71
+ } catch (err) {
72
+ const error2 = err instanceof Error ? err : new Error("Login failed");
73
+ setError(error2);
74
+ throw error2;
75
+ } finally {
76
+ setLoading(false);
77
+ }
78
+ }, [client]);
79
+ const register = useCallback2(async (data) => {
80
+ setLoading(true);
81
+ setError(null);
82
+ try {
83
+ const response = await client.auth.register(data);
84
+ setUser(response.user);
85
+ return response;
86
+ } catch (err) {
87
+ const error2 = err instanceof Error ? err : new Error("Registration failed");
88
+ setError(error2);
89
+ throw error2;
90
+ } finally {
91
+ setLoading(false);
92
+ }
93
+ }, [client]);
94
+ const logout = useCallback2(async () => {
95
+ setLoading(true);
96
+ try {
97
+ await client.auth.logout();
98
+ } finally {
99
+ setUser(null);
100
+ setLoading(false);
101
+ }
102
+ }, [client]);
103
+ const getProfile = useCallback2(async () => {
104
+ const profile = await client.auth.me();
105
+ setUser(profile);
106
+ return profile;
107
+ }, [client]);
108
+ const updateProfile = useCallback2(async (data) => {
109
+ const profile = await client.auth.updateProfile(data);
110
+ setUser(profile);
111
+ return profile;
112
+ }, [client]);
113
+ const forgotPassword = useCallback2(async (email) => {
114
+ return await client.auth.forgotPassword({ email });
115
+ }, [client]);
116
+ const resetPassword = useCallback2(async (data) => {
117
+ return await client.auth.resetPassword(data);
118
+ }, [client]);
119
+ const refresh = useCallback2(async () => {
120
+ await fetchProfile();
121
+ }, [fetchProfile]);
122
+ return {
123
+ user,
124
+ isAuthenticated,
125
+ loading,
126
+ error,
127
+ login,
128
+ register,
129
+ logout,
130
+ getProfile,
131
+ updateProfile,
132
+ forgotPassword,
133
+ resetPassword,
134
+ refresh
135
+ };
136
+ }
137
+
138
+ // src/hooks/useSocialAuth.ts
139
+ import { useState as useState3, useEffect as useEffect3, useCallback as useCallback3 } from "react";
140
+ function useSocialAuth() {
141
+ const client = useClient();
142
+ const [providers, setProviders] = useState3([]);
143
+ const [loading, setLoading] = useState3(true);
144
+ const [error, setError] = useState3(null);
145
+ const fetchProviders = useCallback3(async () => {
146
+ setLoading(true);
147
+ setError(null);
148
+ try {
149
+ const data = await client.auth.getSocialProviders();
150
+ setProviders(data);
151
+ } catch (err) {
152
+ setError(err instanceof Error ? err : new Error("Failed to fetch providers"));
153
+ } finally {
154
+ setLoading(false);
155
+ }
156
+ }, [client]);
157
+ useEffect3(() => {
158
+ fetchProviders();
159
+ }, [fetchProviders]);
160
+ const getAuthUrl = useCallback3(async (provider) => {
161
+ const result = await client.auth.getSocialAuthUrl(provider);
162
+ return result.url;
163
+ }, [client]);
164
+ const handleCallback = useCallback3(async (provider, code) => {
165
+ return await client.auth.socialCallback(provider, code);
166
+ }, [client]);
167
+ return {
168
+ providers,
169
+ loading,
170
+ error,
171
+ getAuthUrl,
172
+ handleCallback,
173
+ refresh: fetchProviders
174
+ };
175
+ }
176
+
177
+ // src/hooks/useCart.ts
178
+ import { useState as useState4, useEffect as useEffect4, useCallback as useCallback4 } from "react";
179
+ function useCart() {
180
+ const client = useClient();
181
+ const [cart, setCart] = useState4(null);
182
+ const [loading, setLoading] = useState4(true);
183
+ const [error, setError] = useState4(null);
184
+ const fetchCart = useCallback4(async () => {
185
+ try {
186
+ const cartData = await client.shop.getCart();
187
+ setCart(cartData);
188
+ setError(null);
189
+ } catch (err) {
190
+ setCart(null);
191
+ setError(err instanceof Error ? err : new Error("Failed to fetch cart"));
192
+ } finally {
193
+ setLoading(false);
194
+ }
195
+ }, [client]);
196
+ useEffect4(() => {
197
+ fetchCart();
198
+ }, [fetchCart]);
199
+ const addToCart = useCallback4(async (productId, quantity = 1, variantId, options) => {
200
+ const data = {
201
+ product_id: productId,
202
+ quantity,
203
+ variant_id: variantId,
204
+ options
205
+ };
206
+ const updatedCart = await client.shop.addToCart(data);
207
+ setCart(updatedCart);
208
+ return updatedCart;
209
+ }, [client]);
210
+ const updateItem = useCallback4(async (itemId, quantity) => {
211
+ const updatedCart = await client.shop.updateCartItem(itemId, { quantity });
212
+ setCart(updatedCart);
213
+ return updatedCart;
214
+ }, [client]);
215
+ const removeItem = useCallback4(async (itemId) => {
216
+ const updatedCart = await client.shop.removeFromCart(itemId);
217
+ setCart(updatedCart);
218
+ return updatedCart;
219
+ }, [client]);
220
+ const clearCart = useCallback4(async () => {
221
+ await client.shop.clearCart();
222
+ setCart(null);
223
+ }, [client]);
224
+ const refresh = useCallback4(async () => {
225
+ setLoading(true);
226
+ await fetchCart();
227
+ }, [fetchCart]);
228
+ const isInCart = useCallback4((productId, variantId) => {
229
+ if (!cart?.items) return false;
230
+ return cart.items.some(
231
+ (item) => item.product_id === productId && (variantId === void 0 || item.variant_id === variantId)
232
+ );
233
+ }, [cart]);
234
+ const getItemQuantity = useCallback4((productId, variantId) => {
235
+ if (!cart?.items) return 0;
236
+ const item = cart.items.find(
237
+ (item2) => item2.product_id === productId && (variantId === void 0 || item2.variant_id === variantId)
238
+ );
239
+ return item?.quantity ?? 0;
240
+ }, [cart]);
241
+ return {
242
+ cart,
243
+ items: cart?.items ?? [],
244
+ itemCount: cart?.item_count ?? 0,
245
+ totalQuantity: cart?.total_quantity ?? 0,
246
+ subtotal: cart?.subtotal ?? 0,
247
+ shippingFee: cart?.shipping_fee ?? 0,
248
+ total: cart?.total ?? 0,
249
+ loading,
250
+ error,
251
+ addToCart,
252
+ updateItem,
253
+ removeItem,
254
+ clearCart,
255
+ refresh,
256
+ isInCart,
257
+ getItemQuantity
258
+ };
259
+ }
260
+
261
+ // src/hooks/useWishlist.ts
262
+ import { useState as useState5, useEffect as useEffect5, useCallback as useCallback5 } from "react";
263
+ function useWishlist() {
264
+ const client = useClient();
265
+ const [items, setItems] = useState5([]);
266
+ const [loading, setLoading] = useState5(true);
267
+ const [error, setError] = useState5(null);
268
+ const [wishlistMap, setWishlistMap] = useState5({});
269
+ const fetchWishlist = useCallback5(async () => {
270
+ if (!client.isAuthenticated()) {
271
+ setItems([]);
272
+ setWishlistMap({});
273
+ setLoading(false);
274
+ return;
275
+ }
276
+ try {
277
+ const response = await client.shop.getWishlist({ per_page: 100 });
278
+ setItems(response.data);
279
+ const map = {};
280
+ response.data.forEach((item) => {
281
+ const key = item.variant_id ? `${item.product_id}_${item.variant_id}` : String(item.product_id);
282
+ map[key] = true;
283
+ });
284
+ setWishlistMap(map);
285
+ setError(null);
286
+ } catch (err) {
287
+ setItems([]);
288
+ setWishlistMap({});
289
+ setError(err instanceof Error ? err : new Error("Failed to fetch wishlist"));
290
+ } finally {
291
+ setLoading(false);
292
+ }
293
+ }, [client]);
294
+ useEffect5(() => {
295
+ fetchWishlist();
296
+ }, [fetchWishlist]);
297
+ const isInWishlist = useCallback5((productId, variantId) => {
298
+ const key = variantId ? `${productId}_${variantId}` : String(productId);
299
+ return wishlistMap[key] || false;
300
+ }, [wishlistMap]);
301
+ const toggleWishlist = useCallback5(async (productId, variantId) => {
302
+ const result = await client.shop.toggleWishlist(productId, variantId);
303
+ const key = variantId ? `${productId}_${variantId}` : String(productId);
304
+ setWishlistMap((prev) => ({
305
+ ...prev,
306
+ [key]: result.in_wishlist
307
+ }));
308
+ if (result.action === "added") {
309
+ await fetchWishlist();
310
+ } else {
311
+ setItems((prev) => prev.filter(
312
+ (item) => !(item.product_id === productId && item.variant_id === variantId)
313
+ ));
314
+ }
315
+ return result;
316
+ }, [client, fetchWishlist]);
317
+ const addToWishlist = useCallback5(async (productId, variantId, note) => {
318
+ const item = await client.shop.addToWishlist({
319
+ product_id: productId,
320
+ variant_id: variantId,
321
+ note
322
+ });
323
+ await fetchWishlist();
324
+ return item;
325
+ }, [client, fetchWishlist]);
326
+ const removeFromWishlist = useCallback5(async (wishlistId) => {
327
+ const item = items.find((i) => i.id === wishlistId);
328
+ await client.shop.removeFromWishlist(wishlistId);
329
+ if (item) {
330
+ const key = item.variant_id ? `${item.product_id}_${item.variant_id}` : String(item.product_id);
331
+ setWishlistMap((prev) => {
332
+ const next = { ...prev };
333
+ delete next[key];
334
+ return next;
335
+ });
336
+ }
337
+ setItems((prev) => prev.filter((i) => i.id !== wishlistId));
338
+ }, [client, items]);
339
+ const moveToCart = useCallback5(async (wishlistIds) => {
340
+ const result = await client.shop.moveWishlistToCart(wishlistIds);
341
+ await fetchWishlist();
342
+ return result;
343
+ }, [client, fetchWishlist]);
344
+ const updateNote = useCallback5(async (wishlistId, note) => {
345
+ const item = await client.shop.updateWishlistNote(wishlistId, note);
346
+ setItems((prev) => prev.map((i) => i.id === wishlistId ? item : i));
347
+ return item;
348
+ }, [client]);
349
+ const getProductWishlistCount = useCallback5(async (productSlug) => {
350
+ return await client.shop.getProductWishlistCount(productSlug);
351
+ }, [client]);
352
+ const refresh = useCallback5(async () => {
353
+ setLoading(true);
354
+ await fetchWishlist();
355
+ }, [fetchWishlist]);
356
+ return {
357
+ items,
358
+ count: items.length,
359
+ loading,
360
+ error,
361
+ isInWishlist,
362
+ toggleWishlist,
363
+ addToWishlist,
364
+ removeFromWishlist,
365
+ moveToCart,
366
+ updateNote,
367
+ getProductWishlistCount,
368
+ refresh
369
+ };
370
+ }
371
+
372
+ // src/hooks/useProducts.ts
373
+ import { useState as useState6, useEffect as useEffect6, useCallback as useCallback6 } from "react";
374
+ function useProducts(options = {}) {
375
+ const { autoFetch = true, ...params } = options;
376
+ const client = useClient();
377
+ const [products, setProducts] = useState6([]);
378
+ const [meta, setMeta] = useState6(null);
379
+ const [loading, setLoading] = useState6(autoFetch);
380
+ const [error, setError] = useState6(null);
381
+ const [currentParams, setCurrentParams] = useState6(params);
382
+ const fetchProducts = useCallback6(async (fetchParams, append = false) => {
383
+ setLoading(true);
384
+ setError(null);
385
+ try {
386
+ const response = await client.shop.listProducts(fetchParams);
387
+ if (append) {
388
+ setProducts((prev) => [...prev, ...response.data]);
389
+ } else {
390
+ setProducts(response.data);
391
+ }
392
+ setMeta(response.meta);
393
+ } catch (err) {
394
+ setError(err instanceof Error ? err : new Error("Failed to fetch products"));
395
+ } finally {
396
+ setLoading(false);
397
+ }
398
+ }, [client]);
399
+ useEffect6(() => {
400
+ if (autoFetch) {
401
+ fetchProducts(params);
402
+ }
403
+ }, []);
404
+ const hasMore = meta ? meta.current_page < meta.last_page : false;
405
+ const loadMore = useCallback6(async () => {
406
+ if (!hasMore || loading) return;
407
+ const nextPage = (meta?.current_page ?? 0) + 1;
408
+ await fetchProducts({ ...currentParams, page: nextPage }, true);
409
+ }, [hasMore, loading, meta, currentParams, fetchProducts]);
410
+ const refresh = useCallback6(async () => {
411
+ setCurrentParams(params);
412
+ await fetchProducts(params);
413
+ }, [params, fetchProducts]);
414
+ const search = useCallback6(async (query) => {
415
+ const searchParams = { ...params, search: query, page: 1 };
416
+ setCurrentParams(searchParams);
417
+ await fetchProducts(searchParams);
418
+ }, [params, fetchProducts]);
419
+ return {
420
+ products,
421
+ meta,
422
+ loading,
423
+ error,
424
+ hasMore,
425
+ loadMore,
426
+ refresh,
427
+ search
428
+ };
429
+ }
430
+ function useProduct(idOrSlug) {
431
+ const client = useClient();
432
+ const [product, setProduct] = useState6(null);
433
+ const [loading, setLoading] = useState6(true);
434
+ const [error, setError] = useState6(null);
435
+ const fetchProduct = useCallback6(async () => {
436
+ setLoading(true);
437
+ setError(null);
438
+ try {
439
+ const data = await client.shop.getProduct(idOrSlug);
440
+ setProduct(data);
441
+ } catch (err) {
442
+ setError(err instanceof Error ? err : new Error("Failed to fetch product"));
443
+ } finally {
444
+ setLoading(false);
445
+ }
446
+ }, [client, idOrSlug]);
447
+ useEffect6(() => {
448
+ fetchProduct();
449
+ }, [fetchProduct]);
450
+ return {
451
+ product,
452
+ loading,
453
+ error,
454
+ refresh: fetchProduct
455
+ };
456
+ }
457
+ function useCategories() {
458
+ const client = useClient();
459
+ const [categories, setCategories] = useState6([]);
460
+ const [loading, setLoading] = useState6(true);
461
+ const [error, setError] = useState6(null);
462
+ const fetchCategories = useCallback6(async () => {
463
+ setLoading(true);
464
+ setError(null);
465
+ try {
466
+ const response = await client.shop.listCategories();
467
+ setCategories(response.data);
468
+ } catch (err) {
469
+ setError(err instanceof Error ? err : new Error("Failed to fetch categories"));
470
+ } finally {
471
+ setLoading(false);
472
+ }
473
+ }, [client]);
474
+ useEffect6(() => {
475
+ fetchCategories();
476
+ }, [fetchCategories]);
477
+ return {
478
+ categories,
479
+ loading,
480
+ error,
481
+ refresh: fetchCategories
482
+ };
483
+ }
484
+ function useFeaturedProducts(limit = 8) {
485
+ const client = useClient();
486
+ const [products, setProducts] = useState6([]);
487
+ const [loading, setLoading] = useState6(true);
488
+ const [error, setError] = useState6(null);
489
+ const fetchProducts = useCallback6(async () => {
490
+ setLoading(true);
491
+ setError(null);
492
+ try {
493
+ const data = await client.shop.featuredProducts(limit);
494
+ setProducts(data);
495
+ } catch (err) {
496
+ setError(err instanceof Error ? err : new Error("Failed to fetch featured products"));
497
+ } finally {
498
+ setLoading(false);
499
+ }
500
+ }, [client, limit]);
501
+ useEffect6(() => {
502
+ fetchProducts();
503
+ }, [fetchProducts]);
504
+ return {
505
+ products,
506
+ loading,
507
+ error,
508
+ refresh: fetchProducts
509
+ };
510
+ }
511
+ function useProductsByType(type, params) {
512
+ const client = useClient();
513
+ const [products, setProducts] = useState6([]);
514
+ const [meta, setMeta] = useState6(null);
515
+ const [loading, setLoading] = useState6(true);
516
+ const [error, setError] = useState6(null);
517
+ const fetchProducts = useCallback6(async () => {
518
+ setLoading(true);
519
+ setError(null);
520
+ try {
521
+ const response = await client.shop.listProductsByType(type, params);
522
+ setProducts(response.data);
523
+ setMeta(response.meta);
524
+ } catch (err) {
525
+ setError(err instanceof Error ? err : new Error("Failed to fetch products"));
526
+ } finally {
527
+ setLoading(false);
528
+ }
529
+ }, [client, type, params]);
530
+ useEffect6(() => {
531
+ fetchProducts();
532
+ }, [fetchProducts]);
533
+ return {
534
+ products,
535
+ meta,
536
+ loading,
537
+ error,
538
+ refresh: fetchProducts
539
+ };
540
+ }
541
+ function useDigitalProducts(params) {
542
+ return useProductsByType("digital", params);
543
+ }
544
+ function useSubscriptionProducts(params) {
545
+ return useProductsByType("subscription", params);
546
+ }
547
+ function useBundleProducts(params) {
548
+ return useProductsByType("bundle", params);
549
+ }
550
+ function useBundleItems(productSlug) {
551
+ const client = useClient();
552
+ const [bundle, setBundle] = useState6(null);
553
+ const [loading, setLoading] = useState6(true);
554
+ const [error, setError] = useState6(null);
555
+ const fetchBundle = useCallback6(async () => {
556
+ setLoading(true);
557
+ setError(null);
558
+ try {
559
+ const data = await client.shop.getBundleItems(productSlug);
560
+ setBundle(data);
561
+ } catch (err) {
562
+ setError(err instanceof Error ? err : new Error("Failed to fetch bundle items"));
563
+ } finally {
564
+ setLoading(false);
565
+ }
566
+ }, [client, productSlug]);
567
+ useEffect6(() => {
568
+ fetchBundle();
569
+ }, [fetchBundle]);
570
+ return {
571
+ bundle,
572
+ loading,
573
+ error,
574
+ refresh: fetchBundle
575
+ };
576
+ }
577
+
578
+ // src/hooks/useOrders.ts
579
+ import { useState as useState7, useEffect as useEffect7, useCallback as useCallback7 } from "react";
580
+ function useOrders(params) {
581
+ const client = useClient();
582
+ const [orders, setOrders] = useState7([]);
583
+ const [meta, setMeta] = useState7(null);
584
+ const [loading, setLoading] = useState7(true);
585
+ const [error, setError] = useState7(null);
586
+ const fetchOrders = useCallback7(async (fetchParams, append = false) => {
587
+ if (!client.isAuthenticated()) {
588
+ setOrders([]);
589
+ setLoading(false);
590
+ return;
591
+ }
592
+ setLoading(true);
593
+ setError(null);
594
+ try {
595
+ const response = await client.shop.listOrders(fetchParams);
596
+ if (append) {
597
+ setOrders((prev) => [...prev, ...response.data]);
598
+ } else {
599
+ setOrders(response.data);
600
+ }
601
+ setMeta(response.meta);
602
+ } catch (err) {
603
+ setError(err instanceof Error ? err : new Error("Failed to fetch orders"));
604
+ } finally {
605
+ setLoading(false);
606
+ }
607
+ }, [client]);
608
+ useEffect7(() => {
609
+ fetchOrders(params);
610
+ }, []);
611
+ const hasMore = meta ? meta.current_page < meta.last_page : false;
612
+ const loadMore = useCallback7(async () => {
613
+ if (!hasMore || loading) return;
614
+ const nextPage = (meta?.current_page ?? 0) + 1;
615
+ await fetchOrders({ ...params, page: nextPage }, true);
616
+ }, [hasMore, loading, meta, params, fetchOrders]);
617
+ const refresh = useCallback7(async () => {
618
+ await fetchOrders(params);
619
+ }, [params, fetchOrders]);
620
+ return {
621
+ orders,
622
+ meta,
623
+ loading,
624
+ error,
625
+ hasMore,
626
+ loadMore,
627
+ refresh
628
+ };
629
+ }
630
+ function useOrder(idOrNumber) {
631
+ const client = useClient();
632
+ const [order, setOrder] = useState7(null);
633
+ const [loading, setLoading] = useState7(true);
634
+ const [error, setError] = useState7(null);
635
+ const fetchOrder = useCallback7(async () => {
636
+ setLoading(true);
637
+ setError(null);
638
+ try {
639
+ const data = await client.shop.getOrder(idOrNumber);
640
+ setOrder(data);
641
+ } catch (err) {
642
+ setError(err instanceof Error ? err : new Error("Failed to fetch order"));
643
+ } finally {
644
+ setLoading(false);
645
+ }
646
+ }, [client, idOrNumber]);
647
+ useEffect7(() => {
648
+ fetchOrder();
649
+ }, [fetchOrder]);
650
+ const cancel = useCallback7(async () => {
651
+ if (!order) throw new Error("Order not loaded");
652
+ const cancelled = await client.shop.cancelOrder(order.id);
653
+ setOrder(cancelled);
654
+ return cancelled;
655
+ }, [client, order]);
656
+ return {
657
+ order,
658
+ loading,
659
+ error,
660
+ cancel,
661
+ refresh: fetchOrder
662
+ };
663
+ }
664
+ function useCreateOrder() {
665
+ const client = useClient();
666
+ const [loading, setLoading] = useState7(false);
667
+ const [error, setError] = useState7(null);
668
+ const createOrder = useCallback7(async (data) => {
669
+ setLoading(true);
670
+ setError(null);
671
+ try {
672
+ return await client.shop.createOrder(data);
673
+ } catch (err) {
674
+ const error2 = err instanceof Error ? err : new Error("Failed to create order");
675
+ setError(error2);
676
+ throw error2;
677
+ } finally {
678
+ setLoading(false);
679
+ }
680
+ }, [client]);
681
+ return {
682
+ createOrder,
683
+ loading,
684
+ error
685
+ };
686
+ }
687
+
688
+ // src/hooks/usePayment.ts
689
+ import { useState as useState8, useCallback as useCallback8 } from "react";
690
+ function usePaymentStatus() {
691
+ const client = useClient();
692
+ const [status, setStatus] = useState8(null);
693
+ const [loading, setLoading] = useState8(true);
694
+ const [error, setError] = useState8(null);
695
+ const fetchStatus = useCallback8(async () => {
696
+ setLoading(true);
697
+ setError(null);
698
+ try {
699
+ const data = await client.shop.getPaymentStatus();
700
+ setStatus(data);
701
+ } catch (err) {
702
+ setError(err instanceof Error ? err : new Error("Failed to fetch payment status"));
703
+ } finally {
704
+ setLoading(false);
705
+ }
706
+ }, [client]);
707
+ return {
708
+ status,
709
+ loading,
710
+ error,
711
+ refresh: fetchStatus,
712
+ isTossAvailable: status?.toss?.available ?? false,
713
+ isStripeAvailable: status?.stripe?.available ?? false,
714
+ stripePublishableKey: status?.stripe?.publishable_key ?? null
715
+ };
716
+ }
717
+ function useTossPayment() {
718
+ const client = useClient();
719
+ const [loading, setLoading] = useState8(false);
720
+ const [error, setError] = useState8(null);
721
+ const preparePayment = useCallback8(async (orderNumber, successUrl, failUrl) => {
722
+ setLoading(true);
723
+ setError(null);
724
+ try {
725
+ return await client.shop.tossPaymentReady({
726
+ order_number: orderNumber,
727
+ success_url: successUrl,
728
+ fail_url: failUrl
729
+ });
730
+ } catch (err) {
731
+ const error2 = err instanceof Error ? err : new Error("Failed to prepare payment");
732
+ setError(error2);
733
+ throw error2;
734
+ } finally {
735
+ setLoading(false);
736
+ }
737
+ }, [client]);
738
+ const confirmPayment = useCallback8(async (paymentKey, orderId, amount) => {
739
+ setLoading(true);
740
+ setError(null);
741
+ try {
742
+ return await client.shop.tossPaymentConfirm({
743
+ payment_key: paymentKey,
744
+ order_id: orderId,
745
+ amount
746
+ });
747
+ } catch (err) {
748
+ const error2 = err instanceof Error ? err : new Error("Failed to confirm payment");
749
+ setError(error2);
750
+ throw error2;
751
+ } finally {
752
+ setLoading(false);
753
+ }
754
+ }, [client]);
755
+ const cancelPayment = useCallback8(async (orderNumber, reason, amount) => {
756
+ setLoading(true);
757
+ setError(null);
758
+ try {
759
+ await client.shop.tossPaymentCancel(orderNumber, reason, amount);
760
+ } catch (err) {
761
+ const error2 = err instanceof Error ? err : new Error("Failed to cancel payment");
762
+ setError(error2);
763
+ throw error2;
764
+ } finally {
765
+ setLoading(false);
766
+ }
767
+ }, [client]);
768
+ return {
769
+ preparePayment,
770
+ confirmPayment,
771
+ cancelPayment,
772
+ loading,
773
+ error
774
+ };
775
+ }
776
+ function useStripePayment() {
777
+ const client = useClient();
778
+ const [loading, setLoading] = useState8(false);
779
+ const [error, setError] = useState8(null);
780
+ const createCheckout = useCallback8(async (orderNumber, successUrl, cancelUrl) => {
781
+ setLoading(true);
782
+ setError(null);
783
+ try {
784
+ return await client.shop.stripeCheckout({
785
+ order_number: orderNumber,
786
+ success_url: successUrl,
787
+ cancel_url: cancelUrl
788
+ });
789
+ } catch (err) {
790
+ const error2 = err instanceof Error ? err : new Error("Failed to create checkout");
791
+ setError(error2);
792
+ throw error2;
793
+ } finally {
794
+ setLoading(false);
795
+ }
796
+ }, [client]);
797
+ const verifyPayment = useCallback8(async (sessionId) => {
798
+ setLoading(true);
799
+ setError(null);
800
+ try {
801
+ return await client.shop.stripeVerify({ session_id: sessionId });
802
+ } catch (err) {
803
+ const error2 = err instanceof Error ? err : new Error("Failed to verify payment");
804
+ setError(error2);
805
+ throw error2;
806
+ } finally {
807
+ setLoading(false);
808
+ }
809
+ }, [client]);
810
+ const refund = useCallback8(async (orderNumber, reason, amount) => {
811
+ setLoading(true);
812
+ setError(null);
813
+ try {
814
+ await client.shop.stripeRefund(orderNumber, reason, amount);
815
+ } catch (err) {
816
+ const error2 = err instanceof Error ? err : new Error("Failed to refund");
817
+ setError(error2);
818
+ throw error2;
819
+ } finally {
820
+ setLoading(false);
821
+ }
822
+ }, [client]);
823
+ return {
824
+ createCheckout,
825
+ verifyPayment,
826
+ refund,
827
+ loading,
828
+ error
829
+ };
830
+ }
831
+
832
+ // src/hooks/useCoupons.ts
833
+ import { useState as useState9, useEffect as useEffect8, useCallback as useCallback9 } from "react";
834
+ function useCoupons() {
835
+ const client = useClient();
836
+ const [coupons, setCoupons] = useState9([]);
837
+ const [loading, setLoading] = useState9(true);
838
+ const [error, setError] = useState9(null);
839
+ const fetchCoupons = useCallback9(async () => {
840
+ if (!client.isAuthenticated()) {
841
+ setCoupons([]);
842
+ setLoading(false);
843
+ return;
844
+ }
845
+ setLoading(true);
846
+ setError(null);
847
+ try {
848
+ const data = await client.shop.myCoupons();
849
+ setCoupons(data);
850
+ } catch (err) {
851
+ setError(err instanceof Error ? err : new Error("Failed to fetch coupons"));
852
+ } finally {
853
+ setLoading(false);
854
+ }
855
+ }, [client]);
856
+ useEffect8(() => {
857
+ fetchCoupons();
858
+ }, [fetchCoupons]);
859
+ return {
860
+ coupons,
861
+ loading,
862
+ error,
863
+ refresh: fetchCoupons
864
+ };
865
+ }
866
+ function useValidateCoupon() {
867
+ const client = useClient();
868
+ const [validation, setValidation] = useState9(null);
869
+ const [loading, setLoading] = useState9(false);
870
+ const [error, setError] = useState9(null);
871
+ const validate = useCallback9(async (code, orderAmount) => {
872
+ setLoading(true);
873
+ setError(null);
874
+ try {
875
+ const result = await client.shop.validateCoupon(code, orderAmount);
876
+ setValidation(result);
877
+ return result;
878
+ } catch (err) {
879
+ const error2 = err instanceof Error ? err : new Error("Failed to validate coupon");
880
+ setError(error2);
881
+ setValidation({ valid: false, message: error2.message });
882
+ throw error2;
883
+ } finally {
884
+ setLoading(false);
885
+ }
886
+ }, [client]);
887
+ const reset = useCallback9(() => {
888
+ setValidation(null);
889
+ setError(null);
890
+ }, []);
891
+ return {
892
+ validate,
893
+ validation,
894
+ loading,
895
+ error,
896
+ reset
897
+ };
898
+ }
899
+
900
+ // src/hooks/useSubscriptions.ts
901
+ import { useState as useState10, useEffect as useEffect9, useCallback as useCallback10 } from "react";
902
+ function useSubscriptions() {
903
+ const client = useClient();
904
+ const [subscriptions, setSubscriptions] = useState10([]);
905
+ const [loading, setLoading] = useState10(true);
906
+ const [error, setError] = useState10(null);
907
+ const fetchSubscriptions = useCallback10(async () => {
908
+ if (!client.isAuthenticated()) {
909
+ setSubscriptions([]);
910
+ setLoading(false);
911
+ return;
912
+ }
913
+ setLoading(true);
914
+ setError(null);
915
+ try {
916
+ const data = await client.shop.getSubscriptions();
917
+ setSubscriptions(data);
918
+ } catch (err) {
919
+ setError(err instanceof Error ? err : new Error("Failed to fetch subscriptions"));
920
+ } finally {
921
+ setLoading(false);
922
+ }
923
+ }, [client]);
924
+ useEffect9(() => {
925
+ fetchSubscriptions();
926
+ }, [fetchSubscriptions]);
927
+ const activeSubscription = subscriptions.find((s) => s.is_active) ?? null;
928
+ const hasActiveSubscription = !!activeSubscription;
929
+ return {
930
+ subscriptions,
931
+ loading,
932
+ error,
933
+ activeSubscription,
934
+ hasActiveSubscription,
935
+ refresh: fetchSubscriptions
936
+ };
937
+ }
938
+ function useSubscription(id) {
939
+ const client = useClient();
940
+ const [subscription, setSubscription] = useState10(null);
941
+ const [loading, setLoading] = useState10(true);
942
+ const [error, setError] = useState10(null);
943
+ const fetchSubscription = useCallback10(async () => {
944
+ setLoading(true);
945
+ setError(null);
946
+ try {
947
+ const data = await client.shop.getSubscription(id);
948
+ setSubscription(data);
949
+ } catch (err) {
950
+ setError(err instanceof Error ? err : new Error("Failed to fetch subscription"));
951
+ } finally {
952
+ setLoading(false);
953
+ }
954
+ }, [client, id]);
955
+ useEffect9(() => {
956
+ fetchSubscription();
957
+ }, [fetchSubscription]);
958
+ const cancel = useCallback10(async (immediately = false) => {
959
+ const updated = await client.shop.cancelSubscription(id, immediately);
960
+ setSubscription(updated);
961
+ return updated;
962
+ }, [client, id]);
963
+ const pause = useCallback10(async () => {
964
+ const updated = await client.shop.pauseSubscription(id);
965
+ setSubscription(updated);
966
+ return updated;
967
+ }, [client, id]);
968
+ const resume = useCallback10(async () => {
969
+ const updated = await client.shop.resumeSubscription(id);
970
+ setSubscription(updated);
971
+ return updated;
972
+ }, [client, id]);
973
+ return {
974
+ subscription,
975
+ loading,
976
+ error,
977
+ cancel,
978
+ pause,
979
+ resume,
980
+ refresh: fetchSubscription
981
+ };
982
+ }
983
+ function useCreateSubscription() {
984
+ const client = useClient();
985
+ const [loading, setLoading] = useState10(false);
986
+ const [error, setError] = useState10(null);
987
+ const createCheckout = useCallback10(async (planId, successUrl, cancelUrl) => {
988
+ setLoading(true);
989
+ setError(null);
990
+ try {
991
+ return await client.shop.createSubscriptionCheckout({
992
+ plan_id: planId,
993
+ success_url: successUrl,
994
+ cancel_url: cancelUrl
995
+ });
996
+ } catch (err) {
997
+ const error2 = err instanceof Error ? err : new Error("Failed to create checkout");
998
+ setError(error2);
999
+ throw error2;
1000
+ } finally {
1001
+ setLoading(false);
1002
+ }
1003
+ }, [client]);
1004
+ const verifyCheckout = useCallback10(async (sessionId) => {
1005
+ setLoading(true);
1006
+ setError(null);
1007
+ try {
1008
+ const result = await client.shop.verifySubscriptionCheckout(sessionId);
1009
+ return result.subscription;
1010
+ } catch (err) {
1011
+ const error2 = err instanceof Error ? err : new Error("Failed to verify checkout");
1012
+ setError(error2);
1013
+ throw error2;
1014
+ } finally {
1015
+ setLoading(false);
1016
+ }
1017
+ }, [client]);
1018
+ const createSetupIntent = useCallback10(async () => {
1019
+ setLoading(true);
1020
+ setError(null);
1021
+ try {
1022
+ const result = await client.shop.createSetupIntent();
1023
+ return result.client_secret;
1024
+ } catch (err) {
1025
+ const error2 = err instanceof Error ? err : new Error("Failed to create setup intent");
1026
+ setError(error2);
1027
+ throw error2;
1028
+ } finally {
1029
+ setLoading(false);
1030
+ }
1031
+ }, [client]);
1032
+ return {
1033
+ createCheckout,
1034
+ verifyCheckout,
1035
+ createSetupIntent,
1036
+ loading,
1037
+ error
1038
+ };
1039
+ }
1040
+
1041
+ // src/hooks/useDownloads.ts
1042
+ import { useState as useState11, useEffect as useEffect10, useCallback as useCallback11 } from "react";
1043
+ function useDownloads() {
1044
+ const client = useClient();
1045
+ const [downloads, setDownloads] = useState11([]);
1046
+ const [loading, setLoading] = useState11(true);
1047
+ const [error, setError] = useState11(null);
1048
+ const fetchDownloads = useCallback11(async () => {
1049
+ if (!client.isAuthenticated()) {
1050
+ setDownloads([]);
1051
+ setLoading(false);
1052
+ return;
1053
+ }
1054
+ setLoading(true);
1055
+ setError(null);
1056
+ try {
1057
+ const data = await client.shop.getMyDownloads();
1058
+ setDownloads(data);
1059
+ } catch (err) {
1060
+ setError(err instanceof Error ? err : new Error("Failed to fetch downloads"));
1061
+ } finally {
1062
+ setLoading(false);
1063
+ }
1064
+ }, [client]);
1065
+ useEffect10(() => {
1066
+ fetchDownloads();
1067
+ }, [fetchDownloads]);
1068
+ const getDownloadUrl = useCallback11((token) => {
1069
+ return client.shop.getDownloadUrl(token);
1070
+ }, [client]);
1071
+ const getDownloadInfo = useCallback11(async (token) => {
1072
+ return await client.shop.getDownloadInfo(token);
1073
+ }, [client]);
1074
+ return {
1075
+ downloads,
1076
+ loading,
1077
+ error,
1078
+ getDownloadUrl,
1079
+ getDownloadInfo,
1080
+ refresh: fetchDownloads
1081
+ };
1082
+ }
1083
+ function useOrderDownloads(orderNumber) {
1084
+ const client = useClient();
1085
+ const [downloads, setDownloads] = useState11([]);
1086
+ const [loading, setLoading] = useState11(true);
1087
+ const [error, setError] = useState11(null);
1088
+ const fetchDownloads = useCallback11(async () => {
1089
+ if (!client.isAuthenticated()) {
1090
+ setDownloads([]);
1091
+ setLoading(false);
1092
+ return;
1093
+ }
1094
+ setLoading(true);
1095
+ setError(null);
1096
+ try {
1097
+ const data = await client.shop.getOrderDownloads(orderNumber);
1098
+ setDownloads(data);
1099
+ } catch (err) {
1100
+ setError(err instanceof Error ? err : new Error("Failed to fetch downloads"));
1101
+ } finally {
1102
+ setLoading(false);
1103
+ }
1104
+ }, [client, orderNumber]);
1105
+ useEffect10(() => {
1106
+ fetchDownloads();
1107
+ }, [fetchDownloads]);
1108
+ const getDownloadUrl = useCallback11((token) => {
1109
+ return client.shop.getDownloadUrl(token);
1110
+ }, [client]);
1111
+ const getDownloadInfo = useCallback11(async (token) => {
1112
+ return await client.shop.getDownloadInfo(token);
1113
+ }, [client]);
1114
+ return {
1115
+ downloads,
1116
+ loading,
1117
+ error,
1118
+ getDownloadUrl,
1119
+ getDownloadInfo,
1120
+ refresh: fetchDownloads
1121
+ };
1122
+ }
1123
+
1124
+ // src/hooks/useReviews.ts
1125
+ import { useState as useState12, useEffect as useEffect11, useCallback as useCallback12 } from "react";
1126
+ function useProductReviews(productSlug, params) {
1127
+ const client = useClient();
1128
+ const [reviews, setReviews] = useState12([]);
1129
+ const [stats, setStats] = useState12(null);
1130
+ const [meta, setMeta] = useState12(null);
1131
+ const [loading, setLoading] = useState12(true);
1132
+ const [error, setError] = useState12(null);
1133
+ const fetchReviews = useCallback12(async () => {
1134
+ setLoading(true);
1135
+ setError(null);
1136
+ try {
1137
+ const response = await client.shop.getProductReviews(productSlug, params);
1138
+ setReviews(response.data);
1139
+ setStats(response.stats);
1140
+ setMeta(response.meta);
1141
+ } catch (err) {
1142
+ setError(err instanceof Error ? err : new Error("Failed to fetch reviews"));
1143
+ } finally {
1144
+ setLoading(false);
1145
+ }
1146
+ }, [client, productSlug, params]);
1147
+ useEffect11(() => {
1148
+ fetchReviews();
1149
+ }, [fetchReviews]);
1150
+ return {
1151
+ reviews,
1152
+ stats,
1153
+ meta,
1154
+ loading,
1155
+ error,
1156
+ refresh: fetchReviews
1157
+ };
1158
+ }
1159
+ function useCanReview(productSlug) {
1160
+ const client = useClient();
1161
+ const [canReview, setCanReview] = useState12(false);
1162
+ const [reason, setReason] = useState12(null);
1163
+ const [loading, setLoading] = useState12(true);
1164
+ const [error, setError] = useState12(null);
1165
+ const check = useCallback12(async () => {
1166
+ setLoading(true);
1167
+ setError(null);
1168
+ try {
1169
+ const response = await client.shop.canReviewProduct(productSlug);
1170
+ setCanReview(response.can_review);
1171
+ setReason(response.reason ?? null);
1172
+ return response;
1173
+ } catch (err) {
1174
+ setError(err instanceof Error ? err : new Error("Failed to check review eligibility"));
1175
+ return { can_review: false, reason: "not_logged_in" };
1176
+ } finally {
1177
+ setLoading(false);
1178
+ }
1179
+ }, [client, productSlug]);
1180
+ useEffect11(() => {
1181
+ if (client.isAuthenticated()) {
1182
+ check();
1183
+ } else {
1184
+ setCanReview(false);
1185
+ setReason("not_logged_in");
1186
+ setLoading(false);
1187
+ }
1188
+ }, [check, client]);
1189
+ return {
1190
+ canReview,
1191
+ reason,
1192
+ loading,
1193
+ error,
1194
+ check
1195
+ };
1196
+ }
1197
+ function useCreateReview() {
1198
+ const client = useClient();
1199
+ const [loading, setLoading] = useState12(false);
1200
+ const [error, setError] = useState12(null);
1201
+ const createReview = useCallback12(async (productSlug, data) => {
1202
+ setLoading(true);
1203
+ setError(null);
1204
+ try {
1205
+ return await client.shop.createReview(productSlug, data);
1206
+ } catch (err) {
1207
+ const error2 = err instanceof Error ? err : new Error("Failed to create review");
1208
+ setError(error2);
1209
+ throw error2;
1210
+ } finally {
1211
+ setLoading(false);
1212
+ }
1213
+ }, [client]);
1214
+ return {
1215
+ createReview,
1216
+ loading,
1217
+ error
1218
+ };
1219
+ }
1220
+ function useMyReviews(params) {
1221
+ const client = useClient();
1222
+ const [reviews, setReviews] = useState12([]);
1223
+ const [meta, setMeta] = useState12(null);
1224
+ const [loading, setLoading] = useState12(true);
1225
+ const [error, setError] = useState12(null);
1226
+ const fetchReviews = useCallback12(async () => {
1227
+ if (!client.isAuthenticated()) {
1228
+ setReviews([]);
1229
+ setLoading(false);
1230
+ return;
1231
+ }
1232
+ setLoading(true);
1233
+ setError(null);
1234
+ try {
1235
+ const response = await client.shop.myReviews(params);
1236
+ setReviews(response.data);
1237
+ setMeta(response.meta);
1238
+ } catch (err) {
1239
+ setError(err instanceof Error ? err : new Error("Failed to fetch reviews"));
1240
+ } finally {
1241
+ setLoading(false);
1242
+ }
1243
+ }, [client, params]);
1244
+ useEffect11(() => {
1245
+ fetchReviews();
1246
+ }, [fetchReviews]);
1247
+ const deleteReview = useCallback12(async (reviewId) => {
1248
+ await client.shop.deleteReview(reviewId);
1249
+ setReviews((prev) => prev.filter((r) => r.id !== reviewId));
1250
+ }, [client]);
1251
+ const updateReview = useCallback12(async (reviewId, data) => {
1252
+ const updated = await client.shop.updateReview(reviewId, data);
1253
+ setReviews((prev) => prev.map((r) => r.id === reviewId ? updated : r));
1254
+ return updated;
1255
+ }, [client]);
1256
+ return {
1257
+ reviews,
1258
+ meta,
1259
+ loading,
1260
+ error,
1261
+ refresh: fetchReviews,
1262
+ deleteReview,
1263
+ updateReview
1264
+ };
1265
+ }
1266
+
1267
+ // src/hooks/useBlog.ts
1268
+ import { useState as useState13, useEffect as useEffect12, useCallback as useCallback13 } from "react";
1269
+ function useBlog(options = {}) {
1270
+ const { autoFetch = true, ...params } = options;
1271
+ const client = useClient();
1272
+ const [posts, setPosts] = useState13([]);
1273
+ const [meta, setMeta] = useState13(null);
1274
+ const [loading, setLoading] = useState13(autoFetch);
1275
+ const [error, setError] = useState13(null);
1276
+ const [currentParams, setCurrentParams] = useState13(params);
1277
+ const fetchPosts = useCallback13(async (fetchParams, append = false) => {
1278
+ setLoading(true);
1279
+ setError(null);
1280
+ try {
1281
+ const response = await client.blog.list(fetchParams);
1282
+ if (append) {
1283
+ setPosts((prev) => [...prev, ...response.data]);
1284
+ } else {
1285
+ setPosts(response.data);
1286
+ }
1287
+ setMeta(response.meta);
1288
+ } catch (err) {
1289
+ setError(err instanceof Error ? err : new Error("Failed to fetch blog posts"));
1290
+ } finally {
1291
+ setLoading(false);
1292
+ }
1293
+ }, [client]);
1294
+ useEffect12(() => {
1295
+ if (autoFetch) {
1296
+ fetchPosts(params);
1297
+ }
1298
+ }, []);
1299
+ const hasMore = meta ? meta.current_page < meta.last_page : false;
1300
+ const loadMore = useCallback13(async () => {
1301
+ if (!hasMore || loading) return;
1302
+ const nextPage = (meta?.current_page ?? 0) + 1;
1303
+ await fetchPosts({ ...currentParams, page: nextPage }, true);
1304
+ }, [hasMore, loading, meta, currentParams, fetchPosts]);
1305
+ const refresh = useCallback13(async () => {
1306
+ setCurrentParams(params);
1307
+ await fetchPosts(params);
1308
+ }, [params, fetchPosts]);
1309
+ return {
1310
+ posts,
1311
+ meta,
1312
+ loading,
1313
+ error,
1314
+ hasMore,
1315
+ loadMore,
1316
+ refresh
1317
+ };
1318
+ }
1319
+ function useBlogPost(slug) {
1320
+ const client = useClient();
1321
+ const [post, setPost] = useState13(null);
1322
+ const [loading, setLoading] = useState13(true);
1323
+ const [error, setError] = useState13(null);
1324
+ const fetchPost = useCallback13(async () => {
1325
+ setLoading(true);
1326
+ setError(null);
1327
+ try {
1328
+ const data = await client.blog.get(slug);
1329
+ setPost(data);
1330
+ } catch (err) {
1331
+ setError(err instanceof Error ? err : new Error("Failed to fetch blog post"));
1332
+ } finally {
1333
+ setLoading(false);
1334
+ }
1335
+ }, [client, slug]);
1336
+ useEffect12(() => {
1337
+ fetchPost();
1338
+ }, [fetchPost]);
1339
+ return {
1340
+ post,
1341
+ loading,
1342
+ error,
1343
+ refresh: fetchPost
1344
+ };
1345
+ }
1346
+ function useBlogCategories() {
1347
+ const client = useClient();
1348
+ const [categories, setCategories] = useState13([]);
1349
+ const [loading, setLoading] = useState13(true);
1350
+ const [error, setError] = useState13(null);
1351
+ const fetchCategories = useCallback13(async () => {
1352
+ setLoading(true);
1353
+ setError(null);
1354
+ try {
1355
+ const data = await client.blog.categories();
1356
+ setCategories(data);
1357
+ } catch (err) {
1358
+ setError(err instanceof Error ? err : new Error("Failed to fetch blog categories"));
1359
+ } finally {
1360
+ setLoading(false);
1361
+ }
1362
+ }, [client]);
1363
+ useEffect12(() => {
1364
+ fetchCategories();
1365
+ }, [fetchCategories]);
1366
+ return {
1367
+ categories,
1368
+ loading,
1369
+ error,
1370
+ refresh: fetchCategories
1371
+ };
1372
+ }
1373
+ function useBlogTags() {
1374
+ const client = useClient();
1375
+ const [tags, setTags] = useState13([]);
1376
+ const [loading, setLoading] = useState13(true);
1377
+ const [error, setError] = useState13(null);
1378
+ const fetchTags = useCallback13(async () => {
1379
+ setLoading(true);
1380
+ setError(null);
1381
+ try {
1382
+ const data = await client.blog.tags();
1383
+ setTags(data);
1384
+ } catch (err) {
1385
+ setError(err instanceof Error ? err : new Error("Failed to fetch blog tags"));
1386
+ } finally {
1387
+ setLoading(false);
1388
+ }
1389
+ }, [client]);
1390
+ useEffect12(() => {
1391
+ fetchTags();
1392
+ }, [fetchTags]);
1393
+ return {
1394
+ tags,
1395
+ loading,
1396
+ error,
1397
+ refresh: fetchTags
1398
+ };
1399
+ }
1400
+ function useFeaturedBlog(limit = 5) {
1401
+ const client = useClient();
1402
+ const [posts, setPosts] = useState13([]);
1403
+ const [loading, setLoading] = useState13(true);
1404
+ const [error, setError] = useState13(null);
1405
+ const fetchPosts = useCallback13(async () => {
1406
+ setLoading(true);
1407
+ setError(null);
1408
+ try {
1409
+ const data = await client.blog.featured(limit);
1410
+ setPosts(data);
1411
+ } catch (err) {
1412
+ setError(err instanceof Error ? err : new Error("Failed to fetch featured posts"));
1413
+ } finally {
1414
+ setLoading(false);
1415
+ }
1416
+ }, [client, limit]);
1417
+ useEffect12(() => {
1418
+ fetchPosts();
1419
+ }, [fetchPosts]);
1420
+ return {
1421
+ posts,
1422
+ loading,
1423
+ error,
1424
+ refresh: fetchPosts
1425
+ };
1426
+ }
1427
+ function useBlogSearch() {
1428
+ const client = useClient();
1429
+ const [posts, setPosts] = useState13([]);
1430
+ const [meta, setMeta] = useState13(null);
1431
+ const [loading, setLoading] = useState13(false);
1432
+ const [error, setError] = useState13(null);
1433
+ const search = useCallback13(async (query) => {
1434
+ setLoading(true);
1435
+ setError(null);
1436
+ try {
1437
+ const response = await client.blog.search(query);
1438
+ setPosts(response.data);
1439
+ setMeta(response.meta);
1440
+ } catch (err) {
1441
+ setError(err instanceof Error ? err : new Error("Failed to search posts"));
1442
+ } finally {
1443
+ setLoading(false);
1444
+ }
1445
+ }, [client]);
1446
+ return {
1447
+ posts,
1448
+ meta,
1449
+ loading,
1450
+ error,
1451
+ search
1452
+ };
1453
+ }
1454
+
1455
+ // src/hooks/useBoards.ts
1456
+ import { useState as useState14, useEffect as useEffect13, useCallback as useCallback14 } from "react";
1457
+ function useBoards(params) {
1458
+ const client = useClient();
1459
+ const [boards, setBoards] = useState14([]);
1460
+ const [loading, setLoading] = useState14(true);
1461
+ const [error, setError] = useState14(null);
1462
+ const fetchBoards = useCallback14(async () => {
1463
+ setLoading(true);
1464
+ setError(null);
1465
+ try {
1466
+ const response = await client.boards.list(params);
1467
+ setBoards(response.data);
1468
+ } catch (err) {
1469
+ setError(err instanceof Error ? err : new Error("Failed to fetch boards"));
1470
+ } finally {
1471
+ setLoading(false);
1472
+ }
1473
+ }, [client, params]);
1474
+ useEffect13(() => {
1475
+ fetchBoards();
1476
+ }, [fetchBoards]);
1477
+ return {
1478
+ boards,
1479
+ loading,
1480
+ error,
1481
+ refresh: fetchBoards
1482
+ };
1483
+ }
1484
+ function useBoard(slug) {
1485
+ const client = useClient();
1486
+ const [board, setBoard] = useState14(null);
1487
+ const [loading, setLoading] = useState14(true);
1488
+ const [error, setError] = useState14(null);
1489
+ const fetchBoard = useCallback14(async () => {
1490
+ setLoading(true);
1491
+ setError(null);
1492
+ try {
1493
+ const data = await client.boards.get(slug);
1494
+ setBoard(data);
1495
+ } catch (err) {
1496
+ setError(err instanceof Error ? err : new Error("Failed to fetch board"));
1497
+ } finally {
1498
+ setLoading(false);
1499
+ }
1500
+ }, [client, slug]);
1501
+ useEffect13(() => {
1502
+ fetchBoard();
1503
+ }, [fetchBoard]);
1504
+ return {
1505
+ board,
1506
+ loading,
1507
+ error,
1508
+ refresh: fetchBoard
1509
+ };
1510
+ }
1511
+ function useBoardPosts(boardSlug, params) {
1512
+ const client = useClient();
1513
+ const [posts, setPosts] = useState14([]);
1514
+ const [meta, setMeta] = useState14(null);
1515
+ const [loading, setLoading] = useState14(true);
1516
+ const [error, setError] = useState14(null);
1517
+ const [currentParams, setCurrentParams] = useState14(params);
1518
+ const fetchPosts = useCallback14(async (fetchParams, append = false) => {
1519
+ setLoading(true);
1520
+ setError(null);
1521
+ try {
1522
+ const response = await client.boards.listPosts(boardSlug, fetchParams);
1523
+ if (append) {
1524
+ setPosts((prev) => [...prev, ...response.data]);
1525
+ } else {
1526
+ setPosts(response.data);
1527
+ }
1528
+ setMeta(response.meta);
1529
+ } catch (err) {
1530
+ setError(err instanceof Error ? err : new Error("Failed to fetch posts"));
1531
+ } finally {
1532
+ setLoading(false);
1533
+ }
1534
+ }, [client, boardSlug]);
1535
+ useEffect13(() => {
1536
+ fetchPosts(params);
1537
+ }, []);
1538
+ const hasMore = meta ? meta.current_page < meta.last_page : false;
1539
+ const loadMore = useCallback14(async () => {
1540
+ if (!hasMore || loading) return;
1541
+ const nextPage = (meta?.current_page ?? 0) + 1;
1542
+ await fetchPosts({ ...currentParams, page: nextPage }, true);
1543
+ }, [hasMore, loading, meta, currentParams, fetchPosts]);
1544
+ const refresh = useCallback14(async () => {
1545
+ setCurrentParams(params);
1546
+ await fetchPosts(params);
1547
+ }, [params, fetchPosts]);
1548
+ return {
1549
+ posts,
1550
+ meta,
1551
+ loading,
1552
+ error,
1553
+ hasMore,
1554
+ loadMore,
1555
+ refresh
1556
+ };
1557
+ }
1558
+ function useBoardPost(postId) {
1559
+ const client = useClient();
1560
+ const [post, setPost] = useState14(null);
1561
+ const [loading, setLoading] = useState14(true);
1562
+ const [error, setError] = useState14(null);
1563
+ const fetchPost = useCallback14(async () => {
1564
+ setLoading(true);
1565
+ setError(null);
1566
+ try {
1567
+ const data = await client.boards.getPost(postId);
1568
+ setPost(data);
1569
+ } catch (err) {
1570
+ setError(err instanceof Error ? err : new Error("Failed to fetch post"));
1571
+ } finally {
1572
+ setLoading(false);
1573
+ }
1574
+ }, [client, postId]);
1575
+ useEffect13(() => {
1576
+ fetchPost();
1577
+ }, [fetchPost]);
1578
+ return {
1579
+ post,
1580
+ loading,
1581
+ error,
1582
+ refresh: fetchPost
1583
+ };
1584
+ }
1585
+ function useCreateBoardPost() {
1586
+ const client = useClient();
1587
+ const [loading, setLoading] = useState14(false);
1588
+ const [error, setError] = useState14(null);
1589
+ const createPost = useCallback14(async (data) => {
1590
+ setLoading(true);
1591
+ setError(null);
1592
+ try {
1593
+ return await client.boards.createPost(data);
1594
+ } catch (err) {
1595
+ const error2 = err instanceof Error ? err : new Error("Failed to create post");
1596
+ setError(error2);
1597
+ throw error2;
1598
+ } finally {
1599
+ setLoading(false);
1600
+ }
1601
+ }, [client]);
1602
+ return {
1603
+ createPost,
1604
+ loading,
1605
+ error
1606
+ };
1607
+ }
1608
+
1609
+ // src/hooks/useComments.ts
1610
+ import { useState as useState15, useEffect as useEffect14, useCallback as useCallback15 } from "react";
1611
+ function useComments(options) {
1612
+ const { type, target, page, per_page } = options;
1613
+ const client = useClient();
1614
+ const [comments, setComments] = useState15([]);
1615
+ const [meta, setMeta] = useState15(null);
1616
+ const [loading, setLoading] = useState15(true);
1617
+ const [error, setError] = useState15(null);
1618
+ const fetchComments = useCallback15(async () => {
1619
+ setLoading(true);
1620
+ setError(null);
1621
+ try {
1622
+ let response;
1623
+ const params = { page, per_page };
1624
+ switch (type) {
1625
+ case "board":
1626
+ response = await client.comments.boardPost(target, params);
1627
+ break;
1628
+ case "blog":
1629
+ response = await client.comments.blogPost(target, params);
1630
+ break;
1631
+ case "standalone":
1632
+ response = await client.comments.standalone(target, params);
1633
+ break;
1634
+ }
1635
+ setComments(response.data);
1636
+ setMeta(response.meta);
1637
+ } catch (err) {
1638
+ setError(err instanceof Error ? err : new Error("Failed to fetch comments"));
1639
+ } finally {
1640
+ setLoading(false);
1641
+ }
1642
+ }, [client, type, target, page, per_page]);
1643
+ useEffect14(() => {
1644
+ fetchComments();
1645
+ }, [fetchComments]);
1646
+ const createComment = useCallback15(async (data) => {
1647
+ let response;
1648
+ switch (type) {
1649
+ case "board":
1650
+ response = await client.comments.createBoardPost(target, data);
1651
+ break;
1652
+ case "blog":
1653
+ response = await client.comments.createBlogPost(target, data);
1654
+ break;
1655
+ case "standalone":
1656
+ response = await client.comments.createStandalone(target, data);
1657
+ break;
1658
+ }
1659
+ await fetchComments();
1660
+ return response.data;
1661
+ }, [client, type, target, fetchComments]);
1662
+ const updateComment = useCallback15(async (commentId, content) => {
1663
+ const response = await client.comments.update(commentId, { content });
1664
+ setComments((prev) => prev.map((c) => c.id === commentId ? response.data : c));
1665
+ return response.data;
1666
+ }, [client]);
1667
+ const deleteComment = useCallback15(async (commentId, password) => {
1668
+ await client.comments.delete(commentId, password ? { password } : void 0);
1669
+ setComments((prev) => prev.filter((c) => c.id !== commentId));
1670
+ }, [client]);
1671
+ const likeComment = useCallback15(async (commentId) => {
1672
+ const response = await client.comments.like(commentId);
1673
+ setComments((prev) => prev.map(
1674
+ (c) => c.id === commentId ? { ...c, likes: response.data.likes } : c
1675
+ ));
1676
+ return response.data.likes;
1677
+ }, [client]);
1678
+ return {
1679
+ comments,
1680
+ meta,
1681
+ loading,
1682
+ error,
1683
+ createComment,
1684
+ updateComment,
1685
+ deleteComment,
1686
+ likeComment,
1687
+ refresh: fetchComments
1688
+ };
1689
+ }
1690
+
1691
+ // src/hooks/useForms.ts
1692
+ import { useState as useState16, useEffect as useEffect15, useCallback as useCallback16 } from "react";
1693
+ function useForm(formSlug) {
1694
+ const client = useClient();
1695
+ const [form, setForm] = useState16(null);
1696
+ const [loading, setLoading] = useState16(true);
1697
+ const [error, setError] = useState16(null);
1698
+ const [submitting, setSubmitting] = useState16(false);
1699
+ const [submitted, setSubmitted] = useState16(false);
1700
+ const fetchForm = useCallback16(async () => {
1701
+ setLoading(true);
1702
+ setError(null);
1703
+ try {
1704
+ const data = await client.forms.get(formSlug);
1705
+ setForm(data);
1706
+ } catch (err) {
1707
+ setError(err instanceof Error ? err : new Error("Failed to fetch form"));
1708
+ } finally {
1709
+ setLoading(false);
1710
+ }
1711
+ }, [client, formSlug]);
1712
+ useEffect15(() => {
1713
+ fetchForm();
1714
+ }, [fetchForm]);
1715
+ const submit = useCallback16(async (data) => {
1716
+ setSubmitting(true);
1717
+ setError(null);
1718
+ try {
1719
+ const submission = await client.forms.submit(formSlug, data);
1720
+ setSubmitted(true);
1721
+ return submission;
1722
+ } catch (err) {
1723
+ const error2 = err instanceof Error ? err : new Error("Failed to submit form");
1724
+ setError(error2);
1725
+ throw error2;
1726
+ } finally {
1727
+ setSubmitting(false);
1728
+ }
1729
+ }, [client, formSlug]);
1730
+ const reset = useCallback16(() => {
1731
+ setSubmitted(false);
1732
+ setError(null);
1733
+ }, []);
1734
+ return {
1735
+ form,
1736
+ loading,
1737
+ error,
1738
+ submit,
1739
+ submitting,
1740
+ submitted,
1741
+ reset
1742
+ };
1743
+ }
1744
+
1745
+ // src/hooks/useReservation.ts
1746
+ import { useState as useState17, useEffect as useEffect16, useCallback as useCallback17 } from "react";
1747
+ function useReservationServices() {
1748
+ const client = useClient();
1749
+ const [services, setServices] = useState17([]);
1750
+ const [loading, setLoading] = useState17(true);
1751
+ const [error, setError] = useState17(null);
1752
+ const fetchServices = useCallback17(async () => {
1753
+ setLoading(true);
1754
+ setError(null);
1755
+ try {
1756
+ const data = await client.reservation.listServices();
1757
+ setServices(data);
1758
+ } catch (err) {
1759
+ setError(err instanceof Error ? err : new Error("Failed to fetch services"));
1760
+ } finally {
1761
+ setLoading(false);
1762
+ }
1763
+ }, [client]);
1764
+ useEffect16(() => {
1765
+ fetchServices();
1766
+ }, [fetchServices]);
1767
+ return {
1768
+ services,
1769
+ loading,
1770
+ error,
1771
+ refresh: fetchServices
1772
+ };
1773
+ }
1774
+ function useReservationStaffs() {
1775
+ const client = useClient();
1776
+ const [staffs, setStaffs] = useState17([]);
1777
+ const [loading, setLoading] = useState17(true);
1778
+ const [error, setError] = useState17(null);
1779
+ const fetchStaffs = useCallback17(async () => {
1780
+ setLoading(true);
1781
+ setError(null);
1782
+ try {
1783
+ const data = await client.reservation.listStaff();
1784
+ setStaffs(data);
1785
+ } catch (err) {
1786
+ setError(err instanceof Error ? err : new Error("Failed to fetch staffs"));
1787
+ } finally {
1788
+ setLoading(false);
1789
+ }
1790
+ }, [client]);
1791
+ useEffect16(() => {
1792
+ fetchStaffs();
1793
+ }, [fetchStaffs]);
1794
+ return {
1795
+ staffs,
1796
+ loading,
1797
+ error,
1798
+ refresh: fetchStaffs
1799
+ };
1800
+ }
1801
+ function useAvailableSlots(serviceId, date, staffId) {
1802
+ const client = useClient();
1803
+ const [slots, setSlots] = useState17([]);
1804
+ const [loading, setLoading] = useState17(true);
1805
+ const [error, setError] = useState17(null);
1806
+ const fetchSlots = useCallback17(async () => {
1807
+ if (!serviceId || !date) {
1808
+ setSlots([]);
1809
+ setLoading(false);
1810
+ return;
1811
+ }
1812
+ setLoading(true);
1813
+ setError(null);
1814
+ try {
1815
+ const data = await client.reservation.getAvailableSlots({
1816
+ service_id: serviceId,
1817
+ date,
1818
+ staff_id: staffId
1819
+ });
1820
+ setSlots(data);
1821
+ } catch (err) {
1822
+ setError(err instanceof Error ? err : new Error("Failed to fetch slots"));
1823
+ } finally {
1824
+ setLoading(false);
1825
+ }
1826
+ }, [client, serviceId, date, staffId]);
1827
+ useEffect16(() => {
1828
+ fetchSlots();
1829
+ }, [fetchSlots]);
1830
+ return {
1831
+ slots,
1832
+ loading,
1833
+ error,
1834
+ refresh: fetchSlots
1835
+ };
1836
+ }
1837
+ function useMyReservations(params) {
1838
+ const client = useClient();
1839
+ const [reservations, setReservations] = useState17([]);
1840
+ const [meta, setMeta] = useState17(null);
1841
+ const [loading, setLoading] = useState17(true);
1842
+ const [error, setError] = useState17(null);
1843
+ const fetchReservations = useCallback17(async () => {
1844
+ if (!client.isAuthenticated()) {
1845
+ setReservations([]);
1846
+ setLoading(false);
1847
+ return;
1848
+ }
1849
+ setLoading(true);
1850
+ setError(null);
1851
+ try {
1852
+ const response = await client.reservation.list(params);
1853
+ setReservations(response.data);
1854
+ setMeta(response.meta);
1855
+ } catch (err) {
1856
+ setError(err instanceof Error ? err : new Error("Failed to fetch reservations"));
1857
+ } finally {
1858
+ setLoading(false);
1859
+ }
1860
+ }, [client, params]);
1861
+ useEffect16(() => {
1862
+ fetchReservations();
1863
+ }, [fetchReservations]);
1864
+ return {
1865
+ reservations,
1866
+ meta,
1867
+ loading,
1868
+ error,
1869
+ refresh: fetchReservations
1870
+ };
1871
+ }
1872
+ function useCreateReservation() {
1873
+ const client = useClient();
1874
+ const [loading, setLoading] = useState17(false);
1875
+ const [error, setError] = useState17(null);
1876
+ const createReservation = useCallback17(async (data) => {
1877
+ setLoading(true);
1878
+ setError(null);
1879
+ try {
1880
+ const result = await client.reservation.create(data);
1881
+ return result.reservation;
1882
+ } catch (err) {
1883
+ const error2 = err instanceof Error ? err : new Error("Failed to create reservation");
1884
+ setError(error2);
1885
+ throw error2;
1886
+ } finally {
1887
+ setLoading(false);
1888
+ }
1889
+ }, [client]);
1890
+ return {
1891
+ createReservation,
1892
+ loading,
1893
+ error
1894
+ };
1895
+ }
1896
+ function useReservationSettings() {
1897
+ const client = useClient();
1898
+ const [settings, setSettings] = useState17(null);
1899
+ const [loading, setLoading] = useState17(true);
1900
+ const [error, setError] = useState17(null);
1901
+ const fetchSettings = useCallback17(async () => {
1902
+ setLoading(true);
1903
+ setError(null);
1904
+ try {
1905
+ const data = await client.reservation.getSettings();
1906
+ setSettings(data);
1907
+ } catch (err) {
1908
+ setError(err instanceof Error ? err : new Error("Failed to fetch settings"));
1909
+ } finally {
1910
+ setLoading(false);
1911
+ }
1912
+ }, [client]);
1913
+ useEffect16(() => {
1914
+ fetchSettings();
1915
+ }, [fetchSettings]);
1916
+ return {
1917
+ settings,
1918
+ loading,
1919
+ error,
1920
+ refresh: fetchSettings
1921
+ };
1922
+ }
1923
+
1924
+ // src/hooks/useMedia.ts
1925
+ import { useState as useState18, useEffect as useEffect17, useCallback as useCallback18 } from "react";
1926
+ function useMedia(options = {}) {
1927
+ const { type, page, per_page, autoFetch = true } = options;
1928
+ const client = useClient();
1929
+ const [files, setFiles] = useState18([]);
1930
+ const [meta, setMeta] = useState18(null);
1931
+ const [loading, setLoading] = useState18(autoFetch);
1932
+ const [error, setError] = useState18(null);
1933
+ const [uploading, setUploading] = useState18(false);
1934
+ const [uploadProgress, setUploadProgress] = useState18(0);
1935
+ const fetchMedia = useCallback18(async () => {
1936
+ if (!client.isAuthenticated()) {
1937
+ setFiles([]);
1938
+ setLoading(false);
1939
+ return;
1940
+ }
1941
+ setLoading(true);
1942
+ setError(null);
1943
+ try {
1944
+ const response = await client.media.list({ type, page, per_page });
1945
+ setFiles(response.data);
1946
+ setMeta(response.meta);
1947
+ } catch (err) {
1948
+ setError(err instanceof Error ? err : new Error("Failed to fetch media"));
1949
+ } finally {
1950
+ setLoading(false);
1951
+ }
1952
+ }, [client, type, page, per_page]);
1953
+ useEffect17(() => {
1954
+ if (autoFetch) {
1955
+ fetchMedia();
1956
+ }
1957
+ }, [autoFetch, fetchMedia]);
1958
+ const upload = useCallback18(async (file) => {
1959
+ setUploading(true);
1960
+ setUploadProgress(0);
1961
+ setError(null);
1962
+ try {
1963
+ const media = await client.media.upload(file);
1964
+ setFiles((prev) => [media, ...prev]);
1965
+ setUploadProgress(100);
1966
+ return media;
1967
+ } catch (err) {
1968
+ const error2 = err instanceof Error ? err : new Error("Failed to upload file");
1969
+ setError(error2);
1970
+ throw error2;
1971
+ } finally {
1972
+ setUploading(false);
1973
+ }
1974
+ }, [client]);
1975
+ const uploadMultiple = useCallback18(async (filesToUpload) => {
1976
+ setUploading(true);
1977
+ setUploadProgress(0);
1978
+ setError(null);
1979
+ try {
1980
+ const results = [];
1981
+ for (let i = 0; i < filesToUpload.length; i++) {
1982
+ const media = await client.media.upload(filesToUpload[i]);
1983
+ results.push(media);
1984
+ setUploadProgress(Math.round((i + 1) / filesToUpload.length * 100));
1985
+ }
1986
+ setFiles((prev) => [...results, ...prev]);
1987
+ return results;
1988
+ } catch (err) {
1989
+ const error2 = err instanceof Error ? err : new Error("Failed to upload files");
1990
+ setError(error2);
1991
+ throw error2;
1992
+ } finally {
1993
+ setUploading(false);
1994
+ }
1995
+ }, [client]);
1996
+ const deleteFile = useCallback18(async (mediaId) => {
1997
+ await client.media.delete(mediaId);
1998
+ setFiles((prev) => prev.filter((f) => f.id !== mediaId));
1999
+ }, [client]);
2000
+ return {
2001
+ files,
2002
+ meta,
2003
+ loading,
2004
+ error,
2005
+ upload,
2006
+ uploadMultiple,
2007
+ deleteFile,
2008
+ refresh: fetchMedia,
2009
+ uploading,
2010
+ uploadProgress
2011
+ };
2012
+ }
2013
+
2014
+ // src/hooks/useEntities.ts
2015
+ import { useState as useState19, useEffect as useEffect18, useCallback as useCallback19, useMemo as useMemo2 } from "react";
2016
+ function useEntities() {
2017
+ const client = useClient();
2018
+ const [entities, setEntities] = useState19([]);
2019
+ const [loading, setLoading] = useState19(true);
2020
+ const [error, setError] = useState19(null);
2021
+ const fetchEntities = useCallback19(async () => {
2022
+ setLoading(true);
2023
+ setError(null);
2024
+ try {
2025
+ const data = await client.entities.list();
2026
+ setEntities(data);
2027
+ } catch (err) {
2028
+ setError(err instanceof Error ? err : new Error("Failed to fetch entities"));
2029
+ } finally {
2030
+ setLoading(false);
2031
+ }
2032
+ }, [client]);
2033
+ useEffect18(() => {
2034
+ fetchEntities();
2035
+ }, [fetchEntities]);
2036
+ return {
2037
+ entities,
2038
+ loading,
2039
+ error,
2040
+ refresh: fetchEntities
2041
+ };
2042
+ }
2043
+ function useEntity(slug) {
2044
+ const client = useClient();
2045
+ const [entity, setEntity] = useState19(null);
2046
+ const [loading, setLoading] = useState19(true);
2047
+ const [error, setError] = useState19(null);
2048
+ const fetchEntity = useCallback19(async () => {
2049
+ setLoading(true);
2050
+ setError(null);
2051
+ try {
2052
+ const data = await client.entities.get(slug);
2053
+ setEntity(data);
2054
+ } catch (err) {
2055
+ setError(err instanceof Error ? err : new Error("Failed to fetch entity"));
2056
+ } finally {
2057
+ setLoading(false);
2058
+ }
2059
+ }, [client, slug]);
2060
+ useEffect18(() => {
2061
+ fetchEntity();
2062
+ }, [fetchEntity]);
2063
+ return {
2064
+ entity,
2065
+ loading,
2066
+ error,
2067
+ refresh: fetchEntity
2068
+ };
2069
+ }
2070
+ function useEntityRecords(slug, params) {
2071
+ const client = useClient();
2072
+ const [records, setRecords] = useState19([]);
2073
+ const [meta, setMeta] = useState19(null);
2074
+ const [loading, setLoading] = useState19(true);
2075
+ const [error, setError] = useState19(null);
2076
+ const [currentParams, setCurrentParams] = useState19(params);
2077
+ const fetchRecords = useCallback19(async (fetchParams, append = false) => {
2078
+ setLoading(true);
2079
+ setError(null);
2080
+ try {
2081
+ const response = await client.entities.listRecords(slug, fetchParams);
2082
+ if (append) {
2083
+ setRecords((prev) => [...prev, ...response.data]);
2084
+ } else {
2085
+ setRecords(response.data);
2086
+ }
2087
+ setMeta(response.meta);
2088
+ } catch (err) {
2089
+ setError(err instanceof Error ? err : new Error("Failed to fetch records"));
2090
+ } finally {
2091
+ setLoading(false);
2092
+ }
2093
+ }, [client, slug]);
2094
+ useEffect18(() => {
2095
+ fetchRecords(params);
2096
+ }, []);
2097
+ const hasMore = meta ? meta.current_page < meta.last_page : false;
2098
+ const loadMore = useCallback19(async () => {
2099
+ if (!hasMore || loading) return;
2100
+ const nextPage = (meta?.current_page ?? 0) + 1;
2101
+ await fetchRecords({ ...currentParams, page: nextPage }, true);
2102
+ }, [hasMore, loading, meta, currentParams, fetchRecords]);
2103
+ const createRecord = useCallback19(async (data) => {
2104
+ const record = await client.entities.createRecord(slug, data);
2105
+ setRecords((prev) => [record, ...prev]);
2106
+ return record;
2107
+ }, [client, slug]);
2108
+ const updateRecord = useCallback19(async (id, data) => {
2109
+ const record = await client.entities.updateRecord(slug, id, data);
2110
+ setRecords((prev) => prev.map((r) => r.id === id ? record : r));
2111
+ return record;
2112
+ }, [client, slug]);
2113
+ const deleteRecord = useCallback19(async (id) => {
2114
+ await client.entities.deleteRecord(slug, id);
2115
+ setRecords((prev) => prev.filter((r) => r.id !== id));
2116
+ }, [client, slug]);
2117
+ const refresh = useCallback19(async () => {
2118
+ setCurrentParams(params);
2119
+ await fetchRecords(params);
2120
+ }, [params, fetchRecords]);
2121
+ return {
2122
+ records,
2123
+ meta,
2124
+ loading,
2125
+ error,
2126
+ hasMore,
2127
+ loadMore,
2128
+ createRecord,
2129
+ updateRecord,
2130
+ deleteRecord,
2131
+ refresh
2132
+ };
2133
+ }
2134
+ function useEntityRecord(slug, id) {
2135
+ const client = useClient();
2136
+ const [record, setRecord] = useState19(null);
2137
+ const [loading, setLoading] = useState19(true);
2138
+ const [error, setError] = useState19(null);
2139
+ const fetchRecord = useCallback19(async () => {
2140
+ setLoading(true);
2141
+ setError(null);
2142
+ try {
2143
+ const data = await client.entities.getRecord(slug, id);
2144
+ setRecord(data);
2145
+ } catch (err) {
2146
+ setError(err instanceof Error ? err : new Error("Failed to fetch record"));
2147
+ } finally {
2148
+ setLoading(false);
2149
+ }
2150
+ }, [client, slug, id]);
2151
+ useEffect18(() => {
2152
+ fetchRecord();
2153
+ }, [fetchRecord]);
2154
+ const update = useCallback19(async (data) => {
2155
+ const updated = await client.entities.updateRecord(slug, id, data);
2156
+ setRecord(updated);
2157
+ return updated;
2158
+ }, [client, slug, id]);
2159
+ return {
2160
+ record,
2161
+ loading,
2162
+ error,
2163
+ update,
2164
+ refresh: fetchRecord
2165
+ };
2166
+ }
2167
+ function useTypedEntity(slug) {
2168
+ const client = useClient();
2169
+ return useMemo2(() => ({
2170
+ useRecords: (params) => {
2171
+ const result = useEntityRecords(slug, params);
2172
+ return {
2173
+ ...result,
2174
+ records: result.records
2175
+ };
2176
+ },
2177
+ useRecord: (id) => {
2178
+ const result = useEntityRecord(slug, id);
2179
+ return {
2180
+ ...result,
2181
+ record: result.record
2182
+ };
2183
+ },
2184
+ create: async (data) => {
2185
+ const record = await client.entities.createRecord(slug, data);
2186
+ return record;
2187
+ },
2188
+ update: async (id, data) => {
2189
+ const record = await client.entities.updateRecord(slug, id, data);
2190
+ return record;
2191
+ },
2192
+ delete: (id) => client.entities.deleteRecord(slug, id)
2193
+ }), [client, slug]);
2194
+ }
2195
+ export {
2196
+ DiffsomeContext,
2197
+ DiffsomeProvider,
2198
+ useAuth,
2199
+ useAvailableSlots,
2200
+ useBlog,
2201
+ useBlogCategories,
2202
+ useBlogPost,
2203
+ useBlogSearch,
2204
+ useBlogTags,
2205
+ useBoard,
2206
+ useBoardPost,
2207
+ useBoardPosts,
2208
+ useBoards,
2209
+ useBundleItems,
2210
+ useBundleProducts,
2211
+ useCanReview,
2212
+ useCart,
2213
+ useCategories,
2214
+ useClient,
2215
+ useComments,
2216
+ useCoupons,
2217
+ useCreateBoardPost,
2218
+ useCreateOrder,
2219
+ useCreateReservation,
2220
+ useCreateReview,
2221
+ useCreateSubscription,
2222
+ useDiffsome,
2223
+ useDigitalProducts,
2224
+ useDownloads,
2225
+ useEntities,
2226
+ useEntity,
2227
+ useEntityRecord,
2228
+ useEntityRecords,
2229
+ useFeaturedBlog,
2230
+ useFeaturedProducts,
2231
+ useForm,
2232
+ useMedia,
2233
+ useMyReservations,
2234
+ useMyReviews,
2235
+ useOrder,
2236
+ useOrderDownloads,
2237
+ useOrders,
2238
+ usePaymentStatus,
2239
+ useProduct,
2240
+ useProductReviews,
2241
+ useProducts,
2242
+ useProductsByType,
2243
+ useReservationServices,
2244
+ useReservationSettings,
2245
+ useReservationStaffs,
2246
+ useSocialAuth,
2247
+ useStripePayment,
2248
+ useSubscription,
2249
+ useSubscriptionProducts,
2250
+ useSubscriptions,
2251
+ useTossPayment,
2252
+ useTypedEntity,
2253
+ useValidateCoupon,
2254
+ useWishlist
2255
+ };