@cimplify/sdk 0.20.2 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/advanced.d.mts +1 -1
- package/dist/advanced.d.ts +1 -1
- package/dist/advanced.js +20 -20
- package/dist/advanced.mjs +1 -1
- package/dist/{chunk-WXFEO3LT.js → chunk-A7IQN5EK.js} +17 -17
- package/dist/{chunk-VTMRPTQ7.mjs → chunk-R4EYMPSN.mjs} +39 -0
- package/dist/{chunk-UVBJDWIV.js → chunk-VYSXEDBV.js} +39 -0
- package/dist/{chunk-X23RNZAD.mjs → chunk-W3DMONZR.mjs} +1 -1
- package/dist/{client-D4E9aJy7.d.mts → client-B8PO4NKN.d.mts} +11 -1
- package/dist/{client-VyO6Bqz2.d.ts → client-DjrlvxW7.d.ts} +11 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +58 -58
- package/dist/index.mjs +2 -2
- package/dist/react.d.mts +22 -5
- package/dist/react.d.ts +22 -5
- package/dist/react.js +89 -29
- package/dist/react.mjs +73 -13
- package/package.json +1 -1
- package/registry/order-detail-page.json +1 -1
- package/registry/order-history-page.json +1 -1
- package/registry/order-history.json +1 -1
- package/registry/order-summary.json +1 -1
package/dist/react.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
var
|
|
4
|
+
var chunkA7IQN5EK_js = require('./chunk-A7IQN5EK.js');
|
|
5
|
+
var chunkVYSXEDBV_js = require('./chunk-VYSXEDBV.js');
|
|
6
6
|
var chunk64OCG2TJ_js = require('./chunk-64OCG2TJ.js');
|
|
7
7
|
var React3 = require('react');
|
|
8
8
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -892,6 +892,14 @@ function createCartStore(params) {
|
|
|
892
892
|
await initializePromise;
|
|
893
893
|
initializePromise = null;
|
|
894
894
|
}
|
|
895
|
+
async function reorder(orderId) {
|
|
896
|
+
const result = await client.cart.reorderFromOrder(orderId);
|
|
897
|
+
if (!result.ok) {
|
|
898
|
+
throw result.error;
|
|
899
|
+
}
|
|
900
|
+
await sync();
|
|
901
|
+
return result.value;
|
|
902
|
+
}
|
|
895
903
|
return {
|
|
896
904
|
subscribe(listener) {
|
|
897
905
|
listeners.add(listener);
|
|
@@ -907,7 +915,8 @@ function createCartStore(params) {
|
|
|
907
915
|
removeItem,
|
|
908
916
|
updateQuantity,
|
|
909
917
|
clearCart,
|
|
910
|
-
sync
|
|
918
|
+
sync,
|
|
919
|
+
reorder
|
|
911
920
|
};
|
|
912
921
|
}
|
|
913
922
|
function getStoreKey(client, locationId, isDemoMode) {
|
|
@@ -988,6 +997,12 @@ function useCart(options = {}) {
|
|
|
988
997
|
throw syncError;
|
|
989
998
|
}
|
|
990
999
|
}, [store]);
|
|
1000
|
+
const reorder = React3.useCallback(
|
|
1001
|
+
async (orderId) => {
|
|
1002
|
+
return store.reorder(orderId);
|
|
1003
|
+
},
|
|
1004
|
+
[store]
|
|
1005
|
+
);
|
|
991
1006
|
const itemCount = React3.useMemo(
|
|
992
1007
|
() => snapshot.items.reduce((sum, item) => sum + item.quantity, 0),
|
|
993
1008
|
[snapshot.items]
|
|
@@ -1005,7 +1020,8 @@ function useCart(options = {}) {
|
|
|
1005
1020
|
removeItem,
|
|
1006
1021
|
updateQuantity,
|
|
1007
1022
|
clearCart,
|
|
1008
|
-
sync
|
|
1023
|
+
sync,
|
|
1024
|
+
reorder
|
|
1009
1025
|
};
|
|
1010
1026
|
}
|
|
1011
1027
|
var LOCATION_STORAGE_KEY = "cimplify_location_id";
|
|
@@ -1016,7 +1032,7 @@ var DEFAULT_COUNTRY = "US";
|
|
|
1016
1032
|
function createDefaultClient() {
|
|
1017
1033
|
const processRef = globalThis.process;
|
|
1018
1034
|
const envPublicKey = processRef?.env?.NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY || "";
|
|
1019
|
-
return
|
|
1035
|
+
return chunkA7IQN5EK_js.createCimplifyClient({ publicKey: envPublicKey });
|
|
1020
1036
|
}
|
|
1021
1037
|
function getStoredLocationId() {
|
|
1022
1038
|
if (typeof window === "undefined" || !window.localStorage) {
|
|
@@ -2008,6 +2024,7 @@ function useCategories(options = {}) {
|
|
|
2008
2024
|
}, [cacheKey, load]);
|
|
2009
2025
|
return { categories, isLoading, error, refetch };
|
|
2010
2026
|
}
|
|
2027
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "cancelled", "refunded"]);
|
|
2011
2028
|
var orderCache = /* @__PURE__ */ new Map();
|
|
2012
2029
|
var orderInflight = /* @__PURE__ */ new Map();
|
|
2013
2030
|
function buildOrderCacheKey(client, orderId) {
|
|
@@ -2024,6 +2041,9 @@ function useOrder(orderId, options = {}) {
|
|
|
2024
2041
|
const poll = options.poll ?? false;
|
|
2025
2042
|
const pollInterval = options.pollInterval ?? 5e3;
|
|
2026
2043
|
const requestIdRef = React3.useRef(0);
|
|
2044
|
+
const previousStatusRef = React3.useRef(null);
|
|
2045
|
+
const onStatusChangeRef = React3.useRef(options.onStatusChange);
|
|
2046
|
+
onStatusChangeRef.current = options.onStatusChange;
|
|
2027
2047
|
const cacheKey = React3.useMemo(
|
|
2028
2048
|
() => buildOrderCacheKey(client, normalizedOrderId),
|
|
2029
2049
|
[client, normalizedOrderId]
|
|
@@ -2074,6 +2094,12 @@ function useOrder(orderId, options = {}) {
|
|
|
2074
2094
|
if (nextRequestId === requestIdRef.current) {
|
|
2075
2095
|
setOrder(value);
|
|
2076
2096
|
setError(null);
|
|
2097
|
+
if (value && previousStatusRef.current !== null && previousStatusRef.current !== value.status) {
|
|
2098
|
+
onStatusChangeRef.current?.(previousStatusRef.current, value.status, value);
|
|
2099
|
+
}
|
|
2100
|
+
if (value) {
|
|
2101
|
+
previousStatusRef.current = value.status;
|
|
2102
|
+
}
|
|
2077
2103
|
}
|
|
2078
2104
|
} catch (loadError) {
|
|
2079
2105
|
if (nextRequestId === requestIdRef.current) {
|
|
@@ -2090,8 +2116,9 @@ function useOrder(orderId, options = {}) {
|
|
|
2090
2116
|
React3.useEffect(() => {
|
|
2091
2117
|
void load(false);
|
|
2092
2118
|
}, [load]);
|
|
2119
|
+
const isTerminal = order ? TERMINAL_STATUSES.has(order.status) : false;
|
|
2093
2120
|
React3.useEffect(() => {
|
|
2094
|
-
if (!poll || !enabled || normalizedOrderId.length === 0) {
|
|
2121
|
+
if (!poll || !enabled || normalizedOrderId.length === 0 || isTerminal) {
|
|
2095
2122
|
return;
|
|
2096
2123
|
}
|
|
2097
2124
|
const timer = window.setInterval(() => {
|
|
@@ -2100,12 +2127,12 @@ function useOrder(orderId, options = {}) {
|
|
|
2100
2127
|
return () => {
|
|
2101
2128
|
window.clearInterval(timer);
|
|
2102
2129
|
};
|
|
2103
|
-
}, [enabled, load, normalizedOrderId, poll, pollInterval]);
|
|
2130
|
+
}, [enabled, isTerminal, load, normalizedOrderId, poll, pollInterval]);
|
|
2104
2131
|
const refetch = React3.useCallback(async () => {
|
|
2105
2132
|
orderCache.delete(cacheKey);
|
|
2106
2133
|
await load(true);
|
|
2107
2134
|
}, [cacheKey, load]);
|
|
2108
|
-
return { order, isLoading, error, refetch };
|
|
2135
|
+
return { order, isLoading, error, refetch, isTerminal };
|
|
2109
2136
|
}
|
|
2110
2137
|
var LOCATION_STORAGE_KEY2 = "cimplify_location_id";
|
|
2111
2138
|
function readStoredLocationId() {
|
|
@@ -4751,19 +4778,19 @@ function AuthElement({
|
|
|
4751
4778
|
}, [onReady, onAuthenticated, onRequiresOtp, onError]);
|
|
4752
4779
|
React3.useEffect(() => {
|
|
4753
4780
|
if (!elements || !containerRef.current) return;
|
|
4754
|
-
const element = elements.create(
|
|
4781
|
+
const element = elements.create(chunkVYSXEDBV_js.ELEMENT_TYPES.AUTH, { prefillEmail });
|
|
4755
4782
|
elementRef.current = element;
|
|
4756
|
-
element.on(
|
|
4783
|
+
element.on(chunkVYSXEDBV_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
4757
4784
|
element.on(
|
|
4758
|
-
|
|
4785
|
+
chunkVYSXEDBV_js.EVENT_TYPES.AUTHENTICATED,
|
|
4759
4786
|
(data) => onAuthenticatedRef.current?.(data)
|
|
4760
4787
|
);
|
|
4761
4788
|
element.on(
|
|
4762
|
-
|
|
4789
|
+
chunkVYSXEDBV_js.EVENT_TYPES.REQUIRES_OTP,
|
|
4763
4790
|
(data) => onRequiresOtpRef.current?.(data)
|
|
4764
4791
|
);
|
|
4765
4792
|
element.on(
|
|
4766
|
-
|
|
4793
|
+
chunkVYSXEDBV_js.EVENT_TYPES.ERROR,
|
|
4767
4794
|
(data) => onErrorRef.current?.(data)
|
|
4768
4795
|
);
|
|
4769
4796
|
element.mount(containerRef.current);
|
|
@@ -4792,15 +4819,15 @@ function AddressElement({
|
|
|
4792
4819
|
}, [onReady, onChange, onError]);
|
|
4793
4820
|
React3.useEffect(() => {
|
|
4794
4821
|
if (!elements || !containerRef.current) return;
|
|
4795
|
-
const element = elements.create(
|
|
4822
|
+
const element = elements.create(chunkVYSXEDBV_js.ELEMENT_TYPES.ADDRESS, { mode });
|
|
4796
4823
|
elementRef.current = element;
|
|
4797
|
-
element.on(
|
|
4824
|
+
element.on(chunkVYSXEDBV_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
4798
4825
|
element.on(
|
|
4799
|
-
|
|
4826
|
+
chunkVYSXEDBV_js.EVENT_TYPES.CHANGE,
|
|
4800
4827
|
(data) => onChangeRef.current?.(data)
|
|
4801
4828
|
);
|
|
4802
4829
|
element.on(
|
|
4803
|
-
|
|
4830
|
+
chunkVYSXEDBV_js.EVENT_TYPES.ERROR,
|
|
4804
4831
|
(data) => onErrorRef.current?.(data)
|
|
4805
4832
|
);
|
|
4806
4833
|
element.mount(containerRef.current);
|
|
@@ -4830,15 +4857,15 @@ function PaymentElement({
|
|
|
4830
4857
|
}, [onReady, onChange, onError]);
|
|
4831
4858
|
React3.useEffect(() => {
|
|
4832
4859
|
if (!elements || !containerRef.current) return;
|
|
4833
|
-
const element = elements.create(
|
|
4860
|
+
const element = elements.create(chunkVYSXEDBV_js.ELEMENT_TYPES.PAYMENT, { amount, currency });
|
|
4834
4861
|
elementRef.current = element;
|
|
4835
|
-
element.on(
|
|
4862
|
+
element.on(chunkVYSXEDBV_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
4836
4863
|
element.on(
|
|
4837
|
-
|
|
4864
|
+
chunkVYSXEDBV_js.EVENT_TYPES.CHANGE,
|
|
4838
4865
|
(data) => onChangeRef.current?.(data)
|
|
4839
4866
|
);
|
|
4840
4867
|
element.on(
|
|
4841
|
-
|
|
4868
|
+
chunkVYSXEDBV_js.EVENT_TYPES.ERROR,
|
|
4842
4869
|
(data) => onErrorRef.current?.(data)
|
|
4843
4870
|
);
|
|
4844
4871
|
element.mount(containerRef.current);
|
|
@@ -5101,7 +5128,7 @@ function VariantSelector({
|
|
|
5101
5128
|
{
|
|
5102
5129
|
"data-cimplify-variant-name": true,
|
|
5103
5130
|
className: cn("flex-1 min-w-0 text-sm", classNames?.name),
|
|
5104
|
-
children:
|
|
5131
|
+
children: chunkA7IQN5EK_js.getVariantDisplayName(variant, productName)
|
|
5105
5132
|
}
|
|
5106
5133
|
),
|
|
5107
5134
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm text-muted-foreground", classNames?.pricing), children: [
|
|
@@ -6415,7 +6442,7 @@ function CartLineItemRow({
|
|
|
6415
6442
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item": true, className: classNames?.item, children: [
|
|
6416
6443
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-info": true, children: [
|
|
6417
6444
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-name": true, className: classNames?.itemName, children: item.product.name }),
|
|
6418
|
-
item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children:
|
|
6445
|
+
item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children: chunkA7IQN5EK_js.getVariantDisplayName(item.variant, item.product.name) }),
|
|
6419
6446
|
item.addOnOptions && item.addOnOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-cart-item-addons": true, children: [
|
|
6420
6447
|
"+ ",
|
|
6421
6448
|
item.addOnOptions.map((opt) => opt.name).join(", ")
|
|
@@ -7523,12 +7550,15 @@ function OrderSummary({
|
|
|
7523
7550
|
orderId,
|
|
7524
7551
|
poll = false,
|
|
7525
7552
|
renderLineItem,
|
|
7553
|
+
onReorder,
|
|
7554
|
+
onStatusChange,
|
|
7526
7555
|
className,
|
|
7527
7556
|
classNames
|
|
7528
7557
|
}) {
|
|
7529
7558
|
const { order: fetched, isLoading } = useOrder(orderProp ? null : orderId, {
|
|
7530
7559
|
enabled: !orderProp && !!orderId,
|
|
7531
|
-
poll
|
|
7560
|
+
poll,
|
|
7561
|
+
onStatusChange
|
|
7532
7562
|
});
|
|
7533
7563
|
const order = orderProp ?? fetched;
|
|
7534
7564
|
if (isLoading && !order) {
|
|
@@ -7694,6 +7724,16 @@ function OrderSummary({
|
|
|
7694
7724
|
className: classNames?.trackingLink,
|
|
7695
7725
|
children: "Track your order"
|
|
7696
7726
|
}
|
|
7727
|
+
),
|
|
7728
|
+
onReorder && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7729
|
+
"button",
|
|
7730
|
+
{
|
|
7731
|
+
type: "button",
|
|
7732
|
+
onClick: () => onReorder(order),
|
|
7733
|
+
"data-cimplify-order-reorder": true,
|
|
7734
|
+
className: classNames?.reorderButton,
|
|
7735
|
+
children: "Reorder"
|
|
7736
|
+
}
|
|
7697
7737
|
)
|
|
7698
7738
|
] });
|
|
7699
7739
|
}
|
|
@@ -7717,6 +7757,7 @@ function OrderHistory({
|
|
|
7717
7757
|
limit,
|
|
7718
7758
|
onOrderClick,
|
|
7719
7759
|
renderOrder,
|
|
7760
|
+
onReorder,
|
|
7720
7761
|
emptyMessage = "No orders yet",
|
|
7721
7762
|
className,
|
|
7722
7763
|
classNames
|
|
@@ -7788,7 +7829,20 @@ function OrderHistory({
|
|
|
7788
7829
|
order.total_quantity === 1 ? "item" : "items"
|
|
7789
7830
|
] }),
|
|
7790
7831
|
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-order-history-total": true, className: classNames?.total, children: /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: order.total_price }) })
|
|
7791
|
-
] })
|
|
7832
|
+
] }),
|
|
7833
|
+
onReorder && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7834
|
+
"button",
|
|
7835
|
+
{
|
|
7836
|
+
type: "button",
|
|
7837
|
+
onClick: (e) => {
|
|
7838
|
+
e.stopPropagation();
|
|
7839
|
+
onReorder(order);
|
|
7840
|
+
},
|
|
7841
|
+
"data-cimplify-order-reorder": true,
|
|
7842
|
+
className: classNames?.reorderButton,
|
|
7843
|
+
children: "Reorder"
|
|
7844
|
+
}
|
|
7845
|
+
)
|
|
7792
7846
|
] })
|
|
7793
7847
|
},
|
|
7794
7848
|
order.id
|
|
@@ -8980,6 +9034,8 @@ function OrderDetailPage({
|
|
|
8980
9034
|
poll = true,
|
|
8981
9035
|
onBack,
|
|
8982
9036
|
renderLineItem,
|
|
9037
|
+
onReorder,
|
|
9038
|
+
onStatusChange,
|
|
8983
9039
|
backLabel = "Back to orders",
|
|
8984
9040
|
className,
|
|
8985
9041
|
classNames
|
|
@@ -9004,7 +9060,9 @@ function OrderDetailPage({
|
|
|
9004
9060
|
order,
|
|
9005
9061
|
orderId: order ? void 0 : orderId,
|
|
9006
9062
|
poll,
|
|
9007
|
-
renderLineItem
|
|
9063
|
+
renderLineItem,
|
|
9064
|
+
onReorder,
|
|
9065
|
+
onStatusChange
|
|
9008
9066
|
}
|
|
9009
9067
|
) })
|
|
9010
9068
|
] });
|
|
@@ -9020,6 +9078,7 @@ function OrderHistoryPage({
|
|
|
9020
9078
|
orders: ordersProp,
|
|
9021
9079
|
limit = 20,
|
|
9022
9080
|
onOrderNavigate,
|
|
9081
|
+
onReorder,
|
|
9023
9082
|
showFilters = true,
|
|
9024
9083
|
renderOrder,
|
|
9025
9084
|
className,
|
|
@@ -9057,7 +9116,7 @@ function OrderHistoryPage({
|
|
|
9057
9116
|
children: "Back to orders"
|
|
9058
9117
|
}
|
|
9059
9118
|
),
|
|
9060
|
-
/* @__PURE__ */ jsxRuntime.jsx(OrderSummary, { order: selectedOrder })
|
|
9119
|
+
/* @__PURE__ */ jsxRuntime.jsx(OrderSummary, { order: selectedOrder, onReorder })
|
|
9061
9120
|
] }) });
|
|
9062
9121
|
}
|
|
9063
9122
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-order-history-page": true, className: cn(className, classNames?.root), children: [
|
|
@@ -9080,7 +9139,8 @@ function OrderHistoryPage({
|
|
|
9080
9139
|
status: statusFilter,
|
|
9081
9140
|
limit,
|
|
9082
9141
|
onOrderClick: handleOrderClick,
|
|
9083
|
-
renderOrder
|
|
9142
|
+
renderOrder,
|
|
9143
|
+
onReorder
|
|
9084
9144
|
}
|
|
9085
9145
|
) })
|
|
9086
9146
|
] });
|
|
@@ -9972,7 +10032,7 @@ function CurrencySelector({
|
|
|
9972
10032
|
|
|
9973
10033
|
Object.defineProperty(exports, "getVariantDisplayName", {
|
|
9974
10034
|
enumerable: true,
|
|
9975
|
-
get: function () { return
|
|
10035
|
+
get: function () { return chunkA7IQN5EK_js.getVariantDisplayName; }
|
|
9976
10036
|
});
|
|
9977
10037
|
exports.Ad = Ad;
|
|
9978
10038
|
exports.AdProvider = AdProvider;
|
package/dist/react.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { getVariantDisplayName, createCimplifyClient } from './chunk-
|
|
3
|
-
export { getVariantDisplayName } from './chunk-
|
|
4
|
-
import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-
|
|
2
|
+
import { getVariantDisplayName, createCimplifyClient } from './chunk-W3DMONZR.mjs';
|
|
3
|
+
export { getVariantDisplayName } from './chunk-W3DMONZR.mjs';
|
|
4
|
+
import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-R4EYMPSN.mjs';
|
|
5
5
|
import { isSupportedCurrency, formatPrice, parsePrice, isOnSale, getDiscountPercentage, getBasePrice } from './chunk-JFT63H34.mjs';
|
|
6
6
|
import React3, { createContext, useContext, useState, useEffect, useRef, useMemo, useSyncExternalStore, useCallback, useId } from 'react';
|
|
7
7
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
@@ -887,6 +887,14 @@ function createCartStore(params) {
|
|
|
887
887
|
await initializePromise;
|
|
888
888
|
initializePromise = null;
|
|
889
889
|
}
|
|
890
|
+
async function reorder(orderId) {
|
|
891
|
+
const result = await client.cart.reorderFromOrder(orderId);
|
|
892
|
+
if (!result.ok) {
|
|
893
|
+
throw result.error;
|
|
894
|
+
}
|
|
895
|
+
await sync();
|
|
896
|
+
return result.value;
|
|
897
|
+
}
|
|
890
898
|
return {
|
|
891
899
|
subscribe(listener) {
|
|
892
900
|
listeners.add(listener);
|
|
@@ -902,7 +910,8 @@ function createCartStore(params) {
|
|
|
902
910
|
removeItem,
|
|
903
911
|
updateQuantity,
|
|
904
912
|
clearCart,
|
|
905
|
-
sync
|
|
913
|
+
sync,
|
|
914
|
+
reorder
|
|
906
915
|
};
|
|
907
916
|
}
|
|
908
917
|
function getStoreKey(client, locationId, isDemoMode) {
|
|
@@ -983,6 +992,12 @@ function useCart(options = {}) {
|
|
|
983
992
|
throw syncError;
|
|
984
993
|
}
|
|
985
994
|
}, [store]);
|
|
995
|
+
const reorder = useCallback(
|
|
996
|
+
async (orderId) => {
|
|
997
|
+
return store.reorder(orderId);
|
|
998
|
+
},
|
|
999
|
+
[store]
|
|
1000
|
+
);
|
|
986
1001
|
const itemCount = useMemo(
|
|
987
1002
|
() => snapshot.items.reduce((sum, item) => sum + item.quantity, 0),
|
|
988
1003
|
[snapshot.items]
|
|
@@ -1000,7 +1015,8 @@ function useCart(options = {}) {
|
|
|
1000
1015
|
removeItem,
|
|
1001
1016
|
updateQuantity,
|
|
1002
1017
|
clearCart,
|
|
1003
|
-
sync
|
|
1018
|
+
sync,
|
|
1019
|
+
reorder
|
|
1004
1020
|
};
|
|
1005
1021
|
}
|
|
1006
1022
|
var LOCATION_STORAGE_KEY = "cimplify_location_id";
|
|
@@ -2003,6 +2019,7 @@ function useCategories(options = {}) {
|
|
|
2003
2019
|
}, [cacheKey, load]);
|
|
2004
2020
|
return { categories, isLoading, error, refetch };
|
|
2005
2021
|
}
|
|
2022
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "cancelled", "refunded"]);
|
|
2006
2023
|
var orderCache = /* @__PURE__ */ new Map();
|
|
2007
2024
|
var orderInflight = /* @__PURE__ */ new Map();
|
|
2008
2025
|
function buildOrderCacheKey(client, orderId) {
|
|
@@ -2019,6 +2036,9 @@ function useOrder(orderId, options = {}) {
|
|
|
2019
2036
|
const poll = options.poll ?? false;
|
|
2020
2037
|
const pollInterval = options.pollInterval ?? 5e3;
|
|
2021
2038
|
const requestIdRef = useRef(0);
|
|
2039
|
+
const previousStatusRef = useRef(null);
|
|
2040
|
+
const onStatusChangeRef = useRef(options.onStatusChange);
|
|
2041
|
+
onStatusChangeRef.current = options.onStatusChange;
|
|
2022
2042
|
const cacheKey = useMemo(
|
|
2023
2043
|
() => buildOrderCacheKey(client, normalizedOrderId),
|
|
2024
2044
|
[client, normalizedOrderId]
|
|
@@ -2069,6 +2089,12 @@ function useOrder(orderId, options = {}) {
|
|
|
2069
2089
|
if (nextRequestId === requestIdRef.current) {
|
|
2070
2090
|
setOrder(value);
|
|
2071
2091
|
setError(null);
|
|
2092
|
+
if (value && previousStatusRef.current !== null && previousStatusRef.current !== value.status) {
|
|
2093
|
+
onStatusChangeRef.current?.(previousStatusRef.current, value.status, value);
|
|
2094
|
+
}
|
|
2095
|
+
if (value) {
|
|
2096
|
+
previousStatusRef.current = value.status;
|
|
2097
|
+
}
|
|
2072
2098
|
}
|
|
2073
2099
|
} catch (loadError) {
|
|
2074
2100
|
if (nextRequestId === requestIdRef.current) {
|
|
@@ -2085,8 +2111,9 @@ function useOrder(orderId, options = {}) {
|
|
|
2085
2111
|
useEffect(() => {
|
|
2086
2112
|
void load(false);
|
|
2087
2113
|
}, [load]);
|
|
2114
|
+
const isTerminal = order ? TERMINAL_STATUSES.has(order.status) : false;
|
|
2088
2115
|
useEffect(() => {
|
|
2089
|
-
if (!poll || !enabled || normalizedOrderId.length === 0) {
|
|
2116
|
+
if (!poll || !enabled || normalizedOrderId.length === 0 || isTerminal) {
|
|
2090
2117
|
return;
|
|
2091
2118
|
}
|
|
2092
2119
|
const timer = window.setInterval(() => {
|
|
@@ -2095,12 +2122,12 @@ function useOrder(orderId, options = {}) {
|
|
|
2095
2122
|
return () => {
|
|
2096
2123
|
window.clearInterval(timer);
|
|
2097
2124
|
};
|
|
2098
|
-
}, [enabled, load, normalizedOrderId, poll, pollInterval]);
|
|
2125
|
+
}, [enabled, isTerminal, load, normalizedOrderId, poll, pollInterval]);
|
|
2099
2126
|
const refetch = useCallback(async () => {
|
|
2100
2127
|
orderCache.delete(cacheKey);
|
|
2101
2128
|
await load(true);
|
|
2102
2129
|
}, [cacheKey, load]);
|
|
2103
|
-
return { order, isLoading, error, refetch };
|
|
2130
|
+
return { order, isLoading, error, refetch, isTerminal };
|
|
2104
2131
|
}
|
|
2105
2132
|
var LOCATION_STORAGE_KEY2 = "cimplify_location_id";
|
|
2106
2133
|
function readStoredLocationId() {
|
|
@@ -7518,12 +7545,15 @@ function OrderSummary({
|
|
|
7518
7545
|
orderId,
|
|
7519
7546
|
poll = false,
|
|
7520
7547
|
renderLineItem,
|
|
7548
|
+
onReorder,
|
|
7549
|
+
onStatusChange,
|
|
7521
7550
|
className,
|
|
7522
7551
|
classNames
|
|
7523
7552
|
}) {
|
|
7524
7553
|
const { order: fetched, isLoading } = useOrder(orderProp ? null : orderId, {
|
|
7525
7554
|
enabled: !orderProp && !!orderId,
|
|
7526
|
-
poll
|
|
7555
|
+
poll,
|
|
7556
|
+
onStatusChange
|
|
7527
7557
|
});
|
|
7528
7558
|
const order = orderProp ?? fetched;
|
|
7529
7559
|
if (isLoading && !order) {
|
|
@@ -7689,6 +7719,16 @@ function OrderSummary({
|
|
|
7689
7719
|
className: classNames?.trackingLink,
|
|
7690
7720
|
children: "Track your order"
|
|
7691
7721
|
}
|
|
7722
|
+
),
|
|
7723
|
+
onReorder && /* @__PURE__ */ jsx(
|
|
7724
|
+
"button",
|
|
7725
|
+
{
|
|
7726
|
+
type: "button",
|
|
7727
|
+
onClick: () => onReorder(order),
|
|
7728
|
+
"data-cimplify-order-reorder": true,
|
|
7729
|
+
className: classNames?.reorderButton,
|
|
7730
|
+
children: "Reorder"
|
|
7731
|
+
}
|
|
7692
7732
|
)
|
|
7693
7733
|
] });
|
|
7694
7734
|
}
|
|
@@ -7712,6 +7752,7 @@ function OrderHistory({
|
|
|
7712
7752
|
limit,
|
|
7713
7753
|
onOrderClick,
|
|
7714
7754
|
renderOrder,
|
|
7755
|
+
onReorder,
|
|
7715
7756
|
emptyMessage = "No orders yet",
|
|
7716
7757
|
className,
|
|
7717
7758
|
classNames
|
|
@@ -7783,7 +7824,20 @@ function OrderHistory({
|
|
|
7783
7824
|
order.total_quantity === 1 ? "item" : "items"
|
|
7784
7825
|
] }),
|
|
7785
7826
|
/* @__PURE__ */ jsx("span", { "data-cimplify-order-history-total": true, className: classNames?.total, children: /* @__PURE__ */ jsx(Price, { amount: order.total_price }) })
|
|
7786
|
-
] })
|
|
7827
|
+
] }),
|
|
7828
|
+
onReorder && /* @__PURE__ */ jsx(
|
|
7829
|
+
"button",
|
|
7830
|
+
{
|
|
7831
|
+
type: "button",
|
|
7832
|
+
onClick: (e) => {
|
|
7833
|
+
e.stopPropagation();
|
|
7834
|
+
onReorder(order);
|
|
7835
|
+
},
|
|
7836
|
+
"data-cimplify-order-reorder": true,
|
|
7837
|
+
className: classNames?.reorderButton,
|
|
7838
|
+
children: "Reorder"
|
|
7839
|
+
}
|
|
7840
|
+
)
|
|
7787
7841
|
] })
|
|
7788
7842
|
},
|
|
7789
7843
|
order.id
|
|
@@ -8975,6 +9029,8 @@ function OrderDetailPage({
|
|
|
8975
9029
|
poll = true,
|
|
8976
9030
|
onBack,
|
|
8977
9031
|
renderLineItem,
|
|
9032
|
+
onReorder,
|
|
9033
|
+
onStatusChange,
|
|
8978
9034
|
backLabel = "Back to orders",
|
|
8979
9035
|
className,
|
|
8980
9036
|
classNames
|
|
@@ -8999,7 +9055,9 @@ function OrderDetailPage({
|
|
|
8999
9055
|
order,
|
|
9000
9056
|
orderId: order ? void 0 : orderId,
|
|
9001
9057
|
poll,
|
|
9002
|
-
renderLineItem
|
|
9058
|
+
renderLineItem,
|
|
9059
|
+
onReorder,
|
|
9060
|
+
onStatusChange
|
|
9003
9061
|
}
|
|
9004
9062
|
) })
|
|
9005
9063
|
] });
|
|
@@ -9015,6 +9073,7 @@ function OrderHistoryPage({
|
|
|
9015
9073
|
orders: ordersProp,
|
|
9016
9074
|
limit = 20,
|
|
9017
9075
|
onOrderNavigate,
|
|
9076
|
+
onReorder,
|
|
9018
9077
|
showFilters = true,
|
|
9019
9078
|
renderOrder,
|
|
9020
9079
|
className,
|
|
@@ -9052,7 +9111,7 @@ function OrderHistoryPage({
|
|
|
9052
9111
|
children: "Back to orders"
|
|
9053
9112
|
}
|
|
9054
9113
|
),
|
|
9055
|
-
/* @__PURE__ */ jsx(OrderSummary, { order: selectedOrder })
|
|
9114
|
+
/* @__PURE__ */ jsx(OrderSummary, { order: selectedOrder, onReorder })
|
|
9056
9115
|
] }) });
|
|
9057
9116
|
}
|
|
9058
9117
|
return /* @__PURE__ */ jsxs("div", { "data-cimplify-order-history-page": true, className: cn(className, classNames?.root), children: [
|
|
@@ -9075,7 +9134,8 @@ function OrderHistoryPage({
|
|
|
9075
9134
|
status: statusFilter,
|
|
9076
9135
|
limit,
|
|
9077
9136
|
onOrderClick: handleOrderClick,
|
|
9078
|
-
renderOrder
|
|
9137
|
+
renderOrder,
|
|
9138
|
+
onReorder
|
|
9079
9139
|
}
|
|
9080
9140
|
) })
|
|
9081
9141
|
] });
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
{
|
|
12
12
|
"path": "order-detail-page.tsx",
|
|
13
|
-
"content": "\"use client\";\n\nimport React from \"react\";\nimport type { Order, LineItem } from \"@cimplify/sdk\";\nimport { OrderSummary } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface OrderDetailPageClassNames {\n root?: string;\n header?: string;\n title?: string;\n backButton?: string;\n summary?: string;\n}\n\nexport interface OrderDetailPageProps {\n /** Order ID to display. */\n orderId: string;\n /** Pre-fetched order for SSR. */\n order?: Order;\n /** Poll for status updates. Default: true. */\n poll?: boolean;\n /** Called when back button is clicked. */\n onBack?: () => void;\n /** Custom line item renderer. */\n renderLineItem?: (item: LineItem) => React.ReactNode;\n /** Back button label. */\n backLabel?: string;\n className?: string;\n classNames?: OrderDetailPageClassNames;\n}\n\n/**\n * OrderDetailPage — single order detail view with live status polling.\n *\n * SSR-friendly: pass `order` prop for server rendering.\n */\nexport function OrderDetailPage({\n orderId,\n order,\n poll = true,\n onBack,\n renderLineItem,\n backLabel = \"Back to orders\",\n className,\n classNames,\n}: OrderDetailPageProps): React.ReactElement {\n return (\n <div data-cimplify-order-detail-page className={cn(className, classNames?.root)}>\n {/* Header */}\n <div data-cimplify-order-detail-header className={classNames?.header}>\n {onBack && (\n <button\n type=\"button\"\n onClick={onBack}\n data-cimplify-order-detail-back\n className={classNames?.backButton}\n >\n {backLabel}\n </button>\n )}\n <h1 data-cimplify-order-detail-title className={classNames?.title}>\n Order Details\n </h1>\n </div>\n\n {/* Order summary */}\n <div data-cimplify-order-detail-content className={classNames?.summary}>\n <OrderSummary\n order={order}\n orderId={order ? undefined : orderId}\n poll={poll}\n renderLineItem={renderLineItem}\n />\n </div>\n </div>\n );\n}\n"
|
|
13
|
+
"content": "\"use client\";\n\nimport React from \"react\";\nimport type { Order, LineItem, OrderStatus } from \"@cimplify/sdk\";\nimport { OrderSummary } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface OrderDetailPageClassNames {\n root?: string;\n header?: string;\n title?: string;\n backButton?: string;\n summary?: string;\n}\n\nexport interface OrderDetailPageProps {\n /** Order ID to display. */\n orderId: string;\n /** Pre-fetched order for SSR. */\n order?: Order;\n /** Poll for status updates. Default: true. */\n poll?: boolean;\n /** Called when back button is clicked. */\n onBack?: () => void;\n /** Custom line item renderer. */\n renderLineItem?: (item: LineItem) => React.ReactNode;\n /** Called when the reorder button is clicked. */\n onReorder?: (order: Order) => void;\n /** Called when the order status changes during polling. */\n onStatusChange?: (previousStatus: OrderStatus, newStatus: OrderStatus, order: Order) => void;\n /** Back button label. */\n backLabel?: string;\n className?: string;\n classNames?: OrderDetailPageClassNames;\n}\n\n/**\n * OrderDetailPage — single order detail view with live status polling.\n *\n * SSR-friendly: pass `order` prop for server rendering.\n */\nexport function OrderDetailPage({\n orderId,\n order,\n poll = true,\n onBack,\n renderLineItem,\n onReorder,\n onStatusChange,\n backLabel = \"Back to orders\",\n className,\n classNames,\n}: OrderDetailPageProps): React.ReactElement {\n return (\n <div data-cimplify-order-detail-page className={cn(className, classNames?.root)}>\n {/* Header */}\n <div data-cimplify-order-detail-header className={classNames?.header}>\n {onBack && (\n <button\n type=\"button\"\n onClick={onBack}\n data-cimplify-order-detail-back\n className={classNames?.backButton}\n >\n {backLabel}\n </button>\n )}\n <h1 data-cimplify-order-detail-title className={classNames?.title}>\n Order Details\n </h1>\n </div>\n\n {/* Order summary */}\n <div data-cimplify-order-detail-content className={classNames?.summary}>\n <OrderSummary\n order={order}\n orderId={order ? undefined : orderId}\n poll={poll}\n renderLineItem={renderLineItem}\n onReorder={onReorder}\n onStatusChange={onStatusChange}\n />\n </div>\n </div>\n );\n}\n"
|
|
14
14
|
}
|
|
15
15
|
]
|
|
16
16
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"files": [
|
|
12
12
|
{
|
|
13
13
|
"path": "order-history-page.tsx",
|
|
14
|
-
"content": "\"use client\";\n\nimport React, { useState, useCallback } from \"react\";\nimport { Tabs } from \"@base-ui/react/tabs\";\nimport type { Order, OrderStatus } from \"@cimplify/sdk\";\nimport { OrderHistory } from \"@cimplify/sdk/react\";\nimport { OrderSummary } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface OrderHistoryPageClassNames {\n root?: string;\n header?: string;\n title?: string;\n filters?: string;\n filterButton?: string;\n list?: string;\n detail?: string;\n backButton?: string;\n}\n\nexport interface OrderHistoryPageProps {\n /** Page title. */\n title?: string;\n /** Pre-fetched orders for SSR. */\n orders?: Order[];\n /** Max orders to show per page. */\n limit?: number;\n /** Called when navigating to an order detail (e.g. for routing). */\n onOrderNavigate?: (order: Order) => void;\n /** Show status filter tabs. Default: true. */\n showFilters?: boolean;\n /** Custom order row renderer. */\n renderOrder?: (order: Order) => React.ReactNode;\n className?: string;\n classNames?: OrderHistoryPageClassNames;\n}\n\nconst STATUS_FILTERS: { label: string; value: OrderStatus | undefined; tabValue: string }[] = [\n { label: \"All\", value: undefined, tabValue: \"all\" },\n { label: \"Active\", value: \"confirmed\", tabValue: \"confirmed\" },\n { label: \"Completed\", value: \"completed\", tabValue: \"completed\" },\n { label: \"Cancelled\", value: \"cancelled\", tabValue: \"cancelled\" },\n];\n\n/**\n * OrderHistoryPage — order list with inline detail view and status filtering.\n *\n * SSR-friendly: pass `orders` prop for server rendering.\n * Supports both inline detail view and external navigation via `onOrderNavigate`.\n */\nexport function OrderHistoryPage({\n title = \"Order History\",\n orders: ordersProp,\n limit = 20,\n onOrderNavigate,\n showFilters = true,\n renderOrder,\n className,\n classNames,\n}: OrderHistoryPageProps): React.ReactElement {\n const [statusFilter, setStatusFilter] = useState<OrderStatus | undefined>(undefined);\n const [selectedOrder, setSelectedOrder] = useState<Order | null>(null);\n\n const handleTabChange = useCallback((value: string | number | null) => {\n const filter = STATUS_FILTERS.find((f) => f.tabValue === value);\n setStatusFilter(filter?.value);\n }, []);\n\n const handleOrderClick = useCallback(\n (order: Order) => {\n if (onOrderNavigate) {\n onOrderNavigate(order);\n } else {\n setSelectedOrder(order);\n }\n },\n [onOrderNavigate],\n );\n\n const handleBack = useCallback(() => {\n setSelectedOrder(null);\n }, []);\n\n const activeTabValue = STATUS_FILTERS.find((f) => f.value === statusFilter)?.tabValue ?? \"all\";\n\n // Inline detail view\n if (selectedOrder && !onOrderNavigate) {\n return (\n <div data-cimplify-order-history-page className={cn(className, classNames?.root)}>\n <div data-cimplify-order-history-detail className={classNames?.detail}>\n <button\n type=\"button\"\n onClick={handleBack}\n data-cimplify-order-history-back\n className={classNames?.backButton}\n >\n Back to orders\n </button>\n <OrderSummary order={selectedOrder} />\n </div>\n </div>\n );\n }\n\n return (\n <div data-cimplify-order-history-page className={cn(className, classNames?.root)}>\n {/* Header */}\n <div data-cimplify-order-history-header className={classNames?.header}>\n <h1 data-cimplify-order-history-title className={classNames?.title}>\n {title}\n </h1>\n </div>\n\n {/* Status filter */}\n {showFilters && (\n <Tabs.Root value={activeTabValue} onValueChange={handleTabChange}>\n <Tabs.List data-cimplify-order-history-filters className={classNames?.filters}>\n {STATUS_FILTERS.map((filter) => (\n <Tabs.Tab\n key={filter.tabValue}\n value={filter.tabValue}\n data-cimplify-order-filter\n data-selected={statusFilter === filter.value || undefined}\n className={classNames?.filterButton}\n >\n {filter.label}\n </Tabs.Tab>\n ))}\n </Tabs.List>\n </Tabs.Root>\n )}\n\n {/* Order list */}\n <div data-cimplify-order-history-list className={classNames?.list}>\n <OrderHistory\n orders={ordersProp}\n status={statusFilter}\n limit={limit}\n onOrderClick={handleOrderClick}\n renderOrder={renderOrder}\n />\n </div>\n </div>\n );\n}\n"
|
|
14
|
+
"content": "\"use client\";\n\nimport React, { useState, useCallback } from \"react\";\nimport { Tabs } from \"@base-ui/react/tabs\";\nimport type { Order, OrderStatus } from \"@cimplify/sdk\";\nimport { OrderHistory } from \"@cimplify/sdk/react\";\nimport { OrderSummary } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface OrderHistoryPageClassNames {\n root?: string;\n header?: string;\n title?: string;\n filters?: string;\n filterButton?: string;\n list?: string;\n detail?: string;\n backButton?: string;\n}\n\nexport interface OrderHistoryPageProps {\n /** Page title. */\n title?: string;\n /** Pre-fetched orders for SSR. */\n orders?: Order[];\n /** Max orders to show per page. */\n limit?: number;\n /** Called when navigating to an order detail (e.g. for routing). */\n onOrderNavigate?: (order: Order) => void;\n /** Called when the reorder button is clicked. */\n onReorder?: (order: Order) => void;\n /** Show status filter tabs. Default: true. */\n showFilters?: boolean;\n /** Custom order row renderer. */\n renderOrder?: (order: Order) => React.ReactNode;\n className?: string;\n classNames?: OrderHistoryPageClassNames;\n}\n\nconst STATUS_FILTERS: { label: string; value: OrderStatus | undefined; tabValue: string }[] = [\n { label: \"All\", value: undefined, tabValue: \"all\" },\n { label: \"Active\", value: \"confirmed\", tabValue: \"confirmed\" },\n { label: \"Completed\", value: \"completed\", tabValue: \"completed\" },\n { label: \"Cancelled\", value: \"cancelled\", tabValue: \"cancelled\" },\n];\n\n/**\n * OrderHistoryPage — order list with inline detail view and status filtering.\n *\n * SSR-friendly: pass `orders` prop for server rendering.\n * Supports both inline detail view and external navigation via `onOrderNavigate`.\n */\nexport function OrderHistoryPage({\n title = \"Order History\",\n orders: ordersProp,\n limit = 20,\n onOrderNavigate,\n onReorder,\n showFilters = true,\n renderOrder,\n className,\n classNames,\n}: OrderHistoryPageProps): React.ReactElement {\n const [statusFilter, setStatusFilter] = useState<OrderStatus | undefined>(undefined);\n const [selectedOrder, setSelectedOrder] = useState<Order | null>(null);\n\n const handleTabChange = useCallback((value: string | number | null) => {\n const filter = STATUS_FILTERS.find((f) => f.tabValue === value);\n setStatusFilter(filter?.value);\n }, []);\n\n const handleOrderClick = useCallback(\n (order: Order) => {\n if (onOrderNavigate) {\n onOrderNavigate(order);\n } else {\n setSelectedOrder(order);\n }\n },\n [onOrderNavigate],\n );\n\n const handleBack = useCallback(() => {\n setSelectedOrder(null);\n }, []);\n\n const activeTabValue = STATUS_FILTERS.find((f) => f.value === statusFilter)?.tabValue ?? \"all\";\n\n // Inline detail view\n if (selectedOrder && !onOrderNavigate) {\n return (\n <div data-cimplify-order-history-page className={cn(className, classNames?.root)}>\n <div data-cimplify-order-history-detail className={classNames?.detail}>\n <button\n type=\"button\"\n onClick={handleBack}\n data-cimplify-order-history-back\n className={classNames?.backButton}\n >\n Back to orders\n </button>\n <OrderSummary order={selectedOrder} onReorder={onReorder} />\n </div>\n </div>\n );\n }\n\n return (\n <div data-cimplify-order-history-page className={cn(className, classNames?.root)}>\n {/* Header */}\n <div data-cimplify-order-history-header className={classNames?.header}>\n <h1 data-cimplify-order-history-title className={classNames?.title}>\n {title}\n </h1>\n </div>\n\n {/* Status filter */}\n {showFilters && (\n <Tabs.Root value={activeTabValue} onValueChange={handleTabChange}>\n <Tabs.List data-cimplify-order-history-filters className={classNames?.filters}>\n {STATUS_FILTERS.map((filter) => (\n <Tabs.Tab\n key={filter.tabValue}\n value={filter.tabValue}\n data-cimplify-order-filter\n data-selected={statusFilter === filter.value || undefined}\n className={classNames?.filterButton}\n >\n {filter.label}\n </Tabs.Tab>\n ))}\n </Tabs.List>\n </Tabs.Root>\n )}\n\n {/* Order list */}\n <div data-cimplify-order-history-list className={classNames?.list}>\n <OrderHistory\n orders={ordersProp}\n status={statusFilter}\n limit={limit}\n onOrderClick={handleOrderClick}\n renderOrder={renderOrder}\n onReorder={onReorder}\n />\n </div>\n </div>\n );\n}\n"
|
|
15
15
|
}
|
|
16
16
|
]
|
|
17
17
|
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
{
|
|
12
12
|
"path": "order-history.tsx",
|
|
13
|
-
"content": "\"use client\";\n\nimport React from \"react\";\nimport type { Order, OrderStatus } from \"@cimplify/sdk\";\nimport { useOrders } from \"@cimplify/sdk/react\";\nimport { Price } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface OrderHistoryClassNames {\n root?: string;\n item?: string;\n orderId?: string;\n status?: string;\n date?: string;\n total?: string;\n empty?: string;\n loading?: string;\n}\n\nexport interface OrderHistoryProps {\n /** Override orders (skips fetch). For SSR, pass pre-fetched orders. */\n orders?: Order[];\n /** Filter by status. */\n status?: OrderStatus;\n /** Max orders to display. */\n limit?: number;\n /** Called when an order row is clicked. */\n onOrderClick?: (order: Order) => void;\n /** Custom order row renderer. */\n renderOrder?: (order: Order) => React.ReactNode;\n /** Text shown when empty. */\n emptyMessage?: string;\n className?: string;\n classNames?: OrderHistoryClassNames;\n}\n\nconst STATUS_LABELS: Record<OrderStatus, string> = {\n pending: \"Pending\",\n created: \"Created\",\n confirmed: \"Confirmed\",\n in_preparation: \"In Preparation\",\n ready_to_serve: \"Ready\",\n partially_served: \"Partially Served\",\n served: \"Served\",\n delivered: \"Delivered\",\n picked_up: \"Picked Up\",\n completed: \"Completed\",\n cancelled: \"Cancelled\",\n refunded: \"Refunded\",\n};\n\n/**\n * OrderHistory — list of past orders with status and totals.\n *\n * Fetches via `useOrders` unless pre-loaded orders are passed.\n */\nexport function OrderHistory({\n orders: ordersProp,\n status,\n limit,\n onOrderClick,\n renderOrder,\n emptyMessage = \"No orders yet\",\n className,\n classNames,\n}: OrderHistoryProps): React.ReactElement {\n const { orders: fetched, isLoading } = useOrders({\n status,\n limit,\n enabled: ordersProp === undefined,\n });\n\n const orders = ordersProp ?? fetched;\n\n if (isLoading && orders.length === 0) {\n return (\n <div\n data-cimplify-order-history\n aria-busy=\"true\"\n className={cn(className, classNames?.root, classNames?.loading)}\n />\n );\n }\n\n if (orders.length === 0) {\n return (\n <div\n data-cimplify-order-history\n data-empty\n className={cn(className, classNames?.root, classNames?.empty)}\n >\n <p>{emptyMessage}</p>\n </div>\n );\n }\n\n return (\n <div data-cimplify-order-history className={cn(className, classNames?.root)}>\n {orders.map((order) => (\n <button\n key={order.id}\n type=\"button\"\n onClick={() => onOrderClick?.(order)}\n data-cimplify-order-history-item\n data-status={order.status}\n className={classNames?.item}\n >\n {renderOrder ? (\n renderOrder(order)\n ) : (\n <>\n <div data-cimplify-order-history-main>\n <span data-cimplify-order-history-id className={classNames?.orderId}>\n #{order.user_friendly_id}\n </span>\n <span\n data-cimplify-order-history-status\n data-status={order.status}\n className={classNames?.status}\n >\n {STATUS_LABELS[order.status] ?? order.status}\n </span>\n </div>\n <div data-cimplify-order-history-details>\n <time\n data-cimplify-order-history-date\n dateTime={order.created_at}\n className={classNames?.date}\n >\n {new Date(order.created_at).toLocaleDateString()}\n </time>\n <span data-cimplify-order-history-items>\n {order.total_quantity} {order.total_quantity === 1 ? \"item\" : \"items\"}\n </span>\n <span data-cimplify-order-history-total className={classNames?.total}>\n <Price amount={order.total_price} />\n </span>\n </div>\n </>\n )}\n </button>\n ))}\n </div>\n );\n}\n"
|
|
13
|
+
"content": "\"use client\";\n\nimport React from \"react\";\nimport type { Order, OrderStatus } from \"@cimplify/sdk\";\nimport { useOrders } from \"@cimplify/sdk/react\";\nimport { Price } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface OrderHistoryClassNames {\n root?: string;\n item?: string;\n orderId?: string;\n status?: string;\n date?: string;\n total?: string;\n empty?: string;\n loading?: string;\n reorderButton?: string;\n}\n\nexport interface OrderHistoryProps {\n /** Override orders (skips fetch). For SSR, pass pre-fetched orders. */\n orders?: Order[];\n /** Filter by status. */\n status?: OrderStatus;\n /** Max orders to display. */\n limit?: number;\n /** Called when an order row is clicked. */\n onOrderClick?: (order: Order) => void;\n /** Custom order row renderer. */\n renderOrder?: (order: Order) => React.ReactNode;\n /** Called when the reorder button is clicked. If provided, a reorder button is rendered. */\n onReorder?: (order: Order) => void;\n /** Text shown when empty. */\n emptyMessage?: string;\n className?: string;\n classNames?: OrderHistoryClassNames;\n}\n\nconst STATUS_LABELS: Record<OrderStatus, string> = {\n pending: \"Pending\",\n created: \"Created\",\n confirmed: \"Confirmed\",\n in_preparation: \"In Preparation\",\n ready_to_serve: \"Ready\",\n partially_served: \"Partially Served\",\n served: \"Served\",\n delivered: \"Delivered\",\n picked_up: \"Picked Up\",\n completed: \"Completed\",\n cancelled: \"Cancelled\",\n refunded: \"Refunded\",\n};\n\n/**\n * OrderHistory — list of past orders with status and totals.\n *\n * Fetches via `useOrders` unless pre-loaded orders are passed.\n */\nexport function OrderHistory({\n orders: ordersProp,\n status,\n limit,\n onOrderClick,\n renderOrder,\n onReorder,\n emptyMessage = \"No orders yet\",\n className,\n classNames,\n}: OrderHistoryProps): React.ReactElement {\n const { orders: fetched, isLoading } = useOrders({\n status,\n limit,\n enabled: ordersProp === undefined,\n });\n\n const orders = ordersProp ?? fetched;\n\n if (isLoading && orders.length === 0) {\n return (\n <div\n data-cimplify-order-history\n aria-busy=\"true\"\n className={cn(className, classNames?.root, classNames?.loading)}\n />\n );\n }\n\n if (orders.length === 0) {\n return (\n <div\n data-cimplify-order-history\n data-empty\n className={cn(className, classNames?.root, classNames?.empty)}\n >\n <p>{emptyMessage}</p>\n </div>\n );\n }\n\n return (\n <div data-cimplify-order-history className={cn(className, classNames?.root)}>\n {orders.map((order) => (\n <button\n key={order.id}\n type=\"button\"\n onClick={() => onOrderClick?.(order)}\n data-cimplify-order-history-item\n data-status={order.status}\n className={classNames?.item}\n >\n {renderOrder ? (\n renderOrder(order)\n ) : (\n <>\n <div data-cimplify-order-history-main>\n <span data-cimplify-order-history-id className={classNames?.orderId}>\n #{order.user_friendly_id}\n </span>\n <span\n data-cimplify-order-history-status\n data-status={order.status}\n className={classNames?.status}\n >\n {STATUS_LABELS[order.status] ?? order.status}\n </span>\n </div>\n <div data-cimplify-order-history-details>\n <time\n data-cimplify-order-history-date\n dateTime={order.created_at}\n className={classNames?.date}\n >\n {new Date(order.created_at).toLocaleDateString()}\n </time>\n <span data-cimplify-order-history-items>\n {order.total_quantity} {order.total_quantity === 1 ? \"item\" : \"items\"}\n </span>\n <span data-cimplify-order-history-total className={classNames?.total}>\n <Price amount={order.total_price} />\n </span>\n </div>\n {onReorder && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onReorder(order);\n }}\n data-cimplify-order-reorder\n className={classNames?.reorderButton}\n >\n Reorder\n </button>\n )}\n </>\n )}\n </button>\n ))}\n </div>\n );\n}\n"
|
|
14
14
|
}
|
|
15
15
|
]
|
|
16
16
|
}
|