@sudobility/subscription_pages 0.0.4 → 0.0.6

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/dist/index.js CHANGED
@@ -1,44 +1,44 @@
1
- import { jsx as i, jsxs as F } from "react/jsx-runtime";
2
- import { useState as C } from "react";
3
- import { usePackagesByDuration as ce, useUserSubscription as V, getSubscriptionInstance as X, refreshSubscription as Z, useAllOfferings as oe, useOfferingPackages as le, periodToMonths as J } from "@sudobility/subscription_lib";
4
- import { SubscriptionLayout as N, SubscriptionTile as se, SegmentedControl as ee } from "@sudobility/subscription-components";
5
- function he({
1
+ import { jsx as i, jsxs as E } from "react/jsx-runtime";
2
+ import { useState as S } from "react";
3
+ import { usePackagesByDuration as oe, useUserSubscription as V, getSubscriptionInstance as X, refreshSubscription as Z, useAllOfferings as le, useOfferingPackages as se, periodToMonths as J } from "@sudobility/subscription_lib";
4
+ import { SubscriptionLayout as L, SubscriptionTile as ue, SegmentedControl as ee } from "@sudobility/subscription-components";
5
+ function me({
6
6
  isLoggedIn: n,
7
- onNavigateToLogin: s,
8
- userId: d,
7
+ onNavigateToLogin: l,
8
+ userId: p,
9
9
  userEmail: o,
10
- featuresByPackage: p,
11
- freeFeatures: u,
12
- title: f = "Choose Your Plan",
13
- className: S
10
+ featuresByPackage: f,
11
+ freeFeatures: s,
12
+ title: g = "Choose Your Plan",
13
+ className: y
14
14
  }) {
15
15
  const {
16
- packagesByDuration: I,
17
- availableDurations: v,
18
- isLoading: g,
19
- error: P
20
- } = ce(), {
16
+ packagesByDuration: x,
17
+ availableDurations: h,
18
+ isLoading: D,
19
+ error: b
20
+ } = oe(), {
21
21
  subscription: r,
22
- isLoading: M,
23
- error: e
24
- } = V({ userId: d, userEmail: o }), [O, R] = C(null), [b, x] = C(null), [T, k] = C(!1), y = O ?? v[0] ?? null, w = g || M, A = P || e, E = async (t, h) => {
22
+ isLoading: $,
23
+ error: B
24
+ } = V({ userId: p, userEmail: o }), [e, N] = S(null), [F, u] = S(null), [M, P] = S(!1), C = e ?? h[0] ?? null, O = D || $, I = b || B, w = async (t, m) => {
25
25
  try {
26
- k(!0), x(null), await X().purchase({
26
+ P(!0), u(null), await X().purchase({
27
27
  packageId: t,
28
- offeringId: h,
28
+ offeringId: m,
29
29
  customerEmail: o
30
30
  }), await Z();
31
- } catch (l) {
32
- x(
33
- l instanceof Error ? l.message : "Purchase failed"
31
+ } catch (d) {
32
+ u(
33
+ d instanceof Error ? d.message : "Purchase failed"
34
34
  );
35
35
  } finally {
36
- k(!1);
36
+ P(!1);
37
37
  }
38
- }, L = () => n ? (r == null ? void 0 : r.isActive) && r.packageId ? {
38
+ }, R = () => n ? (r == null ? void 0 : r.isActive) && r.packageId ? {
39
39
  title: "Free",
40
40
  price: "$0",
41
- features: u ?? [],
41
+ features: s ?? [],
42
42
  ctaButton: {
43
43
  label: "Cancel Subscription",
44
44
  onClick: () => {
@@ -48,7 +48,7 @@ function he({
48
48
  } : {
49
49
  title: "Free",
50
50
  price: "$0",
51
- features: u ?? [],
51
+ features: s ?? [],
52
52
  ctaButton: {
53
53
  label: "Current Plan"
54
54
  },
@@ -56,38 +56,38 @@ function he({
56
56
  } : {
57
57
  title: "Free",
58
58
  price: "$0",
59
- features: u ?? [],
59
+ features: s ?? [],
60
60
  ctaButton: {
61
61
  label: "Try it for Free",
62
- onClick: s
62
+ onClick: l
63
63
  }
64
- }, U = (t) => {
64
+ }, A = (t) => {
65
65
  if (!n)
66
66
  return {
67
67
  label: "Log in to Continue",
68
- onClick: s
68
+ onClick: l
69
69
  };
70
- const h = (r == null ? void 0 : r.isActive) && r.packageId;
70
+ const m = (r == null ? void 0 : r.isActive) && r.packageId;
71
71
  if ((r == null ? void 0 : r.packageId) !== t.package.packageId)
72
- return h ? {
72
+ return m ? {
73
73
  label: "Change Subscription",
74
- onClick: () => E(t.package.packageId, t.offerId)
74
+ onClick: () => w(t.package.packageId, t.offerId)
75
75
  } : {
76
76
  label: "Subscribe",
77
- onClick: () => E(t.package.packageId, t.offerId)
77
+ onClick: () => w(t.package.packageId, t.offerId)
78
78
  };
79
79
  };
80
- if (w)
80
+ if (O)
81
81
  return /* @__PURE__ */ i(
82
- N,
82
+ L,
83
83
  {
84
- title: f,
85
- className: S,
84
+ title: g,
85
+ className: y,
86
86
  variant: "cta",
87
87
  children: /* @__PURE__ */ i("p", { children: "Loading subscription plans..." })
88
88
  }
89
89
  );
90
- const Y = b ?? (A ? A.message : null), j = n && (r != null && r.isActive) && r.packageId ? {
90
+ const T = F ?? (I ? I.message : null), U = n && (r != null && r.isActive) && r.packageId ? {
91
91
  isActive: !0,
92
92
  activeContent: {
93
93
  title: "Active Subscription",
@@ -107,44 +107,44 @@ function he({
107
107
  ] : []
108
108
  ]
109
109
  }
110
- } : void 0, D = y ? I[y] ?? [] : [];
110
+ } : void 0, Y = C ? x[C] ?? [] : [];
111
111
  return /* @__PURE__ */ i(
112
- N,
112
+ L,
113
113
  {
114
- title: f,
115
- className: S,
114
+ title: g,
115
+ className: y,
116
116
  variant: "cta",
117
- error: Y,
118
- currentStatus: j,
119
- freeTileConfig: L(),
120
- aboveProducts: v.length > 1 ? /* @__PURE__ */ i(
117
+ error: T,
118
+ currentStatus: U,
119
+ freeTileConfig: R(),
120
+ aboveProducts: h.length > 1 ? /* @__PURE__ */ i(
121
121
  ee,
122
122
  {
123
- options: v.map((t) => ({
123
+ options: h.map((t) => ({
124
124
  value: t,
125
125
  label: t.charAt(0).toUpperCase() + t.slice(1)
126
126
  })),
127
- value: y ?? v[0],
128
- onChange: (t) => R(t)
127
+ value: C ?? h[0],
128
+ onChange: (t) => N(t)
129
129
  }
130
130
  ) : void 0,
131
- children: D.map((t) => {
132
- var $;
133
- const h = n && (r == null ? void 0 : r.isActive) && r.packageId === t.package.packageId, l = U(t);
131
+ children: Y.map((t) => {
132
+ var k;
133
+ const m = n && (r == null ? void 0 : r.isActive) && r.packageId === t.package.packageId, d = A(t);
134
134
  return /* @__PURE__ */ i(
135
- se,
135
+ ue,
136
136
  {
137
137
  id: t.package.packageId,
138
138
  title: t.package.name,
139
- price: (($ = t.package.product) == null ? void 0 : $.priceString) ?? "$0",
139
+ price: ((k = t.package.product) == null ? void 0 : k.priceString) ?? "$0",
140
140
  periodLabel: t.package.product ? `/${t.package.product.period}` : void 0,
141
- features: (p == null ? void 0 : p[t.package.packageId]) ?? [],
141
+ features: (f == null ? void 0 : f[t.package.packageId]) ?? [],
142
142
  isSelected: !1,
143
143
  onSelect: () => {
144
144
  },
145
- isCurrentPlan: h,
146
- ctaButton: l,
147
- disabled: T
145
+ isCurrentPlan: m,
146
+ ctaButton: d,
147
+ disabled: M
148
148
  },
149
149
  `${t.offerId}-${t.package.packageId}`
150
150
  );
@@ -155,73 +155,76 @@ function he({
155
155
  function K(n) {
156
156
  return n.charAt(0).toUpperCase() + n.slice(1);
157
157
  }
158
- const ue = {
158
+ const de = {
159
159
  weekly: "Weekly",
160
160
  monthly: "Monthly",
161
161
  quarterly: "Quarterly",
162
162
  yearly: "Yearly",
163
163
  lifetime: "Lifetime"
164
164
  };
165
- function de(n, s) {
166
- if (!n.product || !s.product) return null;
167
- const d = J(n.product.period), o = J(s.product.period);
168
- if (d <= 0 || o <= 0 || d === 1 / 0 || o === 1 / 0 || d === o) return null;
169
- const p = n.product.price / d, u = s.product.price / o;
170
- if (p <= 0) return null;
171
- const f = Math.round(
172
- (p - u) / p * 100
165
+ function pe(n, l) {
166
+ if (!n.product || !l.product) return null;
167
+ const p = J(n.product.period), o = J(l.product.period);
168
+ if (p <= 0 || o <= 0 || p === 1 / 0 || o === 1 / 0 || p === o) return null;
169
+ const f = n.product.price / p, s = l.product.price / o;
170
+ if (f <= 0) return null;
171
+ const g = Math.round(
172
+ (f - s) / f * 100
173
173
  );
174
- return f > 0 ? f : null;
174
+ return g > 0 ? g : null;
175
175
  }
176
176
  function ve({
177
177
  isLoggedIn: n,
178
- onNavigateToLogin: s,
179
- userId: d,
178
+ onNavigateToLogin: l,
179
+ userId: p,
180
180
  userEmail: o,
181
- featuresByPackage: p,
182
- freeFeatures: u,
183
- title: f = "Choose Your Plan",
184
- className: S,
185
- t: I,
186
- renderOfferingContent: v
181
+ featuresByPackage: f,
182
+ freeFeatures: s,
183
+ title: g = "Choose Your Plan",
184
+ className: y,
185
+ t: x,
186
+ renderOfferingContent: h,
187
+ initialOfferId: D
187
188
  }) {
188
189
  var q;
189
- const g = (a, c) => I ? I(a, c) : c, {
190
- offerings: P,
191
- isLoading: r,
192
- error: M
193
- } = oe(), {
190
+ const b = (a, c) => x ? x(a, c) : c, {
191
+ offerings: r,
192
+ isLoading: $,
193
+ error: B
194
+ } = le(), {
194
195
  subscription: e,
195
- isLoading: O,
196
- error: R
197
- } = V({ userId: d, userEmail: o }), [b, x] = C("free"), [T, k] = C(null), [y, w] = C(!1), A = ((q = P[0]) == null ? void 0 : q.offerId) ?? "", E = b !== "free" ? b : A, {
198
- packages: L,
199
- isLoading: U,
200
- error: Y
201
- } = le(E), j = r || O || U, D = M || R || Y, t = async (a, c) => {
196
+ isLoading: N,
197
+ error: F
198
+ } = V({ userId: p, userEmail: o }), [u, M] = S(
199
+ D ?? "free"
200
+ ), [P, C] = S(null), [O, I] = S(!1), w = ((q = r[0]) == null ? void 0 : q.offerId) ?? "", R = u !== "free" ? u : w, {
201
+ packages: A,
202
+ isLoading: T,
203
+ error: U
204
+ } = se(R), Y = $ || N || T, t = B || F || U, m = async (a, c) => {
202
205
  try {
203
- w(!0), k(null), await X().purchase({
206
+ I(!0), C(null), await X().purchase({
204
207
  packageId: a,
205
208
  offeringId: c,
206
209
  customerEmail: o
207
210
  }), await Z();
208
- } catch (m) {
209
- k(
210
- m instanceof Error ? m.message : "Purchase failed"
211
+ } catch (v) {
212
+ C(
213
+ v instanceof Error ? v.message : "Purchase failed"
211
214
  );
212
215
  } finally {
213
- w(!1);
216
+ I(!1);
214
217
  }
215
- }, h = [
216
- { value: "free", label: g("free", "Free") },
217
- ...P.map((a) => ({
218
+ }, d = [
219
+ { value: "free", label: b("free", "Free") },
220
+ ...r.map((a) => ({
218
221
  value: a.offerId,
219
- label: g(a.offerId, K(a.offerId))
222
+ label: b(a.offerId, K(a.offerId))
220
223
  }))
221
- ], l = L[0] ?? null, $ = () => n ? (e == null ? void 0 : e.isActive) && e.packageId ? {
222
- title: g("free", "Free"),
224
+ ], k = A[0] ?? null, re = () => n ? (e == null ? void 0 : e.isActive) && e.packageId ? {
225
+ title: b("free", "Free"),
223
226
  price: "$0",
224
- features: u ?? [],
227
+ features: s ?? [],
225
228
  ctaButton: {
226
229
  label: "Cancel Subscription",
227
230
  onClick: () => {
@@ -229,37 +232,37 @@ function ve({
229
232
  }
230
233
  }
231
234
  } : {
232
- title: g("free", "Free"),
235
+ title: b("free", "Free"),
233
236
  price: "$0",
234
- features: u ?? [],
237
+ features: s ?? [],
235
238
  ctaButton: {
236
239
  label: "Current Plan"
237
240
  },
238
241
  topBadge: { text: "Current Plan", color: "blue" }
239
242
  } : {
240
- title: g("free", "Free"),
243
+ title: b("free", "Free"),
241
244
  price: "$0",
242
- features: u ?? [],
245
+ features: s ?? [],
243
246
  ctaButton: {
244
247
  label: "Try it for Free",
245
- onClick: s
248
+ onClick: l
246
249
  }
247
- }, re = (a) => n ? (e == null ? void 0 : e.packageId) === a.packageId ? "Current Plan" : (e == null ? void 0 : e.isActive) && e.packageId ? "Change Subscription" : "Subscribe" : "Log in to Continue", te = (a, c) => {
248
- if (!n) return s;
250
+ }, te = (a) => n ? (e == null ? void 0 : e.packageId) === a.packageId ? "Current Plan" : (e == null ? void 0 : e.isActive) && e.packageId ? "Change Subscription" : "Subscribe" : "Log in to Continue", ae = (a, c) => {
251
+ if (!n) return l;
249
252
  if ((e == null ? void 0 : e.packageId) !== a.packageId)
250
- return () => t(a.packageId, c);
253
+ return () => m(a.packageId, c);
251
254
  };
252
- if (j)
255
+ if (Y)
253
256
  return /* @__PURE__ */ i(
254
- N,
257
+ L,
255
258
  {
256
- title: f,
257
- className: S,
259
+ title: g,
260
+ className: y,
258
261
  variant: "cta",
259
262
  children: /* @__PURE__ */ i("p", { children: "Loading subscription plans..." })
260
263
  }
261
264
  );
262
- const ae = T ?? (D ? D.message : null), ne = n && (e != null && e.isActive) && e.packageId ? {
265
+ const ne = P ?? (t ? t.message : null), ie = n && (e != null && e.isActive) && e.packageId ? {
263
266
  isActive: !0,
264
267
  activeContent: {
265
268
  title: "Active Subscription",
@@ -279,49 +282,50 @@ function ve({
279
282
  ] : []
280
283
  ]
281
284
  }
282
- } : void 0, _ = b === "free";
285
+ } : void 0, _ = u === "free";
283
286
  return /* @__PURE__ */ i(
284
- N,
287
+ L,
285
288
  {
286
- title: f,
287
- className: S,
289
+ title: g,
290
+ className: y,
288
291
  variant: "cta",
289
- error: ae,
290
- currentStatus: ne,
291
- freeTileConfig: _ ? $() : void 0,
292
- aboveProducts: h.length > 1 ? /* @__PURE__ */ i("div", { className: "flex justify-center mb-6", children: /* @__PURE__ */ i(
292
+ error: ne,
293
+ currentStatus: ie,
294
+ freeTileConfig: _ ? re() : void 0,
295
+ aboveProducts: d.length > 1 ? /* @__PURE__ */ i("div", { className: "flex justify-center mb-6", children: /* @__PURE__ */ i(
293
296
  ee,
294
297
  {
295
- options: h,
296
- value: b,
297
- onChange: x
298
+ options: d,
299
+ value: u,
300
+ onChange: M
298
301
  }
299
302
  ) }) : void 0,
300
- children: !_ && /* @__PURE__ */ F("div", { className: "col-span-full space-y-6", children: [
301
- v && /* @__PURE__ */ i("div", { className: "rounded-xl bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700 p-5", children: v(b) }),
302
- /* @__PURE__ */ i("div", { className: "space-y-3", children: L.map((a) => {
303
+ children: !_ && /* @__PURE__ */ E("div", { className: "col-span-full space-y-6", children: [
304
+ h && /* @__PURE__ */ i("div", { className: "rounded-xl bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700 p-5", children: h(u) }),
305
+ /* @__PURE__ */ i("div", { className: "space-y-3", children: A.map((a) => {
303
306
  var G, H;
304
- const c = (G = a.product) == null ? void 0 : G.period, m = c ? g(c, ue[c] ?? K(c)) : a.name, B = n && (e == null ? void 0 : e.isActive) && e.packageId === a.packageId, z = l && a.packageId !== l.packageId ? de(l, a) : null, Q = re(a), W = te(a, b), ie = ((H = a.product) == null ? void 0 : H.priceString) ?? "$0";
305
- return /* @__PURE__ */ F(
307
+ const c = (G = a.product) == null ? void 0 : G.period, v = c ? b(c, de[c] ?? K(c)) : a.name, j = n && (e == null ? void 0 : e.isActive) && e.packageId === a.packageId, z = k && a.packageId !== k.packageId ? pe(k, a) : null, Q = te(a), W = ae(a, u), ce = ((H = a.product) == null ? void 0 : H.priceString) ?? "$0";
308
+ return /* @__PURE__ */ E(
306
309
  "div",
307
310
  {
308
- className: "flex items-center justify-between rounded-xl p-4 transition-all " + (B ? "bg-blue-50 dark:bg-blue-900/20 border-2 border-blue-500 dark:border-blue-400" : "bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700"),
311
+ className: "flex items-center justify-between rounded-xl p-4 transition-all " + (j ? "bg-blue-50 dark:bg-blue-900/20 border-2 border-blue-500 dark:border-blue-400" : "bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-700"),
309
312
  children: [
310
- /* @__PURE__ */ F("div", { className: "min-w-0 flex-1", children: [
311
- /* @__PURE__ */ i("p", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: m }),
312
- z !== null ? /* @__PURE__ */ F("p", { className: "text-sm font-medium text-green-600 dark:text-green-400", children: [
313
+ /* @__PURE__ */ E("div", { className: "min-w-0 flex-1", children: [
314
+ /* @__PURE__ */ i("p", { className: "text-base font-semibold text-gray-900 dark:text-gray-100", children: v }),
315
+ /* @__PURE__ */ i("p", { className: "text-xs text-gray-400 dark:text-gray-500", children: a.packageId }),
316
+ z !== null ? /* @__PURE__ */ E("p", { className: "text-sm font-medium text-green-600 dark:text-green-400", children: [
313
317
  "Save ",
314
318
  z,
315
319
  "%"
316
- ] }) : B ? /* @__PURE__ */ i("p", { className: "text-sm font-medium text-blue-600 dark:text-blue-400", children: "Current Plan" }) : null
320
+ ] }) : j ? /* @__PURE__ */ i("p", { className: "text-sm font-medium text-blue-600 dark:text-blue-400", children: "Current Plan" }) : null
317
321
  ] }),
318
- /* @__PURE__ */ i(
322
+ j ? /* @__PURE__ */ i("span", { className: "ml-4 flex-shrink-0 text-sm font-semibold text-blue-600 dark:text-blue-400", children: Q }) : /* @__PURE__ */ i(
319
323
  "button",
320
324
  {
321
325
  onClick: W,
322
- disabled: y || !W,
323
- className: "ml-4 flex-shrink-0 rounded-lg px-4 py-2 text-sm font-semibold transition-colors " + (B ? "bg-blue-100 dark:bg-blue-900/40 text-blue-700 dark:text-blue-300 cursor-default" : "bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed"),
324
- children: B ? Q : `${ie} · ${Q}`
326
+ disabled: O || !W,
327
+ className: "ml-4 flex-shrink-0 rounded-lg px-4 py-2 text-sm font-semibold transition-colors bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed",
328
+ children: `${ce} · ${Q}`
325
329
  }
326
330
  )
327
331
  ]
@@ -334,6 +338,6 @@ function ve({
334
338
  );
335
339
  }
336
340
  export {
337
- he as SubscriptionByDurationPage,
341
+ me as SubscriptionByDurationPage,
338
342
  ve as SubscriptionByOfferPage
339
343
  };
@@ -29,5 +29,10 @@ export interface SubscriptionByOfferPageProps {
29
29
  * Return a list of strings or React elements shown in a styled container.
30
30
  */
31
31
  renderOfferingContent?: (offerId: string) => React.ReactNode;
32
+ /**
33
+ * If set, automatically select the specified offering on mount.
34
+ * Must match an offering identifier from RevenueCat.
35
+ */
36
+ initialOfferId?: string;
32
37
  }
33
- export declare function SubscriptionByOfferPage({ isLoggedIn, onNavigateToLogin, userId, userEmail, featuresByPackage: _featuresByPackage, freeFeatures, title, className, t: translate, renderOfferingContent, }: SubscriptionByOfferPageProps): import("react/jsx-runtime").JSX.Element;
38
+ export declare function SubscriptionByOfferPage({ isLoggedIn, onNavigateToLogin, userId, userEmail, featuresByPackage: _featuresByPackage, freeFeatures, title, className, t: translate, renderOfferingContent, initialOfferId, }: SubscriptionByOfferPageProps): import("react/jsx-runtime").JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/subscription_pages",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "Subscription page components for React web applications",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -28,13 +28,13 @@
28
28
  "peerDependencies": {
29
29
  "react": "^18.0.0 || ^19.0.0",
30
30
  "react-dom": "^18.0.0 || ^19.0.0",
31
- "@sudobility/subscription_lib": "^0.0.26",
31
+ "@sudobility/subscription_lib": "^0.0.27",
32
32
  "@sudobility/subscription-components": "^1.0.27",
33
33
  "@sudobility/types": "^1.9.58"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@sudobility/subscription-components": "^1.0.27",
37
- "@sudobility/subscription_lib": "^0.0.26",
37
+ "@sudobility/subscription_lib": "^0.0.27",
38
38
  "@sudobility/types": "^1.9.58",
39
39
  "@testing-library/jest-dom": "^6.0.0",
40
40
  "@testing-library/react": "^16.0.0",