@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.
Files changed (29) hide show
  1. package/README.md +21 -0
  2. package/dist/_chunks/{Analytics-CQmAVKsq.mjs → Analytics-CncK5kn-.mjs} +6 -7
  3. package/dist/_chunks/{Analytics-CLjtRWYA.js → Analytics-c8KBuG3k.js} +6 -7
  4. package/dist/_chunks/{App-DXN62SV6.mjs → App-B5AB8Omu.mjs} +7 -7
  5. package/dist/_chunks/{App-Dk7XtjNA.js → App-Cih9sWu1.js} +7 -7
  6. package/dist/_chunks/{Customers-BQzVBQDT.mjs → Customers-BVk2gx7w.mjs} +51 -118
  7. package/dist/_chunks/{Customers-BNDi4QBH.js → Customers-CZWOnN26.js} +50 -117
  8. package/dist/_chunks/{Dashboard-UUwohHZa.js → Dashboard-CEif4jQn.js} +60 -84
  9. package/dist/_chunks/{Dashboard-CuHC-dit.mjs → Dashboard-DAjD8Q_6.mjs} +60 -84
  10. package/dist/_chunks/{Orders-CitNCdWE.js → Orders-DZXb54VO.js} +73 -146
  11. package/dist/_chunks/{Orders-65mNfu2i.mjs → Orders-DdJqI1HB.mjs} +74 -147
  12. package/dist/_chunks/{PaymentList-B0CAzInT.mjs → PaymentList-3HWK7PMz.mjs} +14 -39
  13. package/dist/_chunks/{PaymentList-Dy1BAFoD.js → PaymentList-APfyYD1h.js} +14 -39
  14. package/dist/_chunks/{Payments-FnhoV_2B.mjs → Payments-DFL-Cwgy.mjs} +97 -103
  15. package/dist/_chunks/{Payments-TOnygGIW.js → Payments-VzDGbK4W.js} +96 -102
  16. package/dist/_chunks/{Settings-BJtDagUs.js → Settings-B1tR3WOm.js} +157 -161
  17. package/dist/_chunks/{Settings-EoLSuZLe.mjs → Settings-SALxClBu.mjs} +157 -161
  18. package/dist/_chunks/{index-2Zd_T7bD.mjs → index-CB6TMitx.mjs} +1 -1
  19. package/dist/_chunks/{index-CHEgJ7e5.js → index-D-fFikb8.js} +1 -1
  20. package/dist/admin/index.js +1 -1
  21. package/dist/admin/index.mjs +1 -1
  22. package/dist/server/index.js +17 -5
  23. package/dist/server/index.mjs +17 -5
  24. package/package.json +1 -1
  25. /package/dist/server/src/{types → services/types}/api.d.ts +0 -0
  26. /package/dist/server/src/{types → services/types}/customer.d.ts +0 -0
  27. /package/dist/server/src/{types → services/types}/index.d.ts +0 -0
  28. /package/dist/server/src/{types → services/types}/order.d.ts +0 -0
  29. /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-CHEgJ7e5.js");
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", backgroundColor: isActive ? "success" : "neutral", children: isActive ? "Active" : "Inactive" });
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
- designSystem.Typography,
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
- designSystem.Typography,
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 [pageSize, setPageSize] = React.useState(25);
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, pageSize, filters]);
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.pagination.total);
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 applyFilters = () => {
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 (e) {
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", "Status", "Registration Date"],
210
- ...filteredCustomers.map((customer) => [
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 / 100).toString(),
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
- title: "Error loading customers",
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: "Showing {start}-{end} of {total} customers" },
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
- CustomerList,
320
- {
321
- customers: paginatedCustomers,
322
- onCustomerClick: handleCustomerClick
323
- }
324
- ) }),
325
- totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 4, children: /* @__PURE__ */ jsxRuntime.jsx(
326
- designSystem.Pagination,
327
- {
328
- currentPage,
329
- pageCount: totalPages,
330
- onPageChange: setCurrentPage
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 PaymentList = require("./PaymentList-Dy1BAFoD.js");
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: data.data.summary.totalPayments,
31
- successfulPayments: data.data.summary.successfulPayments,
32
- pendingPayments: data.data.summary.totalPayments - data.data.summary.successfulPayments - data.data.summary.failedPayments,
33
- failedPayments: data.data.summary.failedPayments,
34
- totalCustomers: data.data.topCustomers.length,
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, 0, 0, 0.1)"
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.marginBottom = "1.5rem";
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
- const elementId = `payment-element-${Date.now()}`;
116
- paymentContainer.id = elementId;
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.display = "flex";
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
- try {
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
- alert(`Payment failed: ${result.error.message}`);
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 && result.paymentIntent.status === "succeeded") {
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
- console.error("Payment initialization error:", err);
219
- alert(err instanceof Error ? err.message : "An error occurred during payment initialization");
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
- title: "Error loading dashboard",
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.jsx(
252
- designSystem.Button,
253
- {
254
- onClick: createTestPayment,
255
- loading: creatingTest,
256
- variant: "secondary",
257
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
258
- children: formatMessage({ id: "payment-plugin.dashboard.initPayment", defaultMessage: "Initialize Sample Payment" })
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.jsxs(designSystem.Typography, { variant: "alpha", fontWeight: "bold", children: [
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: "AVO" }) }),
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.viewAll", defaultMessage: "View All" }) })
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
  ] }) })