@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,316 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs, jsx, Fragment } 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 { AFFILIATE_PLUGIN_ID } from '../constants.mjs';
|
|
7
|
+
|
|
8
|
+
function AffiliatePage({
|
|
9
|
+
title,
|
|
10
|
+
description,
|
|
11
|
+
action,
|
|
12
|
+
admin = true,
|
|
13
|
+
children
|
|
14
|
+
}) {
|
|
15
|
+
const { Link, resolve } = usePluginSiteNavigation(AFFILIATE_PLUGIN_ID);
|
|
16
|
+
const { localization } = usePluginOverrides(AFFILIATE_PLUGIN_ID);
|
|
17
|
+
return /* @__PURE__ */ jsxs("div", { className: "affiliate-page", "data-testid": "affiliate-page", children: [
|
|
18
|
+
/* @__PURE__ */ jsxs("header", { className: "affiliate-heading", children: [
|
|
19
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
20
|
+
/* @__PURE__ */ jsx("h1", { children: title }),
|
|
21
|
+
description && /* @__PURE__ */ jsx("p", { className: "affiliate-muted", children: description })
|
|
22
|
+
] }),
|
|
23
|
+
action
|
|
24
|
+
] }),
|
|
25
|
+
admin && /* @__PURE__ */ jsxs("nav", { className: "affiliate-nav", "aria-label": "Affiliate administration", children: [
|
|
26
|
+
/* @__PURE__ */ jsx(
|
|
27
|
+
PermissionAccess,
|
|
28
|
+
{
|
|
29
|
+
permission: affiliatePermissions.affiliate.read({
|
|
30
|
+
scope: "collection"
|
|
31
|
+
}),
|
|
32
|
+
children: /* @__PURE__ */ jsx(Link, { href: resolve("affiliate/admin/affiliates").href, children: localization?.affiliates ?? "Affiliates" })
|
|
33
|
+
}
|
|
34
|
+
),
|
|
35
|
+
/* @__PURE__ */ jsx(PermissionAccess, { permission: affiliatePermissions.commission.read(), children: /* @__PURE__ */ jsx(Link, { href: resolve("affiliate/admin/commissions").href, children: localization?.commissions ?? "Commissions" }) }),
|
|
36
|
+
/* @__PURE__ */ jsx(PermissionAccess, { permission: affiliatePermissions.payout.read(), children: /* @__PURE__ */ jsx(Link, { href: resolve("affiliate/admin/payouts").href, children: localization?.payouts ?? "Payouts" }) })
|
|
37
|
+
] }),
|
|
38
|
+
children
|
|
39
|
+
] });
|
|
40
|
+
}
|
|
41
|
+
function Field({
|
|
42
|
+
label,
|
|
43
|
+
hint,
|
|
44
|
+
children
|
|
45
|
+
}) {
|
|
46
|
+
return /* @__PURE__ */ jsxs("label", { className: "affiliate-field", children: [
|
|
47
|
+
/* @__PURE__ */ jsx("span", { children: label }),
|
|
48
|
+
children,
|
|
49
|
+
hint && /* @__PURE__ */ jsx("span", { className: "affiliate-muted affiliate-small", children: hint })
|
|
50
|
+
] });
|
|
51
|
+
}
|
|
52
|
+
function ProfileFields({
|
|
53
|
+
affiliate,
|
|
54
|
+
defaults,
|
|
55
|
+
userId = false,
|
|
56
|
+
admin = false
|
|
57
|
+
}) {
|
|
58
|
+
return /* @__PURE__ */ jsxs("div", { className: "affiliate-form-grid", children: [
|
|
59
|
+
userId && /* @__PURE__ */ jsx(
|
|
60
|
+
Field,
|
|
61
|
+
{
|
|
62
|
+
label: "User ID",
|
|
63
|
+
hint: "The account that will own this affiliate portal.",
|
|
64
|
+
children: /* @__PURE__ */ jsx("input", { name: "userId", required: true, maxLength: 255 })
|
|
65
|
+
}
|
|
66
|
+
),
|
|
67
|
+
/* @__PURE__ */ jsx(Field, { label: "Name", children: /* @__PURE__ */ jsx(
|
|
68
|
+
"input",
|
|
69
|
+
{
|
|
70
|
+
name: "name",
|
|
71
|
+
required: true,
|
|
72
|
+
maxLength: 200,
|
|
73
|
+
autoComplete: "name",
|
|
74
|
+
defaultValue: affiliate?.name ?? defaults?.name ?? ""
|
|
75
|
+
}
|
|
76
|
+
) }),
|
|
77
|
+
/* @__PURE__ */ jsx(Field, { label: "Email", children: /* @__PURE__ */ jsx(
|
|
78
|
+
"input",
|
|
79
|
+
{
|
|
80
|
+
name: "email",
|
|
81
|
+
type: "email",
|
|
82
|
+
required: true,
|
|
83
|
+
maxLength: 320,
|
|
84
|
+
autoComplete: "email",
|
|
85
|
+
defaultValue: affiliate?.email ?? defaults?.email ?? ""
|
|
86
|
+
}
|
|
87
|
+
) }),
|
|
88
|
+
/* @__PURE__ */ jsx(
|
|
89
|
+
Field,
|
|
90
|
+
{
|
|
91
|
+
label: "Referral code",
|
|
92
|
+
hint: "3\u201364 lowercase letters, numbers, or single hyphens. Leave blank to generate a code.",
|
|
93
|
+
children: /* @__PURE__ */ jsx(
|
|
94
|
+
"input",
|
|
95
|
+
{
|
|
96
|
+
name: "code",
|
|
97
|
+
minLength: 3,
|
|
98
|
+
maxLength: 64,
|
|
99
|
+
pattern: "[a-z0-9]+(-[a-z0-9]+)*",
|
|
100
|
+
defaultValue: affiliate?.code ?? ""
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
),
|
|
105
|
+
/* @__PURE__ */ jsx(
|
|
106
|
+
Field,
|
|
107
|
+
{
|
|
108
|
+
label: "Payout details",
|
|
109
|
+
hint: "Payment instructions for the person arranging your payouts.",
|
|
110
|
+
children: /* @__PURE__ */ jsx(
|
|
111
|
+
"textarea",
|
|
112
|
+
{
|
|
113
|
+
name: "payoutDetails",
|
|
114
|
+
rows: 3,
|
|
115
|
+
maxLength: 1e4,
|
|
116
|
+
defaultValue: affiliate?.payoutDetails ?? ""
|
|
117
|
+
}
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
),
|
|
121
|
+
admin && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
122
|
+
/* @__PURE__ */ jsx(Field, { label: "Status", children: /* @__PURE__ */ jsxs("select", { name: "status", defaultValue: affiliate?.status ?? "pending", children: [
|
|
123
|
+
(!affiliate || affiliate.status === "pending") && /* @__PURE__ */ jsx("option", { value: "pending", children: "Pending" }),
|
|
124
|
+
/* @__PURE__ */ jsx("option", { value: "approved", children: "Approved" }),
|
|
125
|
+
/* @__PURE__ */ jsx("option", { value: "suspended", children: "Suspended" })
|
|
126
|
+
] }) }),
|
|
127
|
+
/* @__PURE__ */ jsx(Field, { label: "Commission rule", children: /* @__PURE__ */ jsxs(
|
|
128
|
+
"select",
|
|
129
|
+
{
|
|
130
|
+
name: "commissionType",
|
|
131
|
+
defaultValue: affiliate?.commissionType ?? "",
|
|
132
|
+
children: [
|
|
133
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "Program default" }),
|
|
134
|
+
/* @__PURE__ */ jsx("option", { value: "percent", children: "Percentage" }),
|
|
135
|
+
/* @__PURE__ */ jsx("option", { value: "flat", children: "Flat amount" })
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
) }),
|
|
139
|
+
/* @__PURE__ */ jsx(
|
|
140
|
+
Field,
|
|
141
|
+
{
|
|
142
|
+
label: "Commission value",
|
|
143
|
+
hint: "Percentage points, or a flat amount in minor units (100 = USD 1.00).",
|
|
144
|
+
children: /* @__PURE__ */ jsx(
|
|
145
|
+
"input",
|
|
146
|
+
{
|
|
147
|
+
name: "commissionValue",
|
|
148
|
+
type: "number",
|
|
149
|
+
min: "0",
|
|
150
|
+
step: "any",
|
|
151
|
+
defaultValue: affiliate?.commissionValue ?? ""
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
),
|
|
156
|
+
/* @__PURE__ */ jsx(Field, { label: "Internal notes", children: /* @__PURE__ */ jsx(
|
|
157
|
+
"textarea",
|
|
158
|
+
{
|
|
159
|
+
name: "notes",
|
|
160
|
+
maxLength: 1e4,
|
|
161
|
+
rows: 3,
|
|
162
|
+
defaultValue: affiliate?.notes ?? ""
|
|
163
|
+
}
|
|
164
|
+
) })
|
|
165
|
+
] })
|
|
166
|
+
] });
|
|
167
|
+
}
|
|
168
|
+
function readProfile(fields) {
|
|
169
|
+
const code = String(fields.get("code") ?? "").trim();
|
|
170
|
+
return {
|
|
171
|
+
name: String(fields.get("name") ?? ""),
|
|
172
|
+
email: String(fields.get("email") ?? ""),
|
|
173
|
+
...code ? { code } : {},
|
|
174
|
+
payoutDetails: String(fields.get("payoutDetails") ?? "")
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function useAffiliateAction() {
|
|
178
|
+
const [error, setError] = useState("");
|
|
179
|
+
const [message, setMessage] = useState("");
|
|
180
|
+
const [pending, setPending] = useState(false);
|
|
181
|
+
const run = async (action, success = "") => {
|
|
182
|
+
setError("");
|
|
183
|
+
setMessage("");
|
|
184
|
+
setPending(true);
|
|
185
|
+
try {
|
|
186
|
+
await action();
|
|
187
|
+
setMessage(success);
|
|
188
|
+
} catch (caught) {
|
|
189
|
+
setError(
|
|
190
|
+
caught instanceof Error ? caught.message : "The change could not be saved. Try again."
|
|
191
|
+
);
|
|
192
|
+
} finally {
|
|
193
|
+
setPending(false);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
return { error, message, pending, run };
|
|
197
|
+
}
|
|
198
|
+
function ActionNotice({
|
|
199
|
+
error,
|
|
200
|
+
message
|
|
201
|
+
}) {
|
|
202
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
203
|
+
error && /* @__PURE__ */ jsx("p", { role: "alert", className: "affiliate-error", children: error }),
|
|
204
|
+
message && /* @__PURE__ */ jsx("p", { role: "status", children: message })
|
|
205
|
+
] });
|
|
206
|
+
}
|
|
207
|
+
function Status({ value }) {
|
|
208
|
+
return /* @__PURE__ */ jsx("span", { className: "affiliate-status", "data-status": value, children: value.charAt(0).toUpperCase() + value.slice(1) });
|
|
209
|
+
}
|
|
210
|
+
function money(amount, currency) {
|
|
211
|
+
const formatter = new Intl.NumberFormat(void 0, {
|
|
212
|
+
style: "currency",
|
|
213
|
+
currency
|
|
214
|
+
});
|
|
215
|
+
const digits = formatter.resolvedOptions().maximumFractionDigits ?? 2;
|
|
216
|
+
return formatter.format(amount / 10 ** digits);
|
|
217
|
+
}
|
|
218
|
+
function date(value) {
|
|
219
|
+
return new Date(value).toLocaleDateString(void 0, {
|
|
220
|
+
year: "numeric",
|
|
221
|
+
month: "short",
|
|
222
|
+
day: "numeric"
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
function Stats({ stats }) {
|
|
226
|
+
return /* @__PURE__ */ jsxs(
|
|
227
|
+
"section",
|
|
228
|
+
{
|
|
229
|
+
"aria-label": "Affiliate performance",
|
|
230
|
+
className: "affiliate-performance",
|
|
231
|
+
children: [
|
|
232
|
+
/* @__PURE__ */ jsxs("dl", { className: "affiliate-metrics", children: [
|
|
233
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
234
|
+
/* @__PURE__ */ jsx("dt", { children: "Referral clicks" }),
|
|
235
|
+
/* @__PURE__ */ jsx("dd", { children: stats.clicks.toLocaleString() })
|
|
236
|
+
] }),
|
|
237
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
238
|
+
/* @__PURE__ */ jsx("dt", { children: "Conversions" }),
|
|
239
|
+
/* @__PURE__ */ jsx("dd", { children: stats.conversions.toLocaleString() })
|
|
240
|
+
] })
|
|
241
|
+
] }),
|
|
242
|
+
stats.totals.length > 0 && /* @__PURE__ */ jsx(
|
|
243
|
+
"div",
|
|
244
|
+
{
|
|
245
|
+
className: "affiliate-table-scroll",
|
|
246
|
+
role: "region",
|
|
247
|
+
"aria-label": "Commission totals",
|
|
248
|
+
tabIndex: 0,
|
|
249
|
+
children: /* @__PURE__ */ jsxs("table", { children: [
|
|
250
|
+
/* @__PURE__ */ jsx("caption", { className: "affiliate-sr-only", children: "Commission totals by currency" }),
|
|
251
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
252
|
+
/* @__PURE__ */ jsx("th", { children: "Currency" }),
|
|
253
|
+
/* @__PURE__ */ jsx("th", { className: "affiliate-number", children: "Pending" }),
|
|
254
|
+
/* @__PURE__ */ jsx("th", { className: "affiliate-number", children: "Approved" }),
|
|
255
|
+
/* @__PURE__ */ jsx("th", { className: "affiliate-number", children: "Paid" })
|
|
256
|
+
] }) }),
|
|
257
|
+
/* @__PURE__ */ jsx("tbody", { children: stats.totals.map((total) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
258
|
+
/* @__PURE__ */ jsx("th", { scope: "row", children: total.currency }),
|
|
259
|
+
/* @__PURE__ */ jsx("td", { className: "affiliate-number", children: money(total.pending, total.currency) }),
|
|
260
|
+
/* @__PURE__ */ jsx("td", { className: "affiliate-number", children: money(total.approved, total.currency) }),
|
|
261
|
+
/* @__PURE__ */ jsx("td", { className: "affiliate-number", children: money(total.paid, total.currency) })
|
|
262
|
+
] }, total.currency)) })
|
|
263
|
+
] })
|
|
264
|
+
}
|
|
265
|
+
)
|
|
266
|
+
]
|
|
267
|
+
}
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
function Pagination({
|
|
271
|
+
offset,
|
|
272
|
+
total,
|
|
273
|
+
onChange
|
|
274
|
+
}) {
|
|
275
|
+
return /* @__PURE__ */ jsxs("div", { className: "affiliate-pagination", children: [
|
|
276
|
+
/* @__PURE__ */ jsx("p", { className: "affiliate-muted", children: total === 0 ? "No results" : `${offset + 1}\u2013${Math.min(offset + 25, total)} of ${total}` }),
|
|
277
|
+
/* @__PURE__ */ jsxs("div", { className: "affiliate-actions", children: [
|
|
278
|
+
/* @__PURE__ */ jsx(
|
|
279
|
+
"button",
|
|
280
|
+
{
|
|
281
|
+
type: "button",
|
|
282
|
+
disabled: offset === 0,
|
|
283
|
+
onClick: () => onChange(Math.max(0, offset - 25)),
|
|
284
|
+
children: "Previous page"
|
|
285
|
+
}
|
|
286
|
+
),
|
|
287
|
+
/* @__PURE__ */ jsx(
|
|
288
|
+
"button",
|
|
289
|
+
{
|
|
290
|
+
type: "button",
|
|
291
|
+
disabled: offset + 25 >= total,
|
|
292
|
+
onClick: () => onChange(offset + 25),
|
|
293
|
+
children: "Next page"
|
|
294
|
+
}
|
|
295
|
+
)
|
|
296
|
+
] })
|
|
297
|
+
] });
|
|
298
|
+
}
|
|
299
|
+
function AffiliateLoading() {
|
|
300
|
+
return /* @__PURE__ */ jsx("div", { className: "affiliate-page", role: "status", children: "Loading affiliate information\u2026" });
|
|
301
|
+
}
|
|
302
|
+
function AffiliateError({ error, resetErrorBoundary }) {
|
|
303
|
+
return /* @__PURE__ */ jsxs("div", { className: "affiliate-page affiliate-stack", role: "alert", children: [
|
|
304
|
+
/* @__PURE__ */ jsx("h1", { children: "Affiliate information unavailable" }),
|
|
305
|
+
/* @__PURE__ */ jsx("p", { children: error instanceof Error && error.message ? error.message : "Check your access and try again." }),
|
|
306
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: resetErrorBoundary, children: "Retry loading" })
|
|
307
|
+
] });
|
|
308
|
+
}
|
|
309
|
+
function AffiliateNotFound({ message }) {
|
|
310
|
+
return /* @__PURE__ */ jsxs("div", { className: "affiliate-page", children: [
|
|
311
|
+
/* @__PURE__ */ jsx("h1", { children: "Affiliate not found" }),
|
|
312
|
+
/* @__PURE__ */ jsx("p", { children: message })
|
|
313
|
+
] });
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export { ActionNotice, AffiliateError, AffiliateLoading, AffiliateNotFound, AffiliatePage, Field, Pagination, ProfileFields, Stats, Status, date, money, readProfile, useAffiliateAction };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const context = require('@btst/stack/context');
|
|
5
|
+
const hooks = require('@btst/stack/plugins/client/hooks');
|
|
6
|
+
const queryKeys = require('../../query-keys.cjs');
|
|
7
|
+
const attribution = require('../../attribution.cjs');
|
|
8
|
+
const constants = require('../constants.cjs');
|
|
9
|
+
|
|
10
|
+
const affiliate = hooks.createResource({
|
|
11
|
+
plugin: constants.AFFILIATE_PLUGIN_ID,
|
|
12
|
+
resources: queryKeys.affiliateResources
|
|
13
|
+
});
|
|
14
|
+
function useAffiliatePartition() {
|
|
15
|
+
const { identity, isPending, error } = context.useIdentity();
|
|
16
|
+
const generation = context.useIdentitySourceGeneration();
|
|
17
|
+
const { plugins } = context.useStack();
|
|
18
|
+
const api = plugins?.[constants.AFFILIATE_PLUGIN_ID]?.api;
|
|
19
|
+
return {
|
|
20
|
+
identity,
|
|
21
|
+
generation,
|
|
22
|
+
isPending,
|
|
23
|
+
error: !!error,
|
|
24
|
+
endpoint: [api?.baseURL, api?.basePath],
|
|
25
|
+
headers: [...new Headers(api?.browserHeaders)],
|
|
26
|
+
credentials: api?.credentials
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const useAffiliates = (params = {}) => affiliate.affiliates.list.useSuspense([params, useAffiliatePartition()]);
|
|
30
|
+
const useAffiliate = (id) => affiliate.affiliates.detail.useSuspense([id, useAffiliatePartition()]);
|
|
31
|
+
const useAffiliateDashboard = () => affiliate.affiliatePortal.detail.useSuspense([useAffiliatePartition()]);
|
|
32
|
+
const useCommissions = (params = {}) => affiliate.affiliateCommissions.list.useSuspense([
|
|
33
|
+
params,
|
|
34
|
+
useAffiliatePartition()
|
|
35
|
+
]);
|
|
36
|
+
const usePayouts = (params = {}) => affiliate.affiliatePayouts.list.useSuspense([
|
|
37
|
+
params,
|
|
38
|
+
useAffiliatePartition()
|
|
39
|
+
]);
|
|
40
|
+
const usePayoutExport = (params = {}) => affiliate.affiliatePayouts.export.use([params, useAffiliatePartition()], {
|
|
41
|
+
enabled: false
|
|
42
|
+
});
|
|
43
|
+
const useCreateAffiliate = () => affiliate.affiliates.create.use();
|
|
44
|
+
const useUpdateAffiliate = () => affiliate.affiliates.update.use();
|
|
45
|
+
const useDeleteAffiliate = () => affiliate.affiliates.delete.use();
|
|
46
|
+
const useApplyAffiliate = () => affiliate.affiliatePortal.apply.use();
|
|
47
|
+
const useUpdateAffiliateProfile = () => affiliate.affiliatePortal.update.use();
|
|
48
|
+
const useUpdateCommission = () => affiliate.affiliateCommissions.update.use();
|
|
49
|
+
const useCreatePayout = () => affiliate.affiliatePayouts.create.use();
|
|
50
|
+
const useUpdatePayout = () => affiliate.affiliatePayouts.update.use();
|
|
51
|
+
function useReferralLink() {
|
|
52
|
+
const { plugins } = context.useStack();
|
|
53
|
+
const api = plugins?.[constants.AFFILIATE_PLUGIN_ID]?.api;
|
|
54
|
+
return (code, landingPath = "/") => {
|
|
55
|
+
const apiBaseURL = new URL(
|
|
56
|
+
api?.basePath ?? "/api/data",
|
|
57
|
+
api?.baseURL || window.location.origin
|
|
58
|
+
);
|
|
59
|
+
return attribution.createTrackingLink(apiBaseURL.href, code, landingPath);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
exports.useAffiliate = useAffiliate;
|
|
64
|
+
exports.useAffiliateDashboard = useAffiliateDashboard;
|
|
65
|
+
exports.useAffiliates = useAffiliates;
|
|
66
|
+
exports.useApplyAffiliate = useApplyAffiliate;
|
|
67
|
+
exports.useCommissions = useCommissions;
|
|
68
|
+
exports.useCreateAffiliate = useCreateAffiliate;
|
|
69
|
+
exports.useCreatePayout = useCreatePayout;
|
|
70
|
+
exports.useDeleteAffiliate = useDeleteAffiliate;
|
|
71
|
+
exports.usePayoutExport = usePayoutExport;
|
|
72
|
+
exports.usePayouts = usePayouts;
|
|
73
|
+
exports.useReferralLink = useReferralLink;
|
|
74
|
+
exports.useUpdateAffiliate = useUpdateAffiliate;
|
|
75
|
+
exports.useUpdateAffiliateProfile = useUpdateAffiliateProfile;
|
|
76
|
+
exports.useUpdateCommission = useUpdateCommission;
|
|
77
|
+
exports.useUpdatePayout = useUpdatePayout;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { AffiliateApplicationInput, AffiliatePortalInput } from '../../query-keys.cjs';
|
|
3
|
+
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
4
|
+
import { Affiliate, AffiliateStats, AffiliatePortal, ListParams, ListResult, Commission, CreateAffiliateInput, Payout, CreatePayoutInput, UpdateAffiliateInput } from '../../types.cjs';
|
|
5
|
+
import '@btst/stack/plugins/client';
|
|
6
|
+
|
|
7
|
+
declare const useAffiliates: (params?: ListParams) => _tanstack_react_query.UseSuspenseQueryResult<ListResult<Affiliate>, Error>;
|
|
8
|
+
declare const useAffiliate: (id: string) => _tanstack_react_query.UseSuspenseQueryResult<{
|
|
9
|
+
affiliate: Affiliate;
|
|
10
|
+
stats: AffiliateStats;
|
|
11
|
+
}, Error>;
|
|
12
|
+
declare const useAffiliateDashboard: () => _tanstack_react_query.UseSuspenseQueryResult<AffiliatePortal, Error>;
|
|
13
|
+
declare const useCommissions: (params?: ListParams) => _tanstack_react_query.UseSuspenseQueryResult<ListResult<Commission>, Error>;
|
|
14
|
+
declare const usePayouts: (params?: ListParams) => _tanstack_react_query.UseSuspenseQueryResult<ListResult<Payout>, Error>;
|
|
15
|
+
declare const usePayoutExport: (params?: ListParams) => _tanstack_react_query.UseQueryResult<{
|
|
16
|
+
csv: string;
|
|
17
|
+
}, Error>;
|
|
18
|
+
declare const useCreateAffiliate: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, CreateAffiliateInput>;
|
|
19
|
+
declare const useUpdateAffiliate: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, {
|
|
20
|
+
id: string;
|
|
21
|
+
data: UpdateAffiliateInput;
|
|
22
|
+
}>;
|
|
23
|
+
declare const useDeleteAffiliate: () => _tanstack_react_query.UseMutationResult<unknown, Error, string>;
|
|
24
|
+
declare const useApplyAffiliate: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, AffiliateApplicationInput>;
|
|
25
|
+
declare const useUpdateAffiliateProfile: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, AffiliatePortalInput>;
|
|
26
|
+
declare const useUpdateCommission: () => _tanstack_react_query.UseMutationResult<Commission, Error, {
|
|
27
|
+
id: string;
|
|
28
|
+
status: "approved" | "voided";
|
|
29
|
+
}>;
|
|
30
|
+
declare const useCreatePayout: () => _tanstack_react_query.UseMutationResult<Payout, Error, CreatePayoutInput>;
|
|
31
|
+
declare const useUpdatePayout: () => _tanstack_react_query.UseMutationResult<Payout, Error, {
|
|
32
|
+
id: string;
|
|
33
|
+
status: "sent" | "failed";
|
|
34
|
+
reference?: string;
|
|
35
|
+
}>;
|
|
36
|
+
/** Build a cookie-setting tracking link using the affiliate plugin's resolved API. */
|
|
37
|
+
declare function useReferralLink(): (code: string, landingPath?: string) => string;
|
|
38
|
+
|
|
39
|
+
export { useAffiliate, useAffiliateDashboard, useAffiliates, useApplyAffiliate, useCommissions, useCreateAffiliate, useCreatePayout, useDeleteAffiliate, usePayoutExport, usePayouts, useReferralLink, useUpdateAffiliate, useUpdateAffiliateProfile, useUpdateCommission, useUpdatePayout };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { AffiliateApplicationInput, AffiliatePortalInput } from '../../query-keys.mjs';
|
|
3
|
+
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
4
|
+
import { Affiliate, AffiliateStats, AffiliatePortal, ListParams, ListResult, Commission, CreateAffiliateInput, Payout, CreatePayoutInput, UpdateAffiliateInput } from '../../types.mjs';
|
|
5
|
+
import '@btst/stack/plugins/client';
|
|
6
|
+
|
|
7
|
+
declare const useAffiliates: (params?: ListParams) => _tanstack_react_query.UseSuspenseQueryResult<ListResult<Affiliate>, Error>;
|
|
8
|
+
declare const useAffiliate: (id: string) => _tanstack_react_query.UseSuspenseQueryResult<{
|
|
9
|
+
affiliate: Affiliate;
|
|
10
|
+
stats: AffiliateStats;
|
|
11
|
+
}, Error>;
|
|
12
|
+
declare const useAffiliateDashboard: () => _tanstack_react_query.UseSuspenseQueryResult<AffiliatePortal, Error>;
|
|
13
|
+
declare const useCommissions: (params?: ListParams) => _tanstack_react_query.UseSuspenseQueryResult<ListResult<Commission>, Error>;
|
|
14
|
+
declare const usePayouts: (params?: ListParams) => _tanstack_react_query.UseSuspenseQueryResult<ListResult<Payout>, Error>;
|
|
15
|
+
declare const usePayoutExport: (params?: ListParams) => _tanstack_react_query.UseQueryResult<{
|
|
16
|
+
csv: string;
|
|
17
|
+
}, Error>;
|
|
18
|
+
declare const useCreateAffiliate: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, CreateAffiliateInput>;
|
|
19
|
+
declare const useUpdateAffiliate: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, {
|
|
20
|
+
id: string;
|
|
21
|
+
data: UpdateAffiliateInput;
|
|
22
|
+
}>;
|
|
23
|
+
declare const useDeleteAffiliate: () => _tanstack_react_query.UseMutationResult<unknown, Error, string>;
|
|
24
|
+
declare const useApplyAffiliate: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, AffiliateApplicationInput>;
|
|
25
|
+
declare const useUpdateAffiliateProfile: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, AffiliatePortalInput>;
|
|
26
|
+
declare const useUpdateCommission: () => _tanstack_react_query.UseMutationResult<Commission, Error, {
|
|
27
|
+
id: string;
|
|
28
|
+
status: "approved" | "voided";
|
|
29
|
+
}>;
|
|
30
|
+
declare const useCreatePayout: () => _tanstack_react_query.UseMutationResult<Payout, Error, CreatePayoutInput>;
|
|
31
|
+
declare const useUpdatePayout: () => _tanstack_react_query.UseMutationResult<Payout, Error, {
|
|
32
|
+
id: string;
|
|
33
|
+
status: "sent" | "failed";
|
|
34
|
+
reference?: string;
|
|
35
|
+
}>;
|
|
36
|
+
/** Build a cookie-setting tracking link using the affiliate plugin's resolved API. */
|
|
37
|
+
declare function useReferralLink(): (code: string, landingPath?: string) => string;
|
|
38
|
+
|
|
39
|
+
export { useAffiliate, useAffiliateDashboard, useAffiliates, useApplyAffiliate, useCommissions, useCreateAffiliate, useCreatePayout, useDeleteAffiliate, usePayoutExport, usePayouts, useReferralLink, useUpdateAffiliate, useUpdateAffiliateProfile, useUpdateCommission, useUpdatePayout };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { AffiliateApplicationInput, AffiliatePortalInput } from '../../query-keys.js';
|
|
3
|
+
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
4
|
+
import { Affiliate, AffiliateStats, AffiliatePortal, ListParams, ListResult, Commission, CreateAffiliateInput, Payout, CreatePayoutInput, UpdateAffiliateInput } from '../../types.js';
|
|
5
|
+
import '@btst/stack/plugins/client';
|
|
6
|
+
|
|
7
|
+
declare const useAffiliates: (params?: ListParams) => _tanstack_react_query.UseSuspenseQueryResult<ListResult<Affiliate>, Error>;
|
|
8
|
+
declare const useAffiliate: (id: string) => _tanstack_react_query.UseSuspenseQueryResult<{
|
|
9
|
+
affiliate: Affiliate;
|
|
10
|
+
stats: AffiliateStats;
|
|
11
|
+
}, Error>;
|
|
12
|
+
declare const useAffiliateDashboard: () => _tanstack_react_query.UseSuspenseQueryResult<AffiliatePortal, Error>;
|
|
13
|
+
declare const useCommissions: (params?: ListParams) => _tanstack_react_query.UseSuspenseQueryResult<ListResult<Commission>, Error>;
|
|
14
|
+
declare const usePayouts: (params?: ListParams) => _tanstack_react_query.UseSuspenseQueryResult<ListResult<Payout>, Error>;
|
|
15
|
+
declare const usePayoutExport: (params?: ListParams) => _tanstack_react_query.UseQueryResult<{
|
|
16
|
+
csv: string;
|
|
17
|
+
}, Error>;
|
|
18
|
+
declare const useCreateAffiliate: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, CreateAffiliateInput>;
|
|
19
|
+
declare const useUpdateAffiliate: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, {
|
|
20
|
+
id: string;
|
|
21
|
+
data: UpdateAffiliateInput;
|
|
22
|
+
}>;
|
|
23
|
+
declare const useDeleteAffiliate: () => _tanstack_react_query.UseMutationResult<unknown, Error, string>;
|
|
24
|
+
declare const useApplyAffiliate: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, AffiliateApplicationInput>;
|
|
25
|
+
declare const useUpdateAffiliateProfile: () => _tanstack_react_query.UseMutationResult<Affiliate, Error, AffiliatePortalInput>;
|
|
26
|
+
declare const useUpdateCommission: () => _tanstack_react_query.UseMutationResult<Commission, Error, {
|
|
27
|
+
id: string;
|
|
28
|
+
status: "approved" | "voided";
|
|
29
|
+
}>;
|
|
30
|
+
declare const useCreatePayout: () => _tanstack_react_query.UseMutationResult<Payout, Error, CreatePayoutInput>;
|
|
31
|
+
declare const useUpdatePayout: () => _tanstack_react_query.UseMutationResult<Payout, Error, {
|
|
32
|
+
id: string;
|
|
33
|
+
status: "sent" | "failed";
|
|
34
|
+
reference?: string;
|
|
35
|
+
}>;
|
|
36
|
+
/** Build a cookie-setting tracking link using the affiliate plugin's resolved API. */
|
|
37
|
+
declare function useReferralLink(): (code: string, landingPath?: string) => string;
|
|
38
|
+
|
|
39
|
+
export { useAffiliate, useAffiliateDashboard, useAffiliates, useApplyAffiliate, useCommissions, useCreateAffiliate, useCreatePayout, useDeleteAffiliate, usePayoutExport, usePayouts, useReferralLink, useUpdateAffiliate, useUpdateAffiliateProfile, useUpdateCommission, useUpdatePayout };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useStack, useIdentity, useIdentitySourceGeneration } from '@btst/stack/context';
|
|
3
|
+
import { createResource } from '@btst/stack/plugins/client/hooks';
|
|
4
|
+
import { affiliateResources } from '../../query-keys.mjs';
|
|
5
|
+
import { createTrackingLink } from '../../attribution.mjs';
|
|
6
|
+
import { AFFILIATE_PLUGIN_ID } from '../constants.mjs';
|
|
7
|
+
|
|
8
|
+
const affiliate = createResource({
|
|
9
|
+
plugin: AFFILIATE_PLUGIN_ID,
|
|
10
|
+
resources: affiliateResources
|
|
11
|
+
});
|
|
12
|
+
function useAffiliatePartition() {
|
|
13
|
+
const { identity, isPending, error } = useIdentity();
|
|
14
|
+
const generation = useIdentitySourceGeneration();
|
|
15
|
+
const { plugins } = useStack();
|
|
16
|
+
const api = plugins?.[AFFILIATE_PLUGIN_ID]?.api;
|
|
17
|
+
return {
|
|
18
|
+
identity,
|
|
19
|
+
generation,
|
|
20
|
+
isPending,
|
|
21
|
+
error: !!error,
|
|
22
|
+
endpoint: [api?.baseURL, api?.basePath],
|
|
23
|
+
headers: [...new Headers(api?.browserHeaders)],
|
|
24
|
+
credentials: api?.credentials
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const useAffiliates = (params = {}) => affiliate.affiliates.list.useSuspense([params, useAffiliatePartition()]);
|
|
28
|
+
const useAffiliate = (id) => affiliate.affiliates.detail.useSuspense([id, useAffiliatePartition()]);
|
|
29
|
+
const useAffiliateDashboard = () => affiliate.affiliatePortal.detail.useSuspense([useAffiliatePartition()]);
|
|
30
|
+
const useCommissions = (params = {}) => affiliate.affiliateCommissions.list.useSuspense([
|
|
31
|
+
params,
|
|
32
|
+
useAffiliatePartition()
|
|
33
|
+
]);
|
|
34
|
+
const usePayouts = (params = {}) => affiliate.affiliatePayouts.list.useSuspense([
|
|
35
|
+
params,
|
|
36
|
+
useAffiliatePartition()
|
|
37
|
+
]);
|
|
38
|
+
const usePayoutExport = (params = {}) => affiliate.affiliatePayouts.export.use([params, useAffiliatePartition()], {
|
|
39
|
+
enabled: false
|
|
40
|
+
});
|
|
41
|
+
const useCreateAffiliate = () => affiliate.affiliates.create.use();
|
|
42
|
+
const useUpdateAffiliate = () => affiliate.affiliates.update.use();
|
|
43
|
+
const useDeleteAffiliate = () => affiliate.affiliates.delete.use();
|
|
44
|
+
const useApplyAffiliate = () => affiliate.affiliatePortal.apply.use();
|
|
45
|
+
const useUpdateAffiliateProfile = () => affiliate.affiliatePortal.update.use();
|
|
46
|
+
const useUpdateCommission = () => affiliate.affiliateCommissions.update.use();
|
|
47
|
+
const useCreatePayout = () => affiliate.affiliatePayouts.create.use();
|
|
48
|
+
const useUpdatePayout = () => affiliate.affiliatePayouts.update.use();
|
|
49
|
+
function useReferralLink() {
|
|
50
|
+
const { plugins } = useStack();
|
|
51
|
+
const api = plugins?.[AFFILIATE_PLUGIN_ID]?.api;
|
|
52
|
+
return (code, landingPath = "/") => {
|
|
53
|
+
const apiBaseURL = new URL(
|
|
54
|
+
api?.basePath ?? "/api/data",
|
|
55
|
+
api?.baseURL || window.location.origin
|
|
56
|
+
);
|
|
57
|
+
return createTrackingLink(apiBaseURL.href, code, landingPath);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { useAffiliate, useAffiliateDashboard, useAffiliates, useApplyAffiliate, useCommissions, useCreateAffiliate, useCreatePayout, useDeleteAffiliate, usePayoutExport, usePayouts, useReferralLink, useUpdateAffiliate, useUpdateAffiliateProfile, useUpdateCommission, useUpdatePayout };
|