@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
package/README.md CHANGED
@@ -139,6 +139,27 @@ export default () => ({
139
139
  });
140
140
  ```
141
141
 
142
+ ### Webhook Raw Body Support (CRITICAL)
143
+
144
+ For Stripe webhook signature verification to work, you **must** configure Strapi's body parser middleware to preserve the raw request body.
145
+
146
+ Update `config/middlewares.ts` in your Strapi project:
147
+
148
+ ```typescript
149
+ export default [
150
+ // ... other middlewares
151
+ {
152
+ name: 'strapi::body',
153
+ config: {
154
+ includeUnparsed: true,
155
+ },
156
+ },
157
+ // ... other middlewares
158
+ ];
159
+ ```
160
+
161
+ Without `includeUnparsed: true`, the webhook verification will fail with an error: "No signatures found matching the expected signature for payload".
162
+
142
163
  ## 🚀 Quick Start
143
164
 
144
165
  ### 1. Create a Payment Intent
@@ -4,7 +4,7 @@ import { Box, Typography, Flex, ProgressBar, Grid, Loader, EmptyStateLayout, But
4
4
  import { Download, ArrowClockwise, TrendUp, ChartPie, CheckCircle, User } from "@strapi/icons";
5
5
  import { useIntl } from "react-intl";
6
6
  import { useFetchClient } from "@strapi/strapi/admin";
7
- import { P as PLUGIN_ID } from "./index-2Zd_T7bD.mjs";
7
+ import { P as PLUGIN_ID } from "./index-CB6TMitx.mjs";
8
8
  const AnalyticsChart = ({ data, currency = "usd", type }) => {
9
9
  const formatCurrency = (amount) => {
10
10
  return new Intl.NumberFormat("en-US", {
@@ -225,8 +225,7 @@ const Analytics = () => {
225
225
  return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
226
226
  EmptyStateLayout,
227
227
  {
228
- title: "Error loading analytics",
229
- subtitle: error,
228
+ content: error,
230
229
  action: /* @__PURE__ */ jsx(Button, { onClick: fetchAnalyticsData, children: formatMessage({ id: "payment-plugin.analytics.retry", defaultMessage: "Retry" }) })
231
230
  }
232
231
  ) });
@@ -277,7 +276,7 @@ const Analytics = () => {
277
276
  /* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({ id: "payment-plugin.analytics.totalRevenue", defaultMessage: "Total Revenue" }) }),
278
277
  /* @__PURE__ */ jsx(Typography, { variant: "alpha", fontWeight: "bold", children: formatCurrency(analyticsData.revenue.total, currency) }),
279
278
  /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", children: [
280
- /* @__PURE__ */ jsx(Badge, { size: "S", backgroundColor: "success", children: /* @__PURE__ */ jsxs(Flex, { gap: 1, alignItems: "center", children: [
279
+ /* @__PURE__ */ jsx(Badge, { size: "S", variant: "success", children: /* @__PURE__ */ jsxs(Flex, { gap: 1, alignItems: "center", children: [
281
280
  /* @__PURE__ */ jsx(TrendUp, { width: "12px", height: "12px" }),
282
281
  analyticsData.revenue.growth,
283
282
  "%"
@@ -285,7 +284,7 @@ const Analytics = () => {
285
284
  /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "vs prev period" })
286
285
  ] })
287
286
  ] }),
288
- /* @__PURE__ */ jsx(Box, { padding: 2, backgroundColor: "primary100", borderRadius: "50%", children: /* @__PURE__ */ jsx(ChartPie, { width: "24px", height: "24px" }) })
287
+ /* @__PURE__ */ jsx(Box, { padding: 2, background: "primary100", borderRadius: "50%", children: /* @__PURE__ */ jsx(ChartPie, { width: "24px", height: "24px" }) })
289
288
  ] }) }) }) }),
290
289
  /* @__PURE__ */ jsx(Grid.Item, { col: 4, children: /* @__PURE__ */ jsx(Card, { style: { width: "100%", borderLeft: "4px solid #0F9D58" }, children: /* @__PURE__ */ jsx(Box, { padding: 5, children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "flex-start", children: [
291
290
  /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, alignItems: "flex-start", children: [
@@ -299,7 +298,7 @@ const Analytics = () => {
299
298
  { total: analyticsData.payments.total }
300
299
  ) })
301
300
  ] }),
302
- /* @__PURE__ */ jsx(Box, { padding: 2, backgroundColor: "success100", borderRadius: "50%", children: /* @__PURE__ */ jsx(CheckCircle, { width: "24px", height: "24px" }) })
301
+ /* @__PURE__ */ jsx(Box, { padding: 2, background: "success100", borderRadius: "50%", children: /* @__PURE__ */ jsx(CheckCircle, { width: "24px", height: "24px" }) })
303
302
  ] }) }) }) }),
304
303
  /* @__PURE__ */ jsx(Grid.Item, { col: 4, children: /* @__PURE__ */ jsx(Card, { style: { width: "100%", borderLeft: "4px solid #9C27B0" }, children: /* @__PURE__ */ jsx(Box, { padding: 5, children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "flex-start", children: [
305
304
  /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, alignItems: "flex-start", children: [
@@ -307,7 +306,7 @@ const Analytics = () => {
307
306
  /* @__PURE__ */ jsx(Typography, { variant: "alpha", fontWeight: "bold", children: formatCurrency(analyticsData.payments.averageAmount, currency) }),
308
307
  /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: "Per successful payment" })
309
308
  ] }),
310
- /* @__PURE__ */ jsx(Box, { padding: 2, backgroundColor: "secondary100", borderRadius: "50%", children: /* @__PURE__ */ jsx(User, { width: "24px", height: "24px" }) })
309
+ /* @__PURE__ */ jsx(Box, { padding: 2, background: "secondary100", borderRadius: "50%", children: /* @__PURE__ */ jsx(User, { width: "24px", height: "24px" }) })
311
310
  ] }) }) }) })
312
311
  ] }),
313
312
  /* @__PURE__ */ jsxs(Grid.Root, { gap: 4, marginBottom: 4, children: [
@@ -6,7 +6,7 @@ const designSystem = require("@strapi/design-system");
6
6
  const icons = require("@strapi/icons");
7
7
  const reactIntl = require("react-intl");
8
8
  const admin = require("@strapi/strapi/admin");
9
- const index = require("./index-CHEgJ7e5.js");
9
+ const index = require("./index-D-fFikb8.js");
10
10
  const AnalyticsChart = ({ data, currency = "usd", type }) => {
11
11
  const formatCurrency = (amount) => {
12
12
  return new Intl.NumberFormat("en-US", {
@@ -227,8 +227,7 @@ const Analytics = () => {
227
227
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsx(
228
228
  designSystem.EmptyStateLayout,
229
229
  {
230
- title: "Error loading analytics",
231
- subtitle: error,
230
+ content: error,
232
231
  action: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: fetchAnalyticsData, children: formatMessage({ id: "payment-plugin.analytics.retry", defaultMessage: "Retry" }) })
233
232
  }
234
233
  ) });
@@ -279,7 +278,7 @@ const Analytics = () => {
279
278
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", textColor: "neutral600", textTransform: "uppercase", children: formatMessage({ id: "payment-plugin.analytics.totalRevenue", defaultMessage: "Total Revenue" }) }),
280
279
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", fontWeight: "bold", children: formatCurrency(analyticsData.revenue.total, currency) }),
281
280
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "center", children: [
282
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { size: "S", backgroundColor: "success", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, alignItems: "center", children: [
281
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { size: "S", variant: "success", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, alignItems: "center", children: [
283
282
  /* @__PURE__ */ jsxRuntime.jsx(icons.TrendUp, { width: "12px", height: "12px" }),
284
283
  analyticsData.revenue.growth,
285
284
  "%"
@@ -287,7 +286,7 @@ const Analytics = () => {
287
286
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "vs prev period" })
288
287
  ] })
289
288
  ] }),
290
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 2, backgroundColor: "primary100", borderRadius: "50%", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ChartPie, { width: "24px", height: "24px" }) })
289
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 2, background: "primary100", borderRadius: "50%", children: /* @__PURE__ */ jsxRuntime.jsx(icons.ChartPie, { width: "24px", height: "24px" }) })
291
290
  ] }) }) }) }),
292
291
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { style: { width: "100%", borderLeft: "4px solid #0F9D58" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 5, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "flex-start", children: [
293
292
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, alignItems: "flex-start", children: [
@@ -301,7 +300,7 @@ const Analytics = () => {
301
300
  { total: analyticsData.payments.total }
302
301
  ) })
303
302
  ] }),
304
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 2, backgroundColor: "success100", borderRadius: "50%", children: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { width: "24px", height: "24px" }) })
303
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 2, background: "success100", borderRadius: "50%", children: /* @__PURE__ */ jsxRuntime.jsx(icons.CheckCircle, { width: "24px", height: "24px" }) })
305
304
  ] }) }) }) }),
306
305
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { style: { width: "100%", borderLeft: "4px solid #9C27B0" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 5, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "flex-start", children: [
307
306
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 2, alignItems: "flex-start", children: [
@@ -309,7 +308,7 @@ const Analytics = () => {
309
308
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", fontWeight: "bold", children: formatCurrency(analyticsData.payments.averageAmount, currency) }),
310
309
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Per successful payment" })
311
310
  ] }),
312
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 2, backgroundColor: "secondary100", borderRadius: "50%", children: /* @__PURE__ */ jsxRuntime.jsx(icons.User, { width: "24px", height: "24px" }) })
311
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 2, background: "secondary100", borderRadius: "50%", children: /* @__PURE__ */ jsxRuntime.jsx(icons.User, { width: "24px", height: "24px" }) })
313
312
  ] }) }) }) })
314
313
  ] }),
315
314
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, marginBottom: 4, children: [
@@ -4,13 +4,13 @@ import { Routes, Route, Navigate } from "react-router-dom";
4
4
  import { useIntl } from "react-intl";
5
5
  import { Flex, Divider, Box, Searchbar, Loader } from "@strapi/design-system";
6
6
  import { SubNav } from "@strapi/strapi/admin";
7
- import { P as PLUGIN_ID } from "./index-2Zd_T7bD.mjs";
8
- const Dashboard = React.lazy(() => import("./Dashboard-CuHC-dit.mjs").then((m) => ({ default: m.Dashboard })));
9
- const Payments = React.lazy(() => import("./Payments-FnhoV_2B.mjs").then((m) => ({ default: m.Payments })));
10
- const Orders = React.lazy(() => import("./Orders-65mNfu2i.mjs").then((m) => ({ default: m.Orders })));
11
- const Customers = React.lazy(() => import("./Customers-BQzVBQDT.mjs").then((m) => ({ default: m.Customers })));
12
- const Analytics = React.lazy(() => import("./Analytics-CQmAVKsq.mjs").then((m) => ({ default: m.Analytics })));
13
- const Settings = React.lazy(() => import("./Settings-EoLSuZLe.mjs").then((m) => ({ default: m.Settings })));
7
+ import { P as PLUGIN_ID } from "./index-CB6TMitx.mjs";
8
+ const Dashboard = React.lazy(() => import("./Dashboard-DAjD8Q_6.mjs").then((m) => ({ default: m.Dashboard })));
9
+ const Payments = React.lazy(() => import("./Payments-DFL-Cwgy.mjs").then((m) => ({ default: m.Payments })));
10
+ const Orders = React.lazy(() => import("./Orders-DdJqI1HB.mjs").then((m) => ({ default: m.Orders })));
11
+ const Customers = React.lazy(() => import("./Customers-BVk2gx7w.mjs").then((m) => ({ default: m.Customers })));
12
+ const Analytics = React.lazy(() => import("./Analytics-CncK5kn-.mjs").then((m) => ({ default: m.Analytics })));
13
+ const Settings = React.lazy(() => import("./Settings-SALxClBu.mjs").then((m) => ({ default: m.Settings })));
14
14
  const App = () => {
15
15
  const { formatMessage } = useIntl();
16
16
  const [searchValue, setSearchValue] = useState("");
@@ -6,15 +6,15 @@ const reactRouterDom = require("react-router-dom");
6
6
  const reactIntl = require("react-intl");
7
7
  const designSystem = require("@strapi/design-system");
8
8
  const admin = require("@strapi/strapi/admin");
9
- const index = require("./index-CHEgJ7e5.js");
9
+ const index = require("./index-D-fFikb8.js");
10
10
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
11
11
  const React__default = /* @__PURE__ */ _interopDefault(React);
12
- const Dashboard = React__default.default.lazy(() => Promise.resolve().then(() => require("./Dashboard-UUwohHZa.js")).then((m) => ({ default: m.Dashboard })));
13
- const Payments = React__default.default.lazy(() => Promise.resolve().then(() => require("./Payments-TOnygGIW.js")).then((m) => ({ default: m.Payments })));
14
- const Orders = React__default.default.lazy(() => Promise.resolve().then(() => require("./Orders-CitNCdWE.js")).then((m) => ({ default: m.Orders })));
15
- const Customers = React__default.default.lazy(() => Promise.resolve().then(() => require("./Customers-BNDi4QBH.js")).then((m) => ({ default: m.Customers })));
16
- const Analytics = React__default.default.lazy(() => Promise.resolve().then(() => require("./Analytics-CLjtRWYA.js")).then((m) => ({ default: m.Analytics })));
17
- const Settings = React__default.default.lazy(() => Promise.resolve().then(() => require("./Settings-BJtDagUs.js")).then((m) => ({ default: m.Settings })));
12
+ const Dashboard = React__default.default.lazy(() => Promise.resolve().then(() => require("./Dashboard-CEif4jQn.js")).then((m) => ({ default: m.Dashboard })));
13
+ const Payments = React__default.default.lazy(() => Promise.resolve().then(() => require("./Payments-VzDGbK4W.js")).then((m) => ({ default: m.Payments })));
14
+ const Orders = React__default.default.lazy(() => Promise.resolve().then(() => require("./Orders-DZXb54VO.js")).then((m) => ({ default: m.Orders })));
15
+ const Customers = React__default.default.lazy(() => Promise.resolve().then(() => require("./Customers-CZWOnN26.js")).then((m) => ({ default: m.Customers })));
16
+ const Analytics = React__default.default.lazy(() => Promise.resolve().then(() => require("./Analytics-c8KBuG3k.js")).then((m) => ({ default: m.Analytics })));
17
+ const Settings = React__default.default.lazy(() => Promise.resolve().then(() => require("./Settings-B1tR3WOm.js")).then((m) => ({ default: m.Settings })));
18
18
  const App = () => {
19
19
  const { formatMessage } = reactIntl.useIntl();
20
20
  const [searchValue, setSearchValue] = React.useState("");
@@ -1,9 +1,9 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useState, useEffect } from "react";
3
- import { Box, Typography, Table, Thead, Tr, Th, Tbody, Td, Flex, Badge, Loader, EmptyStateLayout, Button, Card, Grid, TextInput, SingleSelect, SingleSelectOption, Pagination } from "@strapi/design-system";
3
+ import { Box, Typography, Table, Thead, Tr, Th, Tbody, Td, Flex, Badge, Loader, EmptyStateLayout, Button, Card, Grid, TextInput, SingleSelect, SingleSelectOption, Pagination, PreviousLink, PageLink, NextLink } from "@strapi/design-system";
4
4
  import { useIntl } from "react-intl";
5
5
  import { useFetchClient } from "@strapi/strapi/admin";
6
- import { P as PLUGIN_ID } from "./index-2Zd_T7bD.mjs";
6
+ import { P as PLUGIN_ID } from "./index-CB6TMitx.mjs";
7
7
  const CustomerList = ({ customers, onCustomerClick, compact = false }) => {
8
8
  const { formatMessage } = useIntl();
9
9
  const formatCurrency = (amount, currency = "usd") => {
@@ -20,7 +20,7 @@ const CustomerList = ({ customers, onCustomerClick, compact = false }) => {
20
20
  });
21
21
  };
22
22
  const getCustomerStatusBadge = (isActive) => {
23
- return /* @__PURE__ */ jsx(Badge, { size: compact ? "S" : "M", backgroundColor: isActive ? "success" : "neutral", children: isActive ? "Active" : "Inactive" });
23
+ return /* @__PURE__ */ jsx(Badge, { size: compact ? "S" : "M", variant: isActive ? "success" : "neutral", children: isActive ? "Active" : "Inactive" });
24
24
  };
25
25
  const getCustomerName = (customer) => {
26
26
  if (customer.first_name && customer.last_name) {
@@ -51,43 +51,13 @@ const CustomerList = ({ customers, onCustomerClick, compact = false }) => {
51
51
  style: { cursor: onCustomerClick ? "pointer" : "default" },
52
52
  children: [
53
53
  /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 1, children: [
54
- /* @__PURE__ */ jsx(
55
- Typography,
56
- {
57
- textColor: "neutral800",
58
- fontWeight: compact ? "normal" : "bold",
59
- fontSize: compact ? "0.875rem" : "1rem",
60
- children: getCustomerName(customer)
61
- }
62
- ),
63
- /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", fontFamily: "monospace", fontSize: "0.75rem", children: customer.stripe_customer_id }),
54
+ /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", fontWeight: compact ? "normal" : "bold", children: getCustomerName(customer) }),
55
+ /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", fontFamily: "monospace", children: customer.stripe_customer_id }),
64
56
  !compact && /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", variant: "epsilon", children: customer.email })
65
57
  ] }) }),
66
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
67
- Typography,
68
- {
69
- textColor: "neutral800",
70
- fontWeight: "bold",
71
- fontSize: compact ? "0.875rem" : "1rem",
72
- children: formatCurrency(customer.totalSpent, customer.currency)
73
- }
74
- ) }),
75
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
76
- Typography,
77
- {
78
- textColor: "neutral600",
79
- fontSize: compact ? "0.75rem" : "0.875rem",
80
- children: customer.paymentCount
81
- }
82
- ) }),
83
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
84
- Typography,
85
- {
86
- textColor: "neutral600",
87
- fontSize: compact ? "0.75rem" : "0.875rem",
88
- children: customer.lastPaymentDate ? formatDate(customer.lastPaymentDate) : "Never"
89
- }
90
- ) }),
58
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", fontWeight: "bold", children: formatCurrency(customer.totalSpent, customer.currency) }) }),
59
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: customer.paymentCount }) }),
60
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", children: customer.lastPaymentDate ? formatDate(customer.lastPaymentDate) : "Never" }) }),
91
61
  /* @__PURE__ */ jsx(Td, { children: getCustomerStatusBadge(customer.isActive) })
92
62
  ]
93
63
  },
@@ -99,24 +69,19 @@ const Customers = () => {
99
69
  const { formatMessage } = useIntl();
100
70
  const { get } = useFetchClient();
101
71
  const [customers, setCustomers] = useState([]);
102
- const [filteredCustomers, setFilteredCustomers] = useState([]);
103
72
  const [loading, setLoading] = useState(true);
104
73
  const [error, setError] = useState(null);
105
74
  const [currentPage, setCurrentPage] = useState(1);
106
- const [pageSize, setPageSize] = useState(25);
75
+ const pageSize = 25;
107
76
  const [totalCount, setTotalCount] = useState(0);
108
77
  const [filters, setFilters] = useState({
109
78
  search: "",
110
79
  country: "",
111
- isActive: "",
112
- registrationDateRange: { from: null, to: null }
80
+ isActive: ""
113
81
  });
114
82
  useEffect(() => {
115
83
  fetchCustomers();
116
- }, [currentPage, pageSize, filters]);
117
- useEffect(() => {
118
- applyFilters();
119
- }, [customers, filters]);
84
+ }, [currentPage, filters]);
120
85
  const fetchCustomers = async () => {
121
86
  try {
122
87
  setLoading(true);
@@ -138,7 +103,7 @@ const Customers = () => {
138
103
  tags: []
139
104
  }));
140
105
  setCustomers(formattedCustomers);
141
- setTotalCount(data.meta.pagination.total);
106
+ setTotalCount(data.meta?.pagination?.total || 0);
142
107
  }
143
108
  setLoading(false);
144
109
  } catch (err) {
@@ -146,38 +111,7 @@ const Customers = () => {
146
111
  setLoading(false);
147
112
  }
148
113
  };
149
- const applyFilters = () => {
150
- let filtered = [...customers];
151
- if (filters.search) {
152
- const searchLower = filters.search.toLowerCase();
153
- filtered = filtered.filter(
154
- (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)
155
- );
156
- }
157
- if (filters.isActive) {
158
- const isActive = filters.isActive === "active";
159
- filtered = filtered.filter((customer) => customer.isActive === isActive);
160
- }
161
- if (filters.country) {
162
- filtered = filtered.filter(
163
- (customer) => customer.address?.country === filters.country
164
- );
165
- }
166
- if (filters.registrationDateRange.from) {
167
- filtered = filtered.filter(
168
- (customer) => new Date(customer.registrationDate) >= filters.registrationDateRange.from
169
- );
170
- }
171
- if (filters.registrationDateRange.to) {
172
- filtered = filtered.filter(
173
- (customer) => new Date(customer.registrationDate) <= filters.registrationDateRange.to
174
- );
175
- }
176
- setFilteredCustomers(filtered);
177
- };
178
- const handleCustomerClick = (customer) => {
179
- console.log("Clicked customer:", customer);
180
- };
114
+ const totalPages = Math.max(1, Math.ceil(totalCount / pageSize));
181
115
  const formatDate = (dateString) => {
182
116
  try {
183
117
  return new Date(dateString).toLocaleDateString("en-US", {
@@ -185,7 +119,7 @@ const Customers = () => {
185
119
  month: "short",
186
120
  day: "numeric"
187
121
  });
188
- } catch (e) {
122
+ } catch {
189
123
  return "Invalid Date";
190
124
  }
191
125
  };
@@ -194,26 +128,20 @@ const Customers = () => {
194
128
  setCurrentPage(1);
195
129
  };
196
130
  const clearFilters = () => {
197
- setFilters({
198
- search: "",
199
- country: "",
200
- isActive: "",
201
- registrationDateRange: { from: null, to: null }
202
- });
131
+ setFilters({ search: "", country: "", isActive: "" });
203
132
  setCurrentPage(1);
204
133
  };
205
134
  const exportCustomers = () => {
206
135
  const csvContent = [
207
- ["Customer ID", "Email", "First Name", "Last Name", "Total Spent", "Payment Count", "Last Payment", "Status", "Registration Date"],
208
- ...filteredCustomers.map((customer) => [
136
+ ["Customer ID", "Email", "First Name", "Last Name", "Total Spent", "Payment Count", "Last Payment", "Registration Date"],
137
+ ...customers.map((customer) => [
209
138
  customer.stripe_customer_id || "",
210
139
  customer.email,
211
140
  customer.first_name || "",
212
141
  customer.last_name || "",
213
- (customer.totalSpent || 0 / 100).toString(),
142
+ (customer.totalSpent || 0).toString(),
214
143
  (customer.paymentCount || 0).toString(),
215
144
  customer.lastPaymentDate ? formatDate(customer.lastPaymentDate) : "Never",
216
- customer.isActive ? "Active" : "Inactive",
217
145
  customer.registrationDate ? formatDate(customer.registrationDate) : ""
218
146
  ])
219
147
  ].map((row) => row.join(",")).join("\n");
@@ -225,10 +153,6 @@ const Customers = () => {
225
153
  a.click();
226
154
  window.URL.revokeObjectURL(url);
227
155
  };
228
- const startIndex = (currentPage - 1) * pageSize;
229
- const endIndex = startIndex + pageSize;
230
- const paginatedCustomers = filteredCustomers.slice(startIndex, endIndex);
231
- const totalPages = Math.ceil(filteredCustomers.length / pageSize);
232
156
  if (loading && customers.length === 0) {
233
157
  return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", alignItems: "center", style: { minHeight: "400px" }, children: /* @__PURE__ */ jsx(Loader, {}) }) });
234
158
  }
@@ -236,8 +160,7 @@ const Customers = () => {
236
160
  return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(
237
161
  EmptyStateLayout,
238
162
  {
239
- title: "Error loading customers",
240
- subtitle: error,
163
+ content: error,
241
164
  action: /* @__PURE__ */ jsx(Button, { onClick: fetchCustomers, children: formatMessage({ id: "payment-plugin.customers.retry", defaultMessage: "Retry" }) })
242
165
  }
243
166
  ) });
@@ -260,6 +183,7 @@ const Customers = () => {
260
183
  /* @__PURE__ */ jsx(Grid.Item, { col: 4, children: /* @__PURE__ */ jsx(
261
184
  TextInput,
262
185
  {
186
+ label: formatMessage({ id: "payment-plugin.customers.search.label", defaultMessage: "Search" }),
263
187
  placeholder: formatMessage({
264
188
  id: "payment-plugin.customers.search.placeholder",
265
189
  defaultMessage: "Search customers..."
@@ -271,6 +195,7 @@ const Customers = () => {
271
195
  /* @__PURE__ */ jsx(Grid.Item, { col: 2, children: /* @__PURE__ */ jsxs(
272
196
  SingleSelect,
273
197
  {
198
+ label: formatMessage({ id: "payment-plugin.customers.status.label", defaultMessage: "Status" }),
274
199
  placeholder: formatMessage({
275
200
  id: "payment-plugin.customers.status.placeholder",
276
201
  defaultMessage: "All Statuses"
@@ -287,6 +212,7 @@ const Customers = () => {
287
212
  /* @__PURE__ */ jsx(Grid.Item, { col: 2, children: /* @__PURE__ */ jsxs(
288
213
  SingleSelect,
289
214
  {
215
+ label: formatMessage({ id: "payment-plugin.customers.country.label", defaultMessage: "Country" }),
290
216
  placeholder: formatMessage({
291
217
  id: "payment-plugin.customers.country.placeholder",
292
218
  defaultMessage: "All Countries"
@@ -303,31 +229,38 @@ const Customers = () => {
303
229
  ]
304
230
  }
305
231
  ) }),
306
- /* @__PURE__ */ jsx(Grid.Item, { col: 4, children: /* @__PURE__ */ jsx(Flex, { gap: 2, children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", onClick: clearFilters, children: formatMessage({ id: "payment-plugin.customers.clearFilters", defaultMessage: "Clear" }) }) }) })
232
+ /* @__PURE__ */ jsx(Grid.Item, { col: 4, children: /* @__PURE__ */ jsx(Flex, { gap: 2, alignItems: "flex-end", height: "100%", children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", onClick: clearFilters, children: formatMessage({ id: "payment-plugin.customers.clearFilters", defaultMessage: "Clear" }) }) }) })
307
233
  ] }) }) }),
308
234
  /* @__PURE__ */ jsx(Box, { marginTop: 4, marginBottom: 2, children: /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral600", children: formatMessage(
309
- { id: "payment-plugin.customers.results", defaultMessage: "Showing {start}-{end} of {total} customers" },
310
- {
311
- start: startIndex + 1,
312
- end: Math.min(endIndex, filteredCustomers.length),
313
- total: filteredCustomers.length
314
- }
235
+ { id: "payment-plugin.customers.results", defaultMessage: "{total} customers" },
236
+ { total: totalCount }
315
237
  ) }) }),
316
- /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(
317
- CustomerList,
318
- {
319
- customers: paginatedCustomers,
320
- onCustomerClick: handleCustomerClick
321
- }
322
- ) }),
323
- totalPages > 1 && /* @__PURE__ */ jsx(Box, { marginTop: 4, children: /* @__PURE__ */ jsx(
324
- Pagination,
325
- {
326
- currentPage,
327
- pageCount: totalPages,
328
- onPageChange: setCurrentPage
329
- }
330
- ) })
238
+ /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsx(CustomerList, { customers }) }),
239
+ totalPages > 1 && /* @__PURE__ */ jsx(Box, { marginTop: 4, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxs(Pagination, { activePage: currentPage, pageCount: totalPages, label: "Customers pagination", children: [
240
+ /* @__PURE__ */ jsx(
241
+ PreviousLink,
242
+ {
243
+ as: "button",
244
+ onClick: () => setCurrentPage((p) => Math.max(1, p - 1))
245
+ }
246
+ ),
247
+ Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => /* @__PURE__ */ jsx(
248
+ PageLink,
249
+ {
250
+ number: page,
251
+ as: "button",
252
+ onClick: () => setCurrentPage(page)
253
+ },
254
+ page
255
+ )),
256
+ /* @__PURE__ */ jsx(
257
+ NextLink,
258
+ {
259
+ as: "button",
260
+ onClick: () => setCurrentPage((p) => Math.min(totalPages, p + 1))
261
+ }
262
+ )
263
+ ] }) }) })
331
264
  ] });
332
265
  };
333
266
  export {