@reeboot/strapi-payment-plugin 0.0.9 → 0.0.10

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 (36) hide show
  1. package/dist/_chunks/{Analytics-kChERzX4.mjs → Analytics-CPXtqS6s.mjs} +1 -1
  2. package/dist/_chunks/{Analytics-DjXqUZy1.js → Analytics-ZpHHWBQt.js} +1 -1
  3. package/dist/_chunks/{App-D5x-l0Sz.mjs → App-CZNZ1JKf.mjs} +13 -7
  4. package/dist/_chunks/{App-BpwS5-wg.js → App-CsbyykNC.js} +13 -7
  5. package/dist/_chunks/{Customers-ChrS373z.js → Customers-D4RVSZ_m.js} +1 -1
  6. package/dist/_chunks/{Customers-BYQZcZeb.mjs → Customers-DMDEBpH9.mjs} +1 -1
  7. package/dist/_chunks/{Dashboard-DUWxJQ7q.mjs → Dashboard-D-ckyWDO.mjs} +1 -1
  8. package/dist/_chunks/{Dashboard-DANhyMZK.js → Dashboard-NNqGJmYw.js} +1 -1
  9. package/dist/_chunks/{Orders-BXyc3CTW.js → Orders-BELfgToU.js} +1 -1
  10. package/dist/_chunks/{Orders-B3GZULs3.mjs → Orders-BIkRttRZ.mjs} +1 -1
  11. package/dist/_chunks/{Payments-DmAzroEv.js → Payments-CIEb4f07.js} +1 -1
  12. package/dist/_chunks/{Payments-DL6hne_y.mjs → Payments-CKlL-PCV.mjs} +1 -1
  13. package/dist/_chunks/{Settings-Ck1G0iaS.mjs → Settings-BQXkYm-c.mjs} +1 -1
  14. package/dist/_chunks/{Settings-CMEzIMqt.js → Settings-CcY98Hyw.js} +1 -1
  15. package/dist/_chunks/Subscriptions--cI3HC2x.js +178 -0
  16. package/dist/_chunks/Subscriptions-Dq8Uk7sK.mjs +178 -0
  17. package/dist/_chunks/{index-Bo7VLX9i.mjs → index-BBarHYyt.mjs} +1 -1
  18. package/dist/_chunks/{index-Cmn7Tfmf.js → index-DBZ4rcUW.js} +1 -1
  19. package/dist/admin/index.js +1 -1
  20. package/dist/admin/index.mjs +1 -1
  21. package/dist/admin/src/index.d.ts +22 -1
  22. package/dist/admin/src/pages/Subscriptions.d.ts +2 -0
  23. package/dist/admin/src/types/index.d.ts +20 -0
  24. package/dist/server/index.js +618 -46
  25. package/dist/server/index.mjs +618 -46
  26. package/dist/server/src/content-types/customer/index.d.ts +6 -0
  27. package/dist/server/src/content-types/index.d.ts +89 -0
  28. package/dist/server/src/content-types/subscription/index.d.ts +84 -0
  29. package/dist/server/src/controllers/index.d.ts +7 -0
  30. package/dist/server/src/controllers/stripe.d.ts +34 -2
  31. package/dist/server/src/index.d.ts +99 -6
  32. package/dist/server/src/middlewares/index.d.ts +3 -3
  33. package/dist/server/src/services/stripe.d.ts +49 -10
  34. package/dist/server/src/services/types/api.d.ts +24 -5
  35. package/dist/server/src/types/plugin-config.d.ts +360 -0
  36. package/package.json +1 -1
@@ -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-Bo7VLX9i.mjs";
7
+ import { P as PLUGIN_ID } from "./index-BBarHYyt.mjs";
8
8
  const AnalyticsChart = ({ data, currency = "usd", type }) => {
9
9
  const formatCurrency = (amount) => {
10
10
  return new Intl.NumberFormat("en-US", {
@@ -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-Cmn7Tfmf.js");
9
+ const index = require("./index-DBZ4rcUW.js");
10
10
  const AnalyticsChart = ({ data, currency = "usd", type }) => {
11
11
  const formatCurrency = (amount) => {
12
12
  return new Intl.NumberFormat("en-US", {
@@ -4,13 +4,14 @@ 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-Bo7VLX9i.mjs";
8
- const Dashboard = React.lazy(() => import("./Dashboard-DUWxJQ7q.mjs").then((m) => ({ default: m.Dashboard })));
9
- const Payments = React.lazy(() => import("./Payments-DL6hne_y.mjs").then((m) => ({ default: m.Payments })));
10
- const Orders = React.lazy(() => import("./Orders-B3GZULs3.mjs").then((m) => ({ default: m.Orders })));
11
- const Customers = React.lazy(() => import("./Customers-BYQZcZeb.mjs").then((m) => ({ default: m.Customers })));
12
- const Analytics = React.lazy(() => import("./Analytics-kChERzX4.mjs").then((m) => ({ default: m.Analytics })));
13
- const Settings = React.lazy(() => import("./Settings-Ck1G0iaS.mjs").then((m) => ({ default: m.Settings })));
7
+ import { P as PLUGIN_ID } from "./index-BBarHYyt.mjs";
8
+ const Dashboard = React.lazy(() => import("./Dashboard-D-ckyWDO.mjs").then((m) => ({ default: m.Dashboard })));
9
+ const Payments = React.lazy(() => import("./Payments-CKlL-PCV.mjs").then((m) => ({ default: m.Payments })));
10
+ const Orders = React.lazy(() => import("./Orders-BIkRttRZ.mjs").then((m) => ({ default: m.Orders })));
11
+ const Customers = React.lazy(() => import("./Customers-DMDEBpH9.mjs").then((m) => ({ default: m.Customers })));
12
+ const Analytics = React.lazy(() => import("./Analytics-CPXtqS6s.mjs").then((m) => ({ default: m.Analytics })));
13
+ const Subscriptions = React.lazy(() => import("./Subscriptions-Dq8Uk7sK.mjs").then((m) => ({ default: m.Subscriptions })));
14
+ const Settings = React.lazy(() => import("./Settings-BQXkYm-c.mjs").then((m) => ({ default: m.Settings })));
14
15
  const App = () => {
15
16
  const { formatMessage } = useIntl();
16
17
  const [searchValue, setSearchValue] = useState("");
@@ -23,6 +24,10 @@ const App = () => {
23
24
  to: `/plugins/${PLUGIN_ID}/payments`,
24
25
  label: formatMessage({ id: "payment-plugin.payments.title", defaultMessage: "Payments" })
25
26
  },
27
+ {
28
+ to: `/plugins/${PLUGIN_ID}/subscriptions`,
29
+ label: formatMessage({ id: "payment-plugin.subscriptions.title", defaultMessage: "Subscriptions" })
30
+ },
26
31
  {
27
32
  to: `/plugins/${PLUGIN_ID}/orders`,
28
33
  label: formatMessage({ id: "payment-plugin.orders.title", defaultMessage: "Orders" })
@@ -107,6 +112,7 @@ const App = () => {
107
112
  /* @__PURE__ */ jsx(Route, { path: "payments", element: /* @__PURE__ */ jsx(Payments, {}) }),
108
113
  /* @__PURE__ */ jsx(Route, { path: "orders", element: /* @__PURE__ */ jsx(Orders, {}) }),
109
114
  /* @__PURE__ */ jsx(Route, { path: "customers", element: /* @__PURE__ */ jsx(Customers, {}) }),
115
+ /* @__PURE__ */ jsx(Route, { path: "subscriptions", element: /* @__PURE__ */ jsx(Subscriptions, {}) }),
110
116
  /* @__PURE__ */ jsx(Route, { path: "analytics", element: /* @__PURE__ */ jsx(Analytics, {}) }),
111
117
  /* @__PURE__ */ jsx(Route, { path: "settings", element: /* @__PURE__ */ jsx(Settings, {}) }),
112
118
  /* @__PURE__ */ jsx(Route, { path: "*", element: /* @__PURE__ */ jsx(Navigate, { to: "dashboard", replace: true }) })
@@ -6,15 +6,16 @@ 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-Cmn7Tfmf.js");
9
+ const index = require("./index-DBZ4rcUW.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-DANhyMZK.js")).then((m) => ({ default: m.Dashboard })));
13
- const Payments = React__default.default.lazy(() => Promise.resolve().then(() => require("./Payments-DmAzroEv.js")).then((m) => ({ default: m.Payments })));
14
- const Orders = React__default.default.lazy(() => Promise.resolve().then(() => require("./Orders-BXyc3CTW.js")).then((m) => ({ default: m.Orders })));
15
- const Customers = React__default.default.lazy(() => Promise.resolve().then(() => require("./Customers-ChrS373z.js")).then((m) => ({ default: m.Customers })));
16
- const Analytics = React__default.default.lazy(() => Promise.resolve().then(() => require("./Analytics-DjXqUZy1.js")).then((m) => ({ default: m.Analytics })));
17
- const Settings = React__default.default.lazy(() => Promise.resolve().then(() => require("./Settings-CMEzIMqt.js")).then((m) => ({ default: m.Settings })));
12
+ const Dashboard = React__default.default.lazy(() => Promise.resolve().then(() => require("./Dashboard-NNqGJmYw.js")).then((m) => ({ default: m.Dashboard })));
13
+ const Payments = React__default.default.lazy(() => Promise.resolve().then(() => require("./Payments-CIEb4f07.js")).then((m) => ({ default: m.Payments })));
14
+ const Orders = React__default.default.lazy(() => Promise.resolve().then(() => require("./Orders-BELfgToU.js")).then((m) => ({ default: m.Orders })));
15
+ const Customers = React__default.default.lazy(() => Promise.resolve().then(() => require("./Customers-D4RVSZ_m.js")).then((m) => ({ default: m.Customers })));
16
+ const Analytics = React__default.default.lazy(() => Promise.resolve().then(() => require("./Analytics-ZpHHWBQt.js")).then((m) => ({ default: m.Analytics })));
17
+ const Subscriptions = React__default.default.lazy(() => Promise.resolve().then(() => require("./Subscriptions--cI3HC2x.js")).then((m) => ({ default: m.Subscriptions })));
18
+ const Settings = React__default.default.lazy(() => Promise.resolve().then(() => require("./Settings-CcY98Hyw.js")).then((m) => ({ default: m.Settings })));
18
19
  const App = () => {
19
20
  const { formatMessage } = reactIntl.useIntl();
20
21
  const [searchValue, setSearchValue] = React.useState("");
@@ -27,6 +28,10 @@ const App = () => {
27
28
  to: `/plugins/${index.PLUGIN_ID}/payments`,
28
29
  label: formatMessage({ id: "payment-plugin.payments.title", defaultMessage: "Payments" })
29
30
  },
31
+ {
32
+ to: `/plugins/${index.PLUGIN_ID}/subscriptions`,
33
+ label: formatMessage({ id: "payment-plugin.subscriptions.title", defaultMessage: "Subscriptions" })
34
+ },
30
35
  {
31
36
  to: `/plugins/${index.PLUGIN_ID}/orders`,
32
37
  label: formatMessage({ id: "payment-plugin.orders.title", defaultMessage: "Orders" })
@@ -111,6 +116,7 @@ const App = () => {
111
116
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "payments", element: /* @__PURE__ */ jsxRuntime.jsx(Payments, {}) }),
112
117
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "orders", element: /* @__PURE__ */ jsxRuntime.jsx(Orders, {}) }),
113
118
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "customers", element: /* @__PURE__ */ jsxRuntime.jsx(Customers, {}) }),
119
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "subscriptions", element: /* @__PURE__ */ jsxRuntime.jsx(Subscriptions, {}) }),
114
120
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "analytics", element: /* @__PURE__ */ jsxRuntime.jsx(Analytics, {}) }),
115
121
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "settings", element: /* @__PURE__ */ jsxRuntime.jsx(Settings, {}) }),
116
122
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "*", element: /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Navigate, { to: "dashboard", replace: true }) })
@@ -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-Cmn7Tfmf.js");
8
+ const index = require("./index-DBZ4rcUW.js");
9
9
  const CustomerList = ({ customers, onCustomerClick, compact = false }) => {
10
10
  const { formatMessage } = reactIntl.useIntl();
11
11
  const formatCurrency = (amount, currency = "usd") => {
@@ -3,7 +3,7 @@ import { useState, useEffect } from "react";
3
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-Bo7VLX9i.mjs";
6
+ import { P as PLUGIN_ID } from "./index-BBarHYyt.mjs";
7
7
  const CustomerList = ({ customers, onCustomerClick, compact = false }) => {
8
8
  const { formatMessage } = useIntl();
9
9
  const formatCurrency = (amount, currency = "usd") => {
@@ -5,7 +5,7 @@ import { Plus, PriceTag, ShoppingCart, ArrowClockwise, ChartPie } from "@strapi/
5
5
  import { useFetchClient } from "@strapi/strapi/admin";
6
6
  import { useIntl } from "react-intl";
7
7
  import { loadStripe } from "@stripe/stripe-js";
8
- import { P as PLUGIN_ID } from "./index-Bo7VLX9i.mjs";
8
+ import { P as PLUGIN_ID } from "./index-BBarHYyt.mjs";
9
9
  import { P as PaymentList } from "./PaymentList-3HWK7PMz.mjs";
10
10
  const Dashboard = () => {
11
11
  const { formatMessage } = useIntl();
@@ -7,7 +7,7 @@ const icons = require("@strapi/icons");
7
7
  const admin = require("@strapi/strapi/admin");
8
8
  const reactIntl = require("react-intl");
9
9
  const stripeJs = require("@stripe/stripe-js");
10
- const index = require("./index-Cmn7Tfmf.js");
10
+ const index = require("./index-DBZ4rcUW.js");
11
11
  const PaymentList = require("./PaymentList-APfyYD1h.js");
12
12
  const Dashboard = () => {
13
13
  const { formatMessage } = reactIntl.useIntl();
@@ -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-Cmn7Tfmf.js");
8
+ const index = require("./index-DBZ4rcUW.js");
9
9
  const OrderList = ({ orders, onOrderClick, compact = false }) => {
10
10
  const { formatMessage } = reactIntl.useIntl();
11
11
  const formatCurrency = (amount, currency = "usd") => {
@@ -3,7 +3,7 @@ import { useState, useEffect } from "react";
3
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-Bo7VLX9i.mjs";
6
+ import { P as PLUGIN_ID } from "./index-BBarHYyt.mjs";
7
7
  const OrderList = ({ orders, onOrderClick, compact = false }) => {
8
8
  const { formatMessage } = useIntl();
9
9
  const formatCurrency = (amount, currency = "usd") => {
@@ -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-Cmn7Tfmf.js");
8
+ const index = require("./index-DBZ4rcUW.js");
9
9
  const icons = require("@strapi/icons");
10
10
  const PaymentList = require("./PaymentList-APfyYD1h.js");
11
11
  const RefundModal = ({ payment, onClose, onSuccess }) => {
@@ -3,7 +3,7 @@ import { useState, useEffect } from "react";
3
3
  import { Modal, Typography, Flex, Box, Button, TextInput, SingleSelect, SingleSelectOption, Textarea, Alert, Grid, Divider, Table, Tbody, Tr, Td, Badge, Loader, EmptyStateLayout, Card, 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-Bo7VLX9i.mjs";
6
+ import { P as PLUGIN_ID } from "./index-BBarHYyt.mjs";
7
7
  import { Duplicate } from "@strapi/icons";
8
8
  import { P as PaymentList } from "./PaymentList-3HWK7PMz.mjs";
9
9
  const RefundModal = ({ payment, onClose, onSuccess }) => {
@@ -4,7 +4,7 @@ import { Modal, Typography, Box, Tabs, Flex, Button, Alert, Grid, Card, Badge, T
4
4
  import { useIntl } from "react-intl";
5
5
  import { useFetchClient } from "@strapi/strapi/admin";
6
6
  import { Duplicate, Code, Key, EyeStriked, Eye, Globe } from "@strapi/icons";
7
- import { P as PLUGIN_ID } from "./index-Bo7VLX9i.mjs";
7
+ import { P as PLUGIN_ID } from "./index-BBarHYyt.mjs";
8
8
  const IntegrationModal = ({ onClose, publishableKey }) => {
9
9
  const [copied, setCopied] = useState(null);
10
10
  const copyToClipboard = (text, type) => {
@@ -6,7 +6,7 @@ const designSystem = require("@strapi/design-system");
6
6
  const reactIntl = require("react-intl");
7
7
  const admin = require("@strapi/strapi/admin");
8
8
  const icons = require("@strapi/icons");
9
- const index = require("./index-Cmn7Tfmf.js");
9
+ const index = require("./index-DBZ4rcUW.js");
10
10
  const IntegrationModal = ({ onClose, publishableKey }) => {
11
11
  const [copied, setCopied] = React.useState(null);
12
12
  const copyToClipboard = (text, type) => {
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const designSystem = require("@strapi/design-system");
6
+ const reactIntl = require("react-intl");
7
+ const admin = require("@strapi/strapi/admin");
8
+ const index = require("./index-DBZ4rcUW.js");
9
+ const Subscriptions = () => {
10
+ const { formatMessage } = reactIntl.useIntl();
11
+ const { get, post } = admin.useFetchClient();
12
+ const [subscriptions, setSubscriptions] = React.useState([]);
13
+ const [loading, setLoading] = React.useState(true);
14
+ const [error, setError] = React.useState(null);
15
+ const [statusFilter, setStatusFilter] = React.useState("");
16
+ const [page, setPage] = React.useState(1);
17
+ const [total, setTotal] = React.useState(0);
18
+ const [cancelTarget, setCancelTarget] = React.useState(null);
19
+ const [cancelImmediate, setCancelImmediate] = React.useState(false);
20
+ const [actionMessage, setActionMessage] = React.useState(null);
21
+ const PAGE_SIZE = 25;
22
+ const fetchSubscriptions = React.useCallback(async () => {
23
+ try {
24
+ setLoading(true);
25
+ setError(null);
26
+ const params = new URLSearchParams({ page: String(page), pageSize: String(PAGE_SIZE) });
27
+ if (statusFilter) params.set("status", statusFilter);
28
+ const { data } = await get(`/${index.PLUGIN_ID}/admin/subscriptions?${params}`);
29
+ setSubscriptions(data.data || []);
30
+ setTotal(data.meta?.pagination?.total || 0);
31
+ } catch {
32
+ setError("Failed to load subscriptions");
33
+ } finally {
34
+ setLoading(false);
35
+ }
36
+ }, [get, page, statusFilter]);
37
+ React.useEffect(() => {
38
+ fetchSubscriptions();
39
+ }, [fetchSubscriptions]);
40
+ const handleCancel = async () => {
41
+ if (!cancelTarget) return;
42
+ try {
43
+ await post(`/${index.PLUGIN_ID}/admin/subscriptions/${cancelTarget.id}/cancel`, {
44
+ cancelAtPeriodEnd: !cancelImmediate
45
+ });
46
+ setActionMessage({ type: "success", text: cancelImmediate ? "Subscription canceled immediately." : "Subscription will cancel at period end." });
47
+ setCancelTarget(null);
48
+ fetchSubscriptions();
49
+ } catch {
50
+ setActionMessage({ type: "error", text: "Failed to cancel subscription." });
51
+ setCancelTarget(null);
52
+ }
53
+ };
54
+ const formatDate = (iso) => {
55
+ if (!iso) return "—";
56
+ return new Date(iso).toLocaleDateString();
57
+ };
58
+ const totalPages = Math.ceil(total / PAGE_SIZE);
59
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 8, background: "neutral100", children: [
60
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "space-between", alignItems: "center", paddingBottom: 6, children: [
61
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", children: formatMessage({ id: "payment-plugin.subscriptions.title", defaultMessage: "Subscriptions" }) }),
62
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: [
63
+ total,
64
+ " total"
65
+ ] })
66
+ ] }),
67
+ actionMessage && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(
68
+ designSystem.Alert,
69
+ {
70
+ variant: actionMessage.type === "success" ? "success" : "danger",
71
+ onClose: () => setActionMessage(null),
72
+ children: actionMessage.text
73
+ }
74
+ ) }),
75
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, children: [
76
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { width: 200 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
77
+ designSystem.SingleSelect,
78
+ {
79
+ label: "Status",
80
+ value: statusFilter,
81
+ onChange: (val) => {
82
+ setStatusFilter(val);
83
+ setPage(1);
84
+ },
85
+ placeholder: "All statuses",
86
+ children: [
87
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "", children: "All" }),
88
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "active", children: "Active" }),
89
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "trialing", children: "Trialing" }),
90
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "past_due", children: "Past due" }),
91
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "canceled", children: "Canceled" }),
92
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "incomplete", children: "Incomplete" }),
93
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "paused", children: "Paused" }),
94
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "unpaid", children: "Unpaid" })
95
+ ]
96
+ }
97
+ ) }),
98
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 6, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", size: "S", onClick: () => {
99
+ setStatusFilter("");
100
+ setPage(1);
101
+ }, children: "Clear" }) })
102
+ ] }) }),
103
+ loading ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", padding: 12, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, {}) }) : error ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { variant: "danger", children: error }) : subscriptions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(
104
+ designSystem.EmptyStateLayout,
105
+ {
106
+ content: formatMessage({ id: "payment-plugin.subscriptions.empty", defaultMessage: "No subscriptions found." })
107
+ }
108
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
109
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { colCount: 7, rowCount: subscriptions.length, children: [
110
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
111
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Subscription ID" }) }),
112
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Customer" }) }),
113
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Price ID" }) }),
114
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Status" }) }),
115
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Current Period End" }) }),
116
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Trial End" }) }),
117
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Actions" }) })
118
+ ] }) }),
119
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: subscriptions.map((sub) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
120
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", style: { fontFamily: "monospace", fontSize: 12 }, children: sub.stripe_subscription_id }) }),
121
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Td, { children: [
122
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: sub.customerEmail || sub.stripe_customer_id }),
123
+ sub.customerName && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: sub.customerName })
124
+ ] }),
125
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", style: { fontFamily: "monospace", fontSize: 12 }, children: sub.stripe_price_id }) }),
126
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { active: sub.status === "active", style: { textTransform: "capitalize" }, children: sub.cancel_at_period_end && sub.status === "active" ? "canceling" : sub.status }) }),
127
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatDate(sub.current_period_end) }) }),
128
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: formatDate(sub.trial_end) }) }),
129
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: sub.status !== "canceled" && sub.status !== "incomplete_expired" && /* @__PURE__ */ jsxRuntime.jsx(
130
+ designSystem.Button,
131
+ {
132
+ variant: "danger-light",
133
+ size: "S",
134
+ onClick: () => setCancelTarget({ id: sub.stripe_subscription_id, name: sub.customerEmail || sub.stripe_subscription_id }),
135
+ children: "Cancel"
136
+ }
137
+ ) })
138
+ ] }, sub.documentId)) })
139
+ ] }),
140
+ totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "center", gap: 2, paddingTop: 4, children: [
141
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", size: "S", disabled: page === 1, onClick: () => setPage((p) => p - 1), children: "Previous" }),
142
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", paddingTop: 1, children: [
143
+ page,
144
+ " / ",
145
+ totalPages
146
+ ] }),
147
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", size: "S", disabled: page === totalPages, onClick: () => setPage((p) => p + 1), children: "Next" })
148
+ ] })
149
+ ] }),
150
+ cancelTarget && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { open: true, onOpenChange: () => setCancelTarget(null), children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
151
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: "Cancel Subscription" }),
152
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 4, children: [
153
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { children: [
154
+ "Cancel subscription for ",
155
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: cancelTarget.name }),
156
+ "?"
157
+ ] }),
158
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 4, alignItems: "center", children: [
159
+ /* @__PURE__ */ jsxRuntime.jsx(
160
+ "input",
161
+ {
162
+ type: "checkbox",
163
+ id: "immediateCancel",
164
+ checked: cancelImmediate,
165
+ onChange: (e) => setCancelImmediate(e.target.checked)
166
+ }
167
+ ),
168
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "immediateCancel", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: "Cancel immediately (otherwise cancels at period end)" }) })
169
+ ] })
170
+ ] }) }),
171
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
172
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", onClick: () => setCancelTarget(null), children: "Back" }),
173
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger", onClick: handleCancel, children: "Confirm Cancel" })
174
+ ] })
175
+ ] }) })
176
+ ] });
177
+ };
178
+ exports.Subscriptions = Subscriptions;
@@ -0,0 +1,178 @@
1
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
+ import { useState, useCallback, useEffect } from "react";
3
+ import { Box, Flex, Typography, Alert, SingleSelect, SingleSelectOption, Button, Loader, EmptyStateLayout, Table, Thead, Tr, Th, Tbody, Td, Badge, Dialog } from "@strapi/design-system";
4
+ import { useIntl } from "react-intl";
5
+ import { useFetchClient } from "@strapi/strapi/admin";
6
+ import { P as PLUGIN_ID } from "./index-BBarHYyt.mjs";
7
+ const Subscriptions = () => {
8
+ const { formatMessage } = useIntl();
9
+ const { get, post } = useFetchClient();
10
+ const [subscriptions, setSubscriptions] = useState([]);
11
+ const [loading, setLoading] = useState(true);
12
+ const [error, setError] = useState(null);
13
+ const [statusFilter, setStatusFilter] = useState("");
14
+ const [page, setPage] = useState(1);
15
+ const [total, setTotal] = useState(0);
16
+ const [cancelTarget, setCancelTarget] = useState(null);
17
+ const [cancelImmediate, setCancelImmediate] = useState(false);
18
+ const [actionMessage, setActionMessage] = useState(null);
19
+ const PAGE_SIZE = 25;
20
+ const fetchSubscriptions = useCallback(async () => {
21
+ try {
22
+ setLoading(true);
23
+ setError(null);
24
+ const params = new URLSearchParams({ page: String(page), pageSize: String(PAGE_SIZE) });
25
+ if (statusFilter) params.set("status", statusFilter);
26
+ const { data } = await get(`/${PLUGIN_ID}/admin/subscriptions?${params}`);
27
+ setSubscriptions(data.data || []);
28
+ setTotal(data.meta?.pagination?.total || 0);
29
+ } catch {
30
+ setError("Failed to load subscriptions");
31
+ } finally {
32
+ setLoading(false);
33
+ }
34
+ }, [get, page, statusFilter]);
35
+ useEffect(() => {
36
+ fetchSubscriptions();
37
+ }, [fetchSubscriptions]);
38
+ const handleCancel = async () => {
39
+ if (!cancelTarget) return;
40
+ try {
41
+ await post(`/${PLUGIN_ID}/admin/subscriptions/${cancelTarget.id}/cancel`, {
42
+ cancelAtPeriodEnd: !cancelImmediate
43
+ });
44
+ setActionMessage({ type: "success", text: cancelImmediate ? "Subscription canceled immediately." : "Subscription will cancel at period end." });
45
+ setCancelTarget(null);
46
+ fetchSubscriptions();
47
+ } catch {
48
+ setActionMessage({ type: "error", text: "Failed to cancel subscription." });
49
+ setCancelTarget(null);
50
+ }
51
+ };
52
+ const formatDate = (iso) => {
53
+ if (!iso) return "—";
54
+ return new Date(iso).toLocaleDateString();
55
+ };
56
+ const totalPages = Math.ceil(total / PAGE_SIZE);
57
+ return /* @__PURE__ */ jsxs(Box, { padding: 8, background: "neutral100", children: [
58
+ /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", paddingBottom: 6, children: [
59
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", children: formatMessage({ id: "payment-plugin.subscriptions.title", defaultMessage: "Subscriptions" }) }),
60
+ /* @__PURE__ */ jsxs(Typography, { variant: "omega", textColor: "neutral600", children: [
61
+ total,
62
+ " total"
63
+ ] })
64
+ ] }),
65
+ actionMessage && /* @__PURE__ */ jsx(Box, { paddingBottom: 4, children: /* @__PURE__ */ jsx(
66
+ Alert,
67
+ {
68
+ variant: actionMessage.type === "success" ? "success" : "danger",
69
+ onClose: () => setActionMessage(null),
70
+ children: actionMessage.text
71
+ }
72
+ ) }),
73
+ /* @__PURE__ */ jsx(Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxs(Flex, { gap: 4, children: [
74
+ /* @__PURE__ */ jsx(Box, { style: { width: 200 }, children: /* @__PURE__ */ jsxs(
75
+ SingleSelect,
76
+ {
77
+ label: "Status",
78
+ value: statusFilter,
79
+ onChange: (val) => {
80
+ setStatusFilter(val);
81
+ setPage(1);
82
+ },
83
+ placeholder: "All statuses",
84
+ children: [
85
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "", children: "All" }),
86
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "active", children: "Active" }),
87
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "trialing", children: "Trialing" }),
88
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "past_due", children: "Past due" }),
89
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "canceled", children: "Canceled" }),
90
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "incomplete", children: "Incomplete" }),
91
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "paused", children: "Paused" }),
92
+ /* @__PURE__ */ jsx(SingleSelectOption, { value: "unpaid", children: "Unpaid" })
93
+ ]
94
+ }
95
+ ) }),
96
+ /* @__PURE__ */ jsx(Box, { paddingTop: 6, children: /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "S", onClick: () => {
97
+ setStatusFilter("");
98
+ setPage(1);
99
+ }, children: "Clear" }) })
100
+ ] }) }),
101
+ loading ? /* @__PURE__ */ jsx(Flex, { justifyContent: "center", padding: 12, children: /* @__PURE__ */ jsx(Loader, {}) }) : error ? /* @__PURE__ */ jsx(Alert, { variant: "danger", children: error }) : subscriptions.length === 0 ? /* @__PURE__ */ jsx(
102
+ EmptyStateLayout,
103
+ {
104
+ content: formatMessage({ id: "payment-plugin.subscriptions.empty", defaultMessage: "No subscriptions found." })
105
+ }
106
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
107
+ /* @__PURE__ */ jsxs(Table, { colCount: 7, rowCount: subscriptions.length, children: [
108
+ /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
109
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Subscription ID" }) }),
110
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Customer" }) }),
111
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Price ID" }) }),
112
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Status" }) }),
113
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Current Period End" }) }),
114
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Trial End" }) }),
115
+ /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", children: "Actions" }) })
116
+ ] }) }),
117
+ /* @__PURE__ */ jsx(Tbody, { children: subscriptions.map((sub) => /* @__PURE__ */ jsxs(Tr, { children: [
118
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", style: { fontFamily: "monospace", fontSize: 12 }, children: sub.stripe_subscription_id }) }),
119
+ /* @__PURE__ */ jsxs(Td, { children: [
120
+ /* @__PURE__ */ jsx(Typography, { variant: "omega", children: sub.customerEmail || sub.stripe_customer_id }),
121
+ sub.customerName && /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: sub.customerName })
122
+ ] }),
123
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", style: { fontFamily: "monospace", fontSize: 12 }, children: sub.stripe_price_id }) }),
124
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Badge, { active: sub.status === "active", style: { textTransform: "capitalize" }, children: sub.cancel_at_period_end && sub.status === "active" ? "canceling" : sub.status }) }),
125
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatDate(sub.current_period_end) }) }),
126
+ /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: formatDate(sub.trial_end) }) }),
127
+ /* @__PURE__ */ jsx(Td, { children: sub.status !== "canceled" && sub.status !== "incomplete_expired" && /* @__PURE__ */ jsx(
128
+ Button,
129
+ {
130
+ variant: "danger-light",
131
+ size: "S",
132
+ onClick: () => setCancelTarget({ id: sub.stripe_subscription_id, name: sub.customerEmail || sub.stripe_subscription_id }),
133
+ children: "Cancel"
134
+ }
135
+ ) })
136
+ ] }, sub.documentId)) })
137
+ ] }),
138
+ totalPages > 1 && /* @__PURE__ */ jsxs(Flex, { justifyContent: "center", gap: 2, paddingTop: 4, children: [
139
+ /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "S", disabled: page === 1, onClick: () => setPage((p) => p - 1), children: "Previous" }),
140
+ /* @__PURE__ */ jsxs(Typography, { variant: "omega", paddingTop: 1, children: [
141
+ page,
142
+ " / ",
143
+ totalPages
144
+ ] }),
145
+ /* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "S", disabled: page === totalPages, onClick: () => setPage((p) => p + 1), children: "Next" })
146
+ ] })
147
+ ] }),
148
+ cancelTarget && /* @__PURE__ */ jsx(Dialog.Root, { open: true, onOpenChange: () => setCancelTarget(null), children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
149
+ /* @__PURE__ */ jsx(Dialog.Header, { children: "Cancel Subscription" }),
150
+ /* @__PURE__ */ jsx(Dialog.Body, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 4, children: [
151
+ /* @__PURE__ */ jsxs(Typography, { children: [
152
+ "Cancel subscription for ",
153
+ /* @__PURE__ */ jsx("strong", { children: cancelTarget.name }),
154
+ "?"
155
+ ] }),
156
+ /* @__PURE__ */ jsxs(Flex, { gap: 4, alignItems: "center", children: [
157
+ /* @__PURE__ */ jsx(
158
+ "input",
159
+ {
160
+ type: "checkbox",
161
+ id: "immediateCancel",
162
+ checked: cancelImmediate,
163
+ onChange: (e) => setCancelImmediate(e.target.checked)
164
+ }
165
+ ),
166
+ /* @__PURE__ */ jsx("label", { htmlFor: "immediateCancel", children: /* @__PURE__ */ jsx(Typography, { variant: "omega", children: "Cancel immediately (otherwise cancels at period end)" }) })
167
+ ] })
168
+ ] }) }),
169
+ /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
170
+ /* @__PURE__ */ jsx(Button, { variant: "tertiary", onClick: () => setCancelTarget(null), children: "Back" }),
171
+ /* @__PURE__ */ jsx(Button, { variant: "danger", onClick: handleCancel, children: "Confirm Cancel" })
172
+ ] })
173
+ ] }) })
174
+ ] });
175
+ };
176
+ export {
177
+ Subscriptions
178
+ };
@@ -36,7 +36,7 @@ const index = {
36
36
  defaultMessage: "Payment Management"
37
37
  },
38
38
  Component: async () => {
39
- const { App } = await import("./App-D5x-l0Sz.mjs");
39
+ const { App } = await import("./App-CZNZ1JKf.mjs");
40
40
  return App;
41
41
  }
42
42
  });
@@ -37,7 +37,7 @@ const index = {
37
37
  defaultMessage: "Payment Management"
38
38
  },
39
39
  Component: async () => {
40
- const { App } = await Promise.resolve().then(() => require("./App-BpwS5-wg.js"));
40
+ const { App } = await Promise.resolve().then(() => require("./App-CsbyykNC.js"));
41
41
  return App;
42
42
  }
43
43
  });
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-Cmn7Tfmf.js");
2
+ const index = require("../_chunks/index-DBZ4rcUW.js");
3
3
  module.exports = index.index;
@@ -1,4 +1,4 @@
1
- import { i } from "../_chunks/index-Bo7VLX9i.mjs";
1
+ import { i } from "../_chunks/index-BBarHYyt.mjs";
2
2
  export {
3
3
  i as default
4
4
  };