@classytic/commerce-sdk 0.1.1 → 0.1.2
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 +146 -164
- package/dist/{chunk-ANYGZ6O5.js → chunk-4IYW6RF3.js} +35 -3
- package/dist/chunk-4IYW6RF3.js.map +1 -0
- package/dist/{chunk-J4JBQET2.js → chunk-M3B4DFTT.js} +3 -3
- package/dist/{chunk-J4JBQET2.js.map → chunk-M3B4DFTT.js.map} +1 -1
- package/dist/{client-Cs7E_usr.d.ts → client-BPG8fbae.d.ts} +2 -2
- package/dist/index.d.ts +5 -5
- package/dist/index.js +2 -2
- package/dist/logistics/index.d.ts +3 -3
- package/dist/{logistics-CrpKadKE.d.ts → logistics-REVDorcc.d.ts} +1 -1
- package/dist/{order-B3dCvHgK.d.ts → order-BfdPxZiA.d.ts} +54 -2
- package/dist/{pos-BCqkx2-K.d.ts → pos-C-sBzevg.d.ts} +12 -1
- package/dist/sales/index.d.ts +38 -5
- package/dist/sales/index.js +1 -1
- package/dist/server.d.ts +4 -4
- package/dist/server.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-ANYGZ6O5.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,164 +1,146 @@
|
|
|
1
|
-
# @classytic/commerce-sdk
|
|
2
|
-
|
|
3
|
-
Modular API client and React hooks for the Classytic commerce platform.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @classytic/commerce-sdk
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Requirements
|
|
12
|
-
|
|
13
|
-
- React 19+
|
|
14
|
-
- Optional: Next.js
|
|
15
|
-
- Optional: @tanstack/react-query 5+ for hooks
|
|
16
|
-
|
|
17
|
-
## Quick Start
|
|
18
|
-
|
|
19
|
-
```typescript
|
|
20
|
-
import { initCommerceSDK } from '@classytic/commerce-sdk';
|
|
21
|
-
|
|
22
|
-
// Initialize once at app startup
|
|
23
|
-
initCommerceSDK({
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
import {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
import {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
##
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
import {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
All types are co-located with their modules:
|
|
149
|
-
|
|
150
|
-
```typescript
|
|
151
|
-
import type { Product, Category } from '@classytic/commerce-sdk/catalog';
|
|
152
|
-
import type { Order, Customer } from '@classytic/commerce-sdk/sales';
|
|
153
|
-
import type { StockEntry, Transfer } from '@classytic/commerce-sdk/inventory';
|
|
154
|
-
import type { User, UserRoleType } from '@classytic/commerce-sdk/auth';
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
### Local testing:
|
|
158
|
-
```
|
|
159
|
-
"@classytic/commerce-sdk": "file:D:/projects/ecom/commerce-bd-sdk/dist"
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
## License
|
|
163
|
-
|
|
164
|
-
Proprietary - see `LICENSE`
|
|
1
|
+
# @classytic/commerce-sdk
|
|
2
|
+
|
|
3
|
+
Modular API client and React hooks for the Classytic commerce platform.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @classytic/commerce-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
- React 19+
|
|
14
|
+
- Optional: Next.js 14+ for app/router usage
|
|
15
|
+
- Optional: @tanstack/react-query 5+ for hooks
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { initCommerceSDK } from '@classytic/commerce-sdk';
|
|
21
|
+
|
|
22
|
+
// Initialize once at app startup
|
|
23
|
+
initCommerceSDK({ baseUrl: process.env.NEXT_PUBLIC_API_URL! });
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Modules
|
|
27
|
+
|
|
28
|
+
Import what you need from domain-specific modules:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// Catalog (products, categories, size guides)
|
|
32
|
+
import { productApi, useProducts, useProductDetail } from '@classytic/commerce-sdk/catalog';
|
|
33
|
+
|
|
34
|
+
// Sales (orders, customers, cart, POS, transactions)
|
|
35
|
+
import { orderApi, useOrders, useCart } from '@classytic/commerce-sdk/sales';
|
|
36
|
+
|
|
37
|
+
// Inventory (stock, purchases, transfers, suppliers)
|
|
38
|
+
import { stockApi, useInventory, useTransfers } from '@classytic/commerce-sdk/inventory';
|
|
39
|
+
|
|
40
|
+
// Platform (branches, users, coupons, config)
|
|
41
|
+
import { branchApi, useBranches, usePlatformConfig } from '@classytic/commerce-sdk/platform';
|
|
42
|
+
|
|
43
|
+
// Auth (login, register, password reset)
|
|
44
|
+
import { loginApi, UserRole, verifyManagerAuth } from '@classytic/commerce-sdk/auth';
|
|
45
|
+
|
|
46
|
+
// Finance, Logistics, Content, Payments, Analytics
|
|
47
|
+
import { useFinanceSummary } from '@classytic/commerce-sdk/finance';
|
|
48
|
+
import { useDeliveryCharge } from '@classytic/commerce-sdk/logistics';
|
|
49
|
+
import { mediaApi, useCMSPage } from '@classytic/commerce-sdk/content';
|
|
50
|
+
import { usePaymentActions } from '@classytic/commerce-sdk/payments';
|
|
51
|
+
import { useAnalyticsDashboard } from '@classytic/commerce-sdk/analytics';
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Usage Patterns
|
|
55
|
+
|
|
56
|
+
### Server Components / API Routes
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { productApi } from '@classytic/commerce-sdk/catalog';
|
|
60
|
+
|
|
61
|
+
// Fetch data server-side
|
|
62
|
+
const products = await productApi.getAll({ params: { page: 1 } });
|
|
63
|
+
const product = await productApi.getBySlug({ slug: 'my-product' });
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Client Components (React Query hooks)
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { useProducts, useProductActions } from '@classytic/commerce-sdk/catalog';
|
|
70
|
+
|
|
71
|
+
function ProductList({ token }) {
|
|
72
|
+
const { items, isLoading } = useProducts(token, { page: 1 });
|
|
73
|
+
const { create, update, remove } = useProductActions(token);
|
|
74
|
+
|
|
75
|
+
// ...
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Core Utilities
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
import { handleApiRequest, BaseApi } from '@classytic/commerce-sdk/core';
|
|
83
|
+
|
|
84
|
+
// Make custom API calls
|
|
85
|
+
const data = await handleApiRequest('POST', '/api/v1/custom', {
|
|
86
|
+
token,
|
|
87
|
+
body: { ... }
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Guest Checkout
|
|
92
|
+
|
|
93
|
+
Place orders without authentication. The frontend stores cart items in localStorage and sends them directly in the request body along with guest identity.
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import { useGuestCheckout } from '@classytic/commerce-sdk/sales';
|
|
97
|
+
import type { GuestCheckoutPayload } from '@classytic/commerce-sdk/sales';
|
|
98
|
+
|
|
99
|
+
function GuestCheckoutButton({ cartItems }) {
|
|
100
|
+
const { guestCheckout, isCheckingOut } = useGuestCheckout();
|
|
101
|
+
|
|
102
|
+
const handleCheckout = async () => {
|
|
103
|
+
const order = await guestCheckout({
|
|
104
|
+
items: cartItems.map(item => ({
|
|
105
|
+
productId: item.productId,
|
|
106
|
+
variantSku: item.variantSku,
|
|
107
|
+
quantity: item.quantity,
|
|
108
|
+
})),
|
|
109
|
+
guest: { name: 'John Doe', phone: '01712345678', email: 'john@example.com' },
|
|
110
|
+
deliveryAddress: { recipientName: 'John', recipientPhone: '01712345678', addressLine1: '...', areaId: 1 },
|
|
111
|
+
delivery: { method: 'standard', price: 80 },
|
|
112
|
+
paymentData: { type: 'bkash', reference: 'TRX123' },
|
|
113
|
+
idempotencyKey: `guest_01712345678_${Date.now()}`,
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
return <button onClick={handleCheckout} disabled={isCheckingOut}>Place Order</button>;
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Or call the API directly without React:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { orderApi } from '@classytic/commerce-sdk/sales';
|
|
125
|
+
|
|
126
|
+
const response = await orderApi.guestCheckout({
|
|
127
|
+
data: { items, guest, deliveryAddress, delivery, paymentData },
|
|
128
|
+
});
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
No auth token is required. Product prices are always resolved from the database server-side. Repeat guests are matched by phone number.
|
|
132
|
+
|
|
133
|
+
## Types
|
|
134
|
+
|
|
135
|
+
All types are co-located with their modules:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import type { Product, Category } from '@classytic/commerce-sdk/catalog';
|
|
139
|
+
import type { Order, Customer } from '@classytic/commerce-sdk/sales';
|
|
140
|
+
import type { StockEntry, Transfer } from '@classytic/commerce-sdk/inventory';
|
|
141
|
+
import type { User, UserRoleType } from '@classytic/commerce-sdk/auth';
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
Proprietary - see `LICENSE`
|
|
@@ -110,6 +110,17 @@ var OrderApi = class extends BaseApi {
|
|
|
110
110
|
* POST /api/v1/orders
|
|
111
111
|
*/
|
|
112
112
|
this.checkout = ({ token, organizationId, data }) => this.create({ token, organizationId, data });
|
|
113
|
+
/**
|
|
114
|
+
* Guest checkout - create order without authentication
|
|
115
|
+
* POST /api/v1/orders/guest
|
|
116
|
+
*
|
|
117
|
+
* Items are sent in the request body (from FE localStorage).
|
|
118
|
+
* Guest identity is provided via { name, phone, email }.
|
|
119
|
+
*/
|
|
120
|
+
this.guestCheckout = ({ data, organizationId }) => this.request("POST", `${this.baseUrl}/guest`, {
|
|
121
|
+
organizationId,
|
|
122
|
+
data
|
|
123
|
+
});
|
|
113
124
|
/** Get my orders */
|
|
114
125
|
this.getMyOrders = ({ token, params = {} }) => this.request("GET", `${this.baseUrl}/my`, { token, params });
|
|
115
126
|
/** Get my order detail */
|
|
@@ -482,6 +493,27 @@ function useCustomerOrderActions(token) {
|
|
|
482
493
|
isLoading: checkoutMutation.isPending || requestCancelMutation.isPending
|
|
483
494
|
};
|
|
484
495
|
}
|
|
496
|
+
function useGuestCheckout() {
|
|
497
|
+
const queryClient = useQueryClient();
|
|
498
|
+
const toast = getToastHandler();
|
|
499
|
+
const mutation = useMutation({
|
|
500
|
+
mutationFn: async (data) => {
|
|
501
|
+
const response = await orderApi.guestCheckout({ data });
|
|
502
|
+
return response.data;
|
|
503
|
+
},
|
|
504
|
+
onSuccess: () => {
|
|
505
|
+
queryClient.invalidateQueries({ queryKey: ORDER_KEYS.all });
|
|
506
|
+
toast.success("Order placed successfully!");
|
|
507
|
+
},
|
|
508
|
+
onError: (error) => {
|
|
509
|
+
toast.error(error.message || "Failed to place order");
|
|
510
|
+
}
|
|
511
|
+
});
|
|
512
|
+
return {
|
|
513
|
+
guestCheckout: mutation.mutateAsync,
|
|
514
|
+
isCheckingOut: mutation.isPending
|
|
515
|
+
};
|
|
516
|
+
}
|
|
485
517
|
function useAdminOrderActions(token) {
|
|
486
518
|
const queryClient = useQueryClient();
|
|
487
519
|
const toast = getToastHandler();
|
|
@@ -825,6 +857,6 @@ function getPosProductImage(product) {
|
|
|
825
857
|
return firstImage.variants?.thumbnail || firstImage.url;
|
|
826
858
|
}
|
|
827
859
|
|
|
828
|
-
export { CART_KEYS, CUSTOMER_KEYS, CustomerApi, ORDER_KEYS, OrderStatus, POS_KEYS, PaymentStatus, calculateCartSubtotal, calculateItemPrice, calculateItemTotal, calculateVariantPrice, cartApi, customerApi, customerHooks, findVariantBySku, formatVariantAttributes, formatVariantLabel, generateIdempotencyKey, getAvailableVariants, getCartItemCount, getCartItemVariant, getPosProductImage, getVariantStock, isInStock, isVariantProduct, orderApi, orderHooks, order_default, useAdminOrderActions, useCart, useCartCount, useCurrentCustomer, useCustomerActions, useCustomerDetail, useCustomerMembership, useCustomerNavigation, useCustomerOrderActions, useCustomers, useMyOrderDetail, useMyOrders, useOrderActions, useOrderDetail, useOrderNavigation, useOrders, usePosLookup, usePosLookupMutation, usePosOrders, usePosProducts, usePosReceipt, usePosStockActions };
|
|
829
|
-
//# sourceMappingURL=chunk-
|
|
830
|
-
//# sourceMappingURL=chunk-
|
|
860
|
+
export { CART_KEYS, CUSTOMER_KEYS, CustomerApi, ORDER_KEYS, OrderStatus, POS_KEYS, PaymentStatus, calculateCartSubtotal, calculateItemPrice, calculateItemTotal, calculateVariantPrice, cartApi, customerApi, customerHooks, findVariantBySku, formatVariantAttributes, formatVariantLabel, generateIdempotencyKey, getAvailableVariants, getCartItemCount, getCartItemVariant, getPosProductImage, getVariantStock, isInStock, isVariantProduct, orderApi, orderHooks, order_default, useAdminOrderActions, useCart, useCartCount, useCurrentCustomer, useCustomerActions, useCustomerDetail, useCustomerMembership, useCustomerNavigation, useCustomerOrderActions, useCustomers, useGuestCheckout, useMyOrderDetail, useMyOrders, useOrderActions, useOrderDetail, useOrderNavigation, useOrders, usePosLookup, usePosLookupMutation, usePosOrders, usePosProducts, usePosReceipt, usePosStockActions };
|
|
861
|
+
//# sourceMappingURL=chunk-4IYW6RF3.js.map
|
|
862
|
+
//# sourceMappingURL=chunk-4IYW6RF3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sales/types/order.ts","../src/sales/api/cart.ts","../src/sales/api/order.ts","../src/sales/api/customer.ts","../src/sales/hooks/cart.ts","../src/sales/hooks/order.ts","../src/sales/hooks/customer.ts","../src/sales/hooks/pos.ts"],"names":["OrderStatus","PaymentStatus","useQuery","useQueryClient","useMutation"],"mappings":"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","file":"chunk-4IYW6RF3.js","sourcesContent":["/**\r\n * Order Types\r\n *\r\n * Source of truth: modules/commerce/order/order.model.js\r\n */\r\n\r\n// Shipping status types (normalized order shipping status)\r\nexport type ShippingStatus =\r\n | 'pending'\r\n | 'requested'\r\n | 'picked_up'\r\n | 'in_transit'\r\n | 'out_for_delivery'\r\n | 'delivered'\r\n | 'failed_attempt'\r\n | 'returned'\r\n | 'cancelled';\r\n\r\n// Shipping provider types (maps to logistics LogisticsProvider)\r\nexport type ShippingProvider =\r\n | 'redx'\r\n | 'pathao'\r\n | 'steadfast'\r\n | 'paperfly'\r\n | 'sundarban'\r\n | 'sa_paribahan'\r\n | 'dhl'\r\n | 'fedex'\r\n | 'manual'\r\n | 'other';\r\n\r\nexport enum OrderStatus {\r\n PENDING = 'pending',\r\n PROCESSING = 'processing',\r\n CONFIRMED = 'confirmed',\r\n SHIPPED = 'shipped',\r\n DELIVERED = 'delivered',\r\n CANCELLED = 'cancelled',\r\n}\r\n\r\nexport enum PaymentStatus {\r\n PENDING = 'pending',\r\n VERIFIED = 'verified',\r\n FAILED = 'failed',\r\n REFUNDED = 'refunded',\r\n PARTIALLY_REFUNDED = 'partially_refunded',\r\n CANCELLED = 'cancelled',\r\n}\r\n\r\n/**\r\n * Order Item\r\n */\r\nexport interface OrderItem {\r\n _id?: string;\r\n product: string; // Product ID\r\n productName: string;\r\n productSlug?: string;\r\n\r\n // Variant Snapshot\r\n variantSku?: string;\r\n variantAttributes?: Record<string, string>;\r\n variantPriceModifier?: number;\r\n\r\n quantity: number;\r\n price: number;\r\n\r\n /**\r\n * System field: Cost of Goods Sold at time of sale\r\n * Used for profit calculation. Read-only.\r\n */\r\n costPriceAtSale?: number;\r\n\r\n vatRate?: number;\r\n vatAmount?: number;\r\n\r\n // Virtuals\r\n lineTotal?: number;\r\n lineTotalExVat?: number;\r\n profit?: number | null;\r\n profitMargin?: number | null;\r\n}\r\n\r\nexport interface OrderDelivery {\r\n method: string;\r\n price: number;\r\n estimatedDays?: number;\r\n}\r\n\r\n/**\r\n * Order Delivery Address\r\n */\r\nexport interface OrderAddress {\r\n /** Address label (e.g., \"Home\", \"Office\") - optional */\r\n label?: string;\r\n\r\n /** Recipient name for delivery label */\r\n recipientName?: string;\r\n\r\n /** Contact phone for delivery (format: 01XXXXXXXXX) */\r\n recipientPhone?: string;\r\n\r\n /** Street address (required for checkout) */\r\n addressLine1?: string;\r\n\r\n /** Additional address details (apartment, floor, etc.) */\r\n addressLine2?: string;\r\n\r\n /** Area ID from @classytic/bd-areas constants */\r\n areaId?: number;\r\n\r\n /** Area display name (e.g., \"Mohammadpur\", \"Dhanmondi\") */\r\n areaName?: string;\r\n\r\n /** Zone ID for delivery pricing (1-6) */\r\n zoneId?: number;\r\n\r\n /** Provider-specific area IDs for logistics integration */\r\n providerAreaIds?: {\r\n redx?: number;\r\n pathao?: number;\r\n steadfast?: number;\r\n };\r\n\r\n /** City/District name */\r\n city?: string;\r\n\r\n /** Division/State */\r\n division?: string;\r\n\r\n /** Postal code */\r\n postalCode?: string;\r\n\r\n /** Country (defaults to \"Bangladesh\") */\r\n country?: string;\r\n}\r\n\r\nexport interface OrderVat {\r\n applicable: boolean;\r\n rate: number;\r\n amount: number;\r\n pricesIncludeVat: boolean;\r\n taxableAmount: number;\r\n sellerBin?: string;\r\n invoiceNumber?: string;\r\n invoiceIssuedAt?: string;\r\n invoiceBranch?: string;\r\n invoiceDateKey?: string;\r\n}\r\n\r\nexport interface OrderPayment {\r\n transactionId?: string;\r\n /** Amount in paisa (smallest unit). Divide by 100 for BDT display. */\r\n amount: number;\r\n status: PaymentStatus | string;\r\n method: string;\r\n reference?: string;\r\n verifiedAt?: string;\r\n verifiedBy?: string;\r\n}\r\n\r\nexport interface OrderShippingHistory {\r\n status: ShippingStatus | string;\r\n note?: string;\r\n actor?: string;\r\n timestamp: string;\r\n}\r\n\r\nexport interface OrderShipping {\r\n provider?: ShippingProvider | string;\r\n status?: ShippingStatus | string;\r\n trackingNumber?: string;\r\n trackingUrl?: string;\r\n consignmentId?: string;\r\n labelUrl?: string;\r\n estimatedDelivery?: string;\r\n requestedAt?: string;\r\n pickedUpAt?: string;\r\n deliveredAt?: string;\r\n metadata?: Record<string, unknown>;\r\n history?: OrderShippingHistory[];\r\n}\r\n\r\n/**\r\n * Parcel metrics for delivery estimation\r\n */\r\nexport interface OrderParcel {\r\n /** Total weight in grams */\r\n weightGrams: number;\r\n /** Package dimensions in centimeters */\r\n dimensionsCm?: {\r\n length: number;\r\n width: number;\r\n height: number;\r\n };\r\n /** Number of items without weight data */\r\n missingWeightItems: number;\r\n /** Number of items without dimension data */\r\n missingDimensionItems: number;\r\n}\r\n\r\n/**\r\n * Cancellation request details\r\n */\r\nexport interface CancellationRequest {\r\n requested: boolean;\r\n reason?: string;\r\n requestedAt?: string;\r\n requestedBy?: string;\r\n}\r\n\r\n/**\r\n * Main Order Interface\r\n */\r\nexport interface Order {\r\n _id: string;\r\n /** Virtual: last 8 chars of _id (uppercase) */\r\n orderNumber?: string;\r\n\r\n customer?: string;\r\n customerName: string;\r\n customerPhone?: string;\r\n customerEmail?: string;\r\n userId?: string;\r\n\r\n items: OrderItem[];\r\n\r\n subtotal: number;\r\n discountAmount: number;\r\n deliveryCharge: number;\r\n totalAmount: number;\r\n\r\n vat?: OrderVat;\r\n\r\n delivery?: OrderDelivery;\r\n deliveryAddress?: OrderAddress;\r\n /** True if ordering on behalf of someone else (gift order) */\r\n isGift?: boolean;\r\n\r\n status: OrderStatus | string;\r\n source: 'web' | 'pos' | 'api' | 'guest';\r\n\r\n // POS specific\r\n branch?: string;\r\n terminalId?: string;\r\n cashier?: string;\r\n /** Idempotency key for safe retries */\r\n idempotencyKey?: string;\r\n\r\n // Stock reservation (web checkout)\r\n /** Reservation ID for stock hold */\r\n stockReservationId?: string;\r\n stockReservationExpiresAt?: string;\r\n\r\n currentPayment?: OrderPayment;\r\n shipping?: OrderShipping;\r\n\r\n /** Parcel metrics for delivery estimation */\r\n parcel?: OrderParcel;\r\n\r\n /** Customer cancellation request (awaiting admin review) */\r\n cancellationRequest?: CancellationRequest;\r\n /** Final cancellation reason (after cancelled) */\r\n cancellationReason?: string;\r\n\r\n notes?: string;\r\n\r\n createdAt: string;\r\n updatedAt: string;\r\n\r\n // Virtuals\r\n canCancel?: boolean;\r\n isCompleted?: boolean;\r\n paymentStatus?: string;\r\n paymentMethod?: string;\r\n netAmount?: number;\r\n grossAmount?: number;\r\n\r\n // Backward compatibility virtuals (from shipping)\r\n trackingNumber?: string;\r\n shippedAt?: string;\r\n deliveredAt?: string;\r\n shippingStatus?: string;\r\n}\r\n\r\n/**\r\n * Payment Data for checkout\r\n */\r\nexport interface PaymentData {\r\n /**\r\n * Payment method (optional, defaults to 'cash')\r\n */\r\n type?: 'cash' | 'bkash' | 'nagad' | 'rocket' | 'bank_transfer' | 'card' | string;\r\n\r\n /**\r\n * Payment gateway (default: 'manual')\r\n */\r\n gateway?: string;\r\n\r\n /**\r\n * Transaction ID/reference (recommended for verification)\r\n */\r\n reference?: string;\r\n\r\n /**\r\n * Mobile wallet sender phone (REQUIRED for bkash/nagad/rocket)\r\n */\r\n senderPhone?: string;\r\n\r\n /**\r\n * Additional payment verification details\r\n */\r\n paymentDetails?: {\r\n walletNumber?: string;\r\n walletType?: 'personal' | 'merchant';\r\n bankName?: string;\r\n accountNumber?: string;\r\n accountName?: string;\r\n proofUrl?: string;\r\n };\r\n\r\n /** Additional payment notes */\r\n notes?: string;\r\n}\r\n\r\n/**\r\n * Payload for Creating an Order (Web/API)\r\n */\r\nexport interface CreateOrderPayload {\r\n /** Delivery address (required) */\r\n deliveryAddress: OrderAddress & {\r\n recipientName: string;\r\n recipientPhone: string;\r\n addressLine1: string;\r\n areaId: number;\r\n areaName: string;\r\n zoneId: number;\r\n city: string;\r\n };\r\n\r\n /** Delivery method and pricing (required) */\r\n delivery: OrderDelivery & {\r\n method: string;\r\n price: number;\r\n };\r\n\r\n /**\r\n * Payment details for verification (optional, defaults to cash)\r\n */\r\n paymentData?: PaymentData;\r\n\r\n /** True if ordering on behalf of someone else (gift order) */\r\n isGift?: boolean;\r\n /** Coupon code to apply */\r\n couponCode?: string;\r\n /** Order notes */\r\n notes?: string;\r\n\r\n /** Preferred branch ID for fulfillment */\r\n branchId?: string;\r\n /** Preferred branch slug (alternative to branchId) */\r\n branchSlug?: string;\r\n /** Idempotency key for safe retries (prevents duplicate orders) */\r\n idempotencyKey?: string;\r\n}\r\n\r\n/**\r\n * Guest checkout item (from FE localStorage)\r\n */\r\nexport interface GuestCheckoutItem {\r\n /** Product ID */\r\n productId: string;\r\n /** Variant SKU (for variant products) */\r\n variantSku?: string | null;\r\n /** Quantity */\r\n quantity: number;\r\n}\r\n\r\n/**\r\n * Guest identity for unauthenticated checkout\r\n */\r\nexport interface GuestInfo {\r\n /** Guest name */\r\n name: string;\r\n /** Guest phone (BD format: 01XXXXXXXXX) */\r\n phone: string;\r\n /** Guest email (optional) */\r\n email?: string;\r\n}\r\n\r\n/**\r\n * Payload for Guest Checkout (no auth required)\r\n *\r\n * Items come from FE localStorage instead of a DB cart.\r\n * Guest identity is provided via name + phone.\r\n */\r\nexport interface GuestCheckoutPayload {\r\n /** Cart items from frontend localStorage */\r\n items: GuestCheckoutItem[];\r\n /** Guest identity (used to create/find customer record) */\r\n guest: GuestInfo;\r\n\r\n /** Delivery address (required) */\r\n deliveryAddress: CreateOrderPayload['deliveryAddress'];\r\n /** Delivery method and pricing (required) */\r\n delivery: CreateOrderPayload['delivery'];\r\n\r\n /** Payment details for verification (optional, defaults to cash) */\r\n paymentData?: PaymentData;\r\n /** True if ordering on behalf of someone else (gift order) */\r\n isGift?: boolean;\r\n /** Coupon code to apply */\r\n couponCode?: string;\r\n /** Order notes */\r\n notes?: string;\r\n /** Preferred branch ID for fulfillment */\r\n branchId?: string;\r\n /** Preferred branch slug (alternative to branchId) */\r\n branchSlug?: string;\r\n /** Idempotency key for safe retries */\r\n idempotencyKey?: string;\r\n}\r\n\r\n/**\r\n * Payload for Updating Order Status (Admin)\r\n */\r\nexport interface UpdateStatusPayload {\r\n status: OrderStatus;\r\n /** Optional note for status change */\r\n note?: string;\r\n}\r\n\r\n/**\r\n * Payload for Cancelling an Order\r\n */\r\nexport interface CancelOrderPayload {\r\n /** Cancellation reason */\r\n reason?: string;\r\n /** Process refund if payment was verified */\r\n refund?: boolean;\r\n}\r\n\r\n/**\r\n * Payload for Requesting Cancellation (awaits admin review)\r\n */\r\nexport interface CancelRequestPayload {\r\n /** Reason for cancellation request */\r\n reason?: string;\r\n}\r\n\r\n/**\r\n * Payload for Fulfilling/Shipping an Order (Admin)\r\n */\r\nexport interface FulfillOrderPayload {\r\n /** Shipping tracking number */\r\n trackingNumber?: string;\r\n /** Shipping carrier (e.g., Pathao, Redx) */\r\n carrier?: string;\r\n /** Fulfillment notes */\r\n notes?: string;\r\n /** Shipping date */\r\n shippedAt?: string;\r\n /** Estimated delivery date */\r\n estimatedDelivery?: string;\r\n /** Branch ID for inventory decrement (overrides order.branch) */\r\n branchId?: string;\r\n /** Branch slug (alternative to branchId) */\r\n branchSlug?: string;\r\n /**\r\n * Record COGS expense transaction (default: false)\r\n */\r\n recordCogs?: boolean;\r\n}\r\n\r\n/**\r\n * Payload for Refunding an Order (Admin)\r\n */\r\nexport interface RefundOrderPayload {\r\n /** Refund amount in smallest unit (paisa). Omit for full refund. */\r\n amount?: number;\r\n /** Refund reason */\r\n reason?: string;\r\n}\r\n\r\n/**\r\n * Payload for Requesting Shipping Pickup (Admin)\r\n */\r\nexport interface RequestShippingPayload {\r\n /** Shipping provider (required) */\r\n provider: string;\r\n /** Additional shipping options */\r\n options?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Payload for Updating Shipping Status (Admin/Webhook)\r\n */\r\nexport interface UpdateShippingPayload {\r\n /** Shipping status (required) */\r\n status: string;\r\n /** Status note */\r\n note?: string;\r\n /** Tracking number */\r\n trackingNumber?: string;\r\n /** Tracking URL */\r\n trackingUrl?: string;\r\n}\r\n","/**\r\n * Cart API Client\r\n *\r\n * **Authentication:** Required for all endpoints (use Bearer token)\r\n *\r\n * **Base URL:** `/api/v1/cart`\r\n *\r\n * **Endpoints:**\r\n * - `GET /api/v1/cart` - Get current user's cart (auto-creates if doesn't exist)\r\n * - `POST /api/v1/cart/items` - Add item to cart (productId + quantity + optional variantSku)\r\n * - `PATCH /api/v1/cart/items/:itemId` - Update cart item quantity\r\n * - `DELETE /api/v1/cart/items/:itemId` - Remove item from cart\r\n * - `DELETE /api/v1/cart` - Clear all items from cart\r\n *\r\n * **Response Format:** All endpoints return `{ success: true, data: Cart }`\r\n */\r\n\r\nimport { type ApiResponse } from '../../core/api-factory';\r\nimport { handleApiRequest } from '../../core/api-handler';\r\nimport type { Cart, AddCartItemPayload } from '../types/cart';\r\n\r\nconst ENDPOINT = '/api/v1/cart';\r\n\r\nexport const cartApi = {\r\n /**\r\n * Get current user's cart\r\n * GET /api/v1/cart\r\n *\r\n * Auto-creates cart if it doesn't exist for the user.\r\n * Returns cart with fully populated product details.\r\n *\r\n * @param token - User authentication token\r\n * @returns Cart with items array\r\n */\r\n getCart: async (token: string): Promise<Cart> => {\r\n const response = await handleApiRequest<ApiResponse<Cart>>('GET', ENDPOINT, { token });\r\n return response.data!;\r\n },\r\n\r\n /**\r\n * Add item to cart\r\n * POST /api/v1/cart/items\r\n *\r\n * @param token - User authentication token\r\n * @param data - Product ID, quantity, and optional variant SKU\r\n * @returns Updated cart\r\n */\r\n addToCart: async (token: string, data: AddCartItemPayload): Promise<Cart> => {\r\n const response = await handleApiRequest<ApiResponse<Cart>>('POST', `${ENDPOINT}/items`, {\r\n token,\r\n body: data,\r\n });\r\n return response.data!;\r\n },\r\n\r\n /**\r\n * Update cart item quantity\r\n * PATCH /api/v1/cart/items/:itemId\r\n *\r\n * @param token - User authentication token\r\n * @param itemId - Cart item ID (from cart.items[]._id)\r\n * @param quantity - New quantity (minimum: 1)\r\n * @returns Updated cart\r\n */\r\n updateCartItem: async (token: string, itemId: string, quantity: number): Promise<Cart> => {\r\n const response = await handleApiRequest<ApiResponse<Cart>>('PATCH', `${ENDPOINT}/items/${itemId}`, {\r\n token,\r\n body: { quantity },\r\n });\r\n return response.data!;\r\n },\r\n\r\n /**\r\n * Remove item from cart\r\n * DELETE /api/v1/cart/items/:itemId\r\n *\r\n * @param token - User authentication token\r\n * @param itemId - Cart item ID (from cart.items[]._id)\r\n * @returns Updated cart\r\n */\r\n removeCartItem: async (token: string, itemId: string): Promise<Cart> => {\r\n const response = await handleApiRequest<ApiResponse<Cart>>('DELETE', `${ENDPOINT}/items/${itemId}`, {\r\n token,\r\n });\r\n return response.data!;\r\n },\r\n\r\n /**\r\n * Clear all items from cart\r\n * DELETE /api/v1/cart\r\n *\r\n * @param token - User authentication token\r\n * @returns Empty cart\r\n */\r\n clearCart: async (token: string): Promise<Cart> => {\r\n const response = await handleApiRequest<ApiResponse<Cart>>('DELETE', ENDPOINT, { token });\r\n return response.data!;\r\n },\r\n};\r\n","/**\r\n * Order API Client\r\n *\r\n * Customer: checkout, getMyOrders, getMyOrder, cancel, requestCancellation\r\n * Admin: updateStatus, fulfill, refund, requestShipping, updateShipping\r\n */\r\n\r\nimport { BaseApi } from '../../core/api-factory';\r\nimport type {\r\n Order,\r\n OrderShipping,\r\n CreateOrderPayload,\r\n GuestCheckoutPayload,\r\n UpdateStatusPayload,\r\n FulfillOrderPayload,\r\n RefundOrderPayload,\r\n RequestShippingPayload,\r\n UpdateShippingPayload,\r\n} from '../types/order';\r\n\r\nclass OrderApi extends BaseApi<Order, CreateOrderPayload, Partial<Order>> {\r\n\r\n // ============ Customer ============\r\n\r\n /**\r\n * Checkout - create order from cart\r\n * POST /api/v1/orders\r\n */\r\n checkout = ({ token, organizationId, data }: {\r\n token: string;\r\n organizationId?: string | null;\r\n data: CreateOrderPayload;\r\n }) => this.create({ token, organizationId, data });\r\n\r\n /**\r\n * Guest checkout - create order without authentication\r\n * POST /api/v1/orders/guest\r\n *\r\n * Items are sent in the request body (from FE localStorage).\r\n * Guest identity is provided via { name, phone, email }.\r\n */\r\n guestCheckout = ({ data, organizationId }: {\r\n data: GuestCheckoutPayload;\r\n organizationId?: string | null;\r\n }) => this.request<Order>('POST', `${this.baseUrl}/guest`, {\r\n organizationId,\r\n data,\r\n });\r\n\r\n /** Get my orders */\r\n getMyOrders = ({ token, params = {} }: {\r\n token: string;\r\n params?: Record<string, unknown>;\r\n }) => this.request<Order[]>('GET', `${this.baseUrl}/my`, { token, params });\r\n\r\n /** Get my order detail */\r\n getMyOrder = ({ token, id }: {\r\n token: string;\r\n id: string;\r\n }) => this.request<Order>('GET', `${this.baseUrl}/my/${id}`, { token });\r\n\r\n /** Cancel order */\r\n cancel = ({ token, id, reason, refund = false }: {\r\n token: string;\r\n id: string;\r\n reason?: string;\r\n refund?: boolean;\r\n }) => this.request<Order>('POST', `${this.baseUrl}/${id}/cancel`, {\r\n token,\r\n data: { reason, refund },\r\n });\r\n\r\n /** Request cancellation (awaits admin review) */\r\n requestCancellation = ({ token, id, reason }: {\r\n token: string;\r\n id: string;\r\n reason?: string;\r\n }) => this.request<Order>('POST', `${this.baseUrl}/${id}/cancel-request`, {\r\n token,\r\n data: { reason },\r\n });\r\n\r\n // ============ Admin ============\r\n\r\n /** Update order status */\r\n updateStatus = ({ token, organizationId, id, data }: {\r\n token: string;\r\n organizationId?: string | null;\r\n id: string;\r\n data: UpdateStatusPayload;\r\n }) => this.request<Order>('PATCH', `${this.baseUrl}/${id}/status`, {\r\n token,\r\n organizationId,\r\n data,\r\n });\r\n\r\n /**\r\n * Fulfill order (ship)\r\n * - Decrements inventory from branch\r\n * - recordCogs: true -> also creates COGS expense transaction\r\n */\r\n fulfill = ({ token, organizationId, id, data = {} }: {\r\n token: string;\r\n organizationId?: string | null;\r\n id: string;\r\n data?: FulfillOrderPayload;\r\n }) => this.request<Order>('POST', `${this.baseUrl}/${id}/fulfill`, {\r\n token,\r\n organizationId,\r\n data,\r\n });\r\n\r\n /** Refund order */\r\n refund = ({ token, organizationId, id, data = {} }: {\r\n token: string;\r\n organizationId?: string | null;\r\n id: string;\r\n data?: RefundOrderPayload;\r\n }) => this.request<Order>('POST', `${this.baseUrl}/${id}/refund`, {\r\n token,\r\n organizationId,\r\n data,\r\n });\r\n\r\n // ============ Shipping ============\r\n\r\n /** Get shipping info */\r\n getShipping = ({ token, id }: {\r\n token: string;\r\n id: string;\r\n }) => this.request<OrderShipping>('GET', `${this.baseUrl}/${id}/shipping`, { token });\r\n\r\n /** Request shipping pickup */\r\n requestShipping = ({ token, organizationId, id, data }: {\r\n token: string;\r\n organizationId?: string | null;\r\n id: string;\r\n data: RequestShippingPayload;\r\n }) => this.request<OrderShipping>('POST', `${this.baseUrl}/${id}/shipping`, {\r\n token,\r\n organizationId,\r\n data,\r\n });\r\n\r\n /** Update shipping status */\r\n updateShipping = ({ token, organizationId, id, data }: {\r\n token: string;\r\n organizationId?: string | null;\r\n id: string;\r\n data: UpdateShippingPayload;\r\n }) => this.request<OrderShipping>('PATCH', `${this.baseUrl}/${id}/shipping`, {\r\n token,\r\n organizationId,\r\n data,\r\n });\r\n}\r\n\r\nexport const orderApi = new OrderApi('orders');\r\nexport default orderApi;\r\n","/**\r\n * Customer API - CRUD + helper endpoint\r\n *\r\n * Standard CRUD (inherited from BaseApi):\r\n * - getAll({ token, params }) - list with filtering/search/pagination\r\n * - getById({ token, id }) - get by ID\r\n * - update({ token, id, data }) - update (admin/staff rules apply)\r\n * - delete({ token, id }) - delete (admin only)\r\n *\r\n * Notes:\r\n * - Customers may be auto-created by backend workflows; some environments may not expose create.\r\n *\r\n * Extra endpoint:\r\n * - getMe({ token }) - current user's customer profile\r\n */\r\n\r\nimport { BaseApi, type ApiResponse, type RequestOptions } from '../../core/api-factory';\r\nimport { handleApiRequest } from '../../core/api-handler';\r\nimport type { Customer, CustomerPayload, CustomerQueryParams } from '../types/customer';\r\n\r\ntype FetchOptions = Omit<RequestOptions, 'token' | 'organizationId'>;\r\n\r\nclass CustomerApi extends BaseApi<Customer, CustomerPayload, CustomerPayload> {\r\n constructor(config = {}) {\r\n super('customers', config);\r\n }\r\n\r\n /**\r\n * Get current user's customer profile\r\n * GET /customers/me\r\n */\r\n async getMe({\r\n token,\r\n options = {},\r\n }: {\r\n token: string;\r\n options?: FetchOptions;\r\n }): Promise<ApiResponse<Customer>> {\r\n if (!token) {\r\n throw new Error('Authentication required');\r\n }\r\n\r\n return handleApiRequest('GET', `${this.baseUrl}/me`, {\r\n token,\r\n cache: this.config.cache,\r\n ...options,\r\n });\r\n }\r\n\r\n /**\r\n * Membership actions\r\n * POST /customers/:id/membership\r\n */\r\n async membershipAction({\r\n token,\r\n id,\r\n data,\r\n }: {\r\n token: string;\r\n id: string;\r\n data: {\r\n action: 'enroll' | 'deactivate' | 'reactivate' | 'adjust';\r\n points?: number;\r\n reason?: string;\r\n type?: 'bonus' | 'correction' | 'manual_redemption' | 'redemption' | 'expiry';\r\n };\r\n }): Promise<ApiResponse<Customer>> {\r\n if (!token) {\r\n throw new Error('Authentication required');\r\n }\r\n\r\n return handleApiRequest('POST', `${this.baseUrl}/${id}/membership`, {\r\n token,\r\n body: data,\r\n cache: this.config.cache,\r\n });\r\n }\r\n}\r\n\r\nexport const customerApi = new CustomerApi();\r\nexport { CustomerApi };\r\nexport type { CustomerQueryParams };\r\n","\"use client\";\n\n/**\n * Cart Hooks\n *\n * React hooks for shopping cart operations with optimistic updates.\n */\n\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { cartApi } from \"../api/cart\";\nimport { createQueryKeys, type QueryKeys } from \"../../core/react\";\nimport { getToastHandler } from \"../../core/react/mutation.factory\";\nimport type { Cart, CartItem, AddCartItemPayload, UpdateCartItemPayload } from \"../types/cart\";\n\n// ============================================\n// Query Keys\n// ============================================\n\nexport const CART_KEYS: QueryKeys = createQueryKeys(\"cart\");\n\n// ============================================\n// Utility Functions\n// ============================================\n\n/**\n * Calculate unit price for a cart item\n * Handles both simple products and variant products\n */\nexport function calculateItemPrice(item: CartItem): number {\n if (!item?.product) return 0;\n\n const product = item.product;\n const basePrice = product.currentPrice ?? product.basePrice ?? 0;\n\n // For variant products, add the priceModifier from the selected variant\n if (item.variantSku && product.variants && product.variants.length > 0) {\n const variant = product.variants.find((v) => v.sku === item.variantSku);\n if (variant) {\n return basePrice + (variant.priceModifier || 0);\n }\n }\n\n return basePrice;\n}\n\n/**\n * Calculate total for a cart item\n */\nexport function calculateItemTotal(item: CartItem): number {\n return calculateItemPrice(item) * (item.quantity || 1);\n}\n\n/**\n * Calculate cart subtotal\n */\nexport function calculateCartSubtotal(items: CartItem[]): number {\n return items?.reduce((total, item) => total + calculateItemTotal(item), 0) || 0;\n}\n\n/**\n * Get total item count in cart\n */\nexport function getCartItemCount(items: CartItem[]): number {\n return items?.reduce((count, item) => count + (item.quantity || 0), 0) || 0;\n}\n\n/**\n * Get variant details from a cart item\n */\nexport function getCartItemVariant(item: CartItem) {\n if (!item?.variantSku || !item?.product?.variants) return null;\n return item.product.variants.find((v) => v.sku === item.variantSku) || null;\n}\n\n/**\n * Format variant attributes for display\n * @example \"Size: M, Color: Red\"\n */\nexport function formatVariantAttributes(attributes?: Record<string, string> | null): string {\n if (!attributes || Object.keys(attributes).length === 0) return \"\";\n return Object.entries(attributes)\n .map(([key, value]) => `${key.charAt(0).toUpperCase() + key.slice(1)}: ${value}`)\n .join(\", \");\n}\n\n// ============================================\n// Types\n// ============================================\n\nexport interface UseCartReturn {\n cart: Cart | null | undefined;\n items: CartItem[];\n itemCount: number;\n subtotal: number;\n isLoading: boolean;\n isFetching: boolean;\n isUpdating: boolean;\n error: Error | null;\n addToCart: (data: AddCartItemPayload) => void;\n addToCartAsync: (data: AddCartItemPayload) => Promise<Cart>;\n updateCartItem: (data: UpdateCartItemPayload) => void;\n updateCartItemAsync: (data: UpdateCartItemPayload) => Promise<Cart>;\n removeCartItem: (itemId: string) => void;\n removeCartItemAsync: (itemId: string) => Promise<Cart>;\n clearCart: () => void;\n clearCartAsync: () => Promise<Cart>;\n refetch: () => void;\n getItemPrice: typeof calculateItemPrice;\n}\n\nexport interface UseCartCountReturn {\n count: number;\n isLoading: boolean;\n}\n\nexport interface CartOptions {\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n}\n\n// ============================================\n// Hooks\n// ============================================\n\nconst CART_QUERY_KEY = [\"cart\"];\n\n/**\n * Full cart hook with optimistic updates\n *\n * @example\n * ```tsx\n * function CartPage() {\n * const {\n * items,\n * itemCount,\n * subtotal,\n * addToCart,\n * updateCartItem,\n * removeCartItem,\n * clearCart,\n * isLoading,\n * isUpdating,\n * } = useCart(token);\n *\n * // Add item\n * addToCart({ productId: \"123\", quantity: 2 });\n *\n * // Add variant item\n * addToCart({ productId: \"123\", variantSku: \"SIZE-M\", quantity: 1 });\n *\n * // Update quantity\n * updateCartItem({ itemId: \"item_id\", quantity: 3 });\n *\n * // Remove item\n * removeCartItem(\"item_id\");\n *\n * // Clear cart\n * clearCart();\n * }\n * ```\n */\nexport function useCart(\n token: string | null | undefined,\n options: CartOptions = {}\n): UseCartReturn {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n const { enabled = true, staleTime = 2 * 60 * 1000, gcTime = 10 * 60 * 1000 } = options;\n\n // Query\n const {\n data: cart,\n isLoading,\n error,\n isFetching,\n refetch,\n } = useQuery<Cart | null>({\n queryKey: CART_QUERY_KEY,\n queryFn: () => cartApi.getCart(token!),\n enabled: enabled && !!token,\n staleTime,\n gcTime,\n });\n\n // Add to cart mutation\n const addMutation = useMutation({\n mutationFn: (data: AddCartItemPayload) => cartApi.addToCart(token!, data),\n onMutate: async () => {\n await queryClient.cancelQueries({ queryKey: CART_QUERY_KEY });\n return { previousCart: queryClient.getQueryData<Cart>(CART_QUERY_KEY) };\n },\n onError: (err: Error, _, context) => {\n if (context?.previousCart) {\n queryClient.setQueryData(CART_QUERY_KEY, context.previousCart);\n }\n toast.error?.(err.message || \"Failed to add item to cart\");\n },\n onSuccess: (data) => {\n queryClient.setQueryData(CART_QUERY_KEY, data);\n toast.success?.(\"Added to cart!\");\n },\n });\n\n // Update quantity mutation\n const updateMutation = useMutation({\n mutationFn: ({ itemId, quantity }: UpdateCartItemPayload) =>\n cartApi.updateCartItem(token!, itemId, quantity),\n onMutate: async ({ itemId, quantity }) => {\n await queryClient.cancelQueries({ queryKey: CART_QUERY_KEY });\n const previousCart = queryClient.getQueryData<Cart>(CART_QUERY_KEY);\n\n queryClient.setQueryData<Cart | null>(CART_QUERY_KEY, (old) =>\n old\n ? {\n ...old,\n items: old.items.map((i) =>\n i._id === itemId ? { ...i, quantity } : i\n ),\n }\n : old\n );\n\n return { previousCart };\n },\n onError: (err: Error, _, context) => {\n if (context?.previousCart) {\n queryClient.setQueryData(CART_QUERY_KEY, context.previousCart);\n }\n toast.error?.(err.message || \"Failed to update cart\");\n },\n onSuccess: (data) => {\n queryClient.setQueryData(CART_QUERY_KEY, data);\n },\n });\n\n // Remove item mutation\n const removeMutation = useMutation({\n mutationFn: (itemId: string) => cartApi.removeCartItem(token!, itemId),\n onMutate: async (itemId) => {\n await queryClient.cancelQueries({ queryKey: CART_QUERY_KEY });\n const previousCart = queryClient.getQueryData<Cart>(CART_QUERY_KEY);\n\n queryClient.setQueryData<Cart | null>(CART_QUERY_KEY, (old) =>\n old ? { ...old, items: old.items.filter((i) => i._id !== itemId) } : old\n );\n\n return { previousCart };\n },\n onError: (err: Error, _, context) => {\n if (context?.previousCart) {\n queryClient.setQueryData(CART_QUERY_KEY, context.previousCart);\n }\n toast.error?.(err.message || \"Failed to remove item\");\n },\n onSuccess: (data) => {\n queryClient.setQueryData(CART_QUERY_KEY, data);\n toast.success?.(\"Item removed\");\n },\n });\n\n // Clear cart mutation\n const clearMutation = useMutation({\n mutationFn: () => cartApi.clearCart(token!),\n onMutate: async () => {\n await queryClient.cancelQueries({ queryKey: CART_QUERY_KEY });\n const previousCart = queryClient.getQueryData<Cart>(CART_QUERY_KEY);\n queryClient.setQueryData<Cart | null>(CART_QUERY_KEY, (old) =>\n old ? { ...old, items: [] } : old\n );\n return { previousCart };\n },\n onError: (err: Error, _, context) => {\n if (context?.previousCart) {\n queryClient.setQueryData(CART_QUERY_KEY, context.previousCart);\n }\n toast.error?.(err.message || \"Failed to clear cart\");\n },\n onSuccess: (data) => {\n queryClient.setQueryData(CART_QUERY_KEY, data);\n toast.success?.(\"Cart cleared\");\n },\n });\n\n const items = cart?.items || [];\n const isUpdating =\n addMutation.isPending ||\n updateMutation.isPending ||\n removeMutation.isPending ||\n clearMutation.isPending;\n\n return {\n cart,\n items,\n itemCount: getCartItemCount(items),\n subtotal: calculateCartSubtotal(items),\n isLoading,\n isFetching,\n isUpdating,\n error: error as Error | null,\n addToCart: (data) => addMutation.mutate(data),\n addToCartAsync: (data) => addMutation.mutateAsync(data),\n updateCartItem: (data) => updateMutation.mutate(data),\n updateCartItemAsync: (data) => updateMutation.mutateAsync(data),\n removeCartItem: (itemId) => removeMutation.mutate(itemId),\n removeCartItemAsync: (itemId) => removeMutation.mutateAsync(itemId),\n clearCart: () => clearMutation.mutate(),\n clearCartAsync: () => clearMutation.mutateAsync(),\n refetch: () => refetch(),\n getItemPrice: calculateItemPrice,\n };\n}\n\n/**\n * Lightweight hook for cart count (header badge)\n *\n * @example\n * ```tsx\n * function CartBadge() {\n * const { count, isLoading } = useCartCount(token);\n * return <Badge>{isLoading ? \"...\" : count}</Badge>;\n * }\n * ```\n */\nexport function useCartCount(\n token: string | null | undefined,\n options: CartOptions = {}\n): UseCartCountReturn {\n const { enabled = true, staleTime = 2 * 60 * 1000, gcTime = 10 * 60 * 1000 } = options;\n\n const { data: cart, isLoading } = useQuery<Cart | null>({\n queryKey: CART_QUERY_KEY,\n queryFn: () => cartApi.getCart(token!),\n enabled: enabled && !!token,\n staleTime,\n gcTime,\n });\n\n return {\n count: getCartItemCount(cart?.items || []),\n isLoading,\n };\n}\n","\"use client\";\n\n/**\n * Order Hooks\n *\n * React hooks for order CRUD operations using the factory pattern.\n * Includes customer-facing and admin-specific hooks.\n */\n\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { createCrudHooks, type CrudApi } from \"../../core/react\";\nimport { getToastHandler } from \"../../core/react/mutation.factory\";\nimport { orderApi } from \"../api/order\";\nimport type { ApiResponse, PaginatedResponse } from \"../../core\";\nimport type {\n Order,\n OrderShipping,\n CreateOrderPayload,\n GuestCheckoutPayload,\n UpdateStatusPayload,\n FulfillOrderPayload,\n RequestShippingPayload,\n UpdateShippingPayload,\n} from \"../types/order\";\n\n// Response types for type safety\ninterface OrderListResponse {\n success: boolean;\n data?: Order[];\n docs?: Order[];\n pagination?: {\n total?: number;\n page?: number;\n limit?: number;\n hasMore?: boolean;\n };\n}\n\n// Type helper for API compatibility\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyApi = CrudApi<any, any, any>;\n\n// ============================================\n// Query Keys\n// ============================================\n\n/**\n * Extended order query keys\n */\nconst createOrderKeys = () => ({\n all: [\"orders\"] as const,\n lists: () => [...createOrderKeys().all, \"list\"] as const,\n list: (params?: Record<string, unknown>) => [...createOrderKeys().lists(), params] as const,\n details: () => [...createOrderKeys().all, \"detail\"] as const,\n detail: (id: string) => [...createOrderKeys().details(), id] as const,\n // Customer-specific keys\n myOrders: (params?: Record<string, unknown>) => [...createOrderKeys().all, \"my\", params] as const,\n myDetail: (id: string) => [...createOrderKeys().all, \"my\", \"detail\", id] as const,\n});\n\n// ============================================\n// Base CRUD Hooks (Admin)\n// ============================================\n\n/**\n * Order hooks using createCrudHooks factory\n *\n * Provides:\n * - useOrders: List orders with filtering/pagination\n * - useOrderDetail: Get single order\n * - useOrderActions: Create, update, delete mutations\n * - useOrderNavigation: Navigation between orders\n */\nexport const orderHooks = createCrudHooks<Order, CreateOrderPayload, Partial<Order>>({\n api: orderApi as AnyApi,\n entityKey: \"orders\",\n singular: \"Order\",\n plural: \"Orders\",\n defaults: {\n staleTime: 1 * 60 * 1000, // 1 minute (orders change frequently)\n },\n});\n\n// Export ORDER_KEYS with extended keys for customer-facing hooks\nexport const ORDER_KEYS = createOrderKeys();\n\nexport const {\n useList: useOrders,\n useDetail: useOrderDetail,\n useActions: useOrderActions,\n useNavigation: useOrderNavigation,\n} = orderHooks;\n\n// ============================================\n// Types\n// ============================================\n\ninterface QueryOptions {\n enabled?: boolean;\n staleTime?: number;\n}\n\nexport interface UseMyOrdersReturn {\n orders: Order[];\n total: number;\n page: number;\n limit: number;\n hasMore: boolean;\n isLoading: boolean;\n isFetching: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\nexport interface UseCustomerOrderActionsReturn {\n checkout: (data: CreateOrderPayload) => Promise<Order>;\n isCheckingOut: boolean;\n requestCancel: (params: { orderId: string; reason?: string }) => Promise<Order>;\n isRequestingCancel: boolean;\n isLoading: boolean;\n}\n\nexport interface UseAdminOrderActionsReturn {\n updateStatus: (params: { orderId: string; status: string; note?: string }) => Promise<Order>;\n isUpdatingStatus: boolean;\n fulfillOrder: (params: FulfillOrderPayload & { orderId: string }) => Promise<Order>;\n isFulfilling: boolean;\n refundOrder: (params: { orderId: string; amount?: number; reason?: string }) => Promise<Order>;\n isRefunding: boolean;\n cancelOrder: (params: { orderId: string; reason?: string; refund?: boolean }) => Promise<Order>;\n isCancelling: boolean;\n requestShipping: (params: RequestShippingPayload & { orderId: string }) => Promise<OrderShipping>;\n isRequestingShipping: boolean;\n updateShipping: (params: UpdateShippingPayload & { orderId: string }) => Promise<OrderShipping>;\n isUpdatingShipping: boolean;\n isLoading: boolean;\n}\n\n// ============================================\n// Customer-Facing Hooks\n// ============================================\n\n/**\n * Get customer's own orders\n *\n * @param token - Auth token\n * @param params - Query params { page, limit, status, sort }\n * @param options - Query options\n *\n * @example\n * ```tsx\n * function MyOrdersPage() {\n * const { orders, isLoading, hasMore } = useMyOrders(token, { limit: 10 });\n *\n * return (\n * <OrderList orders={orders} loading={isLoading} />\n * );\n * }\n * ```\n */\nexport function useMyOrders(\n token: string,\n params: Record<string, unknown> = {},\n options: QueryOptions = {}\n): UseMyOrdersReturn {\n const { data, isLoading, isFetching, error, refetch } = useQuery<OrderListResponse>({\n queryKey: ORDER_KEYS.myOrders(params),\n queryFn: async () => {\n const response = await orderApi.getMyOrders({ token, params });\n return response as unknown as OrderListResponse;\n },\n enabled: !!token && options.enabled !== false,\n staleTime: options.staleTime ?? 30 * 1000,\n });\n\n const orders = data?.data || data?.docs || [];\n const pagination = data?.pagination;\n\n return {\n orders,\n total: pagination?.total || orders.length,\n page: pagination?.page || 1,\n limit: pagination?.limit || 10,\n hasMore: pagination?.hasMore ?? false,\n isLoading,\n isFetching,\n error: error as Error | null,\n refetch,\n };\n}\n\n/**\n * Get customer's own order detail\n *\n * @param token - Auth token\n * @param orderId - Order ID\n * @param options - Query options\n *\n * @example\n * ```tsx\n * function OrderDetailPage({ orderId }) {\n * const { data: order, isLoading } = useMyOrderDetail(token, orderId);\n *\n * if (isLoading) return <Skeleton />;\n * return <OrderDetail order={order} />;\n * }\n * ```\n */\nexport function useMyOrderDetail(\n token: string,\n orderId: string,\n options: QueryOptions = {}\n) {\n return useQuery<Order>({\n queryKey: ORDER_KEYS.myDetail(orderId),\n queryFn: async () => {\n const response = await orderApi.getMyOrder({ token, id: orderId }) as unknown as ApiResponse<Order>;\n return response.data as Order;\n },\n enabled: !!token && !!orderId && options.enabled !== false,\n staleTime: options.staleTime ?? 30 * 1000,\n });\n}\n\n/**\n * Customer order actions (checkout, request cancellation)\n *\n * @param token - Customer auth token\n *\n * @example\n * ```tsx\n * function CheckoutButton({ cart }) {\n * const { checkout, isCheckingOut } = useCustomerOrderActions(token);\n *\n * const handleCheckout = async () => {\n * const order = await checkout({\n * items: cart.items,\n * shipping: shippingAddress,\n * payment: { method: 'bkash' },\n * });\n * router.push(`/orders/${order._id}`);\n * };\n *\n * return (\n * <Button onClick={handleCheckout} disabled={isCheckingOut}>\n * {isCheckingOut ? 'Processing...' : 'Place Order'}\n * </Button>\n * );\n * }\n * ```\n */\nexport function useCustomerOrderActions(token: string): UseCustomerOrderActionsReturn {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n // Checkout mutation\n const checkoutMutation = useMutation({\n mutationFn: async (data: CreateOrderPayload) => {\n const response = await orderApi.checkout({ token, data }) as unknown as ApiResponse<Order>;\n return response.data as Order;\n },\n onSuccess: () => {\n // Clear cart and invalidate queries\n queryClient.setQueryData([\"cart\"], null);\n queryClient.invalidateQueries({ queryKey: [\"cart\"] });\n queryClient.invalidateQueries({ queryKey: ORDER_KEYS.all });\n toast.success(\"Order placed successfully!\");\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to place order\");\n },\n });\n\n // Request cancellation mutation\n const requestCancelMutation = useMutation({\n mutationFn: async ({ orderId, reason }: { orderId: string; reason?: string }) => {\n const response = await orderApi.requestCancellation({ token, id: orderId, reason }) as unknown as ApiResponse<Order>;\n return response.data as Order;\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ORDER_KEYS.all });\n toast.success(\"Cancellation request submitted\");\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to request cancellation\");\n },\n });\n\n return {\n checkout: checkoutMutation.mutateAsync,\n isCheckingOut: checkoutMutation.isPending,\n requestCancel: requestCancelMutation.mutateAsync,\n isRequestingCancel: requestCancelMutation.isPending,\n isLoading: checkoutMutation.isPending || requestCancelMutation.isPending,\n };\n}\n\n// ============================================\n// Guest Checkout Hook\n// ============================================\n\nexport interface UseGuestCheckoutReturn {\n guestCheckout: (data: GuestCheckoutPayload) => Promise<Order>;\n isCheckingOut: boolean;\n}\n\n/**\n * Guest checkout mutation (no auth required)\n *\n * For unauthenticated users. Items are sent from FE localStorage.\n *\n * @example\n * ```tsx\n * function GuestCheckoutButton({ cartItems, guestInfo, address }) {\n * const { guestCheckout, isCheckingOut } = useGuestCheckout();\n *\n * const handleCheckout = async () => {\n * const order = await guestCheckout({\n * items: cartItems,\n * guest: guestInfo,\n * deliveryAddress: address,\n * delivery: { method: 'standard', price: 80 },\n * });\n * router.push(`/order-confirmation/${order._id}`);\n * };\n *\n * return (\n * <Button onClick={handleCheckout} disabled={isCheckingOut}>\n * {isCheckingOut ? 'Processing...' : 'Place Order'}\n * </Button>\n * );\n * }\n * ```\n */\nexport function useGuestCheckout(): UseGuestCheckoutReturn {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n const mutation = useMutation({\n mutationFn: async (data: GuestCheckoutPayload) => {\n const response = await orderApi.guestCheckout({ data }) as unknown as ApiResponse<Order>;\n return response.data as Order;\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ORDER_KEYS.all });\n toast.success(\"Order placed successfully!\");\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to place order\");\n },\n });\n\n return {\n guestCheckout: mutation.mutateAsync,\n isCheckingOut: mutation.isPending,\n };\n}\n\n// ============================================\n// Admin Hooks\n// ============================================\n\n/**\n * Admin order actions (status, fulfill, refund, cancel, shipping)\n *\n * @param token - Admin auth token\n *\n * @example\n * ```tsx\n * function OrderActions({ order }) {\n * const {\n * updateStatus,\n * fulfillOrder,\n * cancelOrder,\n * isLoading,\n * } = useAdminOrderActions(token);\n *\n * return (\n * <>\n * <Button onClick={() => updateStatus({ orderId: order._id, status: 'processing' })}>\n * Mark Processing\n * </Button>\n * <Button onClick={() => fulfillOrder({ orderId: order._id, branchId: 'branch_123' })}>\n * Fulfill Order\n * </Button>\n * </>\n * );\n * }\n * ```\n */\nexport function useAdminOrderActions(token: string): UseAdminOrderActionsReturn {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n // Update status\n const updateStatusMutation = useMutation({\n mutationFn: async ({ orderId, status, note }: { orderId: string; status: string; note?: string }) => {\n const response = await orderApi.updateStatus({\n token,\n id: orderId,\n data: { status, note } as UpdateStatusPayload,\n }) as unknown as ApiResponse<Order>;\n return response.data as Order;\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ORDER_KEYS.all });\n toast.success(\"Order status updated\");\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to update status\");\n },\n });\n\n // Fulfill order\n const fulfillMutation = useMutation({\n mutationFn: async ({ orderId, ...data }: FulfillOrderPayload & { orderId: string }) => {\n const response = await orderApi.fulfill({ token, id: orderId, data }) as unknown as ApiResponse<Order>;\n return response.data as Order;\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ORDER_KEYS.all });\n queryClient.invalidateQueries({ queryKey: [\"branches\"] });\n queryClient.invalidateQueries({ queryKey: [\"stock\"] });\n toast.success(\"Order fulfilled successfully\");\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to fulfill order\");\n },\n });\n\n // Refund order\n const refundMutation = useMutation({\n mutationFn: async ({ orderId, amount, reason }: { orderId: string; amount?: number; reason?: string }) => {\n const response = await orderApi.refund({ token, id: orderId, data: { amount, reason } }) as unknown as ApiResponse<Order>;\n return response.data as Order;\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ORDER_KEYS.all });\n toast.success(\"Refund processed successfully\");\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to process refund\");\n },\n });\n\n // Cancel order\n const cancelMutation = useMutation({\n mutationFn: async ({ orderId, reason, refund }: { orderId: string; reason?: string; refund?: boolean }) => {\n const response = await orderApi.cancel({ token, id: orderId, reason, refund }) as unknown as ApiResponse<Order>;\n return response.data as Order;\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ORDER_KEYS.all });\n toast.success(\"Order cancelled\");\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to cancel order\");\n },\n });\n\n // Request shipping\n const requestShippingMutation = useMutation({\n mutationFn: async ({ orderId, ...data }: RequestShippingPayload & { orderId: string }) => {\n const response = await orderApi.requestShipping({ token, id: orderId, data }) as unknown as ApiResponse<OrderShipping>;\n return response.data as OrderShipping;\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ORDER_KEYS.all });\n toast.success(\"Shipping pickup requested\");\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to request shipping\");\n },\n });\n\n // Update shipping\n const updateShippingMutation = useMutation({\n mutationFn: async ({ orderId, ...data }: UpdateShippingPayload & { orderId: string }) => {\n const response = await orderApi.updateShipping({ token, id: orderId, data }) as unknown as ApiResponse<OrderShipping>;\n return response.data as OrderShipping;\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: ORDER_KEYS.all });\n toast.success(\"Shipping status updated\");\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to update shipping\");\n },\n });\n\n return {\n updateStatus: updateStatusMutation.mutateAsync,\n isUpdatingStatus: updateStatusMutation.isPending,\n fulfillOrder: fulfillMutation.mutateAsync,\n isFulfilling: fulfillMutation.isPending,\n refundOrder: refundMutation.mutateAsync,\n isRefunding: refundMutation.isPending,\n cancelOrder: cancelMutation.mutateAsync,\n isCancelling: cancelMutation.isPending,\n requestShipping: requestShippingMutation.mutateAsync,\n isRequestingShipping: requestShippingMutation.isPending,\n updateShipping: updateShippingMutation.mutateAsync,\n isUpdatingShipping: updateShippingMutation.isPending,\n isLoading:\n updateStatusMutation.isPending ||\n fulfillMutation.isPending ||\n refundMutation.isPending ||\n cancelMutation.isPending ||\n requestShippingMutation.isPending ||\n updateShippingMutation.isPending,\n };\n}\n","\"use client\";\n\n/**\n * Customer Hooks\n *\n * React hooks for customer CRUD operations using the factory pattern.\n * Includes customer profile and membership management.\n */\n\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { createCrudHooks, type CrudApi } from \"../../core/react\";\nimport { getToastHandler } from \"../../core/react/mutation.factory\";\nimport { customerApi } from \"../api/customer\";\nimport type { Customer, CustomerPayload } from \"../types/customer\";\n\n// Type helper for API compatibility\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyApi = CrudApi<any, any, any>;\n\n// ============================================\n// Types\n// ============================================\n\ninterface QueryOptions {\n enabled?: boolean;\n staleTime?: number;\n}\n\ntype MembershipAction = \"enroll\" | \"deactivate\" | \"reactivate\" | \"adjust\";\ntype PointsType = \"bonus\" | \"correction\" | \"manual_redemption\" | \"redemption\" | \"expiry\";\n\nexport interface MembershipActionParams {\n id: string;\n action: MembershipAction;\n points?: number;\n reason?: string;\n type?: PointsType;\n}\n\nexport interface UseCustomerMembershipReturn {\n membershipAction: (params: MembershipActionParams) => Promise<Customer>;\n isPending: boolean;\n}\n\n// ============================================\n// Base CRUD Hooks (Admin)\n// ============================================\n\n/**\n * Customer hooks using createCrudHooks factory\n *\n * Provides:\n * - useCustomers: List customers with filtering/pagination\n * - useCustomerDetail: Get single customer\n * - useCustomerActions: Create, update, delete mutations\n * - useCustomerNavigation: Navigation between customers\n */\nexport const customerHooks = createCrudHooks<Customer, CustomerPayload, CustomerPayload>({\n api: customerApi as AnyApi,\n entityKey: \"customers\",\n singular: \"Customer\",\n plural: \"Customers\",\n defaults: {\n staleTime: 5 * 60 * 1000, // 5 minutes\n },\n});\n\nexport const {\n KEYS: CUSTOMER_KEYS,\n useList: useCustomers,\n useDetail: useCustomerDetail,\n useActions: useCustomerActions,\n useNavigation: useCustomerNavigation,\n} = customerHooks;\n\n// ============================================\n// Customer Profile Hooks\n// ============================================\n\n/**\n * Get current user's customer profile\n *\n * @param token - Auth token\n * @param options - Query options\n *\n * @example\n * ```tsx\n * function ProfilePage() {\n * const { data: customer, isLoading } = useCurrentCustomer(token);\n *\n * if (isLoading) return <Skeleton />;\n * return (\n * <div>\n * <h1>{customer?.name}</h1>\n * <p>Points: {customer?.membership?.points || 0}</p>\n * </div>\n * );\n * }\n * ```\n */\nexport function useCurrentCustomer(\n token: string,\n options: QueryOptions = {}\n) {\n return useQuery({\n queryKey: [...CUSTOMER_KEYS.all, \"me\"] as const,\n queryFn: async () => {\n const response = await customerApi.getMe({ token });\n return response.data as Customer;\n },\n enabled: !!token && options.enabled !== false,\n staleTime: options.staleTime ?? 5 * 60 * 1000,\n });\n}\n\n// ============================================\n// Membership Hooks\n// ============================================\n\n/**\n * Customer membership actions (enroll, deactivate, reactivate, adjust points)\n *\n * @param token - Admin auth token\n *\n * @example\n * ```tsx\n * function MembershipManager({ customer }) {\n * const { membershipAction, isPending } = useCustomerMembership(token);\n *\n * const handleEnroll = async () => {\n * await membershipAction({\n * id: customer._id,\n * action: 'enroll',\n * });\n * };\n *\n * const handleAdjustPoints = async (points: number) => {\n * await membershipAction({\n * id: customer._id,\n * action: 'adjust',\n * points,\n * type: 'bonus',\n * reason: 'Birthday bonus',\n * });\n * };\n *\n * return (\n * <Button onClick={handleEnroll} disabled={isPending}>\n * Enroll in Membership\n * </Button>\n * );\n * }\n * ```\n */\nexport function useCustomerMembership(token: string): UseCustomerMembershipReturn {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n const mutation = useMutation({\n mutationFn: async ({ id, action, points, reason, type }: MembershipActionParams) => {\n const response = await customerApi.membershipAction({\n token,\n id,\n data: { action, points, reason, type },\n });\n return response.data as Customer;\n },\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: CUSTOMER_KEYS.lists() });\n queryClient.invalidateQueries({ queryKey: CUSTOMER_KEYS.details() });\n toast.success(\"Membership updated successfully\");\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to update membership\");\n },\n });\n\n return {\n membershipAction: mutation.mutateAsync,\n isPending: mutation.isPending,\n };\n}\n","\"use client\";\n\n/**\n * POS Hooks\n *\n * React hooks for Point of Sale operations.\n */\n\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { posApi } from \"../api/pos\";\nimport { getToastHandler } from \"../../core/react/mutation.factory\";\nimport type {\n PosProduct,\n PosProductsResponse,\n PosOrderPayload,\n PosLookupResponse,\n PosReceiptResponse,\n} from \"../types/pos\";\nimport type {\n CreateAdjustmentPayload,\n BulkAdjustmentPayload,\n} from \"../../inventory/types\";\n\n// ============================================\n// Query Keys\n// ============================================\n\nexport const POS_KEYS = {\n all: [\"pos\"] as const,\n products: (branchId?: string) => [...POS_KEYS.all, \"products\", branchId] as const,\n productsList: (branchId?: string, params?: Record<string, unknown>) =>\n [...POS_KEYS.products(branchId), params] as const,\n lookup: (code: string, branchId?: string) =>\n [...POS_KEYS.all, \"lookup\", code, branchId] as const,\n orders: () => [...POS_KEYS.all, \"orders\"] as const,\n receipt: (orderId: string) => [...POS_KEYS.orders(), orderId, \"receipt\"] as const,\n};\n\n// ============================================\n// Types\n// ============================================\n\nexport interface PosProductFilters {\n category?: string;\n search?: string;\n inStockOnly?: boolean;\n lowStockOnly?: boolean;\n after?: string;\n limit?: number;\n sort?: string;\n [key: string]: unknown;\n}\n\nexport interface UsePosProductsReturn {\n products: PosProduct[];\n summary: PosProductsResponse[\"summary\"];\n branch: PosProductsResponse[\"branch\"];\n hasMore: boolean;\n nextCursor: string | null;\n isLoading: boolean;\n isFetching: boolean;\n error: Error | null;\n refetch: () => void;\n}\n\ninterface QueryOptions {\n enabled?: boolean;\n}\n\n// ============================================\n// Product Hooks\n// ============================================\n\n/**\n * Fetch POS products with branch-specific stock\n *\n * @param token - Auth token\n * @param branchId - Branch to get stock for\n * @param filters - Product filters\n * @param options - Query options\n *\n * @example\n * ```tsx\n * function ProductGrid({ branchId }) {\n * const { products, isLoading, summary } = usePosProducts(token, branchId, {\n * category: 'electronics',\n * inStockOnly: true,\n * });\n *\n * return (\n * <Grid>\n * {products.map(product => (\n * <ProductCard key={product._id} product={product} />\n * ))}\n * </Grid>\n * );\n * }\n * ```\n */\nexport function usePosProducts(\n token: string,\n branchId: string | undefined,\n filters: PosProductFilters = {},\n options: QueryOptions = {}\n): UsePosProductsReturn {\n const queryKey = POS_KEYS.productsList(branchId, filters);\n\n const { data, isLoading, isFetching, error, refetch } = useQuery({\n queryKey,\n queryFn: () =>\n posApi.getProducts({\n token,\n branchId,\n category: filters.category,\n search: filters.search,\n inStockOnly: filters.inStockOnly,\n lowStockOnly: filters.lowStockOnly,\n after: filters.after,\n limit: filters.limit || 50,\n sort: filters.sort || \"name\",\n }),\n enabled: !!token && options.enabled !== false,\n staleTime: 30 * 1000, // 30 seconds\n refetchOnWindowFocus: true,\n });\n\n return {\n products: data?.docs || [],\n summary: data?.summary || { totalItems: 0, totalQuantity: 0, lowStockCount: 0, outOfStockCount: 0 },\n branch: data?.branch || { _id: \"\", code: \"\", name: \"\" },\n hasMore: data?.hasMore || false,\n nextCursor: data?.next || null,\n isLoading,\n isFetching,\n error: error as Error | null,\n refetch,\n };\n}\n\n/**\n * Lookup product by barcode/SKU (query-based)\n *\n * @param token - Auth token\n * @param code - Barcode or SKU to lookup\n * @param branchId - Branch for stock info\n * @param options - Query options\n */\nexport function usePosLookup(\n token: string,\n code: string,\n branchId?: string,\n options: QueryOptions = {}\n) {\n return useQuery<PosLookupResponse>({\n queryKey: POS_KEYS.lookup(code, branchId),\n queryFn: () => posApi.lookup({ token, code, branchId }),\n enabled: !!token && !!code && code.length >= 2 && options.enabled !== false,\n staleTime: 10 * 1000, // 10 seconds\n retry: false, // Don't retry failed lookups\n });\n}\n\n/**\n * Lookup product by barcode/SKU (mutation-based)\n * Preferred for \"scan -> act\" flows\n *\n * @param token - Auth token\n *\n * @example\n * ```tsx\n * function BarcodeScanner() {\n * const { lookup, isLooking } = usePosLookupMutation(token);\n *\n * const handleScan = async (code: string) => {\n * const result = await lookup({ code, branchId });\n * if (result) addToCart(result.data);\n * };\n * }\n * ```\n */\nexport function usePosLookupMutation(token: string) {\n const toast = getToastHandler();\n\n const mutation = useMutation<PosLookupResponse, Error, { code: string; branchId?: string }>({\n mutationFn: ({ code, branchId }) => posApi.lookup({ token, code, branchId }),\n onError: (error: Error) => {\n toast.error(error.message || \"Lookup failed\");\n },\n });\n\n return {\n lookup: mutation.mutateAsync,\n isLooking: mutation.isPending,\n error: mutation.error,\n };\n}\n\n/**\n * Get receipt for an order\n *\n * @param token - Auth token\n * @param orderId - Order ID\n * @param options - Query options\n */\nexport function usePosReceipt(\n token: string,\n orderId: string,\n options: QueryOptions = {}\n) {\n return useQuery<PosReceiptResponse>({\n queryKey: POS_KEYS.receipt(orderId),\n queryFn: async (): Promise<PosReceiptResponse> => {\n const result = await posApi.getReceipt({ token, orderId });\n return result as PosReceiptResponse;\n },\n enabled: !!token && !!orderId && options.enabled !== false,\n staleTime: Infinity, // Receipts don't change\n });\n}\n\n// ============================================\n// Order Mutations\n// ============================================\n\nexport interface UsePosOrdersReturn {\n createOrder: (data: PosOrderPayload) => Promise<unknown>;\n isCreatingOrder: boolean;\n}\n\n/**\n * POS order operations\n *\n * @param token - Auth token\n *\n * @example\n * ```tsx\n * function Checkout({ cart, branchId }) {\n * const { createOrder, isCreatingOrder } = usePosOrders(token);\n *\n * const handleCheckout = async () => {\n * const order = await createOrder({\n * items: cart.items,\n * branchId,\n * payment: { method: 'cash' },\n * });\n * // Handle success (show receipt, clear cart, etc.)\n * };\n * }\n * ```\n */\nexport function usePosOrders(token: string): UsePosOrdersReturn {\n const queryClient = useQueryClient();\n\n const createOrderMutation = useMutation({\n mutationFn: (data: PosOrderPayload) => posApi.createOrder({ token, data }),\n onSuccess: (_result, variables) => {\n // Invalidate inventory queries for the branch\n queryClient.invalidateQueries({\n queryKey: POS_KEYS.products(variables.branchId),\n });\n },\n });\n\n return {\n createOrder: createOrderMutation.mutateAsync,\n isCreatingOrder: createOrderMutation.isPending,\n };\n}\n\n// ============================================\n// Stock Adjustment Mutations\n// ============================================\n\nexport interface UsePosStockActionsReturn {\n adjustStock: (data: CreateAdjustmentPayload) => Promise<unknown>;\n isAdjusting: boolean;\n setStock: (params: {\n productId: string;\n quantity: number;\n branchId?: string;\n variantSku?: string;\n reason?: string;\n }) => Promise<unknown>;\n isSetting: boolean;\n bulkAdjust: (data: BulkAdjustmentPayload) => Promise<unknown>;\n isBulkAdjusting: boolean;\n isLoading: boolean;\n}\n\n/**\n * POS stock adjustment actions\n *\n * @param token - Auth token\n * @param branchId - Branch for cache invalidation\n *\n * @example\n * ```tsx\n * function StockAdjuster({ product, branchId }) {\n * const { setStock, isSetting } = usePosStockActions(token, branchId);\n *\n * const handleSetStock = async (newQuantity: number) => {\n * await setStock({\n * productId: product._id,\n * quantity: newQuantity,\n * reason: 'Inventory count',\n * });\n * };\n * }\n * ```\n */\nexport function usePosStockActions(token: string, branchId?: string): UsePosStockActionsReturn {\n const queryClient = useQueryClient();\n const toast = getToastHandler();\n\n const adjustMutation = useMutation({\n mutationFn: (data: CreateAdjustmentPayload) => posApi.adjustStock({ token, data }),\n onSuccess: () => {\n toast.success(\"Stock adjusted\");\n queryClient.invalidateQueries({ queryKey: POS_KEYS.products(branchId) });\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to adjust stock\");\n },\n });\n\n const setMutation = useMutation({\n mutationFn: (params: {\n productId: string;\n quantity: number;\n branchId?: string;\n variantSku?: string;\n reason?: string;\n }) =>\n posApi.setStock({\n token,\n productId: params.productId,\n data: {\n quantity: params.quantity,\n branchId: params.branchId || branchId,\n variantSku: params.variantSku,\n reason: params.reason,\n },\n }),\n onSuccess: () => {\n toast.success(\"Stock updated\");\n queryClient.invalidateQueries({ queryKey: POS_KEYS.products(branchId) });\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to set stock\");\n },\n });\n\n const bulkMutation = useMutation({\n mutationFn: (data: BulkAdjustmentPayload) => posApi.bulkAdjust({ token, data }),\n onSuccess: () => {\n toast.success(\"Bulk adjustment complete\");\n queryClient.invalidateQueries({ queryKey: POS_KEYS.products(branchId) });\n },\n onError: (error: Error) => {\n toast.error(error.message || \"Failed to bulk adjust\");\n },\n });\n\n return {\n adjustStock: adjustMutation.mutateAsync,\n isAdjusting: adjustMutation.isPending,\n setStock: setMutation.mutateAsync,\n isSetting: setMutation.isPending,\n bulkAdjust: bulkMutation.mutateAsync,\n isBulkAdjusting: bulkMutation.isPending,\n isLoading: adjustMutation.isPending || setMutation.isPending || bulkMutation.isPending,\n };\n}\n\n// ============================================\n// Helper Functions\n// ============================================\n\n/**\n * Generate idempotency key for POS orders\n * Format: pos_{terminal}_{timestamp}_{counter}\n */\nexport function generateIdempotencyKey(terminalId?: string): string {\n const terminal = terminalId || \"default\";\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const counter = Math.floor(Math.random() * 10000).toString().padStart(4, \"0\");\n return `pos_${terminal}_${timestamp}_${counter}`;\n}\n\n/**\n * Calculate price for variant product\n */\nexport function calculateVariantPrice(basePrice: number, priceModifier: number = 0): number {\n return basePrice + priceModifier;\n}\n\n/**\n * Format variant attributes for display\n */\nexport function formatVariantLabel(attributes?: Record<string, string>): string {\n if (!attributes || Object.keys(attributes).length === 0) return \"\";\n return Object.entries(attributes)\n .map(([key, value]) => `${key.charAt(0).toUpperCase() + key.slice(1)}: ${value}`)\n .join(\", \");\n}\n\n/**\n * Check if product has variants\n */\nexport function isVariantProduct(product: PosProduct): boolean {\n return product.productType === \"variant\" || (!!product.variants && product.variants.length > 0);\n}\n\n/**\n * Get available (active) variants for a product\n */\nexport function getAvailableVariants(product: PosProduct) {\n if (!product.variants) return [];\n return product.variants.filter((v) => v.isActive);\n}\n\n/**\n * Find variant by SKU\n */\nexport function findVariantBySku(product: PosProduct, sku: string) {\n if (!product.variants) return null;\n return product.variants.find((v) => v.sku === sku) || null;\n}\n\n/**\n * Get variant stock for branch\n */\nexport function getVariantStock(product: PosProduct, variantSku: string): number {\n if (!product.branchStock?.variants) return 0;\n const variantStock = product.branchStock.variants.find((v) => v.sku === variantSku);\n return variantStock?.quantity || 0;\n}\n\n/**\n * Check if product/variant is in stock\n */\nexport function isInStock(product: PosProduct, variantSku?: string): boolean {\n if (variantSku) {\n const stock = getVariantStock(product, variantSku);\n return stock > 0;\n }\n return product.branchStock?.inStock ?? false;\n}\n\n/**\n * Get product image URL (thumbnail preferred)\n */\nexport function getPosProductImage(product: PosProduct): string {\n const firstImage = product.images?.[0];\n if (!firstImage) return \"/placeholder.png\";\n return firstImage.variants?.thumbnail || firstImage.url;\n}\n"]}
|
|
@@ -6,7 +6,7 @@ import { platformConfigApi, branchApi, userApi, couponApi } from './chunk-YYFKLO
|
|
|
6
6
|
import { paymentApi } from './chunk-5E57JODA.js';
|
|
7
7
|
import { authApi } from './chunk-W22WB3WZ.js';
|
|
8
8
|
import { sizeGuideApi, categoryApi, productApi } from './chunk-FOTUJPM4.js';
|
|
9
|
-
import { customerApi, orderApi, cartApi } from './chunk-
|
|
9
|
+
import { customerApi, orderApi, cartApi } from './chunk-4IYW6RF3.js';
|
|
10
10
|
import { purchaseApi } from './chunk-L4OEI4VZ.js';
|
|
11
11
|
import { transferApi } from './chunk-36NLLAVH.js';
|
|
12
12
|
import { requestApi } from './chunk-2TF7QNYV.js';
|
|
@@ -72,5 +72,5 @@ function initCommerceSDK(config) {
|
|
|
72
72
|
var client_default = createCommerceSDK;
|
|
73
73
|
|
|
74
74
|
export { client_default, createCommerceSDK, initCommerceSDK };
|
|
75
|
-
//# sourceMappingURL=chunk-
|
|
76
|
-
//# sourceMappingURL=chunk-
|
|
75
|
+
//# sourceMappingURL=chunk-M3B4DFTT.js.map
|
|
76
|
+
//# sourceMappingURL=chunk-M3B4DFTT.js.map
|