@btst/plugin-affiliate 0.0.0-stage → 1.0.0-beta.0

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 (79) hide show
  1. package/LICENSE.md +17 -0
  2. package/dist/api/getters.cjs +182 -0
  3. package/dist/api/getters.mjs +166 -0
  4. package/dist/api/index.cjs +49 -0
  5. package/dist/api/index.d.cts +975 -0
  6. package/dist/api/index.d.mts +975 -0
  7. package/dist/api/index.d.ts +975 -0
  8. package/dist/api/index.mjs +7 -0
  9. package/dist/api/mutations.cjs +362 -0
  10. package/dist/api/mutations.mjs +352 -0
  11. package/dist/api/operations.cjs +328 -0
  12. package/dist/api/operations.mjs +326 -0
  13. package/dist/api/plugin.cjs +146 -0
  14. package/dist/api/plugin.mjs +144 -0
  15. package/dist/attribution.cjs +92 -0
  16. package/dist/attribution.d.cts +20 -0
  17. package/dist/attribution.d.mts +20 -0
  18. package/dist/attribution.d.ts +20 -0
  19. package/dist/attribution.mjs +82 -0
  20. package/dist/client/components/index.cjs +12 -0
  21. package/dist/client/components/index.d.cts +13 -0
  22. package/dist/client/components/index.d.mts +13 -0
  23. package/dist/client/components/index.d.ts +13 -0
  24. package/dist/client/components/index.mjs +1 -0
  25. package/dist/client/components/pages/affiliate-apply-page.internal.cjs +59 -0
  26. package/dist/client/components/pages/affiliate-apply-page.internal.mjs +57 -0
  27. package/dist/client/components/pages/affiliate-detail-page.internal.cjs +112 -0
  28. package/dist/client/components/pages/affiliate-detail-page.internal.mjs +110 -0
  29. package/dist/client/components/pages/affiliate-portal-page.internal.cjs +252 -0
  30. package/dist/client/components/pages/affiliate-portal-page.internal.mjs +250 -0
  31. package/dist/client/components/pages/affiliates-page.internal.cjs +160 -0
  32. package/dist/client/components/pages/affiliates-page.internal.mjs +158 -0
  33. package/dist/client/components/pages/commissions-page.internal.cjs +151 -0
  34. package/dist/client/components/pages/commissions-page.internal.mjs +149 -0
  35. package/dist/client/components/pages/payouts-page.internal.cjs +230 -0
  36. package/dist/client/components/pages/payouts-page.internal.mjs +228 -0
  37. package/dist/client/components/pages.cjs +145 -0
  38. package/dist/client/components/pages.mjs +138 -0
  39. package/dist/client/components/shared.cjs +331 -0
  40. package/dist/client/components/shared.mjs +316 -0
  41. package/dist/client/constants.cjs +5 -0
  42. package/dist/client/constants.mjs +3 -0
  43. package/dist/client/hooks/index.cjs +77 -0
  44. package/dist/client/hooks/index.d.cts +39 -0
  45. package/dist/client/hooks/index.d.mts +39 -0
  46. package/dist/client/hooks/index.d.ts +39 -0
  47. package/dist/client/hooks/index.mjs +61 -0
  48. package/dist/client/index.cjs +7 -0
  49. package/dist/client/index.d.cts +110 -0
  50. package/dist/client/index.d.mts +110 -0
  51. package/dist/client/index.d.ts +110 -0
  52. package/dist/client/index.mjs +1 -0
  53. package/dist/client/plugin.cjs +77 -0
  54. package/dist/client/plugin.mjs +75 -0
  55. package/dist/client.css +311 -0
  56. package/dist/commission.cjs +24 -0
  57. package/dist/commission.mjs +22 -0
  58. package/dist/db.cjs +74 -0
  59. package/dist/db.mjs +72 -0
  60. package/dist/permissions.cjs +53 -0
  61. package/dist/permissions.d.cts +78 -0
  62. package/dist/permissions.d.mts +78 -0
  63. package/dist/permissions.d.ts +78 -0
  64. package/dist/permissions.mjs +51 -0
  65. package/dist/query-keys.cjs +152 -0
  66. package/dist/query-keys.d.cts +394 -0
  67. package/dist/query-keys.d.mts +394 -0
  68. package/dist/query-keys.d.ts +394 -0
  69. package/dist/query-keys.mjs +149 -0
  70. package/dist/schemas.cjs +95 -0
  71. package/dist/schemas.mjs +77 -0
  72. package/dist/style.css +313 -0
  73. package/dist/types.cjs +2 -0
  74. package/dist/types.d.cts +176 -0
  75. package/dist/types.d.mts +176 -0
  76. package/dist/types.d.ts +176 -0
  77. package/dist/types.mjs +1 -0
  78. package/package.json +159 -3
  79. package/README.md +0 -3
@@ -0,0 +1,158 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useState } from 'react';
4
+ import { usePluginSiteNavigation, usePluginOverrides, PermissionAccess } from '@btst/stack/context';
5
+ import { affiliatePermissions } from '../../../permissions.mjs';
6
+ import { useAffiliates, useCreateAffiliate, useUpdateAffiliate } from '../../hooks/index.mjs';
7
+ import { AFFILIATE_PLUGIN_ID } from '../../constants.mjs';
8
+ import { useAffiliateAction, AffiliatePage, ActionNotice, ProfileFields, Field, Status, date, Pagination, readProfile } from '../shared.mjs';
9
+
10
+ function AffiliatesPage() {
11
+ const [status, setStatus] = useState("");
12
+ const [offset, setOffset] = useState(0);
13
+ const [adding, setAdding] = useState(false);
14
+ const { data } = useAffiliates({
15
+ status: status || void 0,
16
+ limit: 25,
17
+ offset
18
+ });
19
+ const create = useCreateAffiliate();
20
+ const update = useUpdateAffiliate();
21
+ const action = useAffiliateAction();
22
+ const { Link, resolve } = usePluginSiteNavigation(AFFILIATE_PLUGIN_ID);
23
+ const { localization } = usePluginOverrides(AFFILIATE_PLUGIN_ID);
24
+ const save = (event) => {
25
+ event.preventDefault();
26
+ const fields = new FormData(event.currentTarget);
27
+ void action.run(async () => {
28
+ await create.mutateAsync({
29
+ ...readProfile(fields),
30
+ userId: String(fields.get("userId") ?? "")
31
+ });
32
+ setAdding(false);
33
+ }, "Affiliate added. Review the profile to approve the application.");
34
+ };
35
+ return /* @__PURE__ */ jsxs(
36
+ AffiliatePage,
37
+ {
38
+ title: localization?.affiliates ?? "Affiliates",
39
+ description: "Review applications, approve partners, and manage referral profiles.",
40
+ action: /* @__PURE__ */ jsx(PermissionAccess, { permission: affiliatePermissions.affiliate.create(), children: /* @__PURE__ */ jsx(
41
+ "button",
42
+ {
43
+ className: "affiliate-primary",
44
+ type: "button",
45
+ onClick: () => setAdding(!adding),
46
+ children: adding ? "Close form" : "Add affiliate"
47
+ }
48
+ ) }),
49
+ children: [
50
+ /* @__PURE__ */ jsx(ActionNotice, { ...action }),
51
+ adding && /* @__PURE__ */ jsxs("form", { className: "affiliate-panel affiliate-stack", onSubmit: save, children: [
52
+ /* @__PURE__ */ jsx("h2", { children: "Add affiliate" }),
53
+ /* @__PURE__ */ jsxs("fieldset", { disabled: action.pending, children: [
54
+ /* @__PURE__ */ jsx(ProfileFields, { userId: true }),
55
+ /* @__PURE__ */ jsxs("div", { className: "affiliate-actions", children: [
56
+ /* @__PURE__ */ jsx("button", { className: "affiliate-primary", type: "submit", children: action.pending ? "Saving\u2026" : "Save affiliate" }),
57
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setAdding(false), children: "Cancel" })
58
+ ] })
59
+ ] })
60
+ ] }),
61
+ /* @__PURE__ */ jsxs("div", { className: "affiliate-toolbar", children: [
62
+ /* @__PURE__ */ jsx(Field, { label: "Filter by status", children: /* @__PURE__ */ jsxs(
63
+ "select",
64
+ {
65
+ value: status,
66
+ onChange: (event) => {
67
+ setStatus(event.target.value);
68
+ setOffset(0);
69
+ },
70
+ children: [
71
+ /* @__PURE__ */ jsx("option", { value: "", children: "All statuses" }),
72
+ /* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
73
+ /* @__PURE__ */ jsx("option", { value: "approved", children: "Approved" }),
74
+ /* @__PURE__ */ jsx("option", { value: "suspended", children: "Suspended" })
75
+ ]
76
+ }
77
+ ) }),
78
+ /* @__PURE__ */ jsxs("p", { className: "affiliate-muted", children: [
79
+ data.total,
80
+ " ",
81
+ data.total === 1 ? "affiliate" : "affiliates"
82
+ ] })
83
+ ] }),
84
+ data.items.length === 0 ? /* @__PURE__ */ jsx("p", { className: "affiliate-empty", children: "No affiliates match. Add an affiliate or adjust the status filter." }) : /* @__PURE__ */ jsx(
85
+ "div",
86
+ {
87
+ className: "affiliate-table-scroll",
88
+ role: "region",
89
+ "aria-label": "Affiliates",
90
+ tabIndex: 0,
91
+ children: /* @__PURE__ */ jsxs("table", { children: [
92
+ /* @__PURE__ */ jsx("caption", { className: "affiliate-sr-only", children: "Affiliate applications and profiles" }),
93
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
94
+ /* @__PURE__ */ jsx("th", { children: "Name" }),
95
+ /* @__PURE__ */ jsx("th", { children: "Referral code" }),
96
+ /* @__PURE__ */ jsx("th", { children: "Status" }),
97
+ /* @__PURE__ */ jsx("th", { children: "Applied" }),
98
+ /* @__PURE__ */ jsx("th", { children: "Actions" })
99
+ ] }) }),
100
+ /* @__PURE__ */ jsx("tbody", { children: data.items.map((affiliate) => /* @__PURE__ */ jsxs("tr", { children: [
101
+ /* @__PURE__ */ jsxs("td", { children: [
102
+ /* @__PURE__ */ jsx(
103
+ Link,
104
+ {
105
+ className: "affiliate-record-link",
106
+ href: resolve(
107
+ "affiliate/admin/affiliates",
108
+ encodeURIComponent(affiliate.id)
109
+ ).href,
110
+ children: affiliate.name
111
+ }
112
+ ),
113
+ /* @__PURE__ */ jsx("p", { className: "affiliate-small affiliate-muted", children: affiliate.email })
114
+ ] }),
115
+ /* @__PURE__ */ jsx("td", { children: affiliate.code }),
116
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(Status, { value: affiliate.status }) }),
117
+ /* @__PURE__ */ jsx("td", { children: date(affiliate.createdAt) }),
118
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(
119
+ PermissionAccess,
120
+ {
121
+ permission: affiliatePermissions.affiliate.update({
122
+ affiliateId: affiliate.id,
123
+ userId: affiliate.userId,
124
+ status: affiliate.status
125
+ }),
126
+ children: /* @__PURE__ */ jsx(
127
+ "button",
128
+ {
129
+ type: "button",
130
+ disabled: action.pending,
131
+ "aria-label": `${affiliate.status === "approved" ? "Suspend" : "Approve"} ${affiliate.name}`,
132
+ onClick: () => void action.run(
133
+ async () => {
134
+ await update.mutateAsync({
135
+ id: affiliate.id,
136
+ data: {
137
+ status: affiliate.status === "approved" ? "suspended" : "approved"
138
+ }
139
+ });
140
+ },
141
+ affiliate.status === "approved" ? "Affiliate suspended" : "Affiliate approved"
142
+ ),
143
+ children: affiliate.status === "approved" ? "Suspend" : "Approve"
144
+ }
145
+ )
146
+ }
147
+ ) })
148
+ ] }, affiliate.id)) })
149
+ ] })
150
+ }
151
+ ),
152
+ /* @__PURE__ */ jsx(Pagination, { offset, total: data.total, onChange: setOffset })
153
+ ]
154
+ }
155
+ );
156
+ }
157
+
158
+ export { AffiliatesPage };
@@ -0,0 +1,151 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ const jsxRuntime = require('react/jsx-runtime');
5
+ const react = require('react');
6
+ const context = require('@btst/stack/context');
7
+ const permissions = require('../../../permissions.cjs');
8
+ const client_hooks_index = require('../../hooks/index.cjs');
9
+ const constants = require('../../constants.cjs');
10
+ const shared = require('../shared.cjs');
11
+
12
+ function CommissionsPage() {
13
+ const [status, setStatus] = react.useState("");
14
+ const [affiliateId, setAffiliateId] = react.useState("");
15
+ const [offset, setOffset] = react.useState(0);
16
+ const { data } = client_hooks_index.useCommissions({
17
+ status: status || void 0,
18
+ affiliateId: affiliateId || void 0,
19
+ offset,
20
+ limit: 25
21
+ });
22
+ const update = client_hooks_index.useUpdateCommission();
23
+ const action = shared.useAffiliateAction();
24
+ const { Link, resolve } = context.usePluginSiteNavigation(constants.AFFILIATE_PLUGIN_ID);
25
+ const { localization } = context.usePluginOverrides(constants.AFFILIATE_PLUGIN_ID);
26
+ return /* @__PURE__ */ jsxRuntime.jsxs(
27
+ shared.AffiliatePage,
28
+ {
29
+ title: localization?.commissions ?? "Commissions",
30
+ description: "Review attributed conversions before including commissions in a payout.",
31
+ children: [
32
+ /* @__PURE__ */ jsxRuntime.jsx(shared.ActionNotice, { ...action }),
33
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "affiliate-toolbar", children: [
34
+ /* @__PURE__ */ jsxRuntime.jsx(shared.Field, { label: "Filter by status", children: /* @__PURE__ */ jsxRuntime.jsxs(
35
+ "select",
36
+ {
37
+ value: status,
38
+ onChange: (event) => {
39
+ setStatus(event.target.value);
40
+ setOffset(0);
41
+ },
42
+ children: [
43
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "All statuses" }),
44
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
45
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "approved", children: "Approved" }),
46
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "paid", children: "Paid" }),
47
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "voided", children: "Voided" })
48
+ ]
49
+ }
50
+ ) }),
51
+ /* @__PURE__ */ jsxRuntime.jsx(shared.Field, { label: "Affiliate ID", children: /* @__PURE__ */ jsxRuntime.jsx(
52
+ "input",
53
+ {
54
+ value: affiliateId,
55
+ onChange: (event) => {
56
+ setAffiliateId(event.target.value);
57
+ setOffset(0);
58
+ },
59
+ placeholder: "All affiliates"
60
+ }
61
+ ) })
62
+ ] }),
63
+ data.items.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "affiliate-empty", children: "No commissions match. Commissions appear after an attributed conversion is recorded." }) : /* @__PURE__ */ jsxRuntime.jsx(
64
+ "div",
65
+ {
66
+ className: "affiliate-table-scroll",
67
+ role: "region",
68
+ "aria-label": "Commissions",
69
+ tabIndex: 0,
70
+ children: /* @__PURE__ */ jsxRuntime.jsxs("table", { children: [
71
+ /* @__PURE__ */ jsxRuntime.jsx("caption", { className: "affiliate-sr-only", children: "Affiliate commission review" }),
72
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
73
+ /* @__PURE__ */ jsxRuntime.jsx("th", { children: "Affiliate / conversion" }),
74
+ /* @__PURE__ */ jsxRuntime.jsx("th", { className: "affiliate-number", children: "Commission" }),
75
+ /* @__PURE__ */ jsxRuntime.jsx("th", { children: "Status" }),
76
+ /* @__PURE__ */ jsxRuntime.jsx("th", { children: "Created" }),
77
+ /* @__PURE__ */ jsxRuntime.jsx("th", { children: "Review" })
78
+ ] }) }),
79
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: data.items.map((commission) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
80
+ /* @__PURE__ */ jsxRuntime.jsxs("td", { children: [
81
+ /* @__PURE__ */ jsxRuntime.jsx(
82
+ Link,
83
+ {
84
+ href: resolve(
85
+ "affiliate/admin/affiliates",
86
+ encodeURIComponent(commission.affiliateId)
87
+ ).href,
88
+ children: commission.affiliateId
89
+ }
90
+ ),
91
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "affiliate-small affiliate-muted", children: commission.conversionId })
92
+ ] }),
93
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "affiliate-number", children: shared.money(commission.amount, commission.currency) }),
94
+ /* @__PURE__ */ jsxRuntime.jsxs("td", { children: [
95
+ /* @__PURE__ */ jsxRuntime.jsx(shared.Status, { value: commission.status }),
96
+ commission.payoutId && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "affiliate-small affiliate-muted", children: "Included in payout" })
97
+ ] }),
98
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: shared.date(commission.createdAt) }),
99
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(
100
+ context.PermissionAccess,
101
+ {
102
+ permission: permissions.affiliatePermissions.commission.update({
103
+ commissionId: commission.id,
104
+ affiliateId: commission.affiliateId,
105
+ status: commission.status
106
+ }),
107
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "affiliate-actions", children: [
108
+ commission.status === "pending" && !commission.payoutId && /* @__PURE__ */ jsxRuntime.jsx(
109
+ "button",
110
+ {
111
+ type: "button",
112
+ disabled: action.pending,
113
+ "aria-label": `Approve commission ${commission.id}`,
114
+ onClick: () => void action.run(async () => {
115
+ await update.mutateAsync({
116
+ id: commission.id,
117
+ status: "approved"
118
+ });
119
+ }, "Commission approved"),
120
+ children: "Approve"
121
+ }
122
+ ),
123
+ ["pending", "approved"].includes(commission.status) && !commission.payoutId && /* @__PURE__ */ jsxRuntime.jsx(
124
+ "button",
125
+ {
126
+ type: "button",
127
+ disabled: action.pending,
128
+ "aria-label": `Void commission ${commission.id}`,
129
+ onClick: () => void action.run(async () => {
130
+ await update.mutateAsync({
131
+ id: commission.id,
132
+ status: "voided"
133
+ });
134
+ }, "Commission voided"),
135
+ children: "Void"
136
+ }
137
+ )
138
+ ] })
139
+ }
140
+ ) })
141
+ ] }, commission.id)) })
142
+ ] })
143
+ }
144
+ ),
145
+ /* @__PURE__ */ jsxRuntime.jsx(shared.Pagination, { offset, total: data.total, onChange: setOffset })
146
+ ]
147
+ }
148
+ );
149
+ }
150
+
151
+ exports.CommissionsPage = CommissionsPage;
@@ -0,0 +1,149 @@
1
+ 'use client';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useState } from 'react';
4
+ import { usePluginSiteNavigation, usePluginOverrides, PermissionAccess } from '@btst/stack/context';
5
+ import { affiliatePermissions } from '../../../permissions.mjs';
6
+ import { useCommissions, useUpdateCommission } from '../../hooks/index.mjs';
7
+ import { AFFILIATE_PLUGIN_ID } from '../../constants.mjs';
8
+ import { useAffiliateAction, AffiliatePage, ActionNotice, Field, money, Status, date, Pagination } from '../shared.mjs';
9
+
10
+ function CommissionsPage() {
11
+ const [status, setStatus] = useState("");
12
+ const [affiliateId, setAffiliateId] = useState("");
13
+ const [offset, setOffset] = useState(0);
14
+ const { data } = useCommissions({
15
+ status: status || void 0,
16
+ affiliateId: affiliateId || void 0,
17
+ offset,
18
+ limit: 25
19
+ });
20
+ const update = useUpdateCommission();
21
+ const action = useAffiliateAction();
22
+ const { Link, resolve } = usePluginSiteNavigation(AFFILIATE_PLUGIN_ID);
23
+ const { localization } = usePluginOverrides(AFFILIATE_PLUGIN_ID);
24
+ return /* @__PURE__ */ jsxs(
25
+ AffiliatePage,
26
+ {
27
+ title: localization?.commissions ?? "Commissions",
28
+ description: "Review attributed conversions before including commissions in a payout.",
29
+ children: [
30
+ /* @__PURE__ */ jsx(ActionNotice, { ...action }),
31
+ /* @__PURE__ */ jsxs("div", { className: "affiliate-toolbar", children: [
32
+ /* @__PURE__ */ jsx(Field, { label: "Filter by status", children: /* @__PURE__ */ jsxs(
33
+ "select",
34
+ {
35
+ value: status,
36
+ onChange: (event) => {
37
+ setStatus(event.target.value);
38
+ setOffset(0);
39
+ },
40
+ children: [
41
+ /* @__PURE__ */ jsx("option", { value: "", children: "All statuses" }),
42
+ /* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
43
+ /* @__PURE__ */ jsx("option", { value: "approved", children: "Approved" }),
44
+ /* @__PURE__ */ jsx("option", { value: "paid", children: "Paid" }),
45
+ /* @__PURE__ */ jsx("option", { value: "voided", children: "Voided" })
46
+ ]
47
+ }
48
+ ) }),
49
+ /* @__PURE__ */ jsx(Field, { label: "Affiliate ID", children: /* @__PURE__ */ jsx(
50
+ "input",
51
+ {
52
+ value: affiliateId,
53
+ onChange: (event) => {
54
+ setAffiliateId(event.target.value);
55
+ setOffset(0);
56
+ },
57
+ placeholder: "All affiliates"
58
+ }
59
+ ) })
60
+ ] }),
61
+ data.items.length === 0 ? /* @__PURE__ */ jsx("p", { className: "affiliate-empty", children: "No commissions match. Commissions appear after an attributed conversion is recorded." }) : /* @__PURE__ */ jsx(
62
+ "div",
63
+ {
64
+ className: "affiliate-table-scroll",
65
+ role: "region",
66
+ "aria-label": "Commissions",
67
+ tabIndex: 0,
68
+ children: /* @__PURE__ */ jsxs("table", { children: [
69
+ /* @__PURE__ */ jsx("caption", { className: "affiliate-sr-only", children: "Affiliate commission review" }),
70
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
71
+ /* @__PURE__ */ jsx("th", { children: "Affiliate / conversion" }),
72
+ /* @__PURE__ */ jsx("th", { className: "affiliate-number", children: "Commission" }),
73
+ /* @__PURE__ */ jsx("th", { children: "Status" }),
74
+ /* @__PURE__ */ jsx("th", { children: "Created" }),
75
+ /* @__PURE__ */ jsx("th", { children: "Review" })
76
+ ] }) }),
77
+ /* @__PURE__ */ jsx("tbody", { children: data.items.map((commission) => /* @__PURE__ */ jsxs("tr", { children: [
78
+ /* @__PURE__ */ jsxs("td", { children: [
79
+ /* @__PURE__ */ jsx(
80
+ Link,
81
+ {
82
+ href: resolve(
83
+ "affiliate/admin/affiliates",
84
+ encodeURIComponent(commission.affiliateId)
85
+ ).href,
86
+ children: commission.affiliateId
87
+ }
88
+ ),
89
+ /* @__PURE__ */ jsx("p", { className: "affiliate-small affiliate-muted", children: commission.conversionId })
90
+ ] }),
91
+ /* @__PURE__ */ jsx("td", { className: "affiliate-number", children: money(commission.amount, commission.currency) }),
92
+ /* @__PURE__ */ jsxs("td", { children: [
93
+ /* @__PURE__ */ jsx(Status, { value: commission.status }),
94
+ commission.payoutId && /* @__PURE__ */ jsx("p", { className: "affiliate-small affiliate-muted", children: "Included in payout" })
95
+ ] }),
96
+ /* @__PURE__ */ jsx("td", { children: date(commission.createdAt) }),
97
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(
98
+ PermissionAccess,
99
+ {
100
+ permission: affiliatePermissions.commission.update({
101
+ commissionId: commission.id,
102
+ affiliateId: commission.affiliateId,
103
+ status: commission.status
104
+ }),
105
+ children: /* @__PURE__ */ jsxs("div", { className: "affiliate-actions", children: [
106
+ commission.status === "pending" && !commission.payoutId && /* @__PURE__ */ jsx(
107
+ "button",
108
+ {
109
+ type: "button",
110
+ disabled: action.pending,
111
+ "aria-label": `Approve commission ${commission.id}`,
112
+ onClick: () => void action.run(async () => {
113
+ await update.mutateAsync({
114
+ id: commission.id,
115
+ status: "approved"
116
+ });
117
+ }, "Commission approved"),
118
+ children: "Approve"
119
+ }
120
+ ),
121
+ ["pending", "approved"].includes(commission.status) && !commission.payoutId && /* @__PURE__ */ jsx(
122
+ "button",
123
+ {
124
+ type: "button",
125
+ disabled: action.pending,
126
+ "aria-label": `Void commission ${commission.id}`,
127
+ onClick: () => void action.run(async () => {
128
+ await update.mutateAsync({
129
+ id: commission.id,
130
+ status: "voided"
131
+ });
132
+ }, "Commission voided"),
133
+ children: "Void"
134
+ }
135
+ )
136
+ ] })
137
+ }
138
+ ) })
139
+ ] }, commission.id)) })
140
+ ] })
141
+ }
142
+ ),
143
+ /* @__PURE__ */ jsx(Pagination, { offset, total: data.total, onChange: setOffset })
144
+ ]
145
+ }
146
+ );
147
+ }
148
+
149
+ export { CommissionsPage };