@btst/plugin-affiliate 0.0.0-stage → 1.0.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.
- package/LICENSE.md +17 -0
- package/dist/api/getters.cjs +182 -0
- package/dist/api/getters.mjs +166 -0
- package/dist/api/index.cjs +49 -0
- package/dist/api/index.d.cts +975 -0
- package/dist/api/index.d.mts +975 -0
- package/dist/api/index.d.ts +975 -0
- package/dist/api/index.mjs +7 -0
- package/dist/api/mutations.cjs +362 -0
- package/dist/api/mutations.mjs +352 -0
- package/dist/api/operations.cjs +328 -0
- package/dist/api/operations.mjs +326 -0
- package/dist/api/plugin.cjs +146 -0
- package/dist/api/plugin.mjs +144 -0
- package/dist/attribution.cjs +92 -0
- package/dist/attribution.d.cts +20 -0
- package/dist/attribution.d.mts +20 -0
- package/dist/attribution.d.ts +20 -0
- package/dist/attribution.mjs +82 -0
- package/dist/client/components/index.cjs +12 -0
- package/dist/client/components/index.d.cts +13 -0
- package/dist/client/components/index.d.mts +13 -0
- package/dist/client/components/index.d.ts +13 -0
- package/dist/client/components/index.mjs +1 -0
- package/dist/client/components/pages/affiliate-apply-page.internal.cjs +59 -0
- package/dist/client/components/pages/affiliate-apply-page.internal.mjs +57 -0
- package/dist/client/components/pages/affiliate-detail-page.internal.cjs +112 -0
- package/dist/client/components/pages/affiliate-detail-page.internal.mjs +110 -0
- package/dist/client/components/pages/affiliate-portal-page.internal.cjs +252 -0
- package/dist/client/components/pages/affiliate-portal-page.internal.mjs +250 -0
- package/dist/client/components/pages/affiliates-page.internal.cjs +160 -0
- package/dist/client/components/pages/affiliates-page.internal.mjs +158 -0
- package/dist/client/components/pages/commissions-page.internal.cjs +151 -0
- package/dist/client/components/pages/commissions-page.internal.mjs +149 -0
- package/dist/client/components/pages/payouts-page.internal.cjs +230 -0
- package/dist/client/components/pages/payouts-page.internal.mjs +228 -0
- package/dist/client/components/pages.cjs +145 -0
- package/dist/client/components/pages.mjs +138 -0
- package/dist/client/components/shared.cjs +331 -0
- package/dist/client/components/shared.mjs +316 -0
- package/dist/client/constants.cjs +5 -0
- package/dist/client/constants.mjs +3 -0
- package/dist/client/hooks/index.cjs +77 -0
- package/dist/client/hooks/index.d.cts +39 -0
- package/dist/client/hooks/index.d.mts +39 -0
- package/dist/client/hooks/index.d.ts +39 -0
- package/dist/client/hooks/index.mjs +61 -0
- package/dist/client/index.cjs +7 -0
- package/dist/client/index.d.cts +110 -0
- package/dist/client/index.d.mts +110 -0
- package/dist/client/index.d.ts +110 -0
- package/dist/client/index.mjs +1 -0
- package/dist/client/plugin.cjs +77 -0
- package/dist/client/plugin.mjs +75 -0
- package/dist/client.css +311 -0
- package/dist/commission.cjs +24 -0
- package/dist/commission.mjs +22 -0
- package/dist/db.cjs +74 -0
- package/dist/db.mjs +72 -0
- package/dist/permissions.cjs +53 -0
- package/dist/permissions.d.cts +78 -0
- package/dist/permissions.d.mts +78 -0
- package/dist/permissions.d.ts +78 -0
- package/dist/permissions.mjs +51 -0
- package/dist/query-keys.cjs +152 -0
- package/dist/query-keys.d.cts +394 -0
- package/dist/query-keys.d.mts +394 -0
- package/dist/query-keys.d.ts +394 -0
- package/dist/query-keys.mjs +149 -0
- package/dist/schemas.cjs +95 -0
- package/dist/schemas.mjs +77 -0
- package/dist/style.css +313 -0
- package/dist/types.cjs +2 -0
- package/dist/types.d.cts +176 -0
- package/dist/types.d.mts +176 -0
- package/dist/types.d.ts +176 -0
- package/dist/types.mjs +1 -0
- package/package.json +159 -3
- package/README.md +0 -3
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { useState, useEffect, lazy } from 'react';
|
|
4
|
+
import { ComposedRoute } from '@btst/stack/client/components';
|
|
5
|
+
import { affiliatePermissions } from '../../permissions.mjs';
|
|
6
|
+
import { AffiliateNotFound, AffiliateLoading, AffiliateError } from './shared.mjs';
|
|
7
|
+
|
|
8
|
+
const Affiliates = lazy(
|
|
9
|
+
() => import('./pages/affiliates-page.internal.mjs').then((m) => ({
|
|
10
|
+
default: m.AffiliatesPage
|
|
11
|
+
}))
|
|
12
|
+
);
|
|
13
|
+
const Detail = lazy(
|
|
14
|
+
() => import('./pages/affiliate-detail-page.internal.mjs').then((m) => ({
|
|
15
|
+
default: m.AffiliateDetailPage
|
|
16
|
+
}))
|
|
17
|
+
);
|
|
18
|
+
const Commissions = lazy(
|
|
19
|
+
() => import('./pages/commissions-page.internal.mjs').then((m) => ({
|
|
20
|
+
default: m.CommissionsPage
|
|
21
|
+
}))
|
|
22
|
+
);
|
|
23
|
+
const Payouts = lazy(
|
|
24
|
+
() => import('./pages/payouts-page.internal.mjs').then((m) => ({
|
|
25
|
+
default: m.PayoutsPage
|
|
26
|
+
}))
|
|
27
|
+
);
|
|
28
|
+
const Apply = lazy(
|
|
29
|
+
() => import('./pages/affiliate-apply-page.internal.mjs').then((m) => ({
|
|
30
|
+
default: m.AffiliateApplyPage
|
|
31
|
+
}))
|
|
32
|
+
);
|
|
33
|
+
const Portal = lazy(
|
|
34
|
+
() => import('./pages/affiliate-portal-page.internal.mjs').then((m) => ({
|
|
35
|
+
default: m.AffiliatePortalPage
|
|
36
|
+
}))
|
|
37
|
+
);
|
|
38
|
+
function BrowserPage({ children }) {
|
|
39
|
+
const [mounted, setMounted] = useState(false);
|
|
40
|
+
useEffect(() => setMounted(true), []);
|
|
41
|
+
return mounted ? children : /* @__PURE__ */ jsx(AffiliateLoading, {});
|
|
42
|
+
}
|
|
43
|
+
const boundary = {
|
|
44
|
+
ErrorComponent: AffiliateError,
|
|
45
|
+
LoadingComponent: AffiliateLoading,
|
|
46
|
+
NotFoundComponent: AffiliateNotFound,
|
|
47
|
+
onError: (error) => console.error("[btst/affiliate]", error)
|
|
48
|
+
};
|
|
49
|
+
function AffiliateList() {
|
|
50
|
+
return /* @__PURE__ */ jsx(BrowserPage, { children: /* @__PURE__ */ jsx(Affiliates, {}) });
|
|
51
|
+
}
|
|
52
|
+
function AffiliateDetail(props) {
|
|
53
|
+
return /* @__PURE__ */ jsx(BrowserPage, { children: /* @__PURE__ */ jsx(Detail, { ...props }) });
|
|
54
|
+
}
|
|
55
|
+
function CommissionList() {
|
|
56
|
+
return /* @__PURE__ */ jsx(BrowserPage, { children: /* @__PURE__ */ jsx(Commissions, {}) });
|
|
57
|
+
}
|
|
58
|
+
function PayoutList() {
|
|
59
|
+
return /* @__PURE__ */ jsx(BrowserPage, { children: /* @__PURE__ */ jsx(Payouts, {}) });
|
|
60
|
+
}
|
|
61
|
+
function Application() {
|
|
62
|
+
return /* @__PURE__ */ jsx(BrowserPage, { children: /* @__PURE__ */ jsx(Apply, {}) });
|
|
63
|
+
}
|
|
64
|
+
function PortalDashboard() {
|
|
65
|
+
return /* @__PURE__ */ jsx(BrowserPage, { children: /* @__PURE__ */ jsx(Portal, {}) });
|
|
66
|
+
}
|
|
67
|
+
function AffiliatesPageComponent() {
|
|
68
|
+
return /* @__PURE__ */ jsx(
|
|
69
|
+
ComposedRoute,
|
|
70
|
+
{
|
|
71
|
+
...boundary,
|
|
72
|
+
path: "/affiliate/admin/affiliates",
|
|
73
|
+
permission: affiliatePermissions.affiliate.read({ scope: "collection" }),
|
|
74
|
+
PageComponent: AffiliateList
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
function AffiliateDetailPageComponent({ id }) {
|
|
79
|
+
return /* @__PURE__ */ jsx(
|
|
80
|
+
ComposedRoute,
|
|
81
|
+
{
|
|
82
|
+
...boundary,
|
|
83
|
+
path: `/affiliate/admin/affiliates/${id}`,
|
|
84
|
+
permission: affiliatePermissions.affiliate.read({
|
|
85
|
+
scope: "record",
|
|
86
|
+
affiliateId: id
|
|
87
|
+
}),
|
|
88
|
+
PageComponent: AffiliateDetail,
|
|
89
|
+
props: { id }
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
function CommissionsPageComponent() {
|
|
94
|
+
return /* @__PURE__ */ jsx(
|
|
95
|
+
ComposedRoute,
|
|
96
|
+
{
|
|
97
|
+
...boundary,
|
|
98
|
+
path: "/affiliate/admin/commissions",
|
|
99
|
+
permission: affiliatePermissions.commission.read(),
|
|
100
|
+
PageComponent: CommissionList
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
function PayoutsPageComponent() {
|
|
105
|
+
return /* @__PURE__ */ jsx(
|
|
106
|
+
ComposedRoute,
|
|
107
|
+
{
|
|
108
|
+
...boundary,
|
|
109
|
+
path: "/affiliate/admin/payouts",
|
|
110
|
+
permission: affiliatePermissions.payout.read(),
|
|
111
|
+
PageComponent: PayoutList
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
function AffiliateApplyPageComponent() {
|
|
116
|
+
return /* @__PURE__ */ jsx(
|
|
117
|
+
ComposedRoute,
|
|
118
|
+
{
|
|
119
|
+
...boundary,
|
|
120
|
+
path: "/affiliate/apply",
|
|
121
|
+
permission: affiliatePermissions.application.create(),
|
|
122
|
+
PageComponent: Application
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
function AffiliatePortalPageComponent() {
|
|
127
|
+
return /* @__PURE__ */ jsx(
|
|
128
|
+
ComposedRoute,
|
|
129
|
+
{
|
|
130
|
+
...boundary,
|
|
131
|
+
path: "/affiliate/portal",
|
|
132
|
+
permission: affiliatePermissions.portal.read(),
|
|
133
|
+
PageComponent: PortalDashboard
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export { AffiliateApplyPageComponent, AffiliateDetailPageComponent, AffiliatePortalPageComponent, AffiliatesPageComponent, CommissionsPageComponent, PayoutsPageComponent };
|
|
@@ -0,0 +1,331 @@
|
|
|
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 constants = require('../constants.cjs');
|
|
9
|
+
|
|
10
|
+
function AffiliatePage({
|
|
11
|
+
title,
|
|
12
|
+
description,
|
|
13
|
+
action,
|
|
14
|
+
admin = true,
|
|
15
|
+
children
|
|
16
|
+
}) {
|
|
17
|
+
const { Link, resolve } = context.usePluginSiteNavigation(constants.AFFILIATE_PLUGIN_ID);
|
|
18
|
+
const { localization } = context.usePluginOverrides(constants.AFFILIATE_PLUGIN_ID);
|
|
19
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "affiliate-page", "data-testid": "affiliate-page", children: [
|
|
20
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "affiliate-heading", children: [
|
|
21
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
22
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { children: title }),
|
|
23
|
+
description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "affiliate-muted", children: description })
|
|
24
|
+
] }),
|
|
25
|
+
action
|
|
26
|
+
] }),
|
|
27
|
+
admin && /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "affiliate-nav", "aria-label": "Affiliate administration", children: [
|
|
28
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
29
|
+
context.PermissionAccess,
|
|
30
|
+
{
|
|
31
|
+
permission: permissions.affiliatePermissions.affiliate.read({
|
|
32
|
+
scope: "collection"
|
|
33
|
+
}),
|
|
34
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Link, { href: resolve("affiliate/admin/affiliates").href, children: localization?.affiliates ?? "Affiliates" })
|
|
35
|
+
}
|
|
36
|
+
),
|
|
37
|
+
/* @__PURE__ */ jsxRuntime.jsx(context.PermissionAccess, { permission: permissions.affiliatePermissions.commission.read(), children: /* @__PURE__ */ jsxRuntime.jsx(Link, { href: resolve("affiliate/admin/commissions").href, children: localization?.commissions ?? "Commissions" }) }),
|
|
38
|
+
/* @__PURE__ */ jsxRuntime.jsx(context.PermissionAccess, { permission: permissions.affiliatePermissions.payout.read(), children: /* @__PURE__ */ jsxRuntime.jsx(Link, { href: resolve("affiliate/admin/payouts").href, children: localization?.payouts ?? "Payouts" }) })
|
|
39
|
+
] }),
|
|
40
|
+
children
|
|
41
|
+
] });
|
|
42
|
+
}
|
|
43
|
+
function Field({
|
|
44
|
+
label,
|
|
45
|
+
hint,
|
|
46
|
+
children
|
|
47
|
+
}) {
|
|
48
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "affiliate-field", children: [
|
|
49
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
|
|
50
|
+
children,
|
|
51
|
+
hint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "affiliate-muted affiliate-small", children: hint })
|
|
52
|
+
] });
|
|
53
|
+
}
|
|
54
|
+
function ProfileFields({
|
|
55
|
+
affiliate,
|
|
56
|
+
defaults,
|
|
57
|
+
userId = false,
|
|
58
|
+
admin = false
|
|
59
|
+
}) {
|
|
60
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "affiliate-form-grid", children: [
|
|
61
|
+
userId && /* @__PURE__ */ jsxRuntime.jsx(
|
|
62
|
+
Field,
|
|
63
|
+
{
|
|
64
|
+
label: "User ID",
|
|
65
|
+
hint: "The account that will own this affiliate portal.",
|
|
66
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("input", { name: "userId", required: true, maxLength: 255 })
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Name", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
70
|
+
"input",
|
|
71
|
+
{
|
|
72
|
+
name: "name",
|
|
73
|
+
required: true,
|
|
74
|
+
maxLength: 200,
|
|
75
|
+
autoComplete: "name",
|
|
76
|
+
defaultValue: affiliate?.name ?? defaults?.name ?? ""
|
|
77
|
+
}
|
|
78
|
+
) }),
|
|
79
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Email", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
80
|
+
"input",
|
|
81
|
+
{
|
|
82
|
+
name: "email",
|
|
83
|
+
type: "email",
|
|
84
|
+
required: true,
|
|
85
|
+
maxLength: 320,
|
|
86
|
+
autoComplete: "email",
|
|
87
|
+
defaultValue: affiliate?.email ?? defaults?.email ?? ""
|
|
88
|
+
}
|
|
89
|
+
) }),
|
|
90
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
91
|
+
Field,
|
|
92
|
+
{
|
|
93
|
+
label: "Referral code",
|
|
94
|
+
hint: "3\u201364 lowercase letters, numbers, or single hyphens. Leave blank to generate a code.",
|
|
95
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
96
|
+
"input",
|
|
97
|
+
{
|
|
98
|
+
name: "code",
|
|
99
|
+
minLength: 3,
|
|
100
|
+
maxLength: 64,
|
|
101
|
+
pattern: "[a-z0-9]+(-[a-z0-9]+)*",
|
|
102
|
+
defaultValue: affiliate?.code ?? ""
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
),
|
|
107
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
108
|
+
Field,
|
|
109
|
+
{
|
|
110
|
+
label: "Payout details",
|
|
111
|
+
hint: "Payment instructions for the person arranging your payouts.",
|
|
112
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
113
|
+
"textarea",
|
|
114
|
+
{
|
|
115
|
+
name: "payoutDetails",
|
|
116
|
+
rows: 3,
|
|
117
|
+
maxLength: 1e4,
|
|
118
|
+
defaultValue: affiliate?.payoutDetails ?? ""
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
),
|
|
123
|
+
admin && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
124
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Status", children: /* @__PURE__ */ jsxRuntime.jsxs("select", { name: "status", defaultValue: affiliate?.status ?? "pending", children: [
|
|
125
|
+
(!affiliate || affiliate.status === "pending") && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "pending", children: "Pending" }),
|
|
126
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "approved", children: "Approved" }),
|
|
127
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "suspended", children: "Suspended" })
|
|
128
|
+
] }) }),
|
|
129
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Commission rule", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
130
|
+
"select",
|
|
131
|
+
{
|
|
132
|
+
name: "commissionType",
|
|
133
|
+
defaultValue: affiliate?.commissionType ?? "",
|
|
134
|
+
children: [
|
|
135
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Program default" }),
|
|
136
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "percent", children: "Percentage" }),
|
|
137
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "flat", children: "Flat amount" })
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
) }),
|
|
141
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
142
|
+
Field,
|
|
143
|
+
{
|
|
144
|
+
label: "Commission value",
|
|
145
|
+
hint: "Percentage points, or a flat amount in minor units (100 = USD 1.00).",
|
|
146
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
147
|
+
"input",
|
|
148
|
+
{
|
|
149
|
+
name: "commissionValue",
|
|
150
|
+
type: "number",
|
|
151
|
+
min: "0",
|
|
152
|
+
step: "any",
|
|
153
|
+
defaultValue: affiliate?.commissionValue ?? ""
|
|
154
|
+
}
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
),
|
|
158
|
+
/* @__PURE__ */ jsxRuntime.jsx(Field, { label: "Internal notes", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
159
|
+
"textarea",
|
|
160
|
+
{
|
|
161
|
+
name: "notes",
|
|
162
|
+
maxLength: 1e4,
|
|
163
|
+
rows: 3,
|
|
164
|
+
defaultValue: affiliate?.notes ?? ""
|
|
165
|
+
}
|
|
166
|
+
) })
|
|
167
|
+
] })
|
|
168
|
+
] });
|
|
169
|
+
}
|
|
170
|
+
function readProfile(fields) {
|
|
171
|
+
const code = String(fields.get("code") ?? "").trim();
|
|
172
|
+
return {
|
|
173
|
+
name: String(fields.get("name") ?? ""),
|
|
174
|
+
email: String(fields.get("email") ?? ""),
|
|
175
|
+
...code ? { code } : {},
|
|
176
|
+
payoutDetails: String(fields.get("payoutDetails") ?? "")
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function useAffiliateAction() {
|
|
180
|
+
const [error, setError] = react.useState("");
|
|
181
|
+
const [message, setMessage] = react.useState("");
|
|
182
|
+
const [pending, setPending] = react.useState(false);
|
|
183
|
+
const run = async (action, success = "") => {
|
|
184
|
+
setError("");
|
|
185
|
+
setMessage("");
|
|
186
|
+
setPending(true);
|
|
187
|
+
try {
|
|
188
|
+
await action();
|
|
189
|
+
setMessage(success);
|
|
190
|
+
} catch (caught) {
|
|
191
|
+
setError(
|
|
192
|
+
caught instanceof Error ? caught.message : "The change could not be saved. Try again."
|
|
193
|
+
);
|
|
194
|
+
} finally {
|
|
195
|
+
setPending(false);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
return { error, message, pending, run };
|
|
199
|
+
}
|
|
200
|
+
function ActionNotice({
|
|
201
|
+
error,
|
|
202
|
+
message
|
|
203
|
+
}) {
|
|
204
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
205
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "affiliate-error", children: error }),
|
|
206
|
+
message && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "status", children: message })
|
|
207
|
+
] });
|
|
208
|
+
}
|
|
209
|
+
function Status({ value }) {
|
|
210
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "affiliate-status", "data-status": value, children: value.charAt(0).toUpperCase() + value.slice(1) });
|
|
211
|
+
}
|
|
212
|
+
function money(amount, currency) {
|
|
213
|
+
const formatter = new Intl.NumberFormat(void 0, {
|
|
214
|
+
style: "currency",
|
|
215
|
+
currency
|
|
216
|
+
});
|
|
217
|
+
const digits = formatter.resolvedOptions().maximumFractionDigits ?? 2;
|
|
218
|
+
return formatter.format(amount / 10 ** digits);
|
|
219
|
+
}
|
|
220
|
+
function date(value) {
|
|
221
|
+
return new Date(value).toLocaleDateString(void 0, {
|
|
222
|
+
year: "numeric",
|
|
223
|
+
month: "short",
|
|
224
|
+
day: "numeric"
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
function Stats({ stats }) {
|
|
228
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
229
|
+
"section",
|
|
230
|
+
{
|
|
231
|
+
"aria-label": "Affiliate performance",
|
|
232
|
+
className: "affiliate-performance",
|
|
233
|
+
children: [
|
|
234
|
+
/* @__PURE__ */ jsxRuntime.jsxs("dl", { className: "affiliate-metrics", children: [
|
|
235
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
236
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Referral clicks" }),
|
|
237
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { children: stats.clicks.toLocaleString() })
|
|
238
|
+
] }),
|
|
239
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
240
|
+
/* @__PURE__ */ jsxRuntime.jsx("dt", { children: "Conversions" }),
|
|
241
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { children: stats.conversions.toLocaleString() })
|
|
242
|
+
] })
|
|
243
|
+
] }),
|
|
244
|
+
stats.totals.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
245
|
+
"div",
|
|
246
|
+
{
|
|
247
|
+
className: "affiliate-table-scroll",
|
|
248
|
+
role: "region",
|
|
249
|
+
"aria-label": "Commission totals",
|
|
250
|
+
tabIndex: 0,
|
|
251
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("table", { children: [
|
|
252
|
+
/* @__PURE__ */ jsxRuntime.jsx("caption", { className: "affiliate-sr-only", children: "Commission totals by currency" }),
|
|
253
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
254
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { children: "Currency" }),
|
|
255
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "affiliate-number", children: "Pending" }),
|
|
256
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "affiliate-number", children: "Approved" }),
|
|
257
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "affiliate-number", children: "Paid" })
|
|
258
|
+
] }) }),
|
|
259
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: stats.totals.map((total) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
260
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { scope: "row", children: total.currency }),
|
|
261
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "affiliate-number", children: money(total.pending, total.currency) }),
|
|
262
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "affiliate-number", children: money(total.approved, total.currency) }),
|
|
263
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "affiliate-number", children: money(total.paid, total.currency) })
|
|
264
|
+
] }, total.currency)) })
|
|
265
|
+
] })
|
|
266
|
+
}
|
|
267
|
+
)
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
function Pagination({
|
|
273
|
+
offset,
|
|
274
|
+
total,
|
|
275
|
+
onChange
|
|
276
|
+
}) {
|
|
277
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "affiliate-pagination", children: [
|
|
278
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "affiliate-muted", children: total === 0 ? "No results" : `${offset + 1}\u2013${Math.min(offset + 25, total)} of ${total}` }),
|
|
279
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "affiliate-actions", children: [
|
|
280
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
281
|
+
"button",
|
|
282
|
+
{
|
|
283
|
+
type: "button",
|
|
284
|
+
disabled: offset === 0,
|
|
285
|
+
onClick: () => onChange(Math.max(0, offset - 25)),
|
|
286
|
+
children: "Previous page"
|
|
287
|
+
}
|
|
288
|
+
),
|
|
289
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
290
|
+
"button",
|
|
291
|
+
{
|
|
292
|
+
type: "button",
|
|
293
|
+
disabled: offset + 25 >= total,
|
|
294
|
+
onClick: () => onChange(offset + 25),
|
|
295
|
+
children: "Next page"
|
|
296
|
+
}
|
|
297
|
+
)
|
|
298
|
+
] })
|
|
299
|
+
] });
|
|
300
|
+
}
|
|
301
|
+
function AffiliateLoading() {
|
|
302
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "affiliate-page", role: "status", children: "Loading affiliate information\u2026" });
|
|
303
|
+
}
|
|
304
|
+
function AffiliateError({ error, resetErrorBoundary }) {
|
|
305
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "affiliate-page affiliate-stack", role: "alert", children: [
|
|
306
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { children: "Affiliate information unavailable" }),
|
|
307
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: error instanceof Error && error.message ? error.message : "Check your access and try again." }),
|
|
308
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: resetErrorBoundary, children: "Retry loading" })
|
|
309
|
+
] });
|
|
310
|
+
}
|
|
311
|
+
function AffiliateNotFound({ message }) {
|
|
312
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "affiliate-page", children: [
|
|
313
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { children: "Affiliate not found" }),
|
|
314
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { children: message })
|
|
315
|
+
] });
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
exports.ActionNotice = ActionNotice;
|
|
319
|
+
exports.AffiliateError = AffiliateError;
|
|
320
|
+
exports.AffiliateLoading = AffiliateLoading;
|
|
321
|
+
exports.AffiliateNotFound = AffiliateNotFound;
|
|
322
|
+
exports.AffiliatePage = AffiliatePage;
|
|
323
|
+
exports.Field = Field;
|
|
324
|
+
exports.Pagination = Pagination;
|
|
325
|
+
exports.ProfileFields = ProfileFields;
|
|
326
|
+
exports.Stats = Stats;
|
|
327
|
+
exports.Status = Status;
|
|
328
|
+
exports.date = date;
|
|
329
|
+
exports.money = money;
|
|
330
|
+
exports.readProfile = readProfile;
|
|
331
|
+
exports.useAffiliateAction = useAffiliateAction;
|