@eetech-commerce/cart-react 0.4.1
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 +356 -0
- package/dist/index.d.ts +663 -0
- package/dist/index.js +1692 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
# @eetech-commerce/cart-react
|
|
2
|
+
|
|
3
|
+
React hooks and provider for interacting with the EETech Commerce Cart API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @eetech-commerce/cart-react
|
|
9
|
+
# or
|
|
10
|
+
yarn add @eetech-commerce/cart-react
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @eetech-commerce/cart-react
|
|
13
|
+
# or
|
|
14
|
+
bun add @eetech-commerce/cart-react
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
For payment features (optional):
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @stripe/stripe-js
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import {
|
|
27
|
+
CartProvider,
|
|
28
|
+
useCart,
|
|
29
|
+
useAddToCart,
|
|
30
|
+
} from '@eetech-commerce/cart-react';
|
|
31
|
+
|
|
32
|
+
function App() {
|
|
33
|
+
return (
|
|
34
|
+
<CartProvider
|
|
35
|
+
tenantSlug="my-store"
|
|
36
|
+
cartApiUrl="https://cart.api.com"
|
|
37
|
+
>
|
|
38
|
+
<Shop />
|
|
39
|
+
</CartProvider>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function Shop() {
|
|
44
|
+
const { data: cart, isLoading } = useCart();
|
|
45
|
+
const { addToCart, isPending } = useAddToCart();
|
|
46
|
+
|
|
47
|
+
if (isLoading) return <div>Loading cart...</div>;
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div>
|
|
51
|
+
<h2>Cart ({cart?.items.length ?? 0} items)</h2>
|
|
52
|
+
<button
|
|
53
|
+
onClick={() => addToCart({ offerId: 'offer-123', quantity: 1 })}
|
|
54
|
+
disabled={isPending}
|
|
55
|
+
>
|
|
56
|
+
Add Item
|
|
57
|
+
</button>
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## CartProvider Configuration
|
|
64
|
+
|
|
65
|
+
| Prop | Type | Required | Default | Description |
|
|
66
|
+
|------|------|----------|---------|-------------|
|
|
67
|
+
| `tenantSlug` | `string` | Yes | - | Your tenant identifier |
|
|
68
|
+
| `cartApiUrl` | `string` | Yes | - | Base URL of the cart API |
|
|
69
|
+
| `storageAdapter` | `StorageAdapter` | No | `localStorage` | Custom storage implementation |
|
|
70
|
+
| `autoInitialize` | `boolean` | No | `true` | Auto-create cart on mount |
|
|
71
|
+
| `queryClient` | `QueryClient` | No | - | Custom TanStack Query client instance |
|
|
72
|
+
|
|
73
|
+
## Hooks Reference
|
|
74
|
+
|
|
75
|
+
### Cart Hooks
|
|
76
|
+
|
|
77
|
+
| Hook | Description |
|
|
78
|
+
|------|-------------|
|
|
79
|
+
| `useCart()` | Fetch the current cart |
|
|
80
|
+
| `useCreateCart()` | Create a new cart |
|
|
81
|
+
| `useAddToCart()` | Add an item to the cart |
|
|
82
|
+
| `useUpdateItemQty()` | Update item quantity |
|
|
83
|
+
| `useRemoveItem()` | Remove an item from cart |
|
|
84
|
+
| `useClearCart()` | Clear all items from cart |
|
|
85
|
+
| `useInitializeCart()` | Manually initialize cart (for `autoInitialize={false}`) |
|
|
86
|
+
|
|
87
|
+
### Checkout Hooks
|
|
88
|
+
|
|
89
|
+
| Hook | Description |
|
|
90
|
+
|------|-------------|
|
|
91
|
+
| `useVerifyCart()` | Verify cart items before checkout |
|
|
92
|
+
| `useCreateCheckoutSession()` | Create a checkout session |
|
|
93
|
+
| `useShippingOptions(cartSessionId)` | Fetch available shipping options |
|
|
94
|
+
| `useUpdateShippingSelections()` | Update selected shipping options |
|
|
95
|
+
|
|
96
|
+
### Payment Hooks
|
|
97
|
+
|
|
98
|
+
| Hook | Description |
|
|
99
|
+
|------|-------------|
|
|
100
|
+
| `useStripePromise()` | Get the Stripe.js instance |
|
|
101
|
+
| `useCreateEmbeddedCheckoutSession()` | Create an embedded payment session |
|
|
102
|
+
| `usePaymentSession(sessionId)` | Fetch payment session details |
|
|
103
|
+
|
|
104
|
+
### Context Hook
|
|
105
|
+
|
|
106
|
+
| Hook | Description |
|
|
107
|
+
|------|-------------|
|
|
108
|
+
| `useCartContext()` | Access cart context (tenantSlug, cartSessionId, etc.) |
|
|
109
|
+
|
|
110
|
+
## Mutation Callbacks
|
|
111
|
+
|
|
112
|
+
All mutation hooks support optional callbacks for success and error handling:
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
const { addToCart } = useAddToCart();
|
|
116
|
+
|
|
117
|
+
addToCart(
|
|
118
|
+
{ offerId: 'offer-123', quantity: 1 },
|
|
119
|
+
{
|
|
120
|
+
onSuccess: (cart) => {
|
|
121
|
+
toast('Added to cart!');
|
|
122
|
+
},
|
|
123
|
+
onError: (error) => {
|
|
124
|
+
toast.error(error.message);
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Custom Storage Adapter
|
|
131
|
+
|
|
132
|
+
By default, the cart session ID is stored in `localStorage`. You can provide a custom storage adapter for different storage mechanisms:
|
|
133
|
+
|
|
134
|
+
### Interface
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
interface StorageAdapter {
|
|
138
|
+
get(key: string): string | null;
|
|
139
|
+
set(key: string, value: string): void;
|
|
140
|
+
remove(key: string): void;
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Example: Cookie Adapter
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
import { CartProvider, type StorageAdapter } from '@eetech-commerce/cart-react';
|
|
148
|
+
import Cookies from 'js-cookie';
|
|
149
|
+
|
|
150
|
+
const cookieAdapter: StorageAdapter = {
|
|
151
|
+
get: (key) => Cookies.get(key) ?? null,
|
|
152
|
+
set: (key, value) => Cookies.set(key, value, { expires: 7 }),
|
|
153
|
+
remove: (key) => Cookies.remove(key),
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
function App() {
|
|
157
|
+
return (
|
|
158
|
+
<CartProvider
|
|
159
|
+
tenantSlug="my-store"
|
|
160
|
+
cartApiUrl="https://cart.api.com"
|
|
161
|
+
storageAdapter={cookieAdapter}
|
|
162
|
+
>
|
|
163
|
+
<Shop />
|
|
164
|
+
</CartProvider>
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Manual Cart Initialization
|
|
170
|
+
|
|
171
|
+
By default, `CartProvider` automatically creates a cart on mount. If you need more control over when the cart is created, set `autoInitialize={false}`:
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
import {
|
|
175
|
+
CartProvider,
|
|
176
|
+
useInitializeCart,
|
|
177
|
+
useCartContext,
|
|
178
|
+
} from '@eetech-commerce/cart-react';
|
|
179
|
+
|
|
180
|
+
function App() {
|
|
181
|
+
return (
|
|
182
|
+
<CartProvider
|
|
183
|
+
tenantSlug="my-store"
|
|
184
|
+
cartApiUrl="https://cart.api.com"
|
|
185
|
+
autoInitialize={false}
|
|
186
|
+
>
|
|
187
|
+
<CartInitializer />
|
|
188
|
+
<Shop />
|
|
189
|
+
</CartProvider>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function CartInitializer() {
|
|
194
|
+
const { isInitializing } = useInitializeCart();
|
|
195
|
+
const { cartSessionId } = useCartContext();
|
|
196
|
+
|
|
197
|
+
if (isInitializing) {
|
|
198
|
+
return <div>Initializing cart...</div>;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
This is useful when you want to:
|
|
206
|
+
- Delay cart creation until user interaction
|
|
207
|
+
- Initialize the cart conditionally based on route or user state
|
|
208
|
+
- Handle initialization loading states explicitly
|
|
209
|
+
|
|
210
|
+
## Using with Existing QueryClient
|
|
211
|
+
|
|
212
|
+
If your application already uses TanStack Query, you can pass your existing `QueryClient` to share the cache:
|
|
213
|
+
|
|
214
|
+
```tsx
|
|
215
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
216
|
+
import { CartProvider } from '@eetech-commerce/cart-react';
|
|
217
|
+
|
|
218
|
+
const queryClient = new QueryClient();
|
|
219
|
+
|
|
220
|
+
function App() {
|
|
221
|
+
return (
|
|
222
|
+
<QueryClientProvider client={queryClient}>
|
|
223
|
+
<CartProvider
|
|
224
|
+
tenantSlug="my-store"
|
|
225
|
+
cartApiUrl="https://cart.api.com"
|
|
226
|
+
queryClient={queryClient}
|
|
227
|
+
>
|
|
228
|
+
<Shop />
|
|
229
|
+
</CartProvider>
|
|
230
|
+
</QueryClientProvider>
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Benefits of sharing the QueryClient:
|
|
236
|
+
- Unified cache management across your application
|
|
237
|
+
- Shared devtools integration
|
|
238
|
+
- Consistent query/mutation defaults
|
|
239
|
+
|
|
240
|
+
## Payment Hooks (Stripe)
|
|
241
|
+
|
|
242
|
+
To use payment features, install `@stripe/stripe-js`:
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
npm install @stripe/stripe-js
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Using useStripePromise
|
|
249
|
+
|
|
250
|
+
The `useStripePromise` hook automatically fetches your tenant's Stripe publishable key and initializes Stripe.js:
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
import { useStripePromise } from '@eetech-commerce/cart-react';
|
|
254
|
+
import { Elements } from '@stripe/react-stripe-js';
|
|
255
|
+
|
|
256
|
+
function CheckoutPage() {
|
|
257
|
+
const stripePromise = useStripePromise();
|
|
258
|
+
|
|
259
|
+
if (!stripePromise) {
|
|
260
|
+
return <div>Loading payment provider...</div>;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return (
|
|
264
|
+
<Elements stripe={stripePromise}>
|
|
265
|
+
<PaymentForm />
|
|
266
|
+
</Elements>
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Creating an Embedded Checkout Session
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
import {
|
|
275
|
+
useCreateEmbeddedCheckoutSession,
|
|
276
|
+
useCartContext,
|
|
277
|
+
} from '@eetech-commerce/cart-react';
|
|
278
|
+
|
|
279
|
+
function CheckoutButton() {
|
|
280
|
+
const { cartSessionId } = useCartContext();
|
|
281
|
+
const { createEmbeddedCheckoutSession, isPending, data } =
|
|
282
|
+
useCreateEmbeddedCheckoutSession();
|
|
283
|
+
|
|
284
|
+
const handleCheckout = () => {
|
|
285
|
+
createEmbeddedCheckoutSession(
|
|
286
|
+
{
|
|
287
|
+
cartSessionId: cartSessionId!,
|
|
288
|
+
returnUrl: 'https://my-store.com/checkout/complete',
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
onSuccess: (session) => {
|
|
292
|
+
// Use session.clientSecret with Stripe Embedded Checkout
|
|
293
|
+
console.log('Session created:', session.id);
|
|
294
|
+
},
|
|
295
|
+
onError: (error) => {
|
|
296
|
+
console.error('Failed to create session:', error);
|
|
297
|
+
},
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
return (
|
|
303
|
+
<button onClick={handleCheckout} disabled={isPending}>
|
|
304
|
+
{isPending ? 'Creating session...' : 'Checkout'}
|
|
305
|
+
</button>
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## TypeScript
|
|
311
|
+
|
|
312
|
+
This package is fully typed. All hooks, providers, and utilities include TypeScript definitions.
|
|
313
|
+
|
|
314
|
+
### Exported Types
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
import type {
|
|
318
|
+
// Provider
|
|
319
|
+
CartProviderProps,
|
|
320
|
+
CartContextValue,
|
|
321
|
+
|
|
322
|
+
// Storage
|
|
323
|
+
StorageAdapter,
|
|
324
|
+
|
|
325
|
+
// Mutation callbacks
|
|
326
|
+
MutationCallbacks,
|
|
327
|
+
|
|
328
|
+
// API types
|
|
329
|
+
CartResponseDto,
|
|
330
|
+
LineItemResponseDto,
|
|
331
|
+
CreateCheckoutDto,
|
|
332
|
+
VerificationResultDto,
|
|
333
|
+
ShippingOptionDto,
|
|
334
|
+
ShippingSelectionDto,
|
|
335
|
+
CreateEmbeddedPaymentSessionDto,
|
|
336
|
+
EmbeddedPaymentSessionResponseDto,
|
|
337
|
+
} from '@eetech-commerce/cart-react';
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Advanced: Query Keys
|
|
341
|
+
|
|
342
|
+
For advanced cache control, query key factories are exported:
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
import { cartKeys, shippingKeys, paymentKeys } from '@eetech-commerce/cart-react';
|
|
346
|
+
|
|
347
|
+
// Invalidate all cart queries
|
|
348
|
+
queryClient.invalidateQueries({ queryKey: cartKeys.all() });
|
|
349
|
+
|
|
350
|
+
// Invalidate shipping options
|
|
351
|
+
queryClient.invalidateQueries({ queryKey: shippingKeys.all() });
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
## License
|
|
355
|
+
|
|
356
|
+
MIT
|