@reeboot/strapi-payment-plugin 0.0.5 → 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 +17 -5
- package/dist/server/index.mjs +17 -5
- 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
|
@@ -5,7 +5,7 @@ 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 CustomerList = ({ customers, onCustomerClick, compact = false }) => {
|
|
10
10
|
const { formatMessage } = reactIntl.useIntl();
|
|
11
11
|
const formatCurrency = (amount, currency = "usd") => {
|
|
@@ -22,7 +22,7 @@ const CustomerList = ({ customers, onCustomerClick, compact = false }) => {
|
|
|
22
22
|
});
|
|
23
23
|
};
|
|
24
24
|
const getCustomerStatusBadge = (isActive) => {
|
|
25
|
-
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { size: compact ? "S" : "M",
|
|
25
|
+
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { size: compact ? "S" : "M", variant: isActive ? "success" : "neutral", children: isActive ? "Active" : "Inactive" });
|
|
26
26
|
};
|
|
27
27
|
const getCustomerName = (customer) => {
|
|
28
28
|
if (customer.first_name && customer.last_name) {
|
|
@@ -53,43 +53,13 @@ const CustomerList = ({ customers, onCustomerClick, compact = false }) => {
|
|
|
53
53
|
style: { cursor: onCustomerClick ? "pointer" : "default" },
|
|
54
54
|
children: [
|
|
55
55
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, children: [
|
|
56
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
57
|
-
|
|
58
|
-
{
|
|
59
|
-
textColor: "neutral800",
|
|
60
|
-
fontWeight: compact ? "normal" : "bold",
|
|
61
|
-
fontSize: compact ? "0.875rem" : "1rem",
|
|
62
|
-
children: getCustomerName(customer)
|
|
63
|
-
}
|
|
64
|
-
),
|
|
65
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "epsilon", fontFamily: "monospace", fontSize: "0.75rem", children: customer.stripe_customer_id }),
|
|
56
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", fontWeight: compact ? "normal" : "bold", children: getCustomerName(customer) }),
|
|
57
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "epsilon", fontFamily: "monospace", children: customer.stripe_customer_id }),
|
|
66
58
|
!compact && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "epsilon", children: customer.email })
|
|
67
59
|
] }) }),
|
|
68
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
textColor: "neutral800",
|
|
72
|
-
fontWeight: "bold",
|
|
73
|
-
fontSize: compact ? "0.875rem" : "1rem",
|
|
74
|
-
children: formatCurrency(customer.totalSpent, customer.currency)
|
|
75
|
-
}
|
|
76
|
-
) }),
|
|
77
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
78
|
-
designSystem.Typography,
|
|
79
|
-
{
|
|
80
|
-
textColor: "neutral600",
|
|
81
|
-
fontSize: compact ? "0.75rem" : "0.875rem",
|
|
82
|
-
children: customer.paymentCount
|
|
83
|
-
}
|
|
84
|
-
) }),
|
|
85
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
86
|
-
designSystem.Typography,
|
|
87
|
-
{
|
|
88
|
-
textColor: "neutral600",
|
|
89
|
-
fontSize: compact ? "0.75rem" : "0.875rem",
|
|
90
|
-
children: customer.lastPaymentDate ? formatDate(customer.lastPaymentDate) : "Never"
|
|
91
|
-
}
|
|
92
|
-
) }),
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", fontWeight: "bold", children: formatCurrency(customer.totalSpent, customer.currency) }) }),
|
|
61
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: customer.paymentCount }) }),
|
|
62
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", children: customer.lastPaymentDate ? formatDate(customer.lastPaymentDate) : "Never" }) }),
|
|
93
63
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: getCustomerStatusBadge(customer.isActive) })
|
|
94
64
|
]
|
|
95
65
|
},
|
|
@@ -101,24 +71,19 @@ const Customers = () => {
|
|
|
101
71
|
const { formatMessage } = reactIntl.useIntl();
|
|
102
72
|
const { get } = admin.useFetchClient();
|
|
103
73
|
const [customers, setCustomers] = React.useState([]);
|
|
104
|
-
const [filteredCustomers, setFilteredCustomers] = React.useState([]);
|
|
105
74
|
const [loading, setLoading] = React.useState(true);
|
|
106
75
|
const [error, setError] = React.useState(null);
|
|
107
76
|
const [currentPage, setCurrentPage] = React.useState(1);
|
|
108
|
-
const
|
|
77
|
+
const pageSize = 25;
|
|
109
78
|
const [totalCount, setTotalCount] = React.useState(0);
|
|
110
79
|
const [filters, setFilters] = React.useState({
|
|
111
80
|
search: "",
|
|
112
81
|
country: "",
|
|
113
|
-
isActive: ""
|
|
114
|
-
registrationDateRange: { from: null, to: null }
|
|
82
|
+
isActive: ""
|
|
115
83
|
});
|
|
116
84
|
React.useEffect(() => {
|
|
117
85
|
fetchCustomers();
|
|
118
|
-
}, [currentPage,
|
|
119
|
-
React.useEffect(() => {
|
|
120
|
-
applyFilters();
|
|
121
|
-
}, [customers, filters]);
|
|
86
|
+
}, [currentPage, filters]);
|
|
122
87
|
const fetchCustomers = async () => {
|
|
123
88
|
try {
|
|
124
89
|
setLoading(true);
|
|
@@ -140,7 +105,7 @@ const Customers = () => {
|
|
|
140
105
|
tags: []
|
|
141
106
|
}));
|
|
142
107
|
setCustomers(formattedCustomers);
|
|
143
|
-
setTotalCount(data.meta
|
|
108
|
+
setTotalCount(data.meta?.pagination?.total || 0);
|
|
144
109
|
}
|
|
145
110
|
setLoading(false);
|
|
146
111
|
} catch (err) {
|
|
@@ -148,38 +113,7 @@ const Customers = () => {
|
|
|
148
113
|
setLoading(false);
|
|
149
114
|
}
|
|
150
115
|
};
|
|
151
|
-
const
|
|
152
|
-
let filtered = [...customers];
|
|
153
|
-
if (filters.search) {
|
|
154
|
-
const searchLower = filters.search.toLowerCase();
|
|
155
|
-
filtered = filtered.filter(
|
|
156
|
-
(customer) => customer.email.toLowerCase().includes(searchLower) || `${customer.first_name} ${customer.last_name}`.toLowerCase().includes(searchLower) || customer.stripe_customer_id && customer.stripe_customer_id.toLowerCase().includes(searchLower)
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
if (filters.isActive) {
|
|
160
|
-
const isActive = filters.isActive === "active";
|
|
161
|
-
filtered = filtered.filter((customer) => customer.isActive === isActive);
|
|
162
|
-
}
|
|
163
|
-
if (filters.country) {
|
|
164
|
-
filtered = filtered.filter(
|
|
165
|
-
(customer) => customer.address?.country === filters.country
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
if (filters.registrationDateRange.from) {
|
|
169
|
-
filtered = filtered.filter(
|
|
170
|
-
(customer) => new Date(customer.registrationDate) >= filters.registrationDateRange.from
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
if (filters.registrationDateRange.to) {
|
|
174
|
-
filtered = filtered.filter(
|
|
175
|
-
(customer) => new Date(customer.registrationDate) <= filters.registrationDateRange.to
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
setFilteredCustomers(filtered);
|
|
179
|
-
};
|
|
180
|
-
const handleCustomerClick = (customer) => {
|
|
181
|
-
console.log("Clicked customer:", customer);
|
|
182
|
-
};
|
|
116
|
+
const totalPages = Math.max(1, Math.ceil(totalCount / pageSize));
|
|
183
117
|
const formatDate = (dateString) => {
|
|
184
118
|
try {
|
|
185
119
|
return new Date(dateString).toLocaleDateString("en-US", {
|
|
@@ -187,7 +121,7 @@ const Customers = () => {
|
|
|
187
121
|
month: "short",
|
|
188
122
|
day: "numeric"
|
|
189
123
|
});
|
|
190
|
-
} catch
|
|
124
|
+
} catch {
|
|
191
125
|
return "Invalid Date";
|
|
192
126
|
}
|
|
193
127
|
};
|
|
@@ -196,26 +130,20 @@ const Customers = () => {
|
|
|
196
130
|
setCurrentPage(1);
|
|
197
131
|
};
|
|
198
132
|
const clearFilters = () => {
|
|
199
|
-
setFilters({
|
|
200
|
-
search: "",
|
|
201
|
-
country: "",
|
|
202
|
-
isActive: "",
|
|
203
|
-
registrationDateRange: { from: null, to: null }
|
|
204
|
-
});
|
|
133
|
+
setFilters({ search: "", country: "", isActive: "" });
|
|
205
134
|
setCurrentPage(1);
|
|
206
135
|
};
|
|
207
136
|
const exportCustomers = () => {
|
|
208
137
|
const csvContent = [
|
|
209
|
-
["Customer ID", "Email", "First Name", "Last Name", "Total Spent", "Payment Count", "Last Payment", "
|
|
210
|
-
...
|
|
138
|
+
["Customer ID", "Email", "First Name", "Last Name", "Total Spent", "Payment Count", "Last Payment", "Registration Date"],
|
|
139
|
+
...customers.map((customer) => [
|
|
211
140
|
customer.stripe_customer_id || "",
|
|
212
141
|
customer.email,
|
|
213
142
|
customer.first_name || "",
|
|
214
143
|
customer.last_name || "",
|
|
215
|
-
(customer.totalSpent || 0
|
|
144
|
+
(customer.totalSpent || 0).toString(),
|
|
216
145
|
(customer.paymentCount || 0).toString(),
|
|
217
146
|
customer.lastPaymentDate ? formatDate(customer.lastPaymentDate) : "Never",
|
|
218
|
-
customer.isActive ? "Active" : "Inactive",
|
|
219
147
|
customer.registrationDate ? formatDate(customer.registrationDate) : ""
|
|
220
148
|
])
|
|
221
149
|
].map((row) => row.join(",")).join("\n");
|
|
@@ -227,10 +155,6 @@ const Customers = () => {
|
|
|
227
155
|
a.click();
|
|
228
156
|
window.URL.revokeObjectURL(url);
|
|
229
157
|
};
|
|
230
|
-
const startIndex = (currentPage - 1) * pageSize;
|
|
231
|
-
const endIndex = startIndex + pageSize;
|
|
232
|
-
const paginatedCustomers = filteredCustomers.slice(startIndex, endIndex);
|
|
233
|
-
const totalPages = Math.ceil(filteredCustomers.length / pageSize);
|
|
234
158
|
if (loading && customers.length === 0) {
|
|
235
159
|
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, {}) }) });
|
|
236
160
|
}
|
|
@@ -238,8 +162,7 @@ const Customers = () => {
|
|
|
238
162
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
239
163
|
designSystem.EmptyStateLayout,
|
|
240
164
|
{
|
|
241
|
-
|
|
242
|
-
subtitle: error,
|
|
165
|
+
content: error,
|
|
243
166
|
action: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: fetchCustomers, children: formatMessage({ id: "payment-plugin.customers.retry", defaultMessage: "Retry" }) })
|
|
244
167
|
}
|
|
245
168
|
) });
|
|
@@ -262,6 +185,7 @@ const Customers = () => {
|
|
|
262
185
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
263
186
|
designSystem.TextInput,
|
|
264
187
|
{
|
|
188
|
+
label: formatMessage({ id: "payment-plugin.customers.search.label", defaultMessage: "Search" }),
|
|
265
189
|
placeholder: formatMessage({
|
|
266
190
|
id: "payment-plugin.customers.search.placeholder",
|
|
267
191
|
defaultMessage: "Search customers..."
|
|
@@ -273,6 +197,7 @@ const Customers = () => {
|
|
|
273
197
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
274
198
|
designSystem.SingleSelect,
|
|
275
199
|
{
|
|
200
|
+
label: formatMessage({ id: "payment-plugin.customers.status.label", defaultMessage: "Status" }),
|
|
276
201
|
placeholder: formatMessage({
|
|
277
202
|
id: "payment-plugin.customers.status.placeholder",
|
|
278
203
|
defaultMessage: "All Statuses"
|
|
@@ -289,6 +214,7 @@ const Customers = () => {
|
|
|
289
214
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
290
215
|
designSystem.SingleSelect,
|
|
291
216
|
{
|
|
217
|
+
label: formatMessage({ id: "payment-plugin.customers.country.label", defaultMessage: "Country" }),
|
|
292
218
|
placeholder: formatMessage({
|
|
293
219
|
id: "payment-plugin.customers.country.placeholder",
|
|
294
220
|
defaultMessage: "All Countries"
|
|
@@ -305,31 +231,38 @@ const Customers = () => {
|
|
|
305
231
|
]
|
|
306
232
|
}
|
|
307
233
|
) }),
|
|
308
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", onClick: clearFilters, children: formatMessage({ id: "payment-plugin.customers.clearFilters", defaultMessage: "Clear" }) }) }) })
|
|
234
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, 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.customers.clearFilters", defaultMessage: "Clear" }) }) }) })
|
|
309
235
|
] }) }) }),
|
|
310
236
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 4, marginBottom: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral600", children: formatMessage(
|
|
311
|
-
{ id: "payment-plugin.customers.results", defaultMessage: "
|
|
312
|
-
{
|
|
313
|
-
start: startIndex + 1,
|
|
314
|
-
end: Math.min(endIndex, filteredCustomers.length),
|
|
315
|
-
total: filteredCustomers.length
|
|
316
|
-
}
|
|
237
|
+
{ id: "payment-plugin.customers.results", defaultMessage: "{total} customers" },
|
|
238
|
+
{ total: totalCount }
|
|
317
239
|
) }) }),
|
|
318
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
{
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
240
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { children: /* @__PURE__ */ jsxRuntime.jsx(CustomerList, { customers }) }),
|
|
241
|
+
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: "Customers pagination", children: [
|
|
242
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
243
|
+
designSystem.PreviousLink,
|
|
244
|
+
{
|
|
245
|
+
as: "button",
|
|
246
|
+
onClick: () => setCurrentPage((p) => Math.max(1, p - 1))
|
|
247
|
+
}
|
|
248
|
+
),
|
|
249
|
+
Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
250
|
+
designSystem.PageLink,
|
|
251
|
+
{
|
|
252
|
+
number: page,
|
|
253
|
+
as: "button",
|
|
254
|
+
onClick: () => setCurrentPage(page)
|
|
255
|
+
},
|
|
256
|
+
page
|
|
257
|
+
)),
|
|
258
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
259
|
+
designSystem.NextLink,
|
|
260
|
+
{
|
|
261
|
+
as: "button",
|
|
262
|
+
onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1))
|
|
263
|
+
}
|
|
264
|
+
)
|
|
265
|
+
] }) }) })
|
|
333
266
|
] });
|
|
334
267
|
};
|
|
335
268
|
exports.Customers = Customers;
|
|
@@ -6,9 +6,9 @@ const designSystem = require("@strapi/design-system");
|
|
|
6
6
|
const icons = require("@strapi/icons");
|
|
7
7
|
const admin = require("@strapi/strapi/admin");
|
|
8
8
|
const reactIntl = require("react-intl");
|
|
9
|
-
const index = require("./index-CHEgJ7e5.js");
|
|
10
9
|
const stripeJs = require("@stripe/stripe-js");
|
|
11
|
-
const
|
|
10
|
+
const index = require("./index-D-fFikb8.js");
|
|
11
|
+
const PaymentList = require("./PaymentList-APfyYD1h.js");
|
|
12
12
|
const Dashboard = () => {
|
|
13
13
|
const { formatMessage } = reactIntl.useIntl();
|
|
14
14
|
const { get, post } = admin.useFetchClient();
|
|
@@ -17,25 +17,26 @@ const Dashboard = () => {
|
|
|
17
17
|
const [loading, setLoading] = React.useState(true);
|
|
18
18
|
const [error, setError] = React.useState(null);
|
|
19
19
|
const [creatingTest, setCreatingTest] = React.useState(false);
|
|
20
|
+
const [testMessage, setTestMessage] = React.useState(null);
|
|
20
21
|
React.useEffect(() => {
|
|
21
22
|
fetchDashboardData();
|
|
22
23
|
}, []);
|
|
23
24
|
const fetchDashboardData = async () => {
|
|
24
25
|
try {
|
|
25
26
|
setLoading(true);
|
|
27
|
+
setError(null);
|
|
26
28
|
const { data } = await get(`/${index.PLUGIN_ID}/admin/dashboard`);
|
|
27
29
|
if (data.success && data.data) {
|
|
30
|
+
const total = data.data.summary.totalPayments;
|
|
31
|
+
const succeeded = data.data.summary.successfulPayments;
|
|
32
|
+
const failed = data.data.summary.failedPayments;
|
|
28
33
|
setStats({
|
|
29
34
|
totalRevenue: data.data.summary.totalRevenue,
|
|
30
|
-
totalPayments:
|
|
31
|
-
successfulPayments:
|
|
32
|
-
pendingPayments:
|
|
33
|
-
failedPayments:
|
|
34
|
-
|
|
35
|
-
// Rough estimate
|
|
36
|
-
totalOrders: data.data.summary.totalPayments,
|
|
37
|
-
// Rough estimate
|
|
38
|
-
averageOrderValue: data.data.summary.totalPayments > 0 ? data.data.summary.totalRevenue / data.data.summary.totalPayments : 0
|
|
35
|
+
totalPayments: total,
|
|
36
|
+
successfulPayments: succeeded,
|
|
37
|
+
pendingPayments: Math.max(0, total - succeeded - failed),
|
|
38
|
+
failedPayments: failed,
|
|
39
|
+
averageOrderValue: total > 0 ? data.data.summary.totalRevenue / total : 0
|
|
39
40
|
});
|
|
40
41
|
const formattedPayments = data.data.recentTransactions.map((p) => ({
|
|
41
42
|
...p,
|
|
@@ -54,6 +55,7 @@ const Dashboard = () => {
|
|
|
54
55
|
const createTestPayment = async () => {
|
|
55
56
|
try {
|
|
56
57
|
setCreatingTest(true);
|
|
58
|
+
setTestMessage(null);
|
|
57
59
|
const { data } = await post(`/${index.PLUGIN_ID}/admin/create-sample-payment`);
|
|
58
60
|
if (!data.success) throw new Error(data.error?.message || "Failed to process payment");
|
|
59
61
|
const { publishableKey, clientSecret } = data.data;
|
|
@@ -64,22 +66,14 @@ const Dashboard = () => {
|
|
|
64
66
|
throw new Error("Client secret not returned from server");
|
|
65
67
|
}
|
|
66
68
|
const stripe = await stripeJs.loadStripe(publishableKey);
|
|
67
|
-
if (stripe === null)
|
|
68
|
-
throw new Error("Failed to load Stripe.js");
|
|
69
|
-
}
|
|
69
|
+
if (stripe === null) throw new Error("Failed to load Stripe.js");
|
|
70
70
|
const elements = stripe.elements({
|
|
71
71
|
clientSecret,
|
|
72
|
-
appearance: {
|
|
73
|
-
theme: "stripe"
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
const paymentElement = elements.create("payment", {
|
|
77
|
-
layout: "tabs"
|
|
72
|
+
appearance: { theme: "stripe" }
|
|
78
73
|
});
|
|
74
|
+
const paymentElement = elements.create("payment", { layout: "tabs" });
|
|
79
75
|
const existingModal = document.getElementById("stripe-payment-modal");
|
|
80
|
-
if (existingModal)
|
|
81
|
-
document.body.removeChild(existingModal);
|
|
82
|
-
}
|
|
76
|
+
if (existingModal) document.body.removeChild(existingModal);
|
|
83
77
|
const modal = document.createElement("div");
|
|
84
78
|
modal.id = "stripe-payment-modal";
|
|
85
79
|
Object.assign(modal.style, {
|
|
@@ -101,26 +95,19 @@ const Dashboard = () => {
|
|
|
101
95
|
borderRadius: "8px",
|
|
102
96
|
minWidth: "400px",
|
|
103
97
|
maxWidth: "500px",
|
|
104
|
-
boxShadow: "0 4px 6px rgba(0,
|
|
98
|
+
boxShadow: "0 4px 6px rgba(0,0,0,0.1)"
|
|
105
99
|
});
|
|
106
100
|
const title = document.createElement("h2");
|
|
107
101
|
title.textContent = "Test Payment - $25.00";
|
|
108
|
-
title.style.
|
|
109
|
-
title.style.fontSize = "1.25rem";
|
|
110
|
-
title.style.fontWeight = "600";
|
|
111
|
-
title.style.color = "#333";
|
|
102
|
+
title.style.cssText = "margin-bottom:1.5rem;font-size:1.25rem;font-weight:600;color:#333";
|
|
112
103
|
container.appendChild(title);
|
|
113
104
|
const form = document.createElement("form");
|
|
114
105
|
const paymentContainer = document.createElement("div");
|
|
115
|
-
|
|
116
|
-
paymentContainer.
|
|
117
|
-
paymentContainer.style.marginBottom = "1.5rem";
|
|
118
|
-
paymentContainer.style.minHeight = "200px";
|
|
106
|
+
paymentContainer.id = `payment-element-${Date.now()}`;
|
|
107
|
+
paymentContainer.style.cssText = "margin-bottom:1.5rem;min-height:200px";
|
|
119
108
|
form.appendChild(paymentContainer);
|
|
120
109
|
const buttonContainer = document.createElement("div");
|
|
121
|
-
buttonContainer.style.
|
|
122
|
-
buttonContainer.style.gap = "1rem";
|
|
123
|
-
buttonContainer.style.marginTop = "1rem";
|
|
110
|
+
buttonContainer.style.cssText = "display:flex;gap:1rem;margin-top:1rem";
|
|
124
111
|
const submitButton = document.createElement("button");
|
|
125
112
|
submitButton.type = "submit";
|
|
126
113
|
submitButton.textContent = "Loading...";
|
|
@@ -135,7 +122,6 @@ const Dashboard = () => {
|
|
|
135
122
|
cursor: "not-allowed",
|
|
136
123
|
fontSize: "16px",
|
|
137
124
|
fontWeight: "500",
|
|
138
|
-
transition: "background 0.2s",
|
|
139
125
|
opacity: "0.7"
|
|
140
126
|
});
|
|
141
127
|
const cancelButton = document.createElement("button");
|
|
@@ -149,8 +135,7 @@ const Dashboard = () => {
|
|
|
149
135
|
borderRadius: "4px",
|
|
150
136
|
cursor: "pointer",
|
|
151
137
|
fontSize: "16px",
|
|
152
|
-
fontWeight: "500"
|
|
153
|
-
transition: "background 0.2s"
|
|
138
|
+
fontWeight: "500"
|
|
154
139
|
});
|
|
155
140
|
cancelButton.onclick = () => {
|
|
156
141
|
document.body.removeChild(modal);
|
|
@@ -162,61 +147,46 @@ const Dashboard = () => {
|
|
|
162
147
|
container.appendChild(form);
|
|
163
148
|
modal.appendChild(container);
|
|
164
149
|
document.body.appendChild(modal);
|
|
165
|
-
|
|
166
|
-
console.log("Mounting payment element to container:", paymentContainer);
|
|
167
|
-
paymentElement.mount(paymentContainer);
|
|
168
|
-
} catch (e) {
|
|
169
|
-
console.error("Error mounting payment element:", e);
|
|
170
|
-
alert("Failed to mount Stripe payment form");
|
|
171
|
-
document.body.removeChild(modal);
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
150
|
+
paymentElement.mount(paymentContainer);
|
|
174
151
|
paymentElement.on("ready", () => {
|
|
175
|
-
console.log("Payment Element is ready");
|
|
176
152
|
submitButton.disabled = false;
|
|
177
153
|
submitButton.textContent = "Pay $25.00";
|
|
178
154
|
submitButton.style.cursor = "pointer";
|
|
179
155
|
submitButton.style.opacity = "1";
|
|
180
156
|
});
|
|
181
|
-
paymentElement.on("loaderror", (event) => {
|
|
182
|
-
console.error("Payment Element load error:", event);
|
|
183
|
-
const errorMessage = event?.error?.message || "Unknown error loading Stripe form";
|
|
184
|
-
alert(`Failed to load payment form: ${errorMessage}. Please check your keys and network.`);
|
|
185
|
-
document.body.removeChild(modal);
|
|
186
|
-
});
|
|
187
157
|
setCreatingTest(false);
|
|
188
158
|
form.onsubmit = async (e) => {
|
|
189
159
|
e.preventDefault();
|
|
190
160
|
submitButton.disabled = true;
|
|
191
161
|
submitButton.textContent = "Processing...";
|
|
192
162
|
try {
|
|
193
|
-
const result = await stripe.confirmPayment({
|
|
194
|
-
elements,
|
|
195
|
-
redirect: "if_required"
|
|
196
|
-
});
|
|
163
|
+
const result = await stripe.confirmPayment({ elements, redirect: "if_required" });
|
|
197
164
|
if (result.error) {
|
|
198
|
-
|
|
165
|
+
const errDiv = document.createElement("p");
|
|
166
|
+
errDiv.style.cssText = "color:#ef4444;margin-top:0.5rem;font-size:14px";
|
|
167
|
+
errDiv.textContent = `Payment failed: ${result.error.message}`;
|
|
168
|
+
form.appendChild(errDiv);
|
|
199
169
|
submitButton.disabled = false;
|
|
200
170
|
submitButton.textContent = "Pay $25.00";
|
|
201
|
-
} else if (result.paymentIntent
|
|
202
|
-
alert("Payment successful! ✓");
|
|
171
|
+
} else if (result.paymentIntent?.status === "succeeded") {
|
|
203
172
|
document.body.removeChild(modal);
|
|
173
|
+
setTestMessage({ type: "success", text: "Test payment successful!" });
|
|
174
|
+
setTimeout(() => setTestMessage(null), 4e3);
|
|
204
175
|
await fetchDashboardData();
|
|
205
176
|
} else {
|
|
206
|
-
alert("Payment is being processed...");
|
|
207
177
|
submitButton.disabled = false;
|
|
208
178
|
submitButton.textContent = "Pay $25.00";
|
|
209
179
|
}
|
|
210
180
|
} catch (err) {
|
|
211
|
-
console.error("Payment confirmation error:", err);
|
|
212
|
-
alert(`Error: ${err instanceof Error ? err.message : "Payment confirmation failed"}`);
|
|
213
181
|
submitButton.disabled = false;
|
|
214
182
|
submitButton.textContent = "Pay $25.00";
|
|
215
183
|
}
|
|
216
184
|
};
|
|
217
185
|
} catch (err) {
|
|
218
|
-
|
|
219
|
-
|
|
186
|
+
setTestMessage({
|
|
187
|
+
type: "error",
|
|
188
|
+
text: err instanceof Error ? err.message : "An error occurred during payment initialization"
|
|
189
|
+
});
|
|
220
190
|
setCreatingTest(false);
|
|
221
191
|
}
|
|
222
192
|
};
|
|
@@ -233,8 +203,7 @@ const Dashboard = () => {
|
|
|
233
203
|
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
234
204
|
designSystem.EmptyStateLayout,
|
|
235
205
|
{
|
|
236
|
-
|
|
237
|
-
subtitle: error,
|
|
206
|
+
content: error,
|
|
238
207
|
action: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: fetchDashboardData, children: formatMessage({ id: "payment-plugin.dashboard.retry", defaultMessage: "Retry" }) })
|
|
239
208
|
}
|
|
240
209
|
) });
|
|
@@ -248,16 +217,26 @@ const Dashboard = () => {
|
|
|
248
217
|
defaultMessage: "Overview of your payment operations"
|
|
249
218
|
}) })
|
|
250
219
|
] }),
|
|
251
|
-
/* @__PURE__ */ jsxRuntime.
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
220
|
+
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "flex-end", gap: 2, children: [
|
|
221
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
222
|
+
designSystem.Button,
|
|
223
|
+
{
|
|
224
|
+
onClick: createTestPayment,
|
|
225
|
+
loading: creatingTest,
|
|
226
|
+
variant: "secondary",
|
|
227
|
+
startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
|
|
228
|
+
children: formatMessage({ id: "payment-plugin.dashboard.initPayment", defaultMessage: "Initialize Sample Payment" })
|
|
229
|
+
}
|
|
230
|
+
),
|
|
231
|
+
testMessage && /* @__PURE__ */ jsxRuntime.jsx(
|
|
232
|
+
designSystem.Typography,
|
|
233
|
+
{
|
|
234
|
+
variant: "pi",
|
|
235
|
+
textColor: testMessage.type === "success" ? "success600" : "danger600",
|
|
236
|
+
children: testMessage.text
|
|
237
|
+
}
|
|
238
|
+
)
|
|
239
|
+
] })
|
|
261
240
|
] }) }),
|
|
262
241
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, marginBottom: 8, children: [
|
|
263
242
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 3, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { padding: 4, shadow: "tableShadow", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "start", gap: 2, children: [
|
|
@@ -281,15 +260,12 @@ const Dashboard = () => {
|
|
|
281
260
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({ id: "payment-plugin.dashboard.successRate", defaultMessage: "Success Rate" }) }),
|
|
282
261
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 2, background: "success100", borderRadius: "50%", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowClockwise, { width: "1rem", height: "1rem" }) })
|
|
283
262
|
] }),
|
|
284
|
-
/* @__PURE__ */ jsxRuntime.
|
|
285
|
-
stats ? Math.round(stats.successfulPayments / stats.totalPayments * 100) : 0,
|
|
286
|
-
"%"
|
|
287
|
-
] }),
|
|
263
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", fontWeight: "bold", children: stats && stats.totalPayments > 0 ? `${Math.round(stats.successfulPayments / stats.totalPayments * 100)}%` : "0%" }),
|
|
288
264
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { variant: "success", children: "Good" })
|
|
289
265
|
] }) }) }),
|
|
290
266
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 3, s: 12, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { padding: 4, shadow: "tableShadow", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "start", gap: 2, children: [
|
|
291
267
|
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", width: "100%", children: [
|
|
292
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({ id: "payment-plugin.dashboard.averageOrderValue", defaultMessage: "
|
|
268
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({ id: "payment-plugin.dashboard.averageOrderValue", defaultMessage: "Avg. Order Value" }) }),
|
|
293
269
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 2, background: "warning100", borderRadius: "50%", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ChartPie, { width: "1rem", height: "1rem" }) })
|
|
294
270
|
] }),
|
|
295
271
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", fontWeight: "bold", children: formatCurrency(stats?.averageOrderValue || 0) }),
|
|
@@ -302,7 +278,7 @@ const Dashboard = () => {
|
|
|
302
278
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", tag: "h2", children: formatMessage({ id: "payment-plugin.dashboard.recentPayments", defaultMessage: "Recent Payments" }) }),
|
|
303
279
|
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Latest transactions from your customers" })
|
|
304
280
|
] }),
|
|
305
|
-
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", size: "S", children: formatMessage({ id: "payment-plugin.dashboard.
|
|
281
|
+
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", size: "S", onClick: fetchDashboardData, children: formatMessage({ id: "payment-plugin.dashboard.refresh", defaultMessage: "Refresh" }) })
|
|
306
282
|
] }),
|
|
307
283
|
/* @__PURE__ */ jsxRuntime.jsx(PaymentList.PaymentList, { payments: recentPayments, compact: true })
|
|
308
284
|
] }) })
|