@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
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-
|
|
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
|
-
|
|
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",
|
|
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,
|
|
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,
|
|
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,
|
|
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-
|
|
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
|
-
|
|
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",
|
|
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,
|
|
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,
|
|
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,
|
|
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-
|
|
8
|
-
const Dashboard = React.lazy(() => import("./Dashboard-
|
|
9
|
-
const Payments = React.lazy(() => import("./Payments-
|
|
10
|
-
const Orders = React.lazy(() => import("./Orders-
|
|
11
|
-
const Customers = React.lazy(() => import("./Customers-
|
|
12
|
-
const Analytics = React.lazy(() => import("./Analytics-
|
|
13
|
-
const Settings = React.lazy(() => import("./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-
|
|
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-
|
|
13
|
-
const Payments = React__default.default.lazy(() => Promise.resolve().then(() => require("./Payments-
|
|
14
|
-
const Orders = React__default.default.lazy(() => Promise.resolve().then(() => require("./Orders-
|
|
15
|
-
const Customers = React__default.default.lazy(() => Promise.resolve().then(() => require("./Customers-
|
|
16
|
-
const Analytics = React__default.default.lazy(() => Promise.resolve().then(() => require("./Analytics-
|
|
17
|
-
const Settings = React__default.default.lazy(() => Promise.resolve().then(() => require("./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-
|
|
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",
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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", "
|
|
208
|
-
...
|
|
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
|
|
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
|
-
|
|
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: "
|
|
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
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
{
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
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 {
|