@diffsome/react 1.1.1 → 1.1.3

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/README.md CHANGED
@@ -8,25 +8,91 @@ Headless React hooks and providers for Diffsome SDK. Build any e-commerce or CMS
8
8
  npm install @diffsome/react @diffsome/sdk
9
9
  # or
10
10
  yarn add @diffsome/react @diffsome/sdk
11
+ # or
12
+ pnpm add @diffsome/react @diffsome/sdk
11
13
  ```
12
14
 
13
- ## Quick Start
15
+ ## Configuration
16
+
17
+ ### Option 1: Environment Variables (Recommended)
18
+
19
+ **Next.js** (`.env.local`)
20
+ ```bash
21
+ NEXT_PUBLIC_DIFFSOME_TENANT_ID=my-store
22
+ NEXT_PUBLIC_DIFFSOME_API_KEY=pky_xxx # optional
23
+ NEXT_PUBLIC_DIFFSOME_BASE_URL=https://api.diffsome.com # optional
24
+ ```
25
+
26
+ **Create React App** (`.env`)
27
+ ```bash
28
+ REACT_APP_DIFFSOME_TENANT_ID=my-store
29
+ REACT_APP_DIFFSOME_API_KEY=pky_xxx
30
+ ```
31
+
32
+ Then simply wrap your app:
14
33
 
15
34
  ```tsx
16
- import { DiffsomeProvider, useAuth, useCart, useProducts } from '@diffsome/react';
35
+ import { DiffsomeProvider } from '@diffsome/react';
17
36
 
18
37
  function App() {
19
38
  return (
20
- <DiffsomeProvider
21
- config={{
22
- tenantId: 'my-store',
23
- apiKey: 'pky_your_api_key',
24
- }}
25
- >
26
- <Shop />
39
+ <DiffsomeProvider>
40
+ <YourApp />
27
41
  </DiffsomeProvider>
28
42
  );
29
43
  }
44
+ ```
45
+
46
+ ### Option 2: Direct Config
47
+
48
+ ```tsx
49
+ <DiffsomeProvider
50
+ config={{
51
+ tenantId: 'my-store', // required
52
+ apiKey: 'pky_xxx', // optional
53
+ baseUrl: 'https://api.diffsome.com', // optional
54
+ persistToken: true, // default: true
55
+ storageType: 'localStorage', // 'localStorage' | 'sessionStorage'
56
+ }}
57
+ >
58
+ <YourApp />
59
+ </DiffsomeProvider>
60
+ ```
61
+
62
+ ### Next.js App Router Setup
63
+
64
+ ```tsx
65
+ // app/providers.tsx
66
+ 'use client';
67
+
68
+ import { DiffsomeProvider } from '@diffsome/react';
69
+
70
+ export function Providers({ children }: { children: React.ReactNode }) {
71
+ return (
72
+ <DiffsomeProvider>
73
+ {children}
74
+ </DiffsomeProvider>
75
+ );
76
+ }
77
+
78
+ // app/layout.tsx
79
+ import { Providers } from './providers';
80
+
81
+ export default function RootLayout({ children }) {
82
+ return (
83
+ <html>
84
+ <body>
85
+ <Providers>{children}</Providers>
86
+ </body>
87
+ </html>
88
+ );
89
+ }
90
+ ```
91
+
92
+ ## Quick Start
93
+
94
+ ```tsx
95
+ import { DiffsomeProvider, useAuth, useCart, useProducts } from '@diffsome/react';
30
96
 
31
97
  function Shop() {
32
98
  const { user, login, logout } = useAuth();
@@ -62,29 +128,34 @@ function Shop() {
62
128
  ## Available Hooks
63
129
 
64
130
  ### Authentication
65
- - `useAuth()` - Login, register, logout, profile management
131
+ - `useAuth()` - Login, register, logout, profile, password reset
66
132
  - `useSocialAuth()` - Social login (Google, Kakao, Naver, etc.)
67
133
 
68
134
  ### E-commerce
69
135
  - `useCart()` - Cart management (add, update, remove items)
70
- - `useWishlist()` - Wishlist management
71
- - `useProducts()` - Product listing with pagination
136
+ - `useWishlist()` - Wishlist management with toggle
137
+ - `useProducts(options?)` - Product listing with pagination & search
72
138
  - `useProduct(slug)` - Single product details
73
139
  - `useCategories()` - Product categories
74
- - `useFeaturedProducts()` - Featured products
140
+ - `useFeaturedProducts(limit?)` - Featured products
141
+ - `useProductsByType(type)` - Products by type (digital, subscription, bundle)
142
+ - `useDigitalProducts()` - Digital products shorthand
143
+ - `useSubscriptionProducts()` - Subscription products shorthand
144
+ - `useBundleProducts()` - Bundle products shorthand
145
+ - `useBundleItems(slug)` - Bundle items with pricing
75
146
  - `useOrders()` - Order history
76
147
  - `useOrder(id)` - Single order details
77
148
  - `useCreateOrder()` - Create new order
78
149
 
79
150
  ### Payment
80
- - `usePaymentStatus()` - Check available payment methods (Toss, Stripe)
151
+ - `usePaymentStatus()` - Check available payment methods
81
152
  - `useTossPayment()` - Toss Payments (Korea)
82
153
  - `useStripePayment()` - Stripe Payments (Global)
83
154
  - `useCoupons()` - User's available coupons
84
155
  - `useValidateCoupon()` - Validate coupon code
85
156
 
86
157
  ### Subscriptions
87
- - `useSubscriptions()` - User's subscriptions
158
+ - `useSubscriptions()` - User's subscriptions list
88
159
  - `useSubscription(id)` - Single subscription with cancel/pause/resume
89
160
  - `useCreateSubscription()` - Create subscription via Stripe
90
161
 
@@ -93,15 +164,18 @@ function Shop() {
93
164
  - `useOrderDownloads(orderNumber)` - Downloads for specific order
94
165
 
95
166
  ### Reviews
96
- - `useProductReviews(slug)` - Product reviews
167
+ - `useProductReviews(slug)` - Product reviews with stats
97
168
  - `useMyReviews()` - User's reviews
98
169
  - `useCanReview(slug)` - Check review eligibility
99
170
  - `useCreateReview()` - Create product review
100
171
 
101
172
  ### Content
102
- - `useBlog()` - Blog posts with pagination
173
+ - `useBlog(options?)` - Blog posts with pagination
103
174
  - `useBlogPost(slug)` - Single blog post
104
175
  - `useBlogCategories()` - Blog categories
176
+ - `useBlogTags()` - Blog tags
177
+ - `useFeaturedBlog(limit?)` - Featured blog posts
178
+ - `useBlogSearch()` - Blog search
105
179
  - `useBoards()` - Board listing
106
180
  - `useBoard(slug)` - Single board
107
181
  - `useBoardPosts(slug)` - Board posts
@@ -112,8 +186,8 @@ function Shop() {
112
186
 
113
187
  ### Reservations
114
188
  - `useReservationServices()` - Available services
115
- - `useReservationStaffs()` - Staff members
116
- - `useAvailableSlots(serviceId, date)` - Time slots
189
+ - `useReservationStaffs(serviceId?)` - Staff members
190
+ - `useAvailableSlots(serviceId, staffId?, date)` - Available time slots
117
191
  - `useMyReservations()` - User's reservations
118
192
  - `useCreateReservation()` - Create reservation
119
193
  - `useReservationSettings()` - Reservation settings
@@ -134,7 +208,7 @@ function Shop() {
134
208
 
135
209
  ```tsx
136
210
  function LoginForm() {
137
- const { user, login, logout, loading, error } = useAuth();
211
+ const { user, login, logout, forgotPassword, loading, error } = useAuth();
138
212
  const [email, setEmail] = useState('');
139
213
  const [password, setPassword] = useState('');
140
214
 
@@ -143,6 +217,11 @@ function LoginForm() {
143
217
  await login({ email, password });
144
218
  };
145
219
 
220
+ const handleForgotPassword = async () => {
221
+ await forgotPassword(email);
222
+ alert('Password reset email sent!');
223
+ };
224
+
146
225
  if (user) {
147
226
  return (
148
227
  <div>
@@ -157,17 +236,53 @@ function LoginForm() {
157
236
  <input value={email} onChange={(e) => setEmail(e.target.value)} />
158
237
  <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
159
238
  <button disabled={loading}>Login</button>
239
+ <button type="button" onClick={handleForgotPassword}>Forgot Password</button>
160
240
  {error && <p>{error.message}</p>}
161
241
  </form>
162
242
  );
163
243
  }
164
244
  ```
165
245
 
246
+ ### useProducts with Filters
247
+
248
+ ```tsx
249
+ function ProductGrid() {
250
+ const { products, loading, hasMore, loadMore, search } = useProducts({
251
+ per_page: 12,
252
+ category: 'electronics',
253
+ });
254
+ const [query, setQuery] = useState('');
255
+
256
+ return (
257
+ <div>
258
+ <input
259
+ placeholder="Search products..."
260
+ value={query}
261
+ onChange={(e) => setQuery(e.target.value)}
262
+ onKeyDown={(e) => e.key === 'Enter' && search(query)}
263
+ />
264
+
265
+ <div className="grid grid-cols-4 gap-4">
266
+ {products.map(product => (
267
+ <ProductCard key={product.id} product={product} />
268
+ ))}
269
+ </div>
270
+
271
+ {hasMore && (
272
+ <button onClick={loadMore} disabled={loading}>
273
+ Load More
274
+ </button>
275
+ )}
276
+ </div>
277
+ );
278
+ }
279
+ ```
280
+
166
281
  ### useCart
167
282
 
168
283
  ```tsx
169
284
  function Cart() {
170
- const { items, total, updateItem, removeItem, clearCart } = useCart();
285
+ const { items, total, updateItem, removeItem, clearCart, applyCoupon } = useCart();
171
286
 
172
287
  return (
173
288
  <div>
@@ -193,12 +308,17 @@ function Cart() {
193
308
 
194
309
  ```tsx
195
310
  function WishlistButton({ productId }) {
196
- const { isInWishlist, toggleWishlist } = useWishlist();
311
+ const { isInWishlist, toggleWishlist, getProductWishlistCount } = useWishlist();
312
+ const [count, setCount] = useState(0);
197
313
  const inWishlist = isInWishlist(productId);
198
314
 
315
+ useEffect(() => {
316
+ getProductWishlistCount(productId).then(setCount);
317
+ }, [productId]);
318
+
199
319
  return (
200
320
  <button onClick={() => toggleWishlist(productId)}>
201
- {inWishlist ? '❤️' : '🤍'}
321
+ {inWishlist ? '❤️' : '🤍'} {count}
202
322
  </button>
203
323
  );
204
324
  }
@@ -227,6 +347,65 @@ function CheckoutButton({ orderNumber }) {
227
347
  }
228
348
  ```
229
349
 
350
+ ### useSubscription
351
+
352
+ ```tsx
353
+ function SubscriptionManager({ subscriptionId }) {
354
+ const { subscription, cancel, pause, resume, loading } = useSubscription(subscriptionId);
355
+
356
+ if (!subscription) return null;
357
+
358
+ return (
359
+ <div>
360
+ <p>Plan: {subscription.plan.name}</p>
361
+ <p>Status: {subscription.status}</p>
362
+ <p>Next billing: {subscription.current_period_end}</p>
363
+
364
+ {subscription.status === 'active' && (
365
+ <>
366
+ <button onClick={pause}>Pause</button>
367
+ <button onClick={cancel}>Cancel</button>
368
+ </>
369
+ )}
370
+ {subscription.status === 'paused' && (
371
+ <button onClick={resume}>Resume</button>
372
+ )}
373
+ </div>
374
+ );
375
+ }
376
+ ```
377
+
378
+ ### useBlogSearch
379
+
380
+ ```tsx
381
+ function BlogSearch() {
382
+ const { results, search, loading } = useBlogSearch();
383
+ const [query, setQuery] = useState('');
384
+
385
+ const handleSearch = () => {
386
+ search(query);
387
+ };
388
+
389
+ return (
390
+ <div>
391
+ <input
392
+ value={query}
393
+ onChange={(e) => setQuery(e.target.value)}
394
+ placeholder="Search blog..."
395
+ />
396
+ <button onClick={handleSearch} disabled={loading}>Search</button>
397
+
398
+ {results.map(post => (
399
+ <article key={post.id}>
400
+ <h3>{post.title}</h3>
401
+ <p>{post.excerpt}</p>
402
+ </article>
403
+ ))}
404
+ </div>
405
+ );
406
+ }
407
+ ```
408
+
230
409
  ### useComments
231
410
 
232
411
  ```tsx
@@ -345,9 +524,24 @@ function CustomComponent() {
345
524
  All types are re-exported from `@diffsome/sdk`:
346
525
 
347
526
  ```tsx
348
- import type { Product, Cart, Order, Member, CustomEntity, EntityRecord } from '@diffsome/react';
527
+ import type {
528
+ Product,
529
+ Cart,
530
+ Order,
531
+ Member,
532
+ CustomEntity,
533
+ EntityRecord,
534
+ BlogPost,
535
+ Reservation,
536
+ // ... and more
537
+ } from '@diffsome/react';
349
538
  ```
350
539
 
540
+ ## Requirements
541
+
542
+ - React 18.0+
543
+ - @diffsome/sdk 3.2.0+
544
+
351
545
  ## License
352
546
 
353
547
  MIT
package/dist/index.d.mts CHANGED
@@ -17,24 +17,75 @@ declare function DiffsomeProvider({ children, config }: DiffsomeProviderProps):
17
17
  declare function useDiffsome(): DiffsomeContextValue;
18
18
  declare function useClient(): Diffsome;
19
19
 
20
+ /**
21
+ * Return type for the useAuth hook
22
+ */
20
23
  interface UseAuthReturn {
24
+ /** Currently logged in user, or null if not authenticated */
21
25
  user: Member | null;
26
+ /** Whether the user is currently authenticated */
22
27
  isAuthenticated: boolean;
28
+ /** Whether an auth operation is in progress */
23
29
  loading: boolean;
30
+ /** Error from the last auth operation, if any */
24
31
  error: Error | null;
32
+ /**
33
+ * Log in with email and password
34
+ * @param credentials - { email: string, password: string }
35
+ * @returns AuthResponse with user and token
36
+ */
25
37
  login: (credentials: LoginCredentials) => Promise<AuthResponse>;
38
+ /**
39
+ * Register a new account
40
+ * @param data - { name: string, email: string, password: string, password_confirmation: string }
41
+ * @returns AuthResponse with user and token
42
+ */
26
43
  register: (data: RegisterData) => Promise<AuthResponse>;
44
+ /** Log out and clear session */
27
45
  logout: () => Promise<void>;
46
+ /** Fetch current user profile */
28
47
  getProfile: () => Promise<Member>;
48
+ /**
49
+ * Update user profile
50
+ * @param data - { name?: string, email?: string, phone?: string, avatar?: File }
51
+ */
29
52
  updateProfile: (data: UpdateProfileData) => Promise<Member>;
53
+ /**
54
+ * Send password reset email
55
+ * @param email - User's email address
56
+ */
30
57
  forgotPassword: (email: string) => Promise<{
31
58
  message: string;
32
59
  }>;
60
+ /**
61
+ * Reset password with token
62
+ * @param data - { token: string, email: string, password: string, password_confirmation: string }
63
+ */
33
64
  resetPassword: (data: ResetPasswordData) => Promise<{
34
65
  message: string;
35
66
  }>;
36
- refresh: () => Promise<void>;
37
- }
67
+ /** Refresh user profile from server */
68
+ refresh: () => Promise<void>;
69
+ }
70
+ /**
71
+ * Hook for user authentication - login, register, logout, profile management
72
+ *
73
+ * @example
74
+ * ```tsx
75
+ * const { user, login, logout, loading } = useAuth();
76
+ *
77
+ * // Login
78
+ * await login({ email: 'user@example.com', password: 'secret' });
79
+ *
80
+ * // Check auth state
81
+ * if (user) {
82
+ * console.log('Logged in as:', user.name);
83
+ * }
84
+ *
85
+ * // Logout
86
+ * await logout();
87
+ * ```
88
+ */
38
89
  declare function useAuth(): UseAuthReturn;
39
90
 
40
91
  interface UseSocialAuthReturn {
@@ -47,24 +98,90 @@ interface UseSocialAuthReturn {
47
98
  }
48
99
  declare function useSocialAuth(): UseSocialAuthReturn;
49
100
 
101
+ /**
102
+ * Return type for the useCart hook
103
+ */
50
104
  interface UseCartReturn {
105
+ /** Full cart object with metadata */
51
106
  cart: Cart | null;
107
+ /** Array of cart items */
52
108
  items: CartItem[];
109
+ /** Number of unique items in cart */
53
110
  itemCount: number;
111
+ /** Total quantity of all items */
54
112
  totalQuantity: number;
113
+ /** Cart subtotal before shipping */
55
114
  subtotal: number;
115
+ /** Shipping fee */
56
116
  shippingFee: number;
117
+ /** Cart total including shipping */
57
118
  total: number;
58
- loading: boolean;
59
- error: Error | null;
119
+ /** Whether cart is loading */
120
+ loading: boolean;
121
+ /** Error from last cart operation */
122
+ error: Error | null;
123
+ /**
124
+ * Add product to cart
125
+ * @param productId - Product ID to add
126
+ * @param quantity - Quantity to add (default: 1)
127
+ * @param variantId - Optional variant ID for variable products
128
+ * @param options - Optional custom options
129
+ * @returns Updated cart
130
+ */
60
131
  addToCart: (productId: number, quantity?: number, variantId?: number, options?: Record<string, string>) => Promise<Cart>;
132
+ /**
133
+ * Update item quantity
134
+ * @param itemId - Cart item ID
135
+ * @param quantity - New quantity
136
+ */
61
137
  updateItem: (itemId: number, quantity: number) => Promise<Cart>;
138
+ /**
139
+ * Remove item from cart
140
+ * @param itemId - Cart item ID to remove
141
+ */
62
142
  removeItem: (itemId: number) => Promise<Cart>;
143
+ /** Clear all items from cart */
63
144
  clearCart: () => Promise<void>;
145
+ /** Refresh cart from server */
64
146
  refresh: () => Promise<void>;
147
+ /**
148
+ * Check if product is in cart
149
+ * @param productId - Product ID
150
+ * @param variantId - Optional variant ID
151
+ */
65
152
  isInCart: (productId: number, variantId?: number) => boolean;
153
+ /**
154
+ * Get quantity of product in cart
155
+ * @param productId - Product ID
156
+ * @param variantId - Optional variant ID
157
+ * @returns Quantity in cart (0 if not in cart)
158
+ */
66
159
  getItemQuantity: (productId: number, variantId?: number) => number;
67
160
  }
161
+ /**
162
+ * Hook for shopping cart management
163
+ *
164
+ * @example
165
+ * ```tsx
166
+ * const { items, total, addToCart, removeItem, clearCart } = useCart();
167
+ *
168
+ * // Add to cart
169
+ * await addToCart(123, 2); // Add product ID 123, quantity 2
170
+ *
171
+ * // With variant
172
+ * await addToCart(123, 1, 456); // Product 123, variant 456
173
+ *
174
+ * // Display cart
175
+ * items.map(item => (
176
+ * <div key={item.id}>
177
+ * {item.product_name} x {item.quantity} = ${item.subtotal}
178
+ * </div>
179
+ * ));
180
+ *
181
+ * // Total
182
+ * console.log('Total:', total);
183
+ * ```
184
+ */
68
185
  declare function useCart(): UseCartReturn;
69
186
 
70
187
  interface UseWishlistReturn {
@@ -83,26 +200,96 @@ interface UseWishlistReturn {
83
200
  }
84
201
  declare function useWishlist(): UseWishlistReturn;
85
202
 
203
+ /**
204
+ * Return type for the useProducts hook
205
+ */
86
206
  interface UseProductsReturn {
207
+ /** Array of products */
87
208
  products: Product[];
209
+ /** Pagination metadata (current_page, last_page, total, per_page) */
88
210
  meta: PaginationMeta | null;
211
+ /** Whether products are loading */
89
212
  loading: boolean;
213
+ /** Error from last operation */
90
214
  error: Error | null;
215
+ /** Whether more pages are available */
91
216
  hasMore: boolean;
217
+ /** Load next page of products (appends to list) */
92
218
  loadMore: () => Promise<void>;
219
+ /** Refresh products from server */
93
220
  refresh: () => Promise<void>;
221
+ /**
222
+ * Search products by query
223
+ * @param query - Search term
224
+ */
94
225
  search: (query: string) => Promise<void>;
95
226
  }
227
+ /**
228
+ * Options for useProducts hook
229
+ */
96
230
  interface UseProductsOptions extends ProductListParams {
231
+ /** Whether to fetch products on mount (default: true) */
97
232
  autoFetch?: boolean;
98
233
  }
234
+ /**
235
+ * Hook for fetching products with pagination, filtering, and search
236
+ *
237
+ * @param options - Filtering and pagination options
238
+ * @example
239
+ * ```tsx
240
+ * // Basic usage
241
+ * const { products, loading } = useProducts();
242
+ *
243
+ * // With filters
244
+ * const { products } = useProducts({
245
+ * category: 'electronics',
246
+ * per_page: 20,
247
+ * sort: 'price_low',
248
+ * min_price: 10,
249
+ * max_price: 100,
250
+ * });
251
+ *
252
+ * // Infinite scroll
253
+ * const { products, hasMore, loadMore } = useProducts({ per_page: 12 });
254
+ * // Call loadMore() when user scrolls to bottom
255
+ *
256
+ * // Search
257
+ * const { products, search } = useProducts();
258
+ * await search('laptop'); // Searches products
259
+ * ```
260
+ */
99
261
  declare function useProducts(options?: UseProductsOptions): UseProductsReturn;
262
+ /**
263
+ * Return type for the useProduct hook
264
+ */
100
265
  interface UseProductReturn {
266
+ /** Product data, or null if not loaded */
101
267
  product: Product | null;
102
- loading: boolean;
103
- error: Error | null;
104
- refresh: () => Promise<void>;
105
- }
268
+ /** Whether product is loading */
269
+ loading: boolean;
270
+ /** Error from last operation */
271
+ error: Error | null;
272
+ /** Refresh product from server */
273
+ refresh: () => Promise<void>;
274
+ }
275
+ /**
276
+ * Hook for fetching a single product by ID or slug
277
+ *
278
+ * @param idOrSlug - Product ID (number) or slug (string)
279
+ * @example
280
+ * ```tsx
281
+ * // By slug (recommended)
282
+ * const { product, loading } = useProduct('wireless-headphones');
283
+ *
284
+ * // By ID
285
+ * const { product } = useProduct(123);
286
+ *
287
+ * // Display product
288
+ * if (product) {
289
+ * console.log(product.name, product.sale_price, product.images);
290
+ * }
291
+ * ```
292
+ */
106
293
  declare function useProduct(idOrSlug: number | string): UseProductReturn;
107
294
  interface UseCategoriesReturn {
108
295
  categories: ProductCategory[];
package/dist/index.d.ts CHANGED
@@ -17,24 +17,75 @@ declare function DiffsomeProvider({ children, config }: DiffsomeProviderProps):
17
17
  declare function useDiffsome(): DiffsomeContextValue;
18
18
  declare function useClient(): Diffsome;
19
19
 
20
+ /**
21
+ * Return type for the useAuth hook
22
+ */
20
23
  interface UseAuthReturn {
24
+ /** Currently logged in user, or null if not authenticated */
21
25
  user: Member | null;
26
+ /** Whether the user is currently authenticated */
22
27
  isAuthenticated: boolean;
28
+ /** Whether an auth operation is in progress */
23
29
  loading: boolean;
30
+ /** Error from the last auth operation, if any */
24
31
  error: Error | null;
32
+ /**
33
+ * Log in with email and password
34
+ * @param credentials - { email: string, password: string }
35
+ * @returns AuthResponse with user and token
36
+ */
25
37
  login: (credentials: LoginCredentials) => Promise<AuthResponse>;
38
+ /**
39
+ * Register a new account
40
+ * @param data - { name: string, email: string, password: string, password_confirmation: string }
41
+ * @returns AuthResponse with user and token
42
+ */
26
43
  register: (data: RegisterData) => Promise<AuthResponse>;
44
+ /** Log out and clear session */
27
45
  logout: () => Promise<void>;
46
+ /** Fetch current user profile */
28
47
  getProfile: () => Promise<Member>;
48
+ /**
49
+ * Update user profile
50
+ * @param data - { name?: string, email?: string, phone?: string, avatar?: File }
51
+ */
29
52
  updateProfile: (data: UpdateProfileData) => Promise<Member>;
53
+ /**
54
+ * Send password reset email
55
+ * @param email - User's email address
56
+ */
30
57
  forgotPassword: (email: string) => Promise<{
31
58
  message: string;
32
59
  }>;
60
+ /**
61
+ * Reset password with token
62
+ * @param data - { token: string, email: string, password: string, password_confirmation: string }
63
+ */
33
64
  resetPassword: (data: ResetPasswordData) => Promise<{
34
65
  message: string;
35
66
  }>;
36
- refresh: () => Promise<void>;
37
- }
67
+ /** Refresh user profile from server */
68
+ refresh: () => Promise<void>;
69
+ }
70
+ /**
71
+ * Hook for user authentication - login, register, logout, profile management
72
+ *
73
+ * @example
74
+ * ```tsx
75
+ * const { user, login, logout, loading } = useAuth();
76
+ *
77
+ * // Login
78
+ * await login({ email: 'user@example.com', password: 'secret' });
79
+ *
80
+ * // Check auth state
81
+ * if (user) {
82
+ * console.log('Logged in as:', user.name);
83
+ * }
84
+ *
85
+ * // Logout
86
+ * await logout();
87
+ * ```
88
+ */
38
89
  declare function useAuth(): UseAuthReturn;
39
90
 
40
91
  interface UseSocialAuthReturn {
@@ -47,24 +98,90 @@ interface UseSocialAuthReturn {
47
98
  }
48
99
  declare function useSocialAuth(): UseSocialAuthReturn;
49
100
 
101
+ /**
102
+ * Return type for the useCart hook
103
+ */
50
104
  interface UseCartReturn {
105
+ /** Full cart object with metadata */
51
106
  cart: Cart | null;
107
+ /** Array of cart items */
52
108
  items: CartItem[];
109
+ /** Number of unique items in cart */
53
110
  itemCount: number;
111
+ /** Total quantity of all items */
54
112
  totalQuantity: number;
113
+ /** Cart subtotal before shipping */
55
114
  subtotal: number;
115
+ /** Shipping fee */
56
116
  shippingFee: number;
117
+ /** Cart total including shipping */
57
118
  total: number;
58
- loading: boolean;
59
- error: Error | null;
119
+ /** Whether cart is loading */
120
+ loading: boolean;
121
+ /** Error from last cart operation */
122
+ error: Error | null;
123
+ /**
124
+ * Add product to cart
125
+ * @param productId - Product ID to add
126
+ * @param quantity - Quantity to add (default: 1)
127
+ * @param variantId - Optional variant ID for variable products
128
+ * @param options - Optional custom options
129
+ * @returns Updated cart
130
+ */
60
131
  addToCart: (productId: number, quantity?: number, variantId?: number, options?: Record<string, string>) => Promise<Cart>;
132
+ /**
133
+ * Update item quantity
134
+ * @param itemId - Cart item ID
135
+ * @param quantity - New quantity
136
+ */
61
137
  updateItem: (itemId: number, quantity: number) => Promise<Cart>;
138
+ /**
139
+ * Remove item from cart
140
+ * @param itemId - Cart item ID to remove
141
+ */
62
142
  removeItem: (itemId: number) => Promise<Cart>;
143
+ /** Clear all items from cart */
63
144
  clearCart: () => Promise<void>;
145
+ /** Refresh cart from server */
64
146
  refresh: () => Promise<void>;
147
+ /**
148
+ * Check if product is in cart
149
+ * @param productId - Product ID
150
+ * @param variantId - Optional variant ID
151
+ */
65
152
  isInCart: (productId: number, variantId?: number) => boolean;
153
+ /**
154
+ * Get quantity of product in cart
155
+ * @param productId - Product ID
156
+ * @param variantId - Optional variant ID
157
+ * @returns Quantity in cart (0 if not in cart)
158
+ */
66
159
  getItemQuantity: (productId: number, variantId?: number) => number;
67
160
  }
161
+ /**
162
+ * Hook for shopping cart management
163
+ *
164
+ * @example
165
+ * ```tsx
166
+ * const { items, total, addToCart, removeItem, clearCart } = useCart();
167
+ *
168
+ * // Add to cart
169
+ * await addToCart(123, 2); // Add product ID 123, quantity 2
170
+ *
171
+ * // With variant
172
+ * await addToCart(123, 1, 456); // Product 123, variant 456
173
+ *
174
+ * // Display cart
175
+ * items.map(item => (
176
+ * <div key={item.id}>
177
+ * {item.product_name} x {item.quantity} = ${item.subtotal}
178
+ * </div>
179
+ * ));
180
+ *
181
+ * // Total
182
+ * console.log('Total:', total);
183
+ * ```
184
+ */
68
185
  declare function useCart(): UseCartReturn;
69
186
 
70
187
  interface UseWishlistReturn {
@@ -83,26 +200,96 @@ interface UseWishlistReturn {
83
200
  }
84
201
  declare function useWishlist(): UseWishlistReturn;
85
202
 
203
+ /**
204
+ * Return type for the useProducts hook
205
+ */
86
206
  interface UseProductsReturn {
207
+ /** Array of products */
87
208
  products: Product[];
209
+ /** Pagination metadata (current_page, last_page, total, per_page) */
88
210
  meta: PaginationMeta | null;
211
+ /** Whether products are loading */
89
212
  loading: boolean;
213
+ /** Error from last operation */
90
214
  error: Error | null;
215
+ /** Whether more pages are available */
91
216
  hasMore: boolean;
217
+ /** Load next page of products (appends to list) */
92
218
  loadMore: () => Promise<void>;
219
+ /** Refresh products from server */
93
220
  refresh: () => Promise<void>;
221
+ /**
222
+ * Search products by query
223
+ * @param query - Search term
224
+ */
94
225
  search: (query: string) => Promise<void>;
95
226
  }
227
+ /**
228
+ * Options for useProducts hook
229
+ */
96
230
  interface UseProductsOptions extends ProductListParams {
231
+ /** Whether to fetch products on mount (default: true) */
97
232
  autoFetch?: boolean;
98
233
  }
234
+ /**
235
+ * Hook for fetching products with pagination, filtering, and search
236
+ *
237
+ * @param options - Filtering and pagination options
238
+ * @example
239
+ * ```tsx
240
+ * // Basic usage
241
+ * const { products, loading } = useProducts();
242
+ *
243
+ * // With filters
244
+ * const { products } = useProducts({
245
+ * category: 'electronics',
246
+ * per_page: 20,
247
+ * sort: 'price_low',
248
+ * min_price: 10,
249
+ * max_price: 100,
250
+ * });
251
+ *
252
+ * // Infinite scroll
253
+ * const { products, hasMore, loadMore } = useProducts({ per_page: 12 });
254
+ * // Call loadMore() when user scrolls to bottom
255
+ *
256
+ * // Search
257
+ * const { products, search } = useProducts();
258
+ * await search('laptop'); // Searches products
259
+ * ```
260
+ */
99
261
  declare function useProducts(options?: UseProductsOptions): UseProductsReturn;
262
+ /**
263
+ * Return type for the useProduct hook
264
+ */
100
265
  interface UseProductReturn {
266
+ /** Product data, or null if not loaded */
101
267
  product: Product | null;
102
- loading: boolean;
103
- error: Error | null;
104
- refresh: () => Promise<void>;
105
- }
268
+ /** Whether product is loading */
269
+ loading: boolean;
270
+ /** Error from last operation */
271
+ error: Error | null;
272
+ /** Refresh product from server */
273
+ refresh: () => Promise<void>;
274
+ }
275
+ /**
276
+ * Hook for fetching a single product by ID or slug
277
+ *
278
+ * @param idOrSlug - Product ID (number) or slug (string)
279
+ * @example
280
+ * ```tsx
281
+ * // By slug (recommended)
282
+ * const { product, loading } = useProduct('wireless-headphones');
283
+ *
284
+ * // By ID
285
+ * const { product } = useProduct(123);
286
+ *
287
+ * // Display product
288
+ * if (product) {
289
+ * console.log(product.name, product.sale_price, product.images);
290
+ * }
291
+ * ```
292
+ */
106
293
  declare function useProduct(idOrSlug: number | string): UseProductReturn;
107
294
  interface UseCategoriesReturn {
108
295
  categories: ProductCategory[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diffsome/react",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "description": "React hooks and providers for Diffsome SDK - Headless e-commerce & CMS",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",