@reeboot/strapi-payment-plugin 0.0.1 → 0.0.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.
Files changed (84) hide show
  1. package/README.md +378 -119
  2. package/dist/_chunks/Analytics-C2GKvPDX.js +355 -0
  3. package/dist/_chunks/Analytics-Chydh3dg.mjs +355 -0
  4. package/dist/_chunks/App-BCbEuN6h.mjs +68 -0
  5. package/dist/_chunks/App-E2k2mo5p.js +70 -0
  6. package/dist/_chunks/Customers-B8BlQ1BO.mjs +273 -0
  7. package/dist/_chunks/Customers-D0O5ET5C.js +273 -0
  8. package/dist/_chunks/Dashboard-CuqclLak.js +180 -0
  9. package/dist/_chunks/Dashboard-D8-ifJqB.mjs +180 -0
  10. package/dist/_chunks/Orders-5WGSzPGo.js +308 -0
  11. package/dist/_chunks/Orders-ClJJaQrX.mjs +308 -0
  12. package/dist/_chunks/Payments-CIMyOC3n.js +489 -0
  13. package/dist/_chunks/Payments-CRnRBf48.mjs +489 -0
  14. package/dist/_chunks/Settings-BXMLePI_.js +357 -0
  15. package/dist/_chunks/Settings-TeAvV4RH.mjs +357 -0
  16. package/dist/_chunks/en-BJocyOVu.mjs +240 -0
  17. package/dist/_chunks/en-BkVAf_R4.js +240 -0
  18. package/dist/_chunks/index-BTk7a2T5.js +66 -0
  19. package/dist/_chunks/index-Bz8V_5zH.mjs +67 -0
  20. package/dist/admin/index.js +2 -63
  21. package/dist/admin/index.mjs +2 -63
  22. package/dist/admin/src/components/AnalyticsChart.d.ts +19 -0
  23. package/dist/admin/src/components/CustomerList.d.ts +21 -0
  24. package/dist/admin/src/components/OrderList.d.ts +27 -0
  25. package/dist/admin/src/components/PaymentCard.d.ts +39 -0
  26. package/dist/admin/src/components/PaymentList.d.ts +19 -0
  27. package/dist/admin/src/components/RefundModal.d.ts +15 -0
  28. package/dist/admin/src/pages/Analytics.d.ts +2 -0
  29. package/dist/admin/src/pages/Customers.d.ts +2 -0
  30. package/dist/admin/src/pages/Dashboard.d.ts +2 -0
  31. package/dist/admin/src/pages/HomePage.d.ts +1 -1
  32. package/dist/admin/src/pages/Orders.d.ts +2 -0
  33. package/dist/admin/src/pages/Payments.d.ts +2 -0
  34. package/dist/admin/src/pages/Settings.d.ts +2 -0
  35. package/dist/admin/src/pluginId.d.ts +1 -1
  36. package/dist/server/index.js +1746 -984
  37. package/dist/server/index.mjs +1748 -986
  38. package/dist/server/src/bootstrap.d.ts +5 -11
  39. package/dist/server/src/config/index.d.ts +0 -10
  40. package/dist/server/src/content-types/customer/index.d.ts +69 -0
  41. package/dist/server/src/content-types/index.d.ts +123 -39
  42. package/dist/server/src/content-types/{product.d.ts → order/index.d.ts} +26 -19
  43. package/dist/server/src/content-types/{subscription.d.ts → payment/index.d.ts} +30 -21
  44. package/dist/server/src/controllers/controller.d.ts +5 -12
  45. package/dist/server/src/controllers/index.d.ts +29 -34
  46. package/dist/server/src/controllers/stripe.d.ts +104 -0
  47. package/dist/server/src/index.d.ts +179 -139
  48. package/dist/server/src/middlewares/index.d.ts +19 -1
  49. package/dist/server/src/policies/index.d.ts +3 -1
  50. package/dist/server/src/routes/{admin-routes.d.ts → admin/index.d.ts} +4 -4
  51. package/dist/server/src/routes/content-api/index.d.ts +21 -0
  52. package/dist/server/src/routes/index.d.ts +11 -16
  53. package/dist/server/src/services/index.d.ts +2 -38
  54. package/dist/server/src/services/{stripeDriver.d.ts → stripe.d.ts} +52 -59
  55. package/dist/server/src/types/index.d.ts +179 -0
  56. package/package.json +20 -25
  57. package/dist/_chunks/App-DD7GyuRr.mjs +0 -1424
  58. package/dist/_chunks/App-KZVBFRwo.js +0 -1424
  59. package/dist/_chunks/en-B4KWt_jN.js +0 -4
  60. package/dist/_chunks/en-Byx4XI2L.mjs +0 -4
  61. package/dist/admin/src/components/Header.d.ts +0 -2
  62. package/dist/admin/src/components/NavigationMenu.d.ts +0 -2
  63. package/dist/admin/src/components/Sidebar.d.ts +0 -2
  64. package/dist/admin/src/components/TransactionDetailsModal.d.ts +0 -18
  65. package/dist/admin/src/components/TransactionList.d.ts +0 -18
  66. package/dist/admin/src/pages/ConfigurationPage.d.ts +0 -2
  67. package/dist/admin/src/pages/DashboardPage.d.ts +0 -2
  68. package/dist/admin/src/pages/ProductsPage.d.ts +0 -2
  69. package/dist/admin/src/pages/SubscriptionsPage.d.ts +0 -2
  70. package/dist/admin/src/pages/TransactionsPage.d.ts +0 -2
  71. package/dist/server/src/controllers/product.d.ts +0 -18
  72. package/dist/server/src/controllers/subscription.d.ts +0 -16
  73. package/dist/server/src/controllers/webhook.d.ts +0 -10
  74. package/dist/server/src/routes/content-api.d.ts +0 -12
  75. package/dist/server/src/routes/product.d.ts +0 -2
  76. package/dist/server/src/routes/refund-routes.d.ts +0 -13
  77. package/dist/server/src/routes/subscription.d.ts +0 -5
  78. package/dist/server/src/routes/webhook.d.ts +0 -15
  79. package/dist/server/src/services/paypalDriver.d.ts +0 -47
  80. package/dist/server/src/services/product.d.ts +0 -7
  81. package/dist/server/src/services/service.d.ts +0 -26
  82. package/dist/server/src/services/subscription.d.ts +0 -9
  83. package/dist/server/src/services/sync.d.ts +0 -13
  84. package/jest.config.js +0 -13
@@ -0,0 +1,308 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const designSystem = require("@strapi/design-system");
6
+ const reactIntl = require("react-intl");
7
+ const admin = require("@strapi/strapi/admin");
8
+ const index = require("./index-BTk7a2T5.js");
9
+ const Orders = () => {
10
+ const { formatMessage } = reactIntl.useIntl();
11
+ const { get } = admin.useFetchClient();
12
+ const [orders, setOrders] = React.useState([]);
13
+ const [filteredOrders, setFilteredOrders] = React.useState([]);
14
+ const [loading, setLoading] = React.useState(true);
15
+ const [error, setError] = React.useState(null);
16
+ const [currentPage, setCurrentPage] = React.useState(1);
17
+ const [pageSize, setPageSize] = React.useState(25);
18
+ const [totalCount, setTotalCount] = React.useState(0);
19
+ const [filters, setFilters] = React.useState({
20
+ status: "",
21
+ paymentStatus: "",
22
+ dateRange: { from: null, to: null },
23
+ search: "",
24
+ currency: ""
25
+ });
26
+ React.useEffect(() => {
27
+ fetchOrders();
28
+ }, [currentPage, pageSize, filters]);
29
+ React.useEffect(() => {
30
+ applyFilters();
31
+ }, [orders, filters]);
32
+ const fetchOrders = async () => {
33
+ try {
34
+ setLoading(true);
35
+ const queryParams = new URLSearchParams({
36
+ page: currentPage.toString(),
37
+ pageSize: pageSize.toString(),
38
+ ...filters.status && { status: filters.status }
39
+ });
40
+ const { data } = await get(`/${index.PLUGIN_ID}/admin/orders?${queryParams}`);
41
+ if (data.success && data.data) {
42
+ const formattedOrders = data.data.map((o) => ({
43
+ id: o.documentId,
44
+ orderNumber: o.order_number,
45
+ customerEmail: o.customer?.email || "N/A",
46
+ customerName: o.customer ? `${o.customer.firstName || ""} ${o.customer.lastName || ""}`.trim() : "N/A",
47
+ status: o.status,
48
+ totalAmount: o.total_amount,
49
+ currency: o.currency,
50
+ paymentStatus: o.status === "completed" ? "paid" : "unpaid",
51
+ items: Array.isArray(o.items) ? o.items : [],
52
+ createdAt: o.createdAt,
53
+ updatedAt: o.updatedAt
54
+ }));
55
+ setOrders(formattedOrders);
56
+ setTotalCount(data.meta.pagination.total);
57
+ }
58
+ setLoading(false);
59
+ } catch (err) {
60
+ setError("Failed to fetch orders");
61
+ setLoading(false);
62
+ }
63
+ };
64
+ const applyFilters = () => {
65
+ let filtered = [...orders];
66
+ if (filters.search) {
67
+ const searchLower = filters.search.toLowerCase();
68
+ filtered = filtered.filter(
69
+ (order) => order.orderNumber.toLowerCase().includes(searchLower) || order.customerEmail.toLowerCase().includes(searchLower) || order.customerName?.toLowerCase().includes(searchLower)
70
+ );
71
+ }
72
+ if (filters.status) {
73
+ filtered = filtered.filter((order) => order.status === filters.status);
74
+ }
75
+ if (filters.paymentStatus) {
76
+ filtered = filtered.filter((order) => order.paymentStatus === filters.paymentStatus);
77
+ }
78
+ if (filters.currency) {
79
+ filtered = filtered.filter((order) => order.currency === filters.currency);
80
+ }
81
+ if (filters.dateRange.from) {
82
+ filtered = filtered.filter(
83
+ (order) => new Date(order.createdAt) >= filters.dateRange.from
84
+ );
85
+ }
86
+ if (filters.dateRange.to) {
87
+ filtered = filtered.filter(
88
+ (order) => new Date(order.createdAt) <= filters.dateRange.to
89
+ );
90
+ }
91
+ setFilteredOrders(filtered);
92
+ };
93
+ const formatCurrency = (amount, currency = "usd") => {
94
+ return new Intl.NumberFormat("en-US", {
95
+ style: "currency",
96
+ currency: currency.toUpperCase()
97
+ }).format(amount);
98
+ };
99
+ const formatDate = (dateString) => {
100
+ return new Date(dateString).toLocaleDateString("en-US", {
101
+ year: "numeric",
102
+ month: "short",
103
+ day: "numeric",
104
+ hour: "2-digit",
105
+ minute: "2-digit"
106
+ });
107
+ };
108
+ const getStatusBadge = (status, type) => {
109
+ const configs = {
110
+ order: {
111
+ pending: { color: "warning", label: "Pending" },
112
+ processing: { color: "info", label: "Processing" },
113
+ shipped: { color: "secondary", label: "Shipped" },
114
+ delivered: { color: "success", label: "Delivered" },
115
+ cancelled: { color: "danger", label: "Cancelled" },
116
+ refunded: { color: "neutral", label: "Refunded" }
117
+ },
118
+ payment: {
119
+ unpaid: { color: "danger", label: "Unpaid" },
120
+ paid: { color: "success", label: "Paid" },
121
+ partially_paid: { color: "warning", label: "Partially Paid" },
122
+ refunded: { color: "neutral", label: "Refunded" }
123
+ }
124
+ };
125
+ const config = type === "order" ? configs.order[status] || configs.order.pending : configs.payment[status] || configs.payment.unpaid;
126
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { size: "S", backgroundColor: config.color, children: config.label });
127
+ };
128
+ const handleFilterChange = (key, value) => {
129
+ setFilters((prev) => ({ ...prev, [key]: value }));
130
+ setCurrentPage(1);
131
+ };
132
+ const clearFilters = () => {
133
+ setFilters({
134
+ status: "",
135
+ paymentStatus: "",
136
+ dateRange: { from: null, to: null },
137
+ search: "",
138
+ currency: ""
139
+ });
140
+ setCurrentPage(1);
141
+ };
142
+ const exportOrders = () => {
143
+ const csvContent = [
144
+ ["Order Number", "Customer Email", "Customer Name", "Status", "Payment Status", "Total Amount", "Currency", "Date"],
145
+ ...filteredOrders.map((order) => [
146
+ order.orderNumber,
147
+ order.customerEmail,
148
+ order.customerName || "",
149
+ order.status,
150
+ order.paymentStatus,
151
+ (order.totalAmount / 100).toString(),
152
+ order.currency,
153
+ formatDate(order.createdAt)
154
+ ])
155
+ ].map((row) => row.join(",")).join("\n");
156
+ const blob = new Blob([csvContent], { type: "text/csv" });
157
+ const url = window.URL.createObjectURL(blob);
158
+ const a = document.createElement("a");
159
+ a.href = url;
160
+ a.download = `orders-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.csv`;
161
+ a.click();
162
+ window.URL.revokeObjectURL(url);
163
+ };
164
+ const startIndex = (currentPage - 1) * pageSize;
165
+ const endIndex = startIndex + pageSize;
166
+ const paginatedOrders = filteredOrders.slice(startIndex, endIndex);
167
+ const totalPages = Math.ceil(filteredOrders.length / pageSize);
168
+ if (loading && orders.length === 0) {
169
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingLeft: 10, paddingRight: 10, paddingTop: 4, paddingBottom: 10, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", alignItems: "center", style: { minHeight: "400px" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, {}) }) });
170
+ }
171
+ if (error) {
172
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingLeft: 10, paddingRight: 10, paddingTop: 4, paddingBottom: 10, children: /* @__PURE__ */ jsxRuntime.jsx(
173
+ designSystem.EmptyStateLayout,
174
+ {
175
+ title: "Error loading orders",
176
+ subtitle: error,
177
+ action: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: fetchOrders, children: formatMessage({ id: "payment-plugin.orders.retry", defaultMessage: "Retry" }) })
178
+ }
179
+ ) });
180
+ }
181
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingLeft: 10, paddingRight: 10, paddingTop: 4, paddingBottom: 10, children: [
182
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", children: [
183
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
184
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", tag: "h1", children: formatMessage({ id: "payment-plugin.orders.title", defaultMessage: "Orders" }) }),
185
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral600", children: formatMessage({
186
+ id: "payment-plugin.orders.subtitle",
187
+ defaultMessage: "Manage and track all customer orders"
188
+ }) })
189
+ ] }),
190
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
191
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "secondary", onClick: exportOrders, children: formatMessage({ id: "payment-plugin.orders.export", defaultMessage: "Export" }) }),
192
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: () => window.location.reload(), children: formatMessage({ id: "payment-plugin.orders.refresh", defaultMessage: "Refresh" }) })
193
+ ] })
194
+ ] }) }),
195
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, children: [
196
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 3, children: /* @__PURE__ */ jsxRuntime.jsx(
197
+ designSystem.TextInput,
198
+ {
199
+ placeholder: formatMessage({
200
+ id: "payment-plugin.orders.search.placeholder",
201
+ defaultMessage: "Search orders..."
202
+ }),
203
+ value: filters.search,
204
+ onChange: (e) => handleFilterChange("search", e.target.value)
205
+ }
206
+ ) }),
207
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(
208
+ designSystem.SingleSelect,
209
+ {
210
+ placeholder: formatMessage({
211
+ id: "payment-plugin.orders.status.placeholder",
212
+ defaultMessage: "All Statuses"
213
+ }),
214
+ value: filters.status,
215
+ onChange: (value) => handleFilterChange("status", value),
216
+ children: [
217
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "", children: formatMessage({ id: "payment-plugin.orders.all", defaultMessage: "All" }) }),
218
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "pending", children: formatMessage({ id: "payment-plugin.orders.pending", defaultMessage: "Pending" }) }),
219
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "processing", children: formatMessage({ id: "payment-plugin.orders.processing", defaultMessage: "Processing" }) }),
220
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "shipped", children: formatMessage({ id: "payment-plugin.orders.shipped", defaultMessage: "Shipped" }) }),
221
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "delivered", children: formatMessage({ id: "payment-plugin.orders.delivered", defaultMessage: "Delivered" }) }),
222
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "cancelled", children: formatMessage({ id: "payment-plugin.orders.cancelled", defaultMessage: "Cancelled" }) })
223
+ ]
224
+ }
225
+ ) }),
226
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(
227
+ designSystem.SingleSelect,
228
+ {
229
+ placeholder: formatMessage({
230
+ id: "payment-plugin.orders.paymentStatus.placeholder",
231
+ defaultMessage: "All Payment Statuses"
232
+ }),
233
+ value: filters.paymentStatus,
234
+ onChange: (value) => handleFilterChange("paymentStatus", value),
235
+ children: [
236
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "", children: formatMessage({ id: "payment-plugin.orders.all", defaultMessage: "All" }) }),
237
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "unpaid", children: formatMessage({ id: "payment-plugin.orders.unpaid", defaultMessage: "Unpaid" }) }),
238
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "paid", children: formatMessage({ id: "payment-plugin.orders.paid", defaultMessage: "Paid" }) }),
239
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "partially_paid", children: formatMessage({ id: "payment-plugin.orders.partially_paid", defaultMessage: "Partially Paid" }) }),
240
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "refunded", children: formatMessage({ id: "payment-plugin.orders.refunded", defaultMessage: "Refunded" }) })
241
+ ]
242
+ }
243
+ ) }),
244
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(
245
+ designSystem.SingleSelect,
246
+ {
247
+ placeholder: formatMessage({
248
+ id: "payment-plugin.orders.currency.placeholder",
249
+ defaultMessage: "All Currencies"
250
+ }),
251
+ value: filters.currency,
252
+ onChange: (value) => handleFilterChange("currency", value),
253
+ children: [
254
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "", children: formatMessage({ id: "payment-plugin.orders.all", defaultMessage: "All" }) }),
255
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "usd", children: "USD" }),
256
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "eur", children: "EUR" }),
257
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "gbp", children: "GBP" })
258
+ ]
259
+ }
260
+ ) }),
261
+ /* @__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" }) }) }) })
262
+ ] }) }) }),
263
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 4, marginBottom: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral600", children: formatMessage(
264
+ { id: "payment-plugin.orders.results", defaultMessage: "Showing {start}-{end} of {total} orders" },
265
+ {
266
+ start: startIndex + 1,
267
+ end: Math.min(endIndex, filteredOrders.length),
268
+ total: filteredOrders.length
269
+ }
270
+ ) }) }),
271
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { children: [
272
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
273
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.orderNumber", defaultMessage: "Order #" }) }) }),
274
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.customer", defaultMessage: "Customer" }) }) }),
275
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.items", defaultMessage: "Items" }) }) }),
276
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.total", defaultMessage: "Total" }) }) }),
277
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.status", defaultMessage: "Order Status" }) }) }),
278
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.paymentStatus", defaultMessage: "Payment Status" }) }) }),
279
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.date", defaultMessage: "Date" }) }) })
280
+ ] }) }),
281
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: paginatedOrders.map((order) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
282
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", fontWeight: "bold", fontFamily: "monospace", children: order.orderNumber }) }),
283
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
284
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", fontWeight: "bold", children: order.customerName || "Unknown" }),
285
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "epsilon", children: order.customerEmail })
286
+ ] }) }),
287
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { textColor: "neutral600", children: [
288
+ order.items.length,
289
+ " ",
290
+ order.items.length === 1 ? "item" : "items"
291
+ ] }) }),
292
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", fontWeight: "bold", children: formatCurrency(order.totalAmount, order.currency) }) }),
293
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: getStatusBadge(order.status, "order") }),
294
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: getStatusBadge(order.paymentStatus, "payment") }),
295
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: formatDate(order.createdAt) }) })
296
+ ] }, order.id)) })
297
+ ] }) }) }),
298
+ totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 4, children: /* @__PURE__ */ jsxRuntime.jsx(
299
+ designSystem.Pagination,
300
+ {
301
+ currentPage,
302
+ pageCount: totalPages,
303
+ onPageChange: setCurrentPage
304
+ }
305
+ ) })
306
+ ] });
307
+ };
308
+ exports.Orders = Orders;
@@ -0,0 +1,308 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { Box, Flex, Loader, EmptyStateLayout, Button, Typography, Card, Grid, TextInput, SingleSelect, SingleSelectOption, Table, Thead, Tr, Th, Tbody, Td, Pagination, Badge } from "@strapi/design-system";
4
+ import { useIntl } from "react-intl";
5
+ import { useFetchClient } from "@strapi/strapi/admin";
6
+ import { P as PLUGIN_ID } from "./index-Bz8V_5zH.mjs";
7
+ const Orders = () => {
8
+ const { formatMessage } = useIntl();
9
+ const { get } = useFetchClient();
10
+ const [orders, setOrders] = useState([]);
11
+ const [filteredOrders, setFilteredOrders] = useState([]);
12
+ const [loading, setLoading] = useState(true);
13
+ const [error, setError] = useState(null);
14
+ const [currentPage, setCurrentPage] = useState(1);
15
+ const [pageSize, setPageSize] = useState(25);
16
+ const [totalCount, setTotalCount] = useState(0);
17
+ const [filters, setFilters] = useState({
18
+ status: "",
19
+ paymentStatus: "",
20
+ dateRange: { from: null, to: null },
21
+ search: "",
22
+ currency: ""
23
+ });
24
+ useEffect(() => {
25
+ fetchOrders();
26
+ }, [currentPage, pageSize, filters]);
27
+ useEffect(() => {
28
+ applyFilters();
29
+ }, [orders, filters]);
30
+ const fetchOrders = async () => {
31
+ try {
32
+ setLoading(true);
33
+ const queryParams = new URLSearchParams({
34
+ page: currentPage.toString(),
35
+ pageSize: pageSize.toString(),
36
+ ...filters.status && { status: filters.status }
37
+ });
38
+ const { data } = await get(`/${PLUGIN_ID}/admin/orders?${queryParams}`);
39
+ if (data.success && data.data) {
40
+ const formattedOrders = data.data.map((o) => ({
41
+ id: o.documentId,
42
+ orderNumber: o.order_number,
43
+ customerEmail: o.customer?.email || "N/A",
44
+ customerName: o.customer ? `${o.customer.firstName || ""} ${o.customer.lastName || ""}`.trim() : "N/A",
45
+ status: o.status,
46
+ totalAmount: o.total_amount,
47
+ currency: o.currency,
48
+ paymentStatus: o.status === "completed" ? "paid" : "unpaid",
49
+ items: Array.isArray(o.items) ? o.items : [],
50
+ createdAt: o.createdAt,
51
+ updatedAt: o.updatedAt
52
+ }));
53
+ setOrders(formattedOrders);
54
+ setTotalCount(data.meta.pagination.total);
55
+ }
56
+ setLoading(false);
57
+ } catch (err) {
58
+ setError("Failed to fetch orders");
59
+ setLoading(false);
60
+ }
61
+ };
62
+ const applyFilters = () => {
63
+ let filtered = [...orders];
64
+ if (filters.search) {
65
+ const searchLower = filters.search.toLowerCase();
66
+ filtered = filtered.filter(
67
+ (order) => order.orderNumber.toLowerCase().includes(searchLower) || order.customerEmail.toLowerCase().includes(searchLower) || order.customerName?.toLowerCase().includes(searchLower)
68
+ );
69
+ }
70
+ if (filters.status) {
71
+ filtered = filtered.filter((order) => order.status === filters.status);
72
+ }
73
+ if (filters.paymentStatus) {
74
+ filtered = filtered.filter((order) => order.paymentStatus === filters.paymentStatus);
75
+ }
76
+ if (filters.currency) {
77
+ filtered = filtered.filter((order) => order.currency === filters.currency);
78
+ }
79
+ if (filters.dateRange.from) {
80
+ filtered = filtered.filter(
81
+ (order) => new Date(order.createdAt) >= filters.dateRange.from
82
+ );
83
+ }
84
+ if (filters.dateRange.to) {
85
+ filtered = filtered.filter(
86
+ (order) => new Date(order.createdAt) <= filters.dateRange.to
87
+ );
88
+ }
89
+ setFilteredOrders(filtered);
90
+ };
91
+ const formatCurrency = (amount, currency = "usd") => {
92
+ return new Intl.NumberFormat("en-US", {
93
+ style: "currency",
94
+ currency: currency.toUpperCase()
95
+ }).format(amount);
96
+ };
97
+ const formatDate = (dateString) => {
98
+ return new Date(dateString).toLocaleDateString("en-US", {
99
+ year: "numeric",
100
+ month: "short",
101
+ day: "numeric",
102
+ hour: "2-digit",
103
+ minute: "2-digit"
104
+ });
105
+ };
106
+ const getStatusBadge = (status, type) => {
107
+ const configs = {
108
+ order: {
109
+ pending: { color: "warning", label: "Pending" },
110
+ processing: { color: "info", label: "Processing" },
111
+ shipped: { color: "secondary", label: "Shipped" },
112
+ delivered: { color: "success", label: "Delivered" },
113
+ cancelled: { color: "danger", label: "Cancelled" },
114
+ refunded: { color: "neutral", label: "Refunded" }
115
+ },
116
+ payment: {
117
+ unpaid: { color: "danger", label: "Unpaid" },
118
+ paid: { color: "success", label: "Paid" },
119
+ partially_paid: { color: "warning", label: "Partially Paid" },
120
+ refunded: { color: "neutral", label: "Refunded" }
121
+ }
122
+ };
123
+ const config = type === "order" ? configs.order[status] || configs.order.pending : configs.payment[status] || configs.payment.unpaid;
124
+ return /* @__PURE__ */ jsx(Badge, { size: "S", backgroundColor: config.color, children: config.label });
125
+ };
126
+ const handleFilterChange = (key, value) => {
127
+ setFilters((prev) => ({ ...prev, [key]: value }));
128
+ setCurrentPage(1);
129
+ };
130
+ const clearFilters = () => {
131
+ setFilters({
132
+ status: "",
133
+ paymentStatus: "",
134
+ dateRange: { from: null, to: null },
135
+ search: "",
136
+ currency: ""
137
+ });
138
+ setCurrentPage(1);
139
+ };
140
+ const exportOrders = () => {
141
+ const csvContent = [
142
+ ["Order Number", "Customer Email", "Customer Name", "Status", "Payment Status", "Total Amount", "Currency", "Date"],
143
+ ...filteredOrders.map((order) => [
144
+ order.orderNumber,
145
+ order.customerEmail,
146
+ order.customerName || "",
147
+ order.status,
148
+ order.paymentStatus,
149
+ (order.totalAmount / 100).toString(),
150
+ order.currency,
151
+ formatDate(order.createdAt)
152
+ ])
153
+ ].map((row) => row.join(",")).join("\n");
154
+ const blob = new Blob([csvContent], { type: "text/csv" });
155
+ const url = window.URL.createObjectURL(blob);
156
+ const a = document.createElement("a");
157
+ a.href = url;
158
+ a.download = `orders-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.csv`;
159
+ a.click();
160
+ window.URL.revokeObjectURL(url);
161
+ };
162
+ const startIndex = (currentPage - 1) * pageSize;
163
+ const endIndex = startIndex + pageSize;
164
+ const paginatedOrders = filteredOrders.slice(startIndex, endIndex);
165
+ const totalPages = Math.ceil(filteredOrders.length / pageSize);
166
+ if (loading && orders.length === 0) {
167
+ return /* @__PURE__ */ jsx(Box, { paddingLeft: 10, paddingRight: 10, paddingTop: 4, paddingBottom: 10, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", alignItems: "center", style: { minHeight: "400px" }, children: /* @__PURE__ */ jsx(Loader, {}) }) });
168
+ }
169
+ if (error) {
170
+ return /* @__PURE__ */ jsx(Box, { paddingLeft: 10, paddingRight: 10, paddingTop: 4, paddingBottom: 10, children: /* @__PURE__ */ jsx(
171
+ EmptyStateLayout,
172
+ {
173
+ title: "Error loading orders",
174
+ subtitle: error,
175
+ action: /* @__PURE__ */ jsx(Button, { onClick: fetchOrders, children: formatMessage({ id: "payment-plugin.orders.retry", defaultMessage: "Retry" }) })
176
+ }
177
+ ) });
178
+ }
179
+ return /* @__PURE__ */ jsxs(Box, { paddingLeft: 10, paddingRight: 10, paddingTop: 4, paddingBottom: 10, children: [
180
+ /* @__PURE__ */ jsx(Box, { marginBottom: 4, children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
181
+ /* @__PURE__ */ jsxs(Box, { children: [
182
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: formatMessage({ id: "payment-plugin.orders.title", defaultMessage: "Orders" }) }),
183
+ /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral600", children: formatMessage({
184
+ id: "payment-plugin.orders.subtitle",
185
+ defaultMessage: "Manage and track all customer orders"
186
+ }) })
187
+ ] }),
188
+ /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
189
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: exportOrders, children: formatMessage({ id: "payment-plugin.orders.export", defaultMessage: "Export" }) }),
190
+ /* @__PURE__ */ jsx(Button, { onClick: () => window.location.reload(), children: formatMessage({ id: "payment-plugin.orders.refresh", defaultMessage: "Refresh" }) })
191
+ ] })
192
+ ] }) }),
193
+ /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(Box, { padding: 4, children: /* @__PURE__ */ jsxs(Grid.Root, { gap: 4, children: [
194
+ /* @__PURE__ */ jsx(Grid.Item, { col: 3, children: /* @__PURE__ */ jsx(
195
+ TextInput,
196
+ {
197
+ placeholder: formatMessage({
198
+ id: "payment-plugin.orders.search.placeholder",
199
+ defaultMessage: "Search orders..."
200
+ }),
201
+ value: filters.search,
202
+ onChange: (e) => handleFilterChange("search", e.target.value)
203
+ }
204
+ ) }),
205
+ /* @__PURE__ */ jsx(Grid.Item, { col: 2, children: /* @__PURE__ */ jsxs(
206
+ SingleSelect,
207
+ {
208
+ placeholder: formatMessage({
209
+ id: "payment-plugin.orders.status.placeholder",
210
+ defaultMessage: "All Statuses"
211
+ }),
212
+ value: filters.status,
213
+ onChange: (value) => handleFilterChange("status", value),
214
+ children: [
215
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "", children: formatMessage({ id: "payment-plugin.orders.all", defaultMessage: "All" }) }),
216
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "pending", children: formatMessage({ id: "payment-plugin.orders.pending", defaultMessage: "Pending" }) }),
217
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "processing", children: formatMessage({ id: "payment-plugin.orders.processing", defaultMessage: "Processing" }) }),
218
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "shipped", children: formatMessage({ id: "payment-plugin.orders.shipped", defaultMessage: "Shipped" }) }),
219
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "delivered", children: formatMessage({ id: "payment-plugin.orders.delivered", defaultMessage: "Delivered" }) }),
220
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "cancelled", children: formatMessage({ id: "payment-plugin.orders.cancelled", defaultMessage: "Cancelled" }) })
221
+ ]
222
+ }
223
+ ) }),
224
+ /* @__PURE__ */ jsx(Grid.Item, { col: 2, children: /* @__PURE__ */ jsxs(
225
+ SingleSelect,
226
+ {
227
+ placeholder: formatMessage({
228
+ id: "payment-plugin.orders.paymentStatus.placeholder",
229
+ defaultMessage: "All Payment Statuses"
230
+ }),
231
+ value: filters.paymentStatus,
232
+ onChange: (value) => handleFilterChange("paymentStatus", value),
233
+ children: [
234
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "", children: formatMessage({ id: "payment-plugin.orders.all", defaultMessage: "All" }) }),
235
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "unpaid", children: formatMessage({ id: "payment-plugin.orders.unpaid", defaultMessage: "Unpaid" }) }),
236
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "paid", children: formatMessage({ id: "payment-plugin.orders.paid", defaultMessage: "Paid" }) }),
237
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "partially_paid", children: formatMessage({ id: "payment-plugin.orders.partially_paid", defaultMessage: "Partially Paid" }) }),
238
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "refunded", children: formatMessage({ id: "payment-plugin.orders.refunded", defaultMessage: "Refunded" }) })
239
+ ]
240
+ }
241
+ ) }),
242
+ /* @__PURE__ */ jsx(Grid.Item, { col: 2, children: /* @__PURE__ */ jsxs(
243
+ SingleSelect,
244
+ {
245
+ placeholder: formatMessage({
246
+ id: "payment-plugin.orders.currency.placeholder",
247
+ defaultMessage: "All Currencies"
248
+ }),
249
+ value: filters.currency,
250
+ onChange: (value) => handleFilterChange("currency", value),
251
+ children: [
252
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "", children: formatMessage({ id: "payment-plugin.orders.all", defaultMessage: "All" }) }),
253
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "usd", children: "USD" }),
254
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "eur", children: "EUR" }),
255
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "gbp", children: "GBP" })
256
+ ]
257
+ }
258
+ ) }),
259
+ /* @__PURE__ */ jsx(Grid.Item, { col: 3, children: /* @__PURE__ */ jsx(Flex, { gap: 2, children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", onClick: clearFilters, children: formatMessage({ id: "payment-plugin.orders.clearFilters", defaultMessage: "Clear" }) }) }) })
260
+ ] }) }) }),
261
+ /* @__PURE__ */ jsx(Box, { marginTop: 4, marginBottom: 2, children: /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral600", children: formatMessage(
262
+ { id: "payment-plugin.orders.results", defaultMessage: "Showing {start}-{end} of {total} orders" },
263
+ {
264
+ start: startIndex + 1,
265
+ end: Math.min(endIndex, filteredOrders.length),
266
+ total: filteredOrders.length
267
+ }
268
+ ) }) }),
269
+ /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(Box, { padding: 4, children: /* @__PURE__ */ jsxs(Table, { children: [
270
+ /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
271
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.orderNumber", defaultMessage: "Order #" }) }) }),
272
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.customer", defaultMessage: "Customer" }) }) }),
273
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.items", defaultMessage: "Items" }) }) }),
274
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.total", defaultMessage: "Total" }) }) }),
275
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.status", defaultMessage: "Order Status" }) }) }),
276
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.paymentStatus", defaultMessage: "Payment Status" }) }) }),
277
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "epsilon", children: formatMessage({ id: "payment-plugin.orders.date", defaultMessage: "Date" }) }) })
278
+ ] }) }),
279
+ /* @__PURE__ */ jsx(Tbody, { children: paginatedOrders.map((order) => /* @__PURE__ */ jsxs(Tr, { children: [
280
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", fontWeight: "bold", fontFamily: "monospace", children: order.orderNumber }) }),
281
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Box, { children: [
282
+ /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", fontWeight: "bold", children: order.customerName || "Unknown" }),
283
+ /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", children: order.customerEmail })
284
+ ] }) }),
285
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Typography, { textColor: "neutral600", children: [
286
+ order.items.length,
287
+ " ",
288
+ order.items.length === 1 ? "item" : "items"
289
+ ] }) }),
290
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", fontWeight: "bold", children: formatCurrency(order.totalAmount, order.currency) }) }),
291
+ /* @__PURE__ */ jsx(Td, { children: getStatusBadge(order.status, "order") }),
292
+ /* @__PURE__ */ jsx(Td, { children: getStatusBadge(order.paymentStatus, "payment") }),
293
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: formatDate(order.createdAt) }) })
294
+ ] }, order.id)) })
295
+ ] }) }) }),
296
+ totalPages > 1 && /* @__PURE__ */ jsx(Box, { marginTop: 4, children: /* @__PURE__ */ jsx(
297
+ Pagination,
298
+ {
299
+ currentPage,
300
+ pageCount: totalPages,
301
+ onPageChange: setCurrentPage
302
+ }
303
+ ) })
304
+ ] });
305
+ };
306
+ export {
307
+ Orders
308
+ };