@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.
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,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,5 @@
1
+ 'use strict';
2
+
3
+ const AFFILIATE_PLUGIN_ID = "affiliate";
4
+
5
+ exports.AFFILIATE_PLUGIN_ID = AFFILIATE_PLUGIN_ID;
@@ -0,0 +1,3 @@
1
+ const AFFILIATE_PLUGIN_ID = "affiliate";
2
+
3
+ export { AFFILIATE_PLUGIN_ID };
@@ -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 };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ const plugin = require('./plugin.cjs');
4
+
5
+
6
+
7
+ exports.affiliateClientPlugin = plugin.affiliateClientPlugin;