@reeboot/strapi-payment-plugin 0.0.6 → 0.0.7
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 +21 -0
- package/dist/_chunks/{Analytics-CQmAVKsq.mjs → Analytics-CncK5kn-.mjs} +6 -7
- package/dist/_chunks/{Analytics-CLjtRWYA.js → Analytics-c8KBuG3k.js} +6 -7
- package/dist/_chunks/{App-DXN62SV6.mjs → App-B5AB8Omu.mjs} +7 -7
- package/dist/_chunks/{App-Dk7XtjNA.js → App-Cih9sWu1.js} +7 -7
- package/dist/_chunks/{Customers-BQzVBQDT.mjs → Customers-BVk2gx7w.mjs} +51 -118
- package/dist/_chunks/{Customers-BNDi4QBH.js → Customers-CZWOnN26.js} +50 -117
- package/dist/_chunks/{Dashboard-UUwohHZa.js → Dashboard-CEif4jQn.js} +60 -84
- package/dist/_chunks/{Dashboard-CuHC-dit.mjs → Dashboard-DAjD8Q_6.mjs} +60 -84
- package/dist/_chunks/{Orders-CitNCdWE.js → Orders-DZXb54VO.js} +73 -146
- package/dist/_chunks/{Orders-65mNfu2i.mjs → Orders-DdJqI1HB.mjs} +74 -147
- package/dist/_chunks/{PaymentList-B0CAzInT.mjs → PaymentList-3HWK7PMz.mjs} +14 -39
- package/dist/_chunks/{PaymentList-Dy1BAFoD.js → PaymentList-APfyYD1h.js} +14 -39
- package/dist/_chunks/{Payments-FnhoV_2B.mjs → Payments-DFL-Cwgy.mjs} +97 -103
- package/dist/_chunks/{Payments-TOnygGIW.js → Payments-VzDGbK4W.js} +96 -102
- package/dist/_chunks/{Settings-BJtDagUs.js → Settings-B1tR3WOm.js} +157 -161
- package/dist/_chunks/{Settings-EoLSuZLe.mjs → Settings-SALxClBu.mjs} +157 -161
- package/dist/_chunks/{index-2Zd_T7bD.mjs → index-CB6TMitx.mjs} +1 -1
- package/dist/_chunks/{index-CHEgJ7e5.js → index-D-fFikb8.js} +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +7 -34
- package/dist/server/index.mjs +7 -34
- package/package.json +1 -1
- /package/dist/server/src/{types → services/types}/api.d.ts +0 -0
- /package/dist/server/src/{types → services/types}/customer.d.ts +0 -0
- /package/dist/server/src/{types → services/types}/index.d.ts +0 -0
- /package/dist/server/src/{types → services/types}/order.d.ts +0 -0
- /package/dist/server/src/{types → services/types}/payment.d.ts +0 -0
|
@@ -4,9 +4,9 @@ import { Box, Flex, Loader, EmptyStateLayout, Button, Typography, Grid, Card, Ba
|
|
|
4
4
|
import { Plus, PriceTag, ShoppingCart, ArrowClockwise, ChartPie } from "@strapi/icons";
|
|
5
5
|
import { useFetchClient } from "@strapi/strapi/admin";
|
|
6
6
|
import { useIntl } from "react-intl";
|
|
7
|
-
import { P as PLUGIN_ID } from "./index-2Zd_T7bD.mjs";
|
|
8
7
|
import { loadStripe } from "@stripe/stripe-js";
|
|
9
|
-
import { P as
|
|
8
|
+
import { P as PLUGIN_ID } from "./index-CB6TMitx.mjs";
|
|
9
|
+
import { P as PaymentList } from "./PaymentList-3HWK7PMz.mjs";
|
|
10
10
|
const Dashboard = () => {
|
|
11
11
|
const { formatMessage } = useIntl();
|
|
12
12
|
const { get, post } = useFetchClient();
|
|
@@ -15,25 +15,26 @@ const Dashboard = () => {
|
|
|
15
15
|
const [loading, setLoading] = useState(true);
|
|
16
16
|
const [error, setError] = useState(null);
|
|
17
17
|
const [creatingTest, setCreatingTest] = useState(false);
|
|
18
|
+
const [testMessage, setTestMessage] = useState(null);
|
|
18
19
|
useEffect(() => {
|
|
19
20
|
fetchDashboardData();
|
|
20
21
|
}, []);
|
|
21
22
|
const fetchDashboardData = async () => {
|
|
22
23
|
try {
|
|
23
24
|
setLoading(true);
|
|
25
|
+
setError(null);
|
|
24
26
|
const { data } = await get(`/${PLUGIN_ID}/admin/dashboard`);
|
|
25
27
|
if (data.success && data.data) {
|
|
28
|
+
const total = data.data.summary.totalPayments;
|
|
29
|
+
const succeeded = data.data.summary.successfulPayments;
|
|
30
|
+
const failed = data.data.summary.failedPayments;
|
|
26
31
|
setStats({
|
|
27
32
|
totalRevenue: data.data.summary.totalRevenue,
|
|
28
|
-
totalPayments:
|
|
29
|
-
successfulPayments:
|
|
30
|
-
pendingPayments:
|
|
31
|
-
failedPayments:
|
|
32
|
-
|
|
33
|
-
// Rough estimate
|
|
34
|
-
totalOrders: data.data.summary.totalPayments,
|
|
35
|
-
// Rough estimate
|
|
36
|
-
averageOrderValue: data.data.summary.totalPayments > 0 ? data.data.summary.totalRevenue / data.data.summary.totalPayments : 0
|
|
33
|
+
totalPayments: total,
|
|
34
|
+
successfulPayments: succeeded,
|
|
35
|
+
pendingPayments: Math.max(0, total - succeeded - failed),
|
|
36
|
+
failedPayments: failed,
|
|
37
|
+
averageOrderValue: total > 0 ? data.data.summary.totalRevenue / total : 0
|
|
37
38
|
});
|
|
38
39
|
const formattedPayments = data.data.recentTransactions.map((p) => ({
|
|
39
40
|
...p,
|
|
@@ -52,6 +53,7 @@ const Dashboard = () => {
|
|
|
52
53
|
const createTestPayment = async () => {
|
|
53
54
|
try {
|
|
54
55
|
setCreatingTest(true);
|
|
56
|
+
setTestMessage(null);
|
|
55
57
|
const { data } = await post(`/${PLUGIN_ID}/admin/create-sample-payment`);
|
|
56
58
|
if (!data.success) throw new Error(data.error?.message || "Failed to process payment");
|
|
57
59
|
const { publishableKey, clientSecret } = data.data;
|
|
@@ -62,22 +64,14 @@ const Dashboard = () => {
|
|
|
62
64
|
throw new Error("Client secret not returned from server");
|
|
63
65
|
}
|
|
64
66
|
const stripe = await loadStripe(publishableKey);
|
|
65
|
-
if (stripe === null)
|
|
66
|
-
throw new Error("Failed to load Stripe.js");
|
|
67
|
-
}
|
|
67
|
+
if (stripe === null) throw new Error("Failed to load Stripe.js");
|
|
68
68
|
const elements = stripe.elements({
|
|
69
69
|
clientSecret,
|
|
70
|
-
appearance: {
|
|
71
|
-
theme: "stripe"
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
const paymentElement = elements.create("payment", {
|
|
75
|
-
layout: "tabs"
|
|
70
|
+
appearance: { theme: "stripe" }
|
|
76
71
|
});
|
|
72
|
+
const paymentElement = elements.create("payment", { layout: "tabs" });
|
|
77
73
|
const existingModal = document.getElementById("stripe-payment-modal");
|
|
78
|
-
if (existingModal)
|
|
79
|
-
document.body.removeChild(existingModal);
|
|
80
|
-
}
|
|
74
|
+
if (existingModal) document.body.removeChild(existingModal);
|
|
81
75
|
const modal = document.createElement("div");
|
|
82
76
|
modal.id = "stripe-payment-modal";
|
|
83
77
|
Object.assign(modal.style, {
|
|
@@ -99,26 +93,19 @@ const Dashboard = () => {
|
|
|
99
93
|
borderRadius: "8px",
|
|
100
94
|
minWidth: "400px",
|
|
101
95
|
maxWidth: "500px",
|
|
102
|
-
boxShadow: "0 4px 6px rgba(0,
|
|
96
|
+
boxShadow: "0 4px 6px rgba(0,0,0,0.1)"
|
|
103
97
|
});
|
|
104
98
|
const title = document.createElement("h2");
|
|
105
99
|
title.textContent = "Test Payment - $25.00";
|
|
106
|
-
title.style.
|
|
107
|
-
title.style.fontSize = "1.25rem";
|
|
108
|
-
title.style.fontWeight = "600";
|
|
109
|
-
title.style.color = "#333";
|
|
100
|
+
title.style.cssText = "margin-bottom:1.5rem;font-size:1.25rem;font-weight:600;color:#333";
|
|
110
101
|
container.appendChild(title);
|
|
111
102
|
const form = document.createElement("form");
|
|
112
103
|
const paymentContainer = document.createElement("div");
|
|
113
|
-
|
|
114
|
-
paymentContainer.
|
|
115
|
-
paymentContainer.style.marginBottom = "1.5rem";
|
|
116
|
-
paymentContainer.style.minHeight = "200px";
|
|
104
|
+
paymentContainer.id = `payment-element-${Date.now()}`;
|
|
105
|
+
paymentContainer.style.cssText = "margin-bottom:1.5rem;min-height:200px";
|
|
117
106
|
form.appendChild(paymentContainer);
|
|
118
107
|
const buttonContainer = document.createElement("div");
|
|
119
|
-
buttonContainer.style.
|
|
120
|
-
buttonContainer.style.gap = "1rem";
|
|
121
|
-
buttonContainer.style.marginTop = "1rem";
|
|
108
|
+
buttonContainer.style.cssText = "display:flex;gap:1rem;margin-top:1rem";
|
|
122
109
|
const submitButton = document.createElement("button");
|
|
123
110
|
submitButton.type = "submit";
|
|
124
111
|
submitButton.textContent = "Loading...";
|
|
@@ -133,7 +120,6 @@ const Dashboard = () => {
|
|
|
133
120
|
cursor: "not-allowed",
|
|
134
121
|
fontSize: "16px",
|
|
135
122
|
fontWeight: "500",
|
|
136
|
-
transition: "background 0.2s",
|
|
137
123
|
opacity: "0.7"
|
|
138
124
|
});
|
|
139
125
|
const cancelButton = document.createElement("button");
|
|
@@ -147,8 +133,7 @@ const Dashboard = () => {
|
|
|
147
133
|
borderRadius: "4px",
|
|
148
134
|
cursor: "pointer",
|
|
149
135
|
fontSize: "16px",
|
|
150
|
-
fontWeight: "500"
|
|
151
|
-
transition: "background 0.2s"
|
|
136
|
+
fontWeight: "500"
|
|
152
137
|
});
|
|
153
138
|
cancelButton.onclick = () => {
|
|
154
139
|
document.body.removeChild(modal);
|
|
@@ -160,61 +145,46 @@ const Dashboard = () => {
|
|
|
160
145
|
container.appendChild(form);
|
|
161
146
|
modal.appendChild(container);
|
|
162
147
|
document.body.appendChild(modal);
|
|
163
|
-
|
|
164
|
-
console.log("Mounting payment element to container:", paymentContainer);
|
|
165
|
-
paymentElement.mount(paymentContainer);
|
|
166
|
-
} catch (e) {
|
|
167
|
-
console.error("Error mounting payment element:", e);
|
|
168
|
-
alert("Failed to mount Stripe payment form");
|
|
169
|
-
document.body.removeChild(modal);
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
148
|
+
paymentElement.mount(paymentContainer);
|
|
172
149
|
paymentElement.on("ready", () => {
|
|
173
|
-
console.log("Payment Element is ready");
|
|
174
150
|
submitButton.disabled = false;
|
|
175
151
|
submitButton.textContent = "Pay $25.00";
|
|
176
152
|
submitButton.style.cursor = "pointer";
|
|
177
153
|
submitButton.style.opacity = "1";
|
|
178
154
|
});
|
|
179
|
-
paymentElement.on("loaderror", (event) => {
|
|
180
|
-
console.error("Payment Element load error:", event);
|
|
181
|
-
const errorMessage = event?.error?.message || "Unknown error loading Stripe form";
|
|
182
|
-
alert(`Failed to load payment form: ${errorMessage}. Please check your keys and network.`);
|
|
183
|
-
document.body.removeChild(modal);
|
|
184
|
-
});
|
|
185
155
|
setCreatingTest(false);
|
|
186
156
|
form.onsubmit = async (e) => {
|
|
187
157
|
e.preventDefault();
|
|
188
158
|
submitButton.disabled = true;
|
|
189
159
|
submitButton.textContent = "Processing...";
|
|
190
160
|
try {
|
|
191
|
-
const result = await stripe.confirmPayment({
|
|
192
|
-
elements,
|
|
193
|
-
redirect: "if_required"
|
|
194
|
-
});
|
|
161
|
+
const result = await stripe.confirmPayment({ elements, redirect: "if_required" });
|
|
195
162
|
if (result.error) {
|
|
196
|
-
|
|
163
|
+
const errDiv = document.createElement("p");
|
|
164
|
+
errDiv.style.cssText = "color:#ef4444;margin-top:0.5rem;font-size:14px";
|
|
165
|
+
errDiv.textContent = `Payment failed: ${result.error.message}`;
|
|
166
|
+
form.appendChild(errDiv);
|
|
197
167
|
submitButton.disabled = false;
|
|
198
168
|
submitButton.textContent = "Pay $25.00";
|
|
199
|
-
} else if (result.paymentIntent
|
|
200
|
-
alert("Payment successful! ✓");
|
|
169
|
+
} else if (result.paymentIntent?.status === "succeeded") {
|
|
201
170
|
document.body.removeChild(modal);
|
|
171
|
+
setTestMessage({ type: "success", text: "Test payment successful!" });
|
|
172
|
+
setTimeout(() => setTestMessage(null), 4e3);
|
|
202
173
|
await fetchDashboardData();
|
|
203
174
|
} else {
|
|
204
|
-
alert("Payment is being processed...");
|
|
205
175
|
submitButton.disabled = false;
|
|
206
176
|
submitButton.textContent = "Pay $25.00";
|
|
207
177
|
}
|
|
208
178
|
} catch (err) {
|
|
209
|
-
console.error("Payment confirmation error:", err);
|
|
210
|
-
alert(`Error: ${err instanceof Error ? err.message : "Payment confirmation failed"}`);
|
|
211
179
|
submitButton.disabled = false;
|
|
212
180
|
submitButton.textContent = "Pay $25.00";
|
|
213
181
|
}
|
|
214
182
|
};
|
|
215
183
|
} catch (err) {
|
|
216
|
-
|
|
217
|
-
|
|
184
|
+
setTestMessage({
|
|
185
|
+
type: "error",
|
|
186
|
+
text: err instanceof Error ? err.message : "An error occurred during payment initialization"
|
|
187
|
+
});
|
|
218
188
|
setCreatingTest(false);
|
|
219
189
|
}
|
|
220
190
|
};
|
|
@@ -231,8 +201,7 @@ const Dashboard = () => {
|
|
|
231
201
|
return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
|
|
232
202
|
EmptyStateLayout,
|
|
233
203
|
{
|
|
234
|
-
|
|
235
|
-
subtitle: error,
|
|
204
|
+
content: error,
|
|
236
205
|
action: /* @__PURE__ */ jsx(Button, { onClick: fetchDashboardData, children: formatMessage({ id: "payment-plugin.dashboard.retry", defaultMessage: "Retry" }) })
|
|
237
206
|
}
|
|
238
207
|
) });
|
|
@@ -246,16 +215,26 @@ const Dashboard = () => {
|
|
|
246
215
|
defaultMessage: "Overview of your payment operations"
|
|
247
216
|
}) })
|
|
248
217
|
] }),
|
|
249
|
-
/* @__PURE__ */
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
218
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "flex-end", gap: 2, children: [
|
|
219
|
+
/* @__PURE__ */ jsx(
|
|
220
|
+
Button,
|
|
221
|
+
{
|
|
222
|
+
onClick: createTestPayment,
|
|
223
|
+
loading: creatingTest,
|
|
224
|
+
variant: "secondary",
|
|
225
|
+
startIcon: /* @__PURE__ */ jsx(Plus, {}),
|
|
226
|
+
children: formatMessage({ id: "payment-plugin.dashboard.initPayment", defaultMessage: "Initialize Sample Payment" })
|
|
227
|
+
}
|
|
228
|
+
),
|
|
229
|
+
testMessage && /* @__PURE__ */ jsx(
|
|
230
|
+
Typography,
|
|
231
|
+
{
|
|
232
|
+
variant: "pi",
|
|
233
|
+
textColor: testMessage.type === "success" ? "success600" : "danger600",
|
|
234
|
+
children: testMessage.text
|
|
235
|
+
}
|
|
236
|
+
)
|
|
237
|
+
] })
|
|
259
238
|
] }) }),
|
|
260
239
|
/* @__PURE__ */ jsxs(Grid.Root, { gap: 4, marginBottom: 8, children: [
|
|
261
240
|
/* @__PURE__ */ jsx(Grid.Item, { col: 3, s: 12, children: /* @__PURE__ */ jsx(Card, { padding: 4, shadow: "tableShadow", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", gap: 2, children: [
|
|
@@ -279,15 +258,12 @@ const Dashboard = () => {
|
|
|
279
258
|
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({ id: "payment-plugin.dashboard.successRate", defaultMessage: "Success Rate" }) }),
|
|
280
259
|
/* @__PURE__ */ jsx(Box, { padding: 2, background: "success100", borderRadius: "50%", children: /* @__PURE__ */ jsx(ArrowClockwise, { width: "1rem", height: "1rem" }) })
|
|
281
260
|
] }),
|
|
282
|
-
/* @__PURE__ */
|
|
283
|
-
stats ? Math.round(stats.successfulPayments / stats.totalPayments * 100) : 0,
|
|
284
|
-
"%"
|
|
285
|
-
] }),
|
|
261
|
+
/* @__PURE__ */ jsx(Typography, { variant: "alpha", fontWeight: "bold", children: stats && stats.totalPayments > 0 ? `${Math.round(stats.successfulPayments / stats.totalPayments * 100)}%` : "0%" }),
|
|
286
262
|
/* @__PURE__ */ jsx(Badge, { variant: "success", children: "Good" })
|
|
287
263
|
] }) }) }),
|
|
288
264
|
/* @__PURE__ */ jsx(Grid.Item, { col: 3, s: 12, children: /* @__PURE__ */ jsx(Card, { padding: 4, shadow: "tableShadow", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", gap: 2, children: [
|
|
289
265
|
/* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", width: "100%", children: [
|
|
290
|
-
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({ id: "payment-plugin.dashboard.averageOrderValue", defaultMessage: "
|
|
266
|
+
/* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({ id: "payment-plugin.dashboard.averageOrderValue", defaultMessage: "Avg. Order Value" }) }),
|
|
291
267
|
/* @__PURE__ */ jsx(Box, { padding: 2, background: "warning100", borderRadius: "50%", children: /* @__PURE__ */ jsx(ChartPie, { width: "1rem", height: "1rem" }) })
|
|
292
268
|
] }),
|
|
293
269
|
/* @__PURE__ */ jsx(Typography, { variant: "alpha", fontWeight: "bold", children: formatCurrency(stats?.averageOrderValue || 0) }),
|
|
@@ -300,7 +276,7 @@ const Dashboard = () => {
|
|
|
300
276
|
/* @__PURE__ */ jsx(Typography, { variant: "beta", tag: "h2", children: formatMessage({ id: "payment-plugin.dashboard.recentPayments", defaultMessage: "Recent Payments" }) }),
|
|
301
277
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Latest transactions from your customers" })
|
|
302
278
|
] }),
|
|
303
|
-
/* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "S", children: formatMessage({ id: "payment-plugin.dashboard.
|
|
279
|
+
/* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "S", onClick: fetchDashboardData, children: formatMessage({ id: "payment-plugin.dashboard.refresh", defaultMessage: "Refresh" }) })
|
|
304
280
|
] }),
|
|
305
281
|
/* @__PURE__ */ jsx(PaymentList, { payments: recentPayments, compact: true })
|
|
306
282
|
] }) })
|
|
@@ -5,10 +5,9 @@ const React = require("react");
|
|
|
5
5
|
const designSystem = require("@strapi/design-system");
|
|
6
6
|
const reactIntl = require("react-intl");
|
|
7
7
|
const admin = require("@strapi/strapi/admin");
|
|
8
|
-
const index = require("./index-
|
|
8
|
+
const index = require("./index-D-fFikb8.js");
|
|
9
9
|
const OrderList = ({ orders, onOrderClick, compact = false }) => {
|
|
10
10
|
const { formatMessage } = reactIntl.useIntl();
|
|
11
|
-
console.log("Orders:", orders);
|
|
12
11
|
const formatCurrency = (amount, currency = "usd") => {
|
|
13
12
|
return new Intl.NumberFormat("en-US", {
|
|
14
13
|
style: "currency",
|
|
@@ -16,29 +15,24 @@ const OrderList = ({ orders, onOrderClick, compact = false }) => {
|
|
|
16
15
|
}).format(amount);
|
|
17
16
|
};
|
|
18
17
|
const getStatusBadge = (status, type) => {
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
payment: {
|
|
29
|
-
unpaid: { color: "danger", label: "Unpaid" },
|
|
30
|
-
paid: { color: "success", label: "Paid" },
|
|
31
|
-
partially_paid: { color: "warning", label: "Partially Paid" },
|
|
32
|
-
refunded: { color: "neutral", label: "Refunded" }
|
|
33
|
-
}
|
|
18
|
+
const orderVariants = {
|
|
19
|
+
pending: { variant: "warning", label: "Pending" },
|
|
20
|
+
processing: { variant: "secondary", label: "Processing" },
|
|
21
|
+
shipped: { variant: "secondary", label: "Shipped" },
|
|
22
|
+
delivered: { variant: "success", label: "Delivered" },
|
|
23
|
+
completed: { variant: "success", label: "Completed" },
|
|
24
|
+
cancelled: { variant: "danger", label: "Cancelled" },
|
|
25
|
+
failed: { variant: "danger", label: "Failed" },
|
|
26
|
+
refunded: { variant: "neutral", label: "Refunded" }
|
|
34
27
|
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
28
|
+
const paymentVariants = {
|
|
29
|
+
unpaid: { variant: "danger", label: "Unpaid" },
|
|
30
|
+
paid: { variant: "success", label: "Paid" },
|
|
31
|
+
partially_paid: { variant: "warning", label: "Partially Paid" },
|
|
32
|
+
refunded: { variant: "neutral", label: "Refunded" }
|
|
33
|
+
};
|
|
34
|
+
const config = type === "order" ? orderVariants[status] || orderVariants.pending : paymentVariants[status] || paymentVariants.unpaid;
|
|
35
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { size: compact ? "S" : "M", variant: config.variant, children: config.label });
|
|
42
36
|
};
|
|
43
37
|
const handleOrderClick = (order) => {
|
|
44
38
|
if (onOrderClick) {
|
|
@@ -63,49 +57,17 @@ const OrderList = ({ orders, onOrderClick, compact = false }) => {
|
|
|
63
57
|
onClick: () => handleOrderClick(order),
|
|
64
58
|
style: { cursor: onOrderClick ? "pointer" : "default" },
|
|
65
59
|
children: [
|
|
66
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
67
|
-
designSystem.Typography,
|
|
68
|
-
{
|
|
69
|
-
textColor: "neutral800",
|
|
70
|
-
fontWeight: "bold",
|
|
71
|
-
fontFamily: "monospace",
|
|
72
|
-
fontSize: compact ? "0.875rem" : "1rem",
|
|
73
|
-
children: order.order_number
|
|
74
|
-
}
|
|
75
|
-
) }),
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", fontWeight: "bold", fontFamily: "monospace", children: order.order_number }) }),
|
|
76
61
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, children: [
|
|
77
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
78
|
-
|
|
79
|
-
{
|
|
80
|
-
textColor: "neutral800",
|
|
81
|
-
fontWeight: compact ? "normal" : "bold",
|
|
82
|
-
fontSize: compact ? "0.875rem" : "1rem",
|
|
83
|
-
children: order.customerName || "Unknown"
|
|
84
|
-
}
|
|
85
|
-
),
|
|
86
|
-
compact && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "epsilon", fontSize: "0.75rem", children: order.customerEmail })
|
|
62
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", fontWeight: compact ? "normal" : "bold", children: order.customerName || "Unknown" }),
|
|
63
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "epsilon", children: order.customerEmail })
|
|
87
64
|
] }) }),
|
|
88
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
order.items ? order.items.length : 0,
|
|
95
|
-
" ",
|
|
96
|
-
order.items && order.items.length === 1 ? "item" : "items"
|
|
97
|
-
]
|
|
98
|
-
}
|
|
99
|
-
) }),
|
|
100
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
101
|
-
designSystem.Typography,
|
|
102
|
-
{
|
|
103
|
-
textColor: "neutral800",
|
|
104
|
-
fontWeight: "bold",
|
|
105
|
-
fontSize: compact ? "0.875rem" : "1rem",
|
|
106
|
-
children: formatCurrency(order.total_amount, order.currency)
|
|
107
|
-
}
|
|
108
|
-
) }),
|
|
65
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { textColor: "neutral600", children: [
|
|
66
|
+
order.items ? order.items.length : 0,
|
|
67
|
+
" ",
|
|
68
|
+
order.items && order.items.length === 1 ? "item" : "items"
|
|
69
|
+
] }) }),
|
|
70
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", fontWeight: "bold", children: formatCurrency(order.total_amount, order.currency) }) }),
|
|
109
71
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: getStatusBadge(order.order_status, "order") }),
|
|
110
72
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: getStatusBadge(order.paymentStatus, "payment") })
|
|
111
73
|
]
|
|
@@ -118,32 +80,29 @@ const Orders = () => {
|
|
|
118
80
|
const { formatMessage } = reactIntl.useIntl();
|
|
119
81
|
const { get } = admin.useFetchClient();
|
|
120
82
|
const [orders, setOrders] = React.useState([]);
|
|
121
|
-
const [filteredOrders, setFilteredOrders] = React.useState([]);
|
|
122
83
|
const [loading, setLoading] = React.useState(true);
|
|
123
84
|
const [error, setError] = React.useState(null);
|
|
124
85
|
const [currentPage, setCurrentPage] = React.useState(1);
|
|
125
|
-
const
|
|
86
|
+
const pageSize = 25;
|
|
126
87
|
const [totalCount, setTotalCount] = React.useState(0);
|
|
127
88
|
const [filters, setFilters] = React.useState({
|
|
128
89
|
order_status: "",
|
|
129
90
|
paymentStatus: "",
|
|
130
|
-
dateRange: { from: null, to: null },
|
|
131
91
|
search: "",
|
|
132
92
|
currency: ""
|
|
133
93
|
});
|
|
134
94
|
React.useEffect(() => {
|
|
135
95
|
fetchOrders();
|
|
136
|
-
}, [currentPage,
|
|
137
|
-
React.useEffect(() => {
|
|
138
|
-
applyFilters();
|
|
139
|
-
}, [orders, filters]);
|
|
96
|
+
}, [currentPage, filters]);
|
|
140
97
|
const fetchOrders = async () => {
|
|
141
98
|
try {
|
|
142
99
|
setLoading(true);
|
|
143
100
|
const queryParams = new URLSearchParams({
|
|
144
101
|
page: currentPage.toString(),
|
|
145
102
|
pageSize: pageSize.toString(),
|
|
146
|
-
...filters.order_status && { order_status: filters.order_status }
|
|
103
|
+
...filters.order_status && { order_status: filters.order_status },
|
|
104
|
+
...filters.search && { search: filters.search },
|
|
105
|
+
...filters.currency && { currency: filters.currency }
|
|
147
106
|
});
|
|
148
107
|
const { data } = await get(`/${index.PLUGIN_ID}/admin/orders?${queryParams}`);
|
|
149
108
|
if (data.success && data.data) {
|
|
@@ -156,7 +115,7 @@ const Orders = () => {
|
|
|
156
115
|
items: Array.isArray(o.items) ? o.items : []
|
|
157
116
|
}));
|
|
158
117
|
setOrders(formattedOrders);
|
|
159
|
-
setTotalCount(data.meta
|
|
118
|
+
setTotalCount(data.meta?.pagination?.total || 0);
|
|
160
119
|
}
|
|
161
120
|
setLoading(false);
|
|
162
121
|
} catch (err) {
|
|
@@ -164,38 +123,7 @@ const Orders = () => {
|
|
|
164
123
|
setLoading(false);
|
|
165
124
|
}
|
|
166
125
|
};
|
|
167
|
-
const
|
|
168
|
-
let filtered = [...orders];
|
|
169
|
-
if (filters.search) {
|
|
170
|
-
const searchLower = filters.search.toLowerCase();
|
|
171
|
-
filtered = filtered.filter(
|
|
172
|
-
(order) => order.order_number && order.order_number.toLowerCase().includes(searchLower) || order.customerEmail && order.customerEmail.toLowerCase().includes(searchLower) || order.customerName && order.customerName.toLowerCase().includes(searchLower)
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
if (filters.order_status) {
|
|
176
|
-
filtered = filtered.filter((order) => order.order_status === filters.order_status);
|
|
177
|
-
}
|
|
178
|
-
if (filters.paymentStatus) {
|
|
179
|
-
filtered = filtered.filter((order) => order.paymentStatus === filters.paymentStatus);
|
|
180
|
-
}
|
|
181
|
-
if (filters.currency) {
|
|
182
|
-
filtered = filtered.filter((order) => order.currency === filters.currency);
|
|
183
|
-
}
|
|
184
|
-
if (filters.dateRange.from) {
|
|
185
|
-
filtered = filtered.filter(
|
|
186
|
-
(order) => new Date(order.createdAt) >= filters.dateRange.from
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
if (filters.dateRange.to) {
|
|
190
|
-
filtered = filtered.filter(
|
|
191
|
-
(order) => new Date(order.createdAt) <= filters.dateRange.to
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
setFilteredOrders(filtered);
|
|
195
|
-
};
|
|
196
|
-
const handleOrderClick = (order) => {
|
|
197
|
-
console.log("Clicked order:", order);
|
|
198
|
-
};
|
|
126
|
+
const totalPages = Math.max(1, Math.ceil(totalCount / pageSize));
|
|
199
127
|
const formatDate = (dateString) => {
|
|
200
128
|
return new Date(dateString).toLocaleDateString("en-US", {
|
|
201
129
|
year: "numeric",
|
|
@@ -210,19 +138,13 @@ const Orders = () => {
|
|
|
210
138
|
setCurrentPage(1);
|
|
211
139
|
};
|
|
212
140
|
const clearFilters = () => {
|
|
213
|
-
setFilters({
|
|
214
|
-
order_status: "",
|
|
215
|
-
paymentStatus: "",
|
|
216
|
-
dateRange: { from: null, to: null },
|
|
217
|
-
search: "",
|
|
218
|
-
currency: ""
|
|
219
|
-
});
|
|
141
|
+
setFilters({ order_status: "", paymentStatus: "", search: "", currency: "" });
|
|
220
142
|
setCurrentPage(1);
|
|
221
143
|
};
|
|
222
144
|
const exportOrders = () => {
|
|
223
145
|
const csvContent = [
|
|
224
146
|
["Order Number", "Customer Email", "Customer Name", "Status", "Payment Status", "Total Amount", "Currency", "Date"],
|
|
225
|
-
...
|
|
147
|
+
...orders.map((order) => [
|
|
226
148
|
order.order_number || "",
|
|
227
149
|
order.customerEmail || "",
|
|
228
150
|
order.customerName || "",
|
|
@@ -241,10 +163,6 @@ const Orders = () => {
|
|
|
241
163
|
a.click();
|
|
242
164
|
window.URL.revokeObjectURL(url);
|
|
243
165
|
};
|
|
244
|
-
const startIndex = (currentPage - 1) * pageSize;
|
|
245
|
-
const endIndex = startIndex + pageSize;
|
|
246
|
-
const paginatedOrders = filteredOrders.slice(startIndex, endIndex);
|
|
247
|
-
const totalPages = Math.ceil(filteredOrders.length / pageSize);
|
|
248
166
|
if (loading && orders.length === 0) {
|
|
249
167
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", alignItems: "center", style: { minHeight: "400px" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, {}) }) });
|
|
250
168
|
}
|
|
@@ -252,8 +170,7 @@ const Orders = () => {
|
|
|
252
170
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
253
171
|
designSystem.EmptyStateLayout,
|
|
254
172
|
{
|
|
255
|
-
|
|
256
|
-
subtitle: error,
|
|
173
|
+
content: error,
|
|
257
174
|
action: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: fetchOrders, children: formatMessage({ id: "payment-plugin.orders.retry", defaultMessage: "Retry" }) })
|
|
258
175
|
}
|
|
259
176
|
) });
|
|
@@ -269,13 +186,14 @@ const Orders = () => {
|
|
|
269
186
|
] }),
|
|
270
187
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
|
|
271
188
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "secondary", onClick: exportOrders, children: formatMessage({ id: "payment-plugin.orders.export", defaultMessage: "Export" }) }),
|
|
272
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: fetchOrders })
|
|
189
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: fetchOrders, children: formatMessage({ id: "payment-plugin.orders.refresh", defaultMessage: "Refresh" }) })
|
|
273
190
|
] })
|
|
274
191
|
] }) }),
|
|
275
192
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, children: [
|
|
276
193
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 3, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
277
194
|
designSystem.TextInput,
|
|
278
195
|
{
|
|
196
|
+
label: formatMessage({ id: "payment-plugin.orders.search.label", defaultMessage: "Search" }),
|
|
279
197
|
placeholder: formatMessage({
|
|
280
198
|
id: "payment-plugin.orders.search.placeholder",
|
|
281
199
|
defaultMessage: "Search orders..."
|
|
@@ -287,6 +205,7 @@ const Orders = () => {
|
|
|
287
205
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
288
206
|
designSystem.SingleSelect,
|
|
289
207
|
{
|
|
208
|
+
label: formatMessage({ id: "payment-plugin.orders.status.label", defaultMessage: "Order Status" }),
|
|
290
209
|
placeholder: formatMessage({
|
|
291
210
|
id: "payment-plugin.orders.status.placeholder",
|
|
292
211
|
defaultMessage: "All Statuses"
|
|
@@ -297,8 +216,7 @@ const Orders = () => {
|
|
|
297
216
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "", children: formatMessage({ id: "payment-plugin.orders.all", defaultMessage: "All" }) }),
|
|
298
217
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "pending", children: formatMessage({ id: "payment-plugin.orders.pending", defaultMessage: "Pending" }) }),
|
|
299
218
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "processing", children: formatMessage({ id: "payment-plugin.orders.processing", defaultMessage: "Processing" }) }),
|
|
300
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "
|
|
301
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "delivered", children: formatMessage({ id: "payment-plugin.orders.delivered", defaultMessage: "Delivered" }) }),
|
|
219
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "completed", children: formatMessage({ id: "payment-plugin.orders.completed", defaultMessage: "Completed" }) }),
|
|
302
220
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "cancelled", children: formatMessage({ id: "payment-plugin.orders.cancelled", defaultMessage: "Cancelled" }) })
|
|
303
221
|
]
|
|
304
222
|
}
|
|
@@ -306,9 +224,10 @@ const Orders = () => {
|
|
|
306
224
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
307
225
|
designSystem.SingleSelect,
|
|
308
226
|
{
|
|
227
|
+
label: formatMessage({ id: "payment-plugin.orders.paymentStatus.label", defaultMessage: "Payment Status" }),
|
|
309
228
|
placeholder: formatMessage({
|
|
310
229
|
id: "payment-plugin.orders.paymentStatus.placeholder",
|
|
311
|
-
defaultMessage: "All
|
|
230
|
+
defaultMessage: "All"
|
|
312
231
|
}),
|
|
313
232
|
value: filters.paymentStatus,
|
|
314
233
|
onChange: (value) => handleFilterChange("paymentStatus", value),
|
|
@@ -324,6 +243,7 @@ const Orders = () => {
|
|
|
324
243
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
325
244
|
designSystem.SingleSelect,
|
|
326
245
|
{
|
|
246
|
+
label: formatMessage({ id: "payment-plugin.orders.currency.label", defaultMessage: "Currency" }),
|
|
327
247
|
placeholder: formatMessage({
|
|
328
248
|
id: "payment-plugin.orders.currency.placeholder",
|
|
329
249
|
defaultMessage: "All Currencies"
|
|
@@ -338,31 +258,38 @@ const Orders = () => {
|
|
|
338
258
|
]
|
|
339
259
|
}
|
|
340
260
|
) }),
|
|
341
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", onClick: clearFilters, children: formatMessage({ id: "payment-plugin.orders.clearFilters", defaultMessage: "Clear" }) }) }) })
|
|
261
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, alignItems: "flex-end", height: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", onClick: clearFilters, children: formatMessage({ id: "payment-plugin.orders.clearFilters", defaultMessage: "Clear" }) }) }) })
|
|
342
262
|
] }) }) }),
|
|
343
263
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 4, marginBottom: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral600", children: formatMessage(
|
|
344
|
-
{ id: "payment-plugin.orders.results", defaultMessage: "
|
|
345
|
-
{
|
|
346
|
-
start: startIndex + 1,
|
|
347
|
-
end: Math.min(endIndex, filteredOrders.length),
|
|
348
|
-
total: filteredOrders.length
|
|
349
|
-
}
|
|
264
|
+
{ id: "payment-plugin.orders.results", defaultMessage: "{total} orders" },
|
|
265
|
+
{ total: totalCount }
|
|
350
266
|
) }) }),
|
|
351
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
{
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
267
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(OrderList, { orders }) }),
|
|
268
|
+
totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Pagination, { activePage: currentPage, pageCount: totalPages, label: "Orders pagination", children: [
|
|
269
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
270
|
+
designSystem.PreviousLink,
|
|
271
|
+
{
|
|
272
|
+
as: "button",
|
|
273
|
+
onClick: () => setCurrentPage((p) => Math.max(1, p - 1))
|
|
274
|
+
}
|
|
275
|
+
),
|
|
276
|
+
Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
277
|
+
designSystem.PageLink,
|
|
278
|
+
{
|
|
279
|
+
number: page,
|
|
280
|
+
as: "button",
|
|
281
|
+
onClick: () => setCurrentPage(page)
|
|
282
|
+
},
|
|
283
|
+
page
|
|
284
|
+
)),
|
|
285
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
286
|
+
designSystem.NextLink,
|
|
287
|
+
{
|
|
288
|
+
as: "button",
|
|
289
|
+
onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1))
|
|
290
|
+
}
|
|
291
|
+
)
|
|
292
|
+
] }) }) })
|
|
366
293
|
] });
|
|
367
294
|
};
|
|
368
295
|
exports.Orders = Orders;
|