@reeboot/strapi-payment-plugin 0.0.0 → 0.0.2

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 (81) hide show
  1. package/README.md +398 -66
  2. package/dist/_chunks/Analytics-C2GKvPDX.js +355 -0
  3. package/dist/_chunks/Analytics-Chydh3dg.mjs +355 -0
  4. package/dist/_chunks/App-BCbEuN6h.mjs +68 -0
  5. package/dist/_chunks/App-E2k2mo5p.js +70 -0
  6. package/dist/_chunks/Customers-B8BlQ1BO.mjs +273 -0
  7. package/dist/_chunks/Customers-D0O5ET5C.js +273 -0
  8. package/dist/_chunks/Dashboard-CuqclLak.js +180 -0
  9. package/dist/_chunks/Dashboard-D8-ifJqB.mjs +180 -0
  10. package/dist/_chunks/Orders-5WGSzPGo.js +308 -0
  11. package/dist/_chunks/Orders-ClJJaQrX.mjs +308 -0
  12. package/dist/_chunks/Payments-CIMyOC3n.js +489 -0
  13. package/dist/_chunks/Payments-CRnRBf48.mjs +489 -0
  14. package/dist/_chunks/Settings-BXMLePI_.js +357 -0
  15. package/dist/_chunks/Settings-TeAvV4RH.mjs +357 -0
  16. package/dist/_chunks/en-BJocyOVu.mjs +240 -0
  17. package/dist/_chunks/en-BkVAf_R4.js +240 -0
  18. package/dist/_chunks/index-BTk7a2T5.js +66 -0
  19. package/dist/_chunks/index-Bz8V_5zH.mjs +67 -0
  20. package/dist/admin/index.js +2 -63
  21. package/dist/admin/index.mjs +2 -63
  22. package/dist/admin/src/components/AnalyticsChart.d.ts +19 -0
  23. package/dist/admin/src/components/CustomerList.d.ts +21 -0
  24. package/dist/admin/src/components/OrderList.d.ts +27 -0
  25. package/dist/admin/src/components/PaymentCard.d.ts +39 -0
  26. package/dist/admin/src/components/PaymentList.d.ts +19 -0
  27. package/dist/admin/src/components/RefundModal.d.ts +15 -0
  28. package/dist/admin/src/pages/Analytics.d.ts +2 -0
  29. package/dist/admin/src/pages/Customers.d.ts +2 -0
  30. package/dist/admin/src/pages/Dashboard.d.ts +2 -0
  31. package/dist/admin/src/pages/HomePage.d.ts +1 -1
  32. package/dist/admin/src/pages/Orders.d.ts +2 -0
  33. package/dist/admin/src/pages/Payments.d.ts +2 -0
  34. package/dist/admin/src/pages/Settings.d.ts +2 -0
  35. package/dist/server/index.js +1827 -7101
  36. package/dist/server/index.mjs +1826 -7100
  37. package/dist/server/src/config/index.d.ts +2 -10
  38. package/dist/server/src/content-types/customer/index.d.ts +69 -0
  39. package/dist/server/src/content-types/index.d.ts +207 -1
  40. package/dist/server/src/content-types/order/index.d.ts +70 -0
  41. package/dist/server/src/content-types/payment/index.d.ts +69 -0
  42. package/dist/server/src/controllers/controller.d.ts +6 -9
  43. package/dist/server/src/controllers/index.d.ts +30 -35
  44. package/dist/server/src/controllers/stripe.d.ts +104 -0
  45. package/dist/server/src/index.d.ts +262 -110
  46. package/dist/server/src/middlewares/index.d.ts +19 -1
  47. package/dist/server/src/policies/index.d.ts +3 -1
  48. package/dist/server/src/routes/{admin-routes.d.ts → admin/index.d.ts} +4 -4
  49. package/dist/server/src/routes/content-api/index.d.ts +21 -0
  50. package/dist/server/src/routes/index.d.ts +10 -26
  51. package/dist/server/src/services/index.d.ts +2 -37
  52. package/dist/server/src/services/{stripeDriver.d.ts → stripe.d.ts} +52 -28
  53. package/dist/server/src/types/index.d.ts +179 -0
  54. package/package.json +20 -24
  55. package/dist/_chunks/App-BGle38NN.js +0 -1149
  56. package/dist/_chunks/App-DoUUpjp-.mjs +0 -1149
  57. package/dist/_chunks/en-B4KWt_jN.js +0 -4
  58. package/dist/_chunks/en-Byx4XI2L.mjs +0 -4
  59. package/dist/admin/src/components/Header.d.ts +0 -2
  60. package/dist/admin/src/components/NavigationMenu.d.ts +0 -2
  61. package/dist/admin/src/components/Sidebar.d.ts +0 -2
  62. package/dist/admin/src/components/TransactionDetailsModal.d.ts +0 -18
  63. package/dist/admin/src/components/TransactionList.d.ts +0 -18
  64. package/dist/admin/src/pages/ConfigurationPage.d.ts +0 -2
  65. package/dist/admin/src/pages/DashboardPage.d.ts +0 -2
  66. package/dist/admin/src/pages/ProductsPage.d.ts +0 -2
  67. package/dist/admin/src/pages/SubscriptionsPage.d.ts +0 -2
  68. package/dist/admin/src/pages/TransactionsPage.d.ts +0 -2
  69. package/dist/server/controllers/product.d.ts +0 -12
  70. package/dist/server/controllers/subscription.d.ts +0 -12
  71. package/dist/server/services/product.d.ts +0 -7
  72. package/dist/server/services/subscription.d.ts +0 -7
  73. package/dist/server/src/controllers/productController.d.ts +0 -9
  74. package/dist/server/src/controllers/subscriptionController.d.ts +0 -9
  75. package/dist/server/src/routes/content-api.d.ts +0 -12
  76. package/dist/server/src/routes/product-routes.d.ts +0 -13
  77. package/dist/server/src/routes/refund-routes.d.ts +0 -13
  78. package/dist/server/src/routes/subscription-routes.d.ts +0 -13
  79. package/dist/server/src/services/paypalDriver.d.ts +0 -7
  80. package/dist/server/src/services/service.d.ts +0 -33
  81. package/jest.config.js +0 -13
@@ -1,1149 +0,0 @@
1
- import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { Page } from "@strapi/strapi/admin";
3
- import { NavLink, Routes, Route } from "react-router-dom";
4
- import { useState, useEffect } from "react";
5
- import { Box, Typography, Grid, TextInput, Table, Thead, Tr, Th, Tbody, Td, Main, Flex, Button, SingleSelect, Modal, Alert, SingleSelectOption } from "@strapi/design-system";
6
- import { Formik, Form } from "formik";
7
- const HomePage = () => {
8
- const [transactions, setTransactions] = useState([]);
9
- const [loading, setLoading] = useState(false);
10
- const [error, setError] = useState(null);
11
- const [stats, setStats] = useState({
12
- totalRevenue: 0,
13
- totalTransactions: 0,
14
- successRate: 0
15
- });
16
- const [searchTerm, setSearchTerm] = useState("");
17
- const [filter, setFilter] = useState("all");
18
- const fetchData = async () => {
19
- setLoading(true);
20
- setError(null);
21
- try {
22
- const response = await fetch("/payment-plugin/transactions");
23
- if (!response.ok) {
24
- throw new Error("Failed to fetch transactions");
25
- }
26
- const data = await response.json();
27
- setTransactions(data.data);
28
- const totalAmount = data.data.reduce(
29
- (sum, t) => sum + t.amount,
30
- 0
31
- );
32
- const successCount = data.data.filter(
33
- (t) => t.status === "completed"
34
- ).length;
35
- const successRate = data.data.length > 0 ? successCount / data.data.length * 100 : 0;
36
- setStats({
37
- totalRevenue: totalAmount,
38
- totalTransactions: data.data.length,
39
- successRate
40
- });
41
- } catch (err) {
42
- if (err instanceof Error) {
43
- setError(err.message);
44
- } else {
45
- setError("An unknown error occurred");
46
- }
47
- } finally {
48
- setLoading(false);
49
- }
50
- };
51
- useEffect(() => {
52
- fetchData();
53
- }, []);
54
- const handleSearch = (e) => {
55
- setSearchTerm(e.target.value);
56
- };
57
- const handleFilterChange = (e) => {
58
- setFilter(e.target.value);
59
- };
60
- const filteredTransactions = transactions.filter((transaction) => {
61
- const matchesSearch = [
62
- transaction.id,
63
- transaction.customer,
64
- transaction.amount.toString()
65
- ].some(
66
- (field) => field.toLowerCase().includes(searchTerm.toLowerCase())
67
- );
68
- const matchesFilter = filter === "all" || transaction.status === filter;
69
- return matchesSearch && matchesFilter;
70
- });
71
- return /* @__PURE__ */ jsxs(Box, { padding: 6, background: "neutral0", children: [
72
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", as: "h1", textColor: "primary600", style: { marginBottom: "2rem" }, children: "Payment Plugin Home" }),
73
- /* @__PURE__ */ jsxs(
74
- Box,
75
- {
76
- padding: 4,
77
- background: "neutral100",
78
- borderRadius: "4px",
79
- border: "1px solid #e0e0e0",
80
- style: { marginBottom: "2rem" },
81
- children: [
82
- /* @__PURE__ */ jsx(Typography, { variant: "beta", as: "h2", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Payment Statistics" }),
83
- loading && /* @__PURE__ */ jsx("p", { children: "Loading statistics..." }),
84
- error && /* @__PURE__ */ jsx("p", { style: { color: "red" }, children: error }),
85
- !loading && !error && /* @__PURE__ */ jsxs(Grid.Root, { gap: 4, children: [
86
- /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
87
- /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral800", children: "Total Revenue" }),
88
- /* @__PURE__ */ jsxs(Typography, { variant: "alpha", textColor: "primary600", children: [
89
- "$",
90
- stats.totalRevenue.toFixed(2)
91
- ] })
92
- ] }) }),
93
- /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
94
- /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral800", children: "Total Transactions" }),
95
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", textColor: "primary600", children: stats.totalTransactions })
96
- ] }) }),
97
- /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
98
- /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral800", children: "Successful Payments" }),
99
- /* @__PURE__ */ jsxs(Typography, { variant: "alpha", textColor: "primary600", children: [
100
- stats.successRate.toFixed(2),
101
- "%"
102
- ] })
103
- ] }) })
104
- ] })
105
- ]
106
- }
107
- ),
108
- /* @__PURE__ */ jsxs(
109
- Box,
110
- {
111
- padding: 4,
112
- background: "neutral100",
113
- borderRadius: "4px",
114
- border: "1px solid #e0e0e0",
115
- children: [
116
- /* @__PURE__ */ jsx(Typography, { variant: "beta", as: "h2", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Transactions" }),
117
- /* @__PURE__ */ jsxs("div", { style: { marginBottom: "1rem", display: "flex", gap: "1rem", alignItems: "center", flexWrap: "wrap" }, children: [
118
- /* @__PURE__ */ jsx(
119
- TextInput,
120
- {
121
- label: "Search Transactions",
122
- value: searchTerm,
123
- onChange: handleSearch,
124
- placeholder: "Search by ID, email, or amount",
125
- style: { flex: 1, minWidth: "200px" }
126
- }
127
- ),
128
- /* @__PURE__ */ jsxs("select", { value: filter, onChange: handleFilterChange, style: { minWidth: "150px" }, children: [
129
- /* @__PURE__ */ jsx("option", { value: "all", children: "All Transactions" }),
130
- /* @__PURE__ */ jsx("option", { value: "completed", children: "Successful" }),
131
- /* @__PURE__ */ jsx("option", { value: "failed", children: "Failed" }),
132
- /* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" })
133
- ] })
134
- ] }),
135
- /* @__PURE__ */ jsxs("div", { style: { overflowX: "auto" }, children: [
136
- loading && /* @__PURE__ */ jsx("p", { children: "Loading transactions..." }),
137
- error && /* @__PURE__ */ jsx("p", { style: { color: "red" }, children: error }),
138
- !loading && !error && /* @__PURE__ */ jsx(Fragment, { children: filteredTransactions.length > 0 ? /* @__PURE__ */ jsxs(Table, { children: [
139
- /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
140
- /* @__PURE__ */ jsx(Th, { children: "ID" }),
141
- /* @__PURE__ */ jsx(Th, { children: "Amount" }),
142
- /* @__PURE__ */ jsx(Th, { children: "Currency" }),
143
- /* @__PURE__ */ jsx(Th, { children: "Status" }),
144
- /* @__PURE__ */ jsx(Th, { children: "Date" }),
145
- /* @__PURE__ */ jsx(Th, { children: "Customer" })
146
- ] }) }),
147
- /* @__PURE__ */ jsx(Tbody, { children: filteredTransactions.map((transaction) => /* @__PURE__ */ jsxs(Tr, { children: [
148
- /* @__PURE__ */ jsx(Td, { children: transaction.id }),
149
- /* @__PURE__ */ jsxs(Td, { children: [
150
- "$",
151
- transaction.amount.toFixed(2)
152
- ] }),
153
- /* @__PURE__ */ jsx(Td, { children: transaction.currency }),
154
- /* @__PURE__ */ jsx(Td, { children: transaction.status }),
155
- /* @__PURE__ */ jsx(Td, { children: new Date(transaction.date).toLocaleDateString() }),
156
- /* @__PURE__ */ jsx(Td, { children: transaction.customer })
157
- ] }, transaction.id)) })
158
- ] }) : /* @__PURE__ */ jsx("p", { children: "No transactions found" }) })
159
- ] })
160
- ]
161
- }
162
- )
163
- ] });
164
- };
165
- const ConfigurationPage = () => {
166
- const [stripeSecretKey, setStripeSecretKey] = useState("");
167
- const [stripePublishableKey, setStripePublishableKey] = useState("");
168
- const [stripeWebhookSecret, setStripeWebhookSecret] = useState("");
169
- const [paypalClientId, setPaypalClientId] = useState("");
170
- const [paypalClientSecret, setPaypalClientSecret] = useState("");
171
- const [paypalWebhookId, setPaypalWebhookId] = useState("");
172
- const [configStatus, setConfigStatus] = useState({
173
- stripe: false,
174
- paypal: false
175
- });
176
- useEffect(() => {
177
- const fetchConfigStatus = async () => {
178
- try {
179
- const response = await fetch("/payment-plugin/config-status");
180
- if (response.ok) {
181
- const data = await response.json();
182
- setConfigStatus(data);
183
- }
184
- } catch (error) {
185
- console.error("Failed to fetch config status:", error);
186
- }
187
- };
188
- fetchConfigStatus();
189
- }, []);
190
- const handleSave = async () => {
191
- const response = await fetch("/payment-plugin/config", {
192
- method: "POST",
193
- headers: {
194
- "Content-Type": "application/json"
195
- },
196
- body: JSON.stringify({
197
- stripe: {
198
- secretKey: stripeSecretKey,
199
- publishableKey: stripePublishableKey,
200
- webhookSecret: stripeWebhookSecret
201
- },
202
- paypal: {
203
- clientId: paypalClientId,
204
- clientSecret: paypalClientSecret,
205
- webhookId: paypalWebhookId
206
- }
207
- })
208
- });
209
- if (response.ok) {
210
- alert("Configuration saved successfully");
211
- } else {
212
- alert("Failed to save configuration");
213
- }
214
- };
215
- return /* @__PURE__ */ jsxs(Main, { children: [
216
- /* @__PURE__ */ jsx(Main, { title: "Payment Plugin Configuration" }),
217
- /* @__PURE__ */ jsx(Main, { children: /* @__PURE__ */ jsxs(Box, { padding: 6, background: "neutral0", children: [
218
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", as: "h1", textColor: "primary600", style: { marginBottom: "2rem" }, children: "Payment Configuration" }),
219
- /* @__PURE__ */ jsxs(
220
- Box,
221
- {
222
- padding: 4,
223
- background: "neutral100",
224
- borderRadius: "4px",
225
- border: "1px solid #e0e0e0",
226
- style: { marginBottom: "2rem" },
227
- children: [
228
- /* @__PURE__ */ jsx(Typography, { variant: "beta", as: "h2", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Payment Configuration" }),
229
- /* @__PURE__ */ jsxs(Grid.Root, { gap: 6, style: { marginBottom: "2rem" }, children: [
230
- /* @__PURE__ */ jsx(Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
231
- /* @__PURE__ */ jsx(Typography, { variant: "gamma", as: "h3", textColor: "neutral800", children: "Stripe Status  " }),
232
- /* @__PURE__ */ jsxs(Flex, { alignItems: "center", children: [
233
- /* @__PURE__ */ jsx("div", { style: {
234
- width: "10px",
235
- height: "10px",
236
- borderRadius: "50%",
237
- backgroundColor: configStatus.stripe ? "green" : "red",
238
- marginRight: "8px"
239
- } }),
240
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: configStatus.stripe ? "success600" : "danger600", children: configStatus.stripe ? "Connected" : "Not Connected" })
241
- ] })
242
- ] }) }),
243
- /* @__PURE__ */ jsx(Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
244
- /* @__PURE__ */ jsx(Typography, { variant: "gamma", as: "h3", textColor: "neutral800", children: "PayPal Status  " }),
245
- /* @__PURE__ */ jsxs(Flex, { alignItems: "center", children: [
246
- /* @__PURE__ */ jsx("div", { style: {
247
- width: "10px",
248
- height: "10px",
249
- borderRadius: "50%",
250
- backgroundColor: configStatus.paypal ? "green" : "red",
251
- marginRight: "8px"
252
- } }),
253
- /* @__PURE__ */ jsx(Typography, { variant: "pi", fontWeight: "bold", textColor: configStatus.paypal ? "success600" : "danger600", children: configStatus.paypal ? "Connected" : "Not Connected" })
254
- ] })
255
- ] }) })
256
- ] }),
257
- /* @__PURE__ */ jsxs(Grid.Root, { gap: 6, children: [
258
- /* @__PURE__ */ jsx(Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxs(
259
- Box,
260
- {
261
- padding: 6,
262
- background: "neutral0",
263
- borderRadius: "4px",
264
- border: "1px solid #e0e0e0",
265
- style: { marginBottom: "1rem", width: "100%" },
266
- children: [
267
- /* @__PURE__ */ jsx(Typography, { variant: "gamma", as: "h3", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Stripe Configuration" }),
268
- /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 8, alignItems: "initial", children: [
269
- /* @__PURE__ */ jsx(
270
- TextInput,
271
- {
272
- placeholder: "Secret Key",
273
- name: "stripeSecretKey",
274
- value: stripeSecretKey,
275
- onChange: (e) => setStripeSecretKey(e.target.value),
276
- type: "password",
277
- disabled: configStatus.stripe,
278
- style: {
279
- border: configStatus.stripe ? "2px solid #4CAF50" : ""
280
- },
281
- hint: configStatus.stripe ? "This value is controlled by environment variables" : ""
282
- }
283
- ),
284
- /* @__PURE__ */ jsx(
285
- TextInput,
286
- {
287
- placeholder: "Publishable Key",
288
- name: "stripePublishableKey",
289
- value: stripePublishableKey,
290
- onChange: (e) => setStripePublishableKey(e.target.value),
291
- disabled: configStatus.stripe,
292
- style: {
293
- border: configStatus.stripe ? "2px solid #4CAF50" : ""
294
- },
295
- hint: configStatus.stripe ? "This value is controlled by environment variables" : ""
296
- }
297
- ),
298
- /* @__PURE__ */ jsx(
299
- TextInput,
300
- {
301
- placeholder: "Webhook Secret",
302
- name: "stripeWebhookSecret",
303
- value: stripeWebhookSecret,
304
- onChange: (e) => setStripeWebhookSecret(e.target.value),
305
- type: "password",
306
- disabled: configStatus.stripe,
307
- style: {
308
- border: configStatus.stripe ? "2px solid #4CAF50" : ""
309
- },
310
- hint: configStatus.stripe ? "This value is controlled by environment variables" : ""
311
- }
312
- )
313
- ] })
314
- ]
315
- }
316
- ) }),
317
- /* @__PURE__ */ jsx(Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxs(
318
- Box,
319
- {
320
- padding: 6,
321
- background: "neutral0",
322
- borderRadius: "4px",
323
- border: "1px solid #e0e0e0",
324
- style: { marginBottom: "1rem", width: "100%" },
325
- children: [
326
- /* @__PURE__ */ jsx(Typography, { variant: "gamma", as: "h3", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "PayPal Configuration" }),
327
- /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 8, alignItems: "initial", children: [
328
- /* @__PURE__ */ jsx(
329
- TextInput,
330
- {
331
- placeholder: "Client ID",
332
- name: "paypalClientId",
333
- value: paypalClientId,
334
- onChange: (e) => setPaypalClientId(e.target.value),
335
- disabled: configStatus.paypal,
336
- style: {
337
- border: configStatus.paypal ? "2px solid #4CAF50" : "",
338
- width: "100%"
339
- },
340
- hint: configStatus.paypal ? "This value is controlled by environment variables" : ""
341
- }
342
- ),
343
- /* @__PURE__ */ jsx(
344
- TextInput,
345
- {
346
- placeholder: "Client Secret",
347
- name: "paypalClientSecret",
348
- value: paypalClientSecret,
349
- onChange: (e) => setPaypalClientSecret(e.target.value),
350
- type: "password",
351
- disabled: configStatus.paypal,
352
- style: {
353
- border: configStatus.paypal ? "2px solid #4CAF50" : ""
354
- },
355
- width: "80%",
356
- hint: configStatus.paypal ? "This value is controlled by environment variables" : ""
357
- }
358
- ),
359
- /* @__PURE__ */ jsx(
360
- TextInput,
361
- {
362
- placeholder: "Webhook ID",
363
- name: "paypalWebhookId",
364
- value: paypalWebhookId,
365
- onChange: (e) => setPaypalWebhookId(e.target.value),
366
- disabled: configStatus.paypal,
367
- style: {
368
- border: configStatus.paypal ? "2px solid #4CAF50" : ""
369
- },
370
- hint: configStatus.paypal ? "This value is controlled by environment variables" : ""
371
- }
372
- )
373
- ] })
374
- ]
375
- }
376
- ) })
377
- ] }),
378
- /* @__PURE__ */ jsx(Button, { onClick: handleSave, style: { marginTop: "1rem" }, children: "Save Configuration" })
379
- ]
380
- }
381
- )
382
- ] }) })
383
- ] });
384
- };
385
- const TransactionList = ({ transactions, onViewDetails, onStatusUpdate }) => {
386
- return /* @__PURE__ */ jsxs(Table, { children: [
387
- /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
388
- /* @__PURE__ */ jsx(Th, { children: "ID" }),
389
- /* @__PURE__ */ jsx(Th, { children: "Amount" }),
390
- /* @__PURE__ */ jsx(Th, { children: "Currency" }),
391
- /* @__PURE__ */ jsx(Th, { children: "Status" }),
392
- /* @__PURE__ */ jsx(Th, { children: "Date" }),
393
- /* @__PURE__ */ jsx(Th, { children: "Customer" }),
394
- /* @__PURE__ */ jsx(Th, { children: "Actions" })
395
- ] }) }),
396
- /* @__PURE__ */ jsx(Tbody, { children: transactions.map((transaction) => /* @__PURE__ */ jsxs(Tr, { children: [
397
- /* @__PURE__ */ jsx(Td, { children: transaction.id }),
398
- /* @__PURE__ */ jsxs(Td, { children: [
399
- "$",
400
- transaction.amount.toFixed(2)
401
- ] }),
402
- /* @__PURE__ */ jsx(Td, { children: transaction.currency }),
403
- /* @__PURE__ */ jsx(Td, { children: onStatusUpdate ? /* @__PURE__ */ jsxs(
404
- SingleSelect,
405
- {
406
- value: transaction.status,
407
- onChange: (e) => onStatusUpdate(transaction.id, e.target.value),
408
- style: { minWidth: "120px" },
409
- children: [
410
- /* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
411
- /* @__PURE__ */ jsx("option", { value: "completed", children: "Completed" }),
412
- /* @__PURE__ */ jsx("option", { value: "failed", children: "Failed" }),
413
- /* @__PURE__ */ jsx("option", { value: "refunded", children: "Refunded" })
414
- ]
415
- }
416
- ) : transaction.status }),
417
- /* @__PURE__ */ jsx(Td, { children: new Date(transaction.date).toLocaleDateString() }),
418
- /* @__PURE__ */ jsx(Td, { children: transaction.customer }),
419
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "S", onClick: () => onViewDetails(transaction), children: "View" }) })
420
- ] }, transaction.id)) })
421
- ] });
422
- };
423
- const TransactionDetailsModal = ({
424
- isOpen,
425
- onClose,
426
- transaction,
427
- onRefund
428
- }) => {
429
- if (!transaction) return null;
430
- return /* @__PURE__ */ jsx(Modal.Root, { open: isOpen, onClose, children: /* @__PURE__ */ jsxs(Modal.Content, { onClick: onClose, children: [
431
- /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Typography, { variant: "beta", as: "h2", textColor: "neutral800", children: "Transaction Details" }) }),
432
- /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsxs(Box, { padding: 4, children: [
433
- /* @__PURE__ */ jsx(Typography, { variant: "beta", as: "h2", textColor: "neutral800", children: "Details" }),
434
- /* @__PURE__ */ jsx(Box, { style: { marginTop: "1rem" }, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, children: [
435
- /* @__PURE__ */ jsxs(Typography, { children: [
436
- /* @__PURE__ */ jsx("strong", { children: "Amount:" }),
437
- " $",
438
- transaction.amount.toFixed(2),
439
- " ",
440
- transaction.currency
441
- ] }),
442
- /* @__PURE__ */ jsxs(Typography, { children: [
443
- /* @__PURE__ */ jsx("strong", { children: "Status:" }),
444
- " ",
445
- transaction.status
446
- ] }),
447
- /* @__PURE__ */ jsxs(Typography, { children: [
448
- /* @__PURE__ */ jsx("strong", { children: "Date:" }),
449
- " ",
450
- new Date(transaction.date).toLocaleString()
451
- ] }),
452
- /* @__PURE__ */ jsxs(Typography, { children: [
453
- /* @__PURE__ */ jsx("strong", { children: "Customer:" }),
454
- " ",
455
- transaction.customer
456
- ] }),
457
- /* @__PURE__ */ jsxs(Typography, { children: [
458
- /* @__PURE__ */ jsx("strong", { children: "Payment Method:" }),
459
- " ",
460
- transaction.paymentMethod
461
- ] }),
462
- /* @__PURE__ */ jsxs(Typography, { children: [
463
- /* @__PURE__ */ jsx("strong", { children: "Gateway:" }),
464
- " ",
465
- transaction.gateway
466
- ] })
467
- ] }) }),
468
- /* @__PURE__ */ jsxs(Flex, { style: { marginTop: "2rem", gap: "1rem" }, children: [
469
- /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onClose, children: "Close" }),
470
- transaction.status === "completed" && transaction.gateway !== "paypal" && /* @__PURE__ */ jsx(Button, { variant: "danger", onClick: onRefund, style: { marginLeft: "auto" }, children: "Refund" })
471
- ] })
472
- ] }) })
473
- ] }) });
474
- };
475
- const TransactionsPage = () => {
476
- const [searchTerm, setSearchTerm] = useState("");
477
- const [filter, setFilter] = useState("all");
478
- const [transactions, setTransactions] = useState([]);
479
- const [loading, setLoading] = useState(false);
480
- const [error, setError] = useState(null);
481
- const [selectedTransaction, setSelectedTransaction] = useState(null);
482
- const [isModalOpen, setIsModalOpen] = useState(false);
483
- const handleSearch = (e) => {
484
- setSearchTerm(e.target.value);
485
- };
486
- const handleFilterChange = (value) => {
487
- setFilter(value);
488
- };
489
- const fetchTransactions = async () => {
490
- setLoading(true);
491
- setError(null);
492
- try {
493
- const response = await fetch("/payment-plugin/transactions");
494
- if (!response.ok) {
495
- throw new Error("Failed to fetch transactions");
496
- }
497
- const data = await response.json();
498
- setTransactions(data.data);
499
- } catch (err) {
500
- if (err instanceof Error) {
501
- setError(err.message);
502
- } else {
503
- setError("An unknown error occurred");
504
- }
505
- } finally {
506
- setLoading(false);
507
- }
508
- };
509
- useEffect(() => {
510
- fetchTransactions();
511
- }, []);
512
- const filteredTransactions = transactions.filter((transaction) => {
513
- const matchesSearch = [
514
- transaction.id,
515
- transaction.customer,
516
- transaction.amount.toString()
517
- ].some(
518
- (field) => field.toLowerCase().includes(searchTerm.toLowerCase())
519
- );
520
- const matchesFilter = filter === "all" || transaction.status === filter;
521
- return matchesSearch && matchesFilter;
522
- });
523
- const handleViewDetails = (transaction) => {
524
- setSelectedTransaction(transaction);
525
- setIsModalOpen(true);
526
- };
527
- const handleRefund = async () => {
528
- if (!selectedTransaction) return;
529
- try {
530
- const response = await fetch("/payment-plugin/refund", {
531
- method: "POST",
532
- headers: {
533
- "Content-Type": "application/json"
534
- },
535
- body: JSON.stringify({
536
- gateway: selectedTransaction.gateway,
537
- transactionId: selectedTransaction.id,
538
- amount: selectedTransaction.amount
539
- })
540
- });
541
- if (!response.ok) {
542
- throw new Error("Failed to process refund");
543
- }
544
- const result = await response.json();
545
- if (result.success) {
546
- setTransactions(transactions.map(
547
- (t) => t.id === selectedTransaction.id ? { ...t, status: "refunded" } : t
548
- ));
549
- setIsModalOpen(false);
550
- } else {
551
- throw new Error(result.message || "Refund failed");
552
- }
553
- } catch (err) {
554
- if (err instanceof Error) {
555
- setError(err.message);
556
- } else {
557
- setError("An unknown error occurred");
558
- }
559
- }
560
- };
561
- const handleStatusUpdate = async (transactionId, newStatus) => {
562
- try {
563
- setTransactions(transactions.map(
564
- (t) => t.id === transactionId ? { ...t, status: newStatus } : t
565
- ));
566
- } catch (err) {
567
- if (err instanceof Error) {
568
- setError(err.message);
569
- } else {
570
- setError("An unknown error occurred");
571
- }
572
- }
573
- };
574
- return /* @__PURE__ */ jsxs(Main, { children: [
575
- /* @__PURE__ */ jsx(Main, { title: "Transactions" }),
576
- /* @__PURE__ */ jsxs(Box, { padding: 6, background: "neutral0", children: [
577
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", as: "h1", textColor: "primary600", style: { marginBottom: "2rem" }, children: "Transactions" }),
578
- error && /* @__PURE__ */ jsx(Alert, { variant: "danger", style: { marginBottom: "1rem" }, children: error }),
579
- /* @__PURE__ */ jsxs(
580
- Box,
581
- {
582
- padding: 4,
583
- background: "neutral100",
584
- borderRadius: "4px",
585
- border: "1px solid #e0e0e0",
586
- children: [
587
- /* @__PURE__ */ jsx(Typography, { variant: "beta", as: "h2", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Transaction List" }),
588
- /* @__PURE__ */ jsxs("div", { style: { marginBottom: "1rem", display: "flex", gap: "1rem", alignItems: "center", flexWrap: "wrap" }, children: [
589
- /* @__PURE__ */ jsx(
590
- TextInput,
591
- {
592
- label: "Search Transactions",
593
- value: searchTerm,
594
- onChange: handleSearch,
595
- placeholder: "Search by ID, email, or amount",
596
- style: { flex: 1, minWidth: "200px" }
597
- }
598
- ),
599
- /* @__PURE__ */ jsxs(SingleSelect, { value: filter, onChange: handleFilterChange, style: { minWidth: "150px" }, children: [
600
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "all", children: "All Transactions" }),
601
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "completed", children: "Successful" }),
602
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "failed", children: "Failed" }),
603
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "pending", children: "Pending" }),
604
- /* @__PURE__ */ jsx(SingleSelectOption, { value: "refunded", children: "Refunded" })
605
- ] })
606
- ] }),
607
- /* @__PURE__ */ jsxs("div", { children: [
608
- loading && /* @__PURE__ */ jsx("p", { children: "Loading transactions..." }),
609
- !loading && /* @__PURE__ */ jsx(Fragment, { children: filteredTransactions.length > 0 ? /* @__PURE__ */ jsx(
610
- TransactionList,
611
- {
612
- transactions: filteredTransactions,
613
- onViewDetails: handleViewDetails,
614
- onStatusUpdate: handleStatusUpdate
615
- }
616
- ) : /* @__PURE__ */ jsx("p", { children: "No transactions found" }) })
617
- ] })
618
- ]
619
- }
620
- )
621
- ] }),
622
- /* @__PURE__ */ jsx(
623
- TransactionDetailsModal,
624
- {
625
- isOpen: isModalOpen,
626
- onClose: () => setIsModalOpen(false),
627
- transaction: selectedTransaction,
628
- onRefund: handleRefund
629
- }
630
- )
631
- ] });
632
- };
633
- const DashboardPage = () => {
634
- const [transactions, setTransactions] = useState([]);
635
- const [loading, setLoading] = useState(false);
636
- const [error, setError] = useState(null);
637
- const [stats, setStats] = useState({
638
- totalRevenue: 0,
639
- totalTransactions: 0,
640
- successRate: 0
641
- });
642
- const fetchData = async () => {
643
- setLoading(true);
644
- setError(null);
645
- try {
646
- const response = await fetch("/payment-plugin/transactions");
647
- if (!response.ok) {
648
- throw new Error("Failed to fetch transactions");
649
- }
650
- const data = await response.json();
651
- setTransactions(data.data.slice(0, 5));
652
- const totalAmount = data.data.reduce(
653
- (sum, t) => sum + t.amount,
654
- 0
655
- );
656
- const successCount = data.data.filter(
657
- (t) => t.status === "completed"
658
- ).length;
659
- const successRate = data.data.length > 0 ? successCount / data.data.length * 100 : 0;
660
- setStats({
661
- totalRevenue: totalAmount,
662
- totalTransactions: data.data.length,
663
- successRate
664
- });
665
- } catch (err) {
666
- if (err instanceof Error) {
667
- setError(err.message);
668
- } else {
669
- setError("An unknown error occurred");
670
- }
671
- } finally {
672
- setLoading(false);
673
- }
674
- };
675
- useEffect(() => {
676
- fetchData();
677
- }, []);
678
- return /* @__PURE__ */ jsxs(Main, { children: [
679
- /* @__PURE__ */ jsx(Main, { title: "Payment Dashboard" }),
680
- /* @__PURE__ */ jsxs(Box, { padding: 6, background: "neutral0", children: [
681
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", as: "h1", textColor: "primary600", style: { marginBottom: "2rem" }, children: "Payment Dashboard" }),
682
- /* @__PURE__ */ jsxs(
683
- Box,
684
- {
685
- padding: 4,
686
- background: "neutral100",
687
- borderRadius: "4px",
688
- border: "1px solid #e0e0e0",
689
- style: { marginBottom: "2rem" },
690
- children: [
691
- /* @__PURE__ */ jsx(Typography, { variant: "beta", as: "h2", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Payment Statistics" }),
692
- loading && /* @__PURE__ */ jsx("p", { children: "Loading statistics..." }),
693
- error && /* @__PURE__ */ jsx("p", { style: { color: "red" }, children: error }),
694
- !loading && !error && /* @__PURE__ */ jsxs(Grid.Root, { gap: 4, children: [
695
- /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
696
- /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral800", children: "Total Revenue" }),
697
- /* @__PURE__ */ jsxs(Typography, { variant: "alpha", textColor: "primary600", children: [
698
- "$",
699
- stats.totalRevenue.toFixed(2)
700
- ] })
701
- ] }) }),
702
- /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
703
- /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral800", children: "Total Transactions" }),
704
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", textColor: "primary600", children: stats.totalTransactions })
705
- ] }) }),
706
- /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral0", borderRadius: "4px", border: "1px solid #e0e0e0", children: [
707
- /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral800", children: "Successful Payments" }),
708
- /* @__PURE__ */ jsxs(Typography, { variant: "alpha", textColor: "primary600", children: [
709
- stats.successRate.toFixed(2),
710
- "%"
711
- ] })
712
- ] }) })
713
- ] })
714
- ]
715
- }
716
- ),
717
- /* @__PURE__ */ jsxs(
718
- Box,
719
- {
720
- padding: 4,
721
- background: "neutral100",
722
- borderRadius: "4px",
723
- border: "1px solid #e0e0e0",
724
- children: [
725
- /* @__PURE__ */ jsx(Typography, { variant: "beta", as: "h2", textColor: "neutral800", style: { marginBottom: "1rem" }, children: "Recent Transactions" }),
726
- loading && /* @__PURE__ */ jsx("p", { children: "Loading transactions..." }),
727
- error && /* @__PURE__ */ jsx("p", { style: { color: "red" }, children: error }),
728
- !loading && !error && /* @__PURE__ */ jsx(Fragment, { children: transactions.length > 0 ? /* @__PURE__ */ jsx(TransactionList, { transactions, onViewDetails: () => {
729
- } }) : /* @__PURE__ */ jsx("p", { children: "No recent transactions" }) })
730
- ]
731
- }
732
- )
733
- ] })
734
- ] });
735
- };
736
- const ProductsPage = () => {
737
- const [products, setProducts] = useState([]);
738
- const [loading, setLoading] = useState(false);
739
- const [error, setError] = useState(null);
740
- const [isModalOpen, setIsModalOpen] = useState(false);
741
- const [currentProduct, setCurrentProduct] = useState(null);
742
- const fetchProducts = async () => {
743
- setLoading(true);
744
- setError(null);
745
- try {
746
- const response = await fetch("/payment-plugin/products");
747
- if (!response.ok) {
748
- throw new Error("Failed to fetch products");
749
- }
750
- const data = await response.json();
751
- setProducts(data);
752
- } catch (err) {
753
- if (err instanceof Error) {
754
- setError(err.message);
755
- } else {
756
- setError("An unknown error occurred");
757
- }
758
- } finally {
759
- setLoading(false);
760
- }
761
- };
762
- useEffect(() => {
763
- fetchProducts();
764
- }, []);
765
- const handleEdit = (product) => {
766
- setCurrentProduct(product);
767
- setIsModalOpen(true);
768
- };
769
- const handleDelete = async (id) => {
770
- if (confirm("Are you sure you want to delete this product?")) {
771
- try {
772
- const response = await fetch(`/payment-plugin/products/${id}`, {
773
- method: "DELETE"
774
- });
775
- if (!response.ok) {
776
- throw new Error("Failed to delete product");
777
- }
778
- fetchProducts();
779
- } catch (err) {
780
- if (err instanceof Error) {
781
- setError(err.message);
782
- } else {
783
- setError("An unknown error occurred");
784
- }
785
- }
786
- }
787
- };
788
- return /* @__PURE__ */ jsx(Main, { children: /* @__PURE__ */ jsxs(Box, { padding: 6, background: "neutral0", children: [
789
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", as: "h1", textColor: "primary600", style: { marginBottom: "2rem" }, children: "Products" }),
790
- error && /* @__PURE__ */ jsx(Alert, { variant: "danger", style: { marginBottom: "1rem" }, children: error }),
791
- loading && /* @__PURE__ */ jsx("p", { children: "Loading products..." }),
792
- /* @__PURE__ */ jsxs(Modal.Root, { children: [
793
- /* @__PURE__ */ jsx(Modal.Trigger, { children: /* @__PURE__ */ jsx(Button, { children: "Create product" }) }),
794
- /* @__PURE__ */ jsxs(Modal.Content, { children: [
795
- /* @__PURE__ */ jsxs(Modal.Header, { children: [
796
- /* @__PURE__ */ jsx(Modal.Title, { children: currentProduct ? currentProduct.id ? "Edit Product" : "Create Product" : "Product" }),
797
- /* @__PURE__ */ jsx(Modal.CloseButton, {})
798
- ] }),
799
- /* @__PURE__ */ jsx(Modal.Body, {})
800
- ] })
801
- ] }),
802
- /* @__PURE__ */ jsx(Grid.Root, { gap: 4, children: products.map((product) => /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxs(
803
- Box,
804
- {
805
- padding: 4,
806
- background: "neutral100",
807
- borderRadius: "4px",
808
- border: "1px solid #e0e0e0",
809
- children: [
810
- /* @__PURE__ */ jsx(Typography, { variant: "beta", as: "h2", textColor: "neutral800", children: product.name }),
811
- /* @__PURE__ */ jsxs(Typography, { textColor: "neutral600", children: [
812
- product.price,
813
- " ",
814
- product.currency,
815
- " ",
816
- product.isSubscription ? `/ ${product.subscriptionInterval}` : ""
817
- ] }),
818
- /* @__PURE__ */ jsx(Typography, { textColor: "neutral600", style: { marginTop: "1rem" }, children: product.description }),
819
- /* @__PURE__ */ jsxs(Flex, { style: { marginTop: "1rem", gap: "1rem" }, children: [
820
- /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => handleEdit(product), children: "Edit" }),
821
- /* @__PURE__ */ jsx(Button, { variant: "danger", onClick: () => handleDelete(product.id), children: "Delete" })
822
- ] })
823
- ]
824
- },
825
- product.id
826
- ) }, product.id)) })
827
- ] }) });
828
- };
829
- const SubscriptionsPage = () => {
830
- const [subscriptions, setSubscriptions] = useState([]);
831
- const [products, setProducts] = useState([]);
832
- const [loading, setLoading] = useState(false);
833
- const [error, setError] = useState(null);
834
- const [isModalOpen, setIsModalOpen] = useState(false);
835
- const [currentSubscription, setCurrentSubscription] = useState(null);
836
- const fetchSubscriptions = async () => {
837
- setLoading(true);
838
- setError(null);
839
- try {
840
- const response = await fetch("/payment-plugin/subscriptions");
841
- if (!response.ok) {
842
- throw new Error("Failed to fetch subscriptions");
843
- }
844
- const data = await response.json();
845
- setSubscriptions(data);
846
- } catch (err) {
847
- if (err instanceof Error) {
848
- setError(err.message);
849
- } else {
850
- setError("An unknown error occurred");
851
- }
852
- } finally {
853
- setLoading(false);
854
- }
855
- };
856
- const fetchProducts = async () => {
857
- try {
858
- const response = await fetch("/payment-plugin/products");
859
- if (!response.ok) {
860
- throw new Error("Failed to fetch products");
861
- }
862
- const data = await response.json();
863
- setProducts(data);
864
- } catch (err) {
865
- console.error("Failed to fetch products:", err);
866
- }
867
- };
868
- useEffect(() => {
869
- fetchSubscriptions();
870
- fetchProducts();
871
- }, []);
872
- const handleEdit = (subscription) => {
873
- setCurrentSubscription(subscription);
874
- setIsModalOpen(true);
875
- };
876
- const handleDelete = async (id) => {
877
- if (confirm("Are you sure you want to delete this subscription?")) {
878
- try {
879
- const response = await fetch(`/payment-plugin/subscriptions/${id}`, {
880
- method: "DELETE"
881
- });
882
- if (!response.ok) {
883
- throw new Error("Failed to delete subscription");
884
- }
885
- fetchSubscriptions();
886
- } catch (err) {
887
- if (err instanceof Error) {
888
- setError(err.message);
889
- } else {
890
- setError("An unknown error occurred");
891
- }
892
- }
893
- }
894
- };
895
- const handleSubmit = async (values) => {
896
- if (!currentSubscription) return;
897
- try {
898
- const method = currentSubscription.id ? "PUT" : "POST";
899
- const url = currentSubscription.id ? `/payment-plugin/subscriptions/${currentSubscription.id}` : "/payment-plugin/subscriptions";
900
- const response = await fetch(url, {
901
- method,
902
- headers: {
903
- "Content-Type": "application/json"
904
- },
905
- body: JSON.stringify({ data: values })
906
- });
907
- if (!response.ok) {
908
- throw new Error(`Failed to ${currentSubscription.id ? "update" : "create"} subscription`);
909
- }
910
- setIsModalOpen(false);
911
- fetchSubscriptions();
912
- } catch (err) {
913
- if (err instanceof Error) {
914
- setError(err.message);
915
- } else {
916
- setError("An unknown error occurred");
917
- }
918
- }
919
- };
920
- return /* @__PURE__ */ jsx(Main, { children: /* @__PURE__ */ jsxs(Box, { padding: 6, background: "neutral0", children: [
921
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", as: "h1", textColor: "primary600", style: { marginBottom: "2rem" }, children: "Subscriptions" }),
922
- error && /* @__PURE__ */ jsx(Alert, { variant: "danger", style: { marginBottom: "1rem" }, children: error }),
923
- loading && /* @__PURE__ */ jsx("p", { children: "Loading subscriptions..." }),
924
- /* @__PURE__ */ jsxs(Modal.Root, { children: [
925
- /* @__PURE__ */ jsx(Modal.Trigger, { children: /* @__PURE__ */ jsx(Button, { children: "Create subscription" }) }),
926
- /* @__PURE__ */ jsxs(Modal.Content, { children: [
927
- /* @__PURE__ */ jsx(Modal.Header, { children: /* @__PURE__ */ jsx(Modal.Title, { children: currentSubscription ? currentSubscription.id ? "Edit Subscription" : "Create Subscription" : "Subscription" }) }),
928
- /* @__PURE__ */ jsx(Modal.Body, { children: /* @__PURE__ */ jsx(Box, { padding: 4, children: /* @__PURE__ */ jsx(
929
- Formik,
930
- {
931
- initialValues: {
932
- id: currentSubscription?.id || 0,
933
- product: currentSubscription?.product || { id: 0, name: "" },
934
- user: currentSubscription?.user || { id: 0, email: "" },
935
- status: currentSubscription?.status || "active",
936
- startDate: currentSubscription?.startDate || (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
937
- endDate: currentSubscription?.endDate || ""
938
- },
939
- onSubmit: handleSubmit,
940
- children: ({ values, handleChange, setFieldValue }) => /* @__PURE__ */ jsx(Form, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 4, children: [
941
- /* @__PURE__ */ jsxs(
942
- SingleSelect,
943
- {
944
- placeholder: "Product",
945
- name: "product.id",
946
- value: values.product.id || "",
947
- onChange: (e) => {
948
- const selectedProduct = products.find(
949
- (p) => p.id === parseInt(e.target.value)
950
- );
951
- setFieldValue("product", selectedProduct || { id: 0, name: "" });
952
- },
953
- required: true,
954
- children: [
955
- /* @__PURE__ */ jsx("option", { value: "", children: "Select a product" }),
956
- products.map((product) => /* @__PURE__ */ jsx("option", { value: product.id, children: product.name }, product.id))
957
- ]
958
- }
959
- ),
960
- /* @__PURE__ */ jsx(
961
- TextInput,
962
- {
963
- placeholder: "User Email",
964
- name: "user.email",
965
- value: values.user.email,
966
- onChange: handleChange,
967
- required: true
968
- }
969
- ),
970
- /* @__PURE__ */ jsxs(
971
- SingleSelect,
972
- {
973
- placeholder: "Status",
974
- name: "status",
975
- value: values.status,
976
- onChange: handleChange,
977
- children: [
978
- /* @__PURE__ */ jsx("option", { value: "active", children: "Active" }),
979
- /* @__PURE__ */ jsx("option", { value: "canceled", children: "Canceled" }),
980
- /* @__PURE__ */ jsx("option", { value: "past_due", children: "Past Due" }),
981
- /* @__PURE__ */ jsx("option", { value: "unpaid", children: "Unpaid" }),
982
- /* @__PURE__ */ jsx("option", { value: "trialing", children: "Trialing" })
983
- ]
984
- }
985
- ),
986
- /* @__PURE__ */ jsx(
987
- TextInput,
988
- {
989
- placeholder: "Start Date",
990
- name: "startDate",
991
- type: "date",
992
- value: values.startDate,
993
- onChange: handleChange,
994
- required: true
995
- }
996
- ),
997
- /* @__PURE__ */ jsx(
998
- TextInput,
999
- {
1000
- placeholder: "End Date",
1001
- name: "endDate",
1002
- type: "date",
1003
- value: values.endDate,
1004
- onChange: handleChange
1005
- }
1006
- ),
1007
- /* @__PURE__ */ jsx(Button, { type: "submit", style: { marginTop: "1rem" }, children: currentSubscription?.id ? "Update" : "Create" })
1008
- ] }) })
1009
- }
1010
- ) }) })
1011
- ] })
1012
- ] }),
1013
- /* @__PURE__ */ jsx(Grid.Root, { gap: 4, children: subscriptions.map((subscription) => /* @__PURE__ */ jsx(Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxs(
1014
- Box,
1015
- {
1016
- padding: 4,
1017
- background: "neutral100",
1018
- borderRadius: "4px",
1019
- border: "1px solid #e0e0e0",
1020
- children: [
1021
- /* @__PURE__ */ jsx(Typography, { variant: "beta", as: "h2", textColor: "neutral800", children: subscription.product.name }),
1022
- /* @__PURE__ */ jsxs(Typography, { textColor: "neutral600", children: [
1023
- "User: ",
1024
- subscription.user.email
1025
- ] }),
1026
- /* @__PURE__ */ jsxs(Typography, { textColor: "neutral600", children: [
1027
- "Status: ",
1028
- subscription.status
1029
- ] }),
1030
- /* @__PURE__ */ jsxs(Typography, { textColor: "neutral600", children: [
1031
- "Start Date: ",
1032
- subscription.startDate
1033
- ] }),
1034
- subscription.endDate && /* @__PURE__ */ jsxs(Typography, { textColor: "neutral600", children: [
1035
- "End Date: ",
1036
- subscription.endDate
1037
- ] }),
1038
- /* @__PURE__ */ jsxs(Flex, { style: { marginTop: "1rem", gap: "1rem" }, children: [
1039
- /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => handleEdit(subscription), children: "Edit" }),
1040
- /* @__PURE__ */ jsx(Button, { variant: "danger", onClick: () => handleDelete(subscription.id), children: "Delete" })
1041
- ] })
1042
- ]
1043
- },
1044
- subscription.id
1045
- ) }, subscription.id)) })
1046
- ] }) });
1047
- };
1048
- const NavigationMenu = () => {
1049
- return /* @__PURE__ */ jsxs(
1050
- Box,
1051
- {
1052
- background: "neutral100",
1053
- padding: 4,
1054
- width: "200px",
1055
- height: "100vh",
1056
- position: "fixed",
1057
- top: 0,
1058
- left: 100,
1059
- children: [
1060
- /* @__PURE__ */ jsx(Typography, { variant: "beta", as: "h1", style: { marginBottom: "2rem" }, children: "Payment Plugin" }),
1061
- /* @__PURE__ */ jsx("nav", { children: /* @__PURE__ */ jsxs("ul", { style: { listStyle: "none", padding: 0, fontSize: "14px" }, children: [
1062
- /* @__PURE__ */ jsx("li", { style: { marginBottom: "1rem" }, children: /* @__PURE__ */ jsx(
1063
- NavLink,
1064
- {
1065
- to: "/plugins/payment-plugin/",
1066
- style: ({ isActive }) => ({
1067
- color: isActive ? "#7b79ff" : "inherit",
1068
- textDecoration: "none"
1069
- }),
1070
- children: "Home"
1071
- }
1072
- ) }),
1073
- /* @__PURE__ */ jsx("li", { style: { marginBottom: "1rem" }, children: /* @__PURE__ */ jsx(
1074
- NavLink,
1075
- {
1076
- to: "/plugins/payment-plugin/dashboard",
1077
- style: ({ isActive }) => ({
1078
- color: isActive ? "#7b79ff" : "inherit",
1079
- textDecoration: "none"
1080
- }),
1081
- children: "Dashboard"
1082
- }
1083
- ) }),
1084
- /* @__PURE__ */ jsx("li", { style: { marginBottom: "1rem" }, children: /* @__PURE__ */ jsx(
1085
- NavLink,
1086
- {
1087
- to: "/plugins/payment-plugin/transactions",
1088
- style: ({ isActive }) => ({
1089
- color: isActive ? "#7b79ff" : "inherit",
1090
- textDecoration: "none"
1091
- }),
1092
- children: "Transactions"
1093
- }
1094
- ) }),
1095
- /* @__PURE__ */ jsx("li", { style: { marginBottom: "1rem" }, children: /* @__PURE__ */ jsx(
1096
- NavLink,
1097
- {
1098
- to: "/plugins/payment-plugin/products",
1099
- style: ({ isActive }) => ({
1100
- color: isActive ? "#7b79ff" : "inherit",
1101
- textDecoration: "none"
1102
- }),
1103
- children: "Products"
1104
- }
1105
- ) }),
1106
- /* @__PURE__ */ jsx("li", { style: { marginBottom: "1rem" }, children: /* @__PURE__ */ jsx(
1107
- NavLink,
1108
- {
1109
- to: "/plugins/payment-plugin/subscriptions",
1110
- style: ({ isActive }) => ({
1111
- color: isActive ? "#7b79ff" : "inherit",
1112
- textDecoration: "none"
1113
- }),
1114
- children: "Subscriptions"
1115
- }
1116
- ) }),
1117
- /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
1118
- NavLink,
1119
- {
1120
- to: "/plugins/payment-plugin/configuration",
1121
- style: ({ isActive }) => ({
1122
- color: isActive ? "#7b79ff" : "inherit",
1123
- textDecoration: "none"
1124
- }),
1125
- children: "Configuration"
1126
- }
1127
- ) })
1128
- ] }) })
1129
- ]
1130
- }
1131
- );
1132
- };
1133
- const App = () => {
1134
- return /* @__PURE__ */ jsxs("div", { style: { display: "flex" }, children: [
1135
- /* @__PURE__ */ jsx(NavigationMenu, {}),
1136
- /* @__PURE__ */ jsx("div", { style: { marginLeft: "200px", flex: 1 }, children: /* @__PURE__ */ jsxs(Routes, { children: [
1137
- /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(HomePage, {}) }),
1138
- /* @__PURE__ */ jsx(Route, { path: "/dashboard", element: /* @__PURE__ */ jsx(DashboardPage, {}) }),
1139
- /* @__PURE__ */ jsx(Route, { path: "/transactions", element: /* @__PURE__ */ jsx(TransactionsPage, {}) }),
1140
- /* @__PURE__ */ jsx(Route, { path: "/products", element: /* @__PURE__ */ jsx(ProductsPage, {}) }),
1141
- /* @__PURE__ */ jsx(Route, { path: "/subscriptions", element: /* @__PURE__ */ jsx(SubscriptionsPage, {}) }),
1142
- /* @__PURE__ */ jsx(Route, { path: "/configuration", element: /* @__PURE__ */ jsx(ConfigurationPage, {}) }),
1143
- /* @__PURE__ */ jsx(Route, { path: "*", element: /* @__PURE__ */ jsx(Page.Error, {}) })
1144
- ] }) })
1145
- ] });
1146
- };
1147
- export {
1148
- App
1149
- };