@monetizekit/react 0.1.0 → 0.3.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/dist/index.js CHANGED
@@ -45,7 +45,13 @@ var THEME_PRESETS = {
45
45
  colorPrimaryForeground: "#ffffff",
46
46
  colorAccent: "#10b981",
47
47
  colorBorder: "#e4e4e7",
48
+ colorCard: "#ffffff",
49
+ colorCardForeground: "#0a0a0a",
50
+ colorSuccess: "#16a34a",
51
+ colorWarning: "#d97706",
52
+ colorDanger: "#dc2626",
48
53
  radius: "0.5rem",
54
+ shadow: "0 1px 3px rgba(0,0,0,0.1)",
49
55
  fontFamily: "system-ui, -apple-system, sans-serif"
50
56
  },
51
57
  dark: {
@@ -56,7 +62,13 @@ var THEME_PRESETS = {
56
62
  colorPrimaryForeground: "#0a0a0a",
57
63
  colorAccent: "#10b981",
58
64
  colorBorder: "#27272a",
65
+ colorCard: "#18181b",
66
+ colorCardForeground: "#fafafa",
67
+ colorSuccess: "#22c55e",
68
+ colorWarning: "#f59e0b",
69
+ colorDanger: "#ef4444",
59
70
  radius: "0.5rem",
71
+ shadow: "0 1px 3px rgba(0,0,0,0.4)",
60
72
  fontFamily: "system-ui, -apple-system, sans-serif"
61
73
  },
62
74
  memphis: {
@@ -67,7 +79,13 @@ var THEME_PRESETS = {
67
79
  colorPrimaryForeground: "#1a1a1a",
68
80
  colorAccent: "#00D9FF",
69
81
  colorBorder: "#1a1a1a",
82
+ colorCard: "#ffffff",
83
+ colorCardForeground: "#1a1a1a",
84
+ colorSuccess: "#00C853",
85
+ colorWarning: "#FFB400",
86
+ colorDanger: "#FF3B30",
70
87
  radius: "0",
88
+ shadow: "4px 4px 0 #1a1a1a",
71
89
  fontFamily: "system-ui, -apple-system, sans-serif"
72
90
  },
73
91
  dashboard: {
@@ -78,10 +96,119 @@ var THEME_PRESETS = {
78
96
  colorPrimaryForeground: "oklch(0.985 0 0)",
79
97
  colorAccent: "oklch(0.97 0 0)",
80
98
  colorBorder: "oklch(0.922 0 0)",
99
+ colorCard: "oklch(1 0 0)",
100
+ colorCardForeground: "oklch(0.145 0 0)",
101
+ colorSuccess: "#16a34a",
102
+ colorWarning: "#d97706",
103
+ colorDanger: "#dc2626",
81
104
  radius: "0.625rem",
105
+ shadow: "0 1px 2px rgba(0,0,0,0.06)",
82
106
  fontFamily: "Geist, system-ui, sans-serif"
107
+ },
108
+ console: {
109
+ colorBackground: "#0b0f14",
110
+ colorForeground: "#e6edf3",
111
+ colorMuted: "#8b949e",
112
+ colorPrimary: "#6366f1",
113
+ colorPrimaryForeground: "#ffffff",
114
+ colorAccent: "#00D9FF",
115
+ colorBorder: "#1f2630",
116
+ colorCard: "#11161d",
117
+ colorCardForeground: "#e6edf3",
118
+ colorSuccess: "#34d399",
119
+ colorWarning: "#fbbf24",
120
+ colorDanger: "#f87171",
121
+ radius: "0.625rem",
122
+ shadow: "0 8px 24px rgba(0,0,0,0.5)",
123
+ fontFamily: "Geist, system-ui, sans-serif"
124
+ },
125
+ midnight: {
126
+ colorBackground: "#0f172a",
127
+ colorForeground: "#e2e8f0",
128
+ colorMuted: "#94a3b8",
129
+ colorPrimary: "#818cf8",
130
+ colorPrimaryForeground: "#0f172a",
131
+ colorAccent: "#38bdf8",
132
+ colorBorder: "#1e293b",
133
+ colorCard: "#1e293b",
134
+ colorCardForeground: "#e2e8f0",
135
+ colorSuccess: "#4ade80",
136
+ colorWarning: "#facc15",
137
+ colorDanger: "#fb7185",
138
+ radius: "0.75rem",
139
+ shadow: "0 10px 30px rgba(2,6,23,0.6)",
140
+ fontFamily: "system-ui, -apple-system, sans-serif"
141
+ },
142
+ ocean: {
143
+ colorBackground: "#f0fdfa",
144
+ colorForeground: "#0f3d3e",
145
+ colorMuted: "#5b7c7d",
146
+ colorPrimary: "#0d9488",
147
+ colorPrimaryForeground: "#ffffff",
148
+ colorAccent: "#06b6d4",
149
+ colorBorder: "#99f6e4",
150
+ colorCard: "#ffffff",
151
+ colorCardForeground: "#0f3d3e",
152
+ colorSuccess: "#059669",
153
+ colorWarning: "#d97706",
154
+ colorDanger: "#e11d48",
155
+ radius: "0.75rem",
156
+ shadow: "0 4px 14px rgba(13,148,136,0.15)",
157
+ fontFamily: "system-ui, -apple-system, sans-serif"
158
+ },
159
+ forest: {
160
+ colorBackground: "#f7fee7",
161
+ colorForeground: "#1a2e05",
162
+ colorMuted: "#5c6b47",
163
+ colorPrimary: "#4d7c0f",
164
+ colorPrimaryForeground: "#ffffff",
165
+ colorAccent: "#65a30d",
166
+ colorBorder: "#d9f99d",
167
+ colorCard: "#ffffff",
168
+ colorCardForeground: "#1a2e05",
169
+ colorSuccess: "#16a34a",
170
+ colorWarning: "#ca8a04",
171
+ colorDanger: "#dc2626",
172
+ radius: "0.5rem",
173
+ shadow: "0 4px 14px rgba(77,124,15,0.12)",
174
+ fontFamily: "system-ui, -apple-system, sans-serif"
175
+ },
176
+ sunset: {
177
+ colorBackground: "#fff7ed",
178
+ colorForeground: "#431407",
179
+ colorMuted: "#9a6b4f",
180
+ colorPrimary: "#ea580c",
181
+ colorPrimaryForeground: "#ffffff",
182
+ colorAccent: "#f43f5e",
183
+ colorBorder: "#fed7aa",
184
+ colorCard: "#ffffff",
185
+ colorCardForeground: "#431407",
186
+ colorSuccess: "#16a34a",
187
+ colorWarning: "#d97706",
188
+ colorDanger: "#e11d48",
189
+ radius: "1rem",
190
+ shadow: "0 6px 20px rgba(234,88,12,0.15)",
191
+ fontFamily: "system-ui, -apple-system, sans-serif"
192
+ },
193
+ grape: {
194
+ colorBackground: "#faf5ff",
195
+ colorForeground: "#2e1065",
196
+ colorMuted: "#7c6f93",
197
+ colorPrimary: "#7c3aed",
198
+ colorPrimaryForeground: "#ffffff",
199
+ colorAccent: "#d946ef",
200
+ colorBorder: "#e9d5ff",
201
+ colorCard: "#ffffff",
202
+ colorCardForeground: "#2e1065",
203
+ colorSuccess: "#16a34a",
204
+ colorWarning: "#d97706",
205
+ colorDanger: "#dc2626",
206
+ radius: "0.875rem",
207
+ shadow: "0 6px 20px rgba(124,58,237,0.15)",
208
+ fontFamily: "system-ui, -apple-system, sans-serif"
83
209
  }
84
210
  };
211
+ var THEME_PRESET_NAMES = Object.keys(THEME_PRESETS);
85
212
  function resolveTokens(appearance = "light") {
86
213
  if (typeof appearance === "string") {
87
214
  return THEME_PRESETS[appearance];
@@ -97,7 +224,13 @@ var TOKEN_TO_CSS_VAR = {
97
224
  colorPrimaryForeground: "--mk-primary-fg",
98
225
  colorAccent: "--mk-accent",
99
226
  colorBorder: "--mk-border",
227
+ colorCard: "--mk-card",
228
+ colorCardForeground: "--mk-card-fg",
229
+ colorSuccess: "--mk-success",
230
+ colorWarning: "--mk-warning",
231
+ colorDanger: "--mk-danger",
100
232
  radius: "--mk-radius",
233
+ shadow: "--mk-shadow",
101
234
  fontFamily: "--mk-font"
102
235
  };
103
236
  function tokensToStyle(tokens) {
@@ -256,6 +389,113 @@ function describeUsageTerm(term, locale) {
256
389
  }
257
390
  return parts.join(", ");
258
391
  }
392
+
393
+ // src/lib/sample-data.ts
394
+ var SAMPLE_PLANS = [
395
+ {
396
+ id: "sample_free",
397
+ name: "Starter",
398
+ description: "Evaluate the platform and model your catalog",
399
+ pricing: [{ type: "flat", amount: 0, currency: "USD", interval: "monthly" }],
400
+ entitlements: [
401
+ { featureKey: "max_customers", featureDisplayName: "Tracked customers", type: "limit", value: 100 },
402
+ { featureKey: "api_access", featureDisplayName: "REST & GraphQL API", type: "boolean", value: true },
403
+ { featureKey: "metering", featureDisplayName: "Usage metering", type: "boolean", value: true }
404
+ ]
405
+ },
406
+ {
407
+ id: "sample_pro",
408
+ name: "Growth",
409
+ description: "Product-led monetization at scale",
410
+ pricing: [{ type: "flat", amount: 499, currency: "USD", interval: "monthly" }],
411
+ entitlements: [
412
+ { featureKey: "max_customers", featureDisplayName: "Tracked customers", type: "limit", value: 1e4 },
413
+ { featureKey: "stripe", featureDisplayName: "Stripe integration", type: "boolean", value: true },
414
+ { featureKey: "experiments", featureDisplayName: "Experiments & A/B testing", type: "boolean", value: true },
415
+ { featureKey: "widgets", featureDisplayName: "Embeddable widgets", type: "boolean", value: true }
416
+ ]
417
+ },
418
+ {
419
+ id: "sample_scale",
420
+ name: "Scale",
421
+ description: "Volume-based capacity pricing",
422
+ pricing: [
423
+ { type: "flat", amount: 999, currency: "USD", interval: "monthly" },
424
+ {
425
+ type: "usage",
426
+ amount: 0,
427
+ currency: "USD",
428
+ interval: "monthly",
429
+ meterId: "sample_mtc",
430
+ meterDisplayName: "Tracked customers",
431
+ includedUnits: 25e3,
432
+ tierMode: "graduated",
433
+ tieredPricing: [
434
+ { upTo: 1e5, unitPrice: 0.012 },
435
+ { upTo: null, unitPrice: 6e-3 }
436
+ ]
437
+ }
438
+ ],
439
+ entitlements: [
440
+ { featureKey: "everything_pro", featureDisplayName: "Everything in Growth", type: "boolean", value: true },
441
+ { featureKey: "approvals", featureDisplayName: "Approval workflows", type: "boolean", value: true }
442
+ ]
443
+ },
444
+ {
445
+ id: "sample_enterprise",
446
+ name: "Enterprise",
447
+ description: "Governance, scale, and advanced controls",
448
+ tags: ["contact_sales"],
449
+ pricing: [],
450
+ entitlements: [
451
+ { featureKey: "sso", featureDisplayName: "SSO / SAML", type: "boolean", value: true },
452
+ { featureKey: "sla", featureDisplayName: "Custom SLA", type: "boolean", value: true }
453
+ ]
454
+ }
455
+ ];
456
+ var SAMPLE_USAGE = {
457
+ api_calls: { meterId: "api_calls", current: 72e3, limit: 1e5 },
458
+ seats: { meterId: "seats", current: 8, limit: 10 },
459
+ storage_gb: { meterId: "storage_gb", current: 3, limit: 10 }
460
+ };
461
+ var SAMPLE_CREDITS = { balance: 1200, currency: "USD" };
462
+ var SAMPLE_TEAM = {
463
+ members: [
464
+ { name: "Jordan Lee", email: "jordan@acme.test", role: "owner" },
465
+ { name: "Sam Rivera", email: "sam@acme.test", role: "admin" },
466
+ { name: "Taylor Kim", email: "taylor@acme.test", role: "member" }
467
+ ],
468
+ seats: 3,
469
+ maxSeats: 10
470
+ };
471
+ var SAMPLE_INVOICES = [
472
+ { id: "in_1003", date: "2026-03-01T00:00:00Z", amount: 499, currency: "USD", status: "paid" },
473
+ { id: "in_1002", date: "2026-02-01T00:00:00Z", amount: 499, currency: "USD", status: "paid" },
474
+ { id: "in_1001", date: "2026-01-01T00:00:00Z", amount: 499, currency: "USD", status: "paid" }
475
+ ];
476
+ var SAMPLE_PORTAL = {
477
+ planName: "Growth",
478
+ meterIds: ["api_calls", "seats"]
479
+ };
480
+ var SAMPLE_NOTICE_TEXT = "Sample data for illustration only \u2014 define plans and products to show live values.";
481
+ var noticeStyle = {
482
+ display: "flex",
483
+ alignItems: "center",
484
+ gap: "0.5rem",
485
+ border: "1px dashed var(--mk-warning)",
486
+ borderRadius: "var(--mk-radius)",
487
+ background: "color-mix(in srgb, var(--mk-warning) 12%, transparent)",
488
+ color: "var(--mk-card-fg)",
489
+ fontFamily: "var(--mk-font)",
490
+ fontSize: "0.75rem",
491
+ padding: "0.5rem 0.75rem"
492
+ };
493
+ function SampleNotice({ children }) {
494
+ return /* @__PURE__ */ jsxs("div", { role: "note", "data-mk-component": "sample-notice", style: noticeStyle, children: [
495
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { color: "var(--mk-warning)", fontWeight: 700 }, children: "\u25CF" }),
496
+ /* @__PURE__ */ jsx("span", { children: children ?? SAMPLE_NOTICE_TEXT })
497
+ ] });
498
+ }
259
499
  var wrapperStyle = {
260
500
  display: "grid",
261
501
  gridTemplateColumns: "repeat(auto-fit, minmax(240px, 1fr))",
@@ -277,7 +517,9 @@ function PricingTable({
277
517
  highlightPlan,
278
518
  locale,
279
519
  onSelectPlan,
280
- onContactSales
520
+ onContactSales,
521
+ sampleWhenEmpty = true,
522
+ disclaimer
281
523
  }) {
282
524
  const { client, tokens } = useMonetizeKit();
283
525
  const [plans, setPlans] = useState(plansProp ?? null);
@@ -303,68 +545,84 @@ function PricingTable({
303
545
  if (!plans) {
304
546
  return /* @__PURE__ */ jsx("div", { "aria-busy": "true", style: { color: "var(--mk-muted)" }, children: "Loading pricing\u2026" });
305
547
  }
306
- return /* @__PURE__ */ jsx("div", { style: { ...tokensToStyle(tokens), ...wrapperStyle }, "data-mk-component": "pricing-table", children: plans.map((plan) => {
307
- const price = describePlanPrice(plan, locale);
308
- const highlighted = highlightPlan != null && plan.name.toLowerCase() === highlightPlan.toLowerCase();
309
- return /* @__PURE__ */ jsxs(
310
- "div",
311
- {
312
- style: {
313
- ...cardBase,
314
- borderColor: highlighted ? "var(--mk-primary)" : "var(--mk-border)",
315
- borderWidth: highlighted ? 2 : 1
316
- },
317
- "data-mk-plan": plan.name,
318
- "data-mk-highlighted": highlighted ? "true" : void 0,
319
- children: [
320
- highlighted ? /* @__PURE__ */ jsx(
321
- "span",
322
- {
323
- style: {
324
- alignSelf: "flex-start",
325
- background: "var(--mk-primary)",
326
- color: "var(--mk-primary-fg)",
327
- borderRadius: "var(--mk-radius)",
328
- padding: "0.125rem 0.5rem",
329
- fontSize: "0.75rem",
330
- fontWeight: 600
331
- },
332
- children: "Most Popular"
333
- }
334
- ) : null,
335
- /* @__PURE__ */ jsx("h3", { style: { margin: 0, fontSize: "1.25rem", fontWeight: 700 }, children: plan.name }),
336
- plan.description ? /* @__PURE__ */ jsx("p", { style: { margin: 0, color: "var(--mk-muted)", fontSize: "0.875rem" }, children: plan.description }) : null,
337
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: "0.375rem" }, children: [
338
- /* @__PURE__ */ jsx("span", { style: { fontSize: "2rem", fontWeight: 700 }, children: price.contactSales ? "Custom" : price.headline }),
339
- price.caption ? /* @__PURE__ */ jsx("span", { style: { color: "var(--mk-muted)", fontSize: "0.875rem" }, children: price.caption }) : null
340
- ] }),
341
- plan.entitlements && plan.entitlements.length > 0 ? /* @__PURE__ */ jsx("ul", { style: { margin: 0, paddingLeft: "1rem", color: "var(--mk-fg)", fontSize: "0.875rem" }, children: plan.entitlements.slice(0, 6).map((e) => /* @__PURE__ */ jsxs("li", { children: [
342
- e.featureDisplayName,
343
- e.type !== "boolean" ? `: ${String(e.value)}` : ""
344
- ] }, e.featureKey)) }) : null,
345
- /* @__PURE__ */ jsx(
346
- "button",
548
+ const isSample = plans.length === 0 && sampleWhenEmpty;
549
+ const effectivePlans = isSample ? SAMPLE_PLANS : plans;
550
+ if (effectivePlans.length === 0) {
551
+ return /* @__PURE__ */ jsx("div", { style: { color: "var(--mk-muted)" }, children: "No plans available." });
552
+ }
553
+ return /* @__PURE__ */ jsxs(
554
+ "div",
555
+ {
556
+ style: { ...tokensToStyle(tokens), display: "flex", flexDirection: "column", gap: "1rem" },
557
+ "data-mk-component": "pricing-table",
558
+ "data-mk-sample": isSample ? "true" : void 0,
559
+ children: [
560
+ isSample ? /* @__PURE__ */ jsx(SampleNotice, { children: disclaimer }) : null,
561
+ /* @__PURE__ */ jsx("div", { style: wrapperStyle, children: effectivePlans.map((plan) => {
562
+ const price = describePlanPrice(plan, locale);
563
+ const highlighted = highlightPlan != null && plan.name.toLowerCase() === highlightPlan.toLowerCase();
564
+ return /* @__PURE__ */ jsxs(
565
+ "div",
347
566
  {
348
- type: "button",
349
- onClick: () => price.contactSales ? onContactSales?.(plan.id) : onSelectPlan?.(plan.id),
350
567
  style: {
351
- marginTop: "auto",
352
- background: "var(--mk-primary)",
353
- color: "var(--mk-primary-fg)",
354
- border: "none",
355
- borderRadius: "var(--mk-radius)",
356
- padding: "0.625rem 1rem",
357
- fontWeight: 600,
358
- cursor: "pointer"
568
+ ...cardBase,
569
+ borderColor: highlighted ? "var(--mk-primary)" : "var(--mk-border)",
570
+ borderWidth: highlighted ? 2 : 1
359
571
  },
360
- children: price.contactSales ? "Contact Sales" : "Get started"
361
- }
362
- )
363
- ]
364
- },
365
- plan.id
366
- );
367
- }) });
572
+ "data-mk-plan": plan.name,
573
+ "data-mk-highlighted": highlighted ? "true" : void 0,
574
+ children: [
575
+ highlighted ? /* @__PURE__ */ jsx(
576
+ "span",
577
+ {
578
+ style: {
579
+ alignSelf: "flex-start",
580
+ background: "var(--mk-primary)",
581
+ color: "var(--mk-primary-fg)",
582
+ borderRadius: "var(--mk-radius)",
583
+ padding: "0.125rem 0.5rem",
584
+ fontSize: "0.75rem",
585
+ fontWeight: 600
586
+ },
587
+ children: "Most Popular"
588
+ }
589
+ ) : null,
590
+ /* @__PURE__ */ jsx("h3", { style: { margin: 0, fontSize: "1.25rem", fontWeight: 700 }, children: plan.name }),
591
+ plan.description ? /* @__PURE__ */ jsx("p", { style: { margin: 0, color: "var(--mk-muted)", fontSize: "0.875rem" }, children: plan.description }) : null,
592
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: "0.375rem" }, children: [
593
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "2rem", fontWeight: 700 }, children: price.contactSales ? "Custom" : price.headline }),
594
+ price.caption ? /* @__PURE__ */ jsx("span", { style: { color: "var(--mk-muted)", fontSize: "0.875rem" }, children: price.caption }) : null
595
+ ] }),
596
+ plan.entitlements && plan.entitlements.length > 0 ? /* @__PURE__ */ jsx("ul", { style: { margin: 0, paddingLeft: "1rem", color: "var(--mk-fg)", fontSize: "0.875rem" }, children: plan.entitlements.slice(0, 6).map((e) => /* @__PURE__ */ jsxs("li", { children: [
597
+ e.featureDisplayName,
598
+ e.type !== "boolean" ? `: ${String(e.value)}` : ""
599
+ ] }, e.featureKey)) }) : null,
600
+ /* @__PURE__ */ jsx(
601
+ "button",
602
+ {
603
+ type: "button",
604
+ onClick: () => price.contactSales ? onContactSales?.(plan.id) : onSelectPlan?.(plan.id),
605
+ style: {
606
+ marginTop: "auto",
607
+ background: "var(--mk-primary)",
608
+ color: "var(--mk-primary-fg)",
609
+ border: "none",
610
+ borderRadius: "var(--mk-radius)",
611
+ padding: "0.625rem 1rem",
612
+ fontWeight: 600,
613
+ cursor: "pointer"
614
+ },
615
+ children: price.contactSales ? "Contact Sales" : "Get started"
616
+ }
617
+ )
618
+ ]
619
+ },
620
+ plan.id
621
+ );
622
+ }) })
623
+ ]
624
+ }
625
+ );
368
626
  }
369
627
  var overlayStyle = {
370
628
  border: "1px solid var(--mk-border)",
@@ -443,7 +701,7 @@ function UsageBanner({
443
701
  const fraction = hasLimit ? Math.min(1, current / limit) : 0;
444
702
  const over = hasLimit && current > limit;
445
703
  const warn = hasLimit && fraction >= warnAt;
446
- const barColor = over || warn ? "var(--mk-primary)" : "var(--mk-accent)";
704
+ const barColor = over ? "var(--mk-danger)" : warn ? "var(--mk-warning)" : "var(--mk-accent)";
447
705
  return /* @__PURE__ */ jsxs("div", { style: { ...tokensToStyle(tokens), ...bannerStyle }, "data-mk-component": "usage-banner", children: [
448
706
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", fontSize: "0.875rem" }, children: [
449
707
  /* @__PURE__ */ jsx("span", { style: { fontWeight: 600 }, children: label }),
@@ -468,73 +726,229 @@ function UsageBanner({
468
726
  children: /* @__PURE__ */ jsx("div", { style: { width: `${fraction * 100}%`, height: "100%", background: barColor } })
469
727
  }
470
728
  ) : null,
471
- over ? /* @__PURE__ */ jsx("span", { style: { color: "var(--mk-primary)", fontSize: "0.75rem" }, children: "Over included allotment \u2014 overage billed per usage pricing." }) : null
729
+ over ? /* @__PURE__ */ jsx("span", { style: { color: "var(--mk-danger)", fontSize: "0.75rem" }, children: "Over included allotment \u2014 overage billed per usage pricing." }) : null
472
730
  ] });
473
731
  }
474
732
  var containerStyle = {
475
733
  border: "1px solid var(--mk-border)",
476
734
  borderRadius: "var(--mk-radius)",
477
735
  padding: "1.25rem",
478
- background: "var(--mk-bg)",
479
- color: "var(--mk-fg)",
736
+ background: "var(--mk-card)",
737
+ color: "var(--mk-card-fg)",
738
+ boxShadow: "var(--mk-shadow)",
480
739
  fontFamily: "var(--mk-font)",
481
740
  display: "flex",
482
741
  flexDirection: "column",
483
742
  gap: "1rem",
484
743
  maxWidth: 480
485
744
  };
745
+ var cardStyle = {
746
+ border: "1px solid var(--mk-border)",
747
+ borderRadius: "var(--mk-radius)",
748
+ padding: "0.875rem 1rem",
749
+ display: "flex",
750
+ flexDirection: "column",
751
+ gap: "0.5rem"
752
+ };
753
+ function SampleUsageRow({
754
+ label,
755
+ current,
756
+ limit,
757
+ locale
758
+ }) {
759
+ const hasLimit = typeof limit === "number" && limit > 0;
760
+ const fraction = hasLimit ? Math.min(1, current / limit) : 0;
761
+ const barColor = fraction >= 0.8 ? "var(--mk-warning)" : "var(--mk-accent)";
762
+ return /* @__PURE__ */ jsxs("div", { style: cardStyle, children: [
763
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", fontSize: "0.875rem" }, children: [
764
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600 }, children: label }),
765
+ /* @__PURE__ */ jsxs("span", { style: { color: "var(--mk-muted)" }, children: [
766
+ formatUnits(current, locale),
767
+ hasLimit ? ` / ${formatUnits(limit, locale)}` : ""
768
+ ] })
769
+ ] }),
770
+ hasLimit ? /* @__PURE__ */ jsx("div", { style: { height: 6, borderRadius: 999, background: "var(--mk-border)", overflow: "hidden" }, children: /* @__PURE__ */ jsx("div", { style: { width: `${fraction * 100}%`, height: "100%", background: barColor } }) }) : null
771
+ ] });
772
+ }
773
+ var ROW_DIVIDER = { borderTop: "1px solid var(--mk-border)" };
774
+ var INVOICE_STATUS_COLOR = {
775
+ paid: "var(--mk-success)",
776
+ pending: "var(--mk-warning)",
777
+ overdue: "var(--mk-danger)"
778
+ };
779
+ function StatusBadge({ label, color }) {
780
+ return /* @__PURE__ */ jsx(
781
+ "span",
782
+ {
783
+ style: {
784
+ fontSize: "0.6875rem",
785
+ fontWeight: 600,
786
+ textTransform: "capitalize",
787
+ color,
788
+ border: `1px solid ${color}`,
789
+ borderRadius: 999,
790
+ padding: "0.0625rem 0.5rem"
791
+ },
792
+ children: label
793
+ }
794
+ );
795
+ }
486
796
  function CustomerPortal({
487
- planName = "Current plan",
488
- meterIds = [],
797
+ planName,
798
+ meterIds,
489
799
  showCredits = true,
800
+ showTeam,
801
+ teamMembers,
802
+ seats,
803
+ showInvoices,
804
+ invoices,
805
+ sample = false,
806
+ disclaimer,
807
+ showBranding = false,
490
808
  locale,
491
809
  currency = "USD",
492
810
  onManageBilling
493
811
  }) {
494
812
  const { tokens } = useMonetizeKit();
495
813
  const credits = useCredits();
496
- return /* @__PURE__ */ jsxs("div", { style: { ...tokensToStyle(tokens), ...containerStyle }, "data-mk-component": "customer-portal", children: [
497
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
498
- /* @__PURE__ */ jsxs("div", { children: [
499
- /* @__PURE__ */ jsx("div", { style: { fontSize: "0.75rem", color: "var(--mk-muted)" }, children: "Plan" }),
500
- /* @__PURE__ */ jsx("div", { style: { fontSize: "1.125rem", fontWeight: 700 }, children: planName })
501
- ] }),
502
- /* @__PURE__ */ jsx(
503
- "button",
504
- {
505
- type: "button",
506
- onClick: onManageBilling,
507
- style: {
508
- background: "var(--mk-primary)",
509
- color: "var(--mk-primary-fg)",
510
- border: "none",
511
- borderRadius: "var(--mk-radius)",
512
- padding: "0.5rem 0.875rem",
513
- fontWeight: 600,
514
- cursor: "pointer"
515
- },
516
- children: "Manage billing"
517
- }
518
- )
519
- ] }),
520
- meterIds.map((meterId) => /* @__PURE__ */ jsx(UsageBanner, { meterId, label: meterId, locale }, meterId)),
521
- showCredits ? /* @__PURE__ */ jsxs(
522
- "div",
523
- {
524
- style: {
525
- border: "1px solid var(--mk-border)",
526
- borderRadius: "var(--mk-radius)",
527
- padding: "0.875rem 1rem",
528
- display: "flex",
529
- justifyContent: "space-between"
530
- },
531
- children: [
814
+ const resolvedPlanName = planName ?? (sample ? SAMPLE_PORTAL.planName : "Current plan");
815
+ const resolvedMeterIds = meterIds ?? (sample ? [...SAMPLE_PORTAL.meterIds] : []);
816
+ const creditBalance = sample ? SAMPLE_CREDITS.balance : credits.balance;
817
+ const creditCurrency = sample ? SAMPLE_CREDITS.currency : credits.currency;
818
+ const creditLoading = sample ? false : credits.loading;
819
+ const teamEnabled = showTeam ?? sample;
820
+ const resolvedTeam = teamMembers ?? (sample ? SAMPLE_TEAM.members : []);
821
+ const resolvedSeats = seats ?? (sample ? { used: SAMPLE_TEAM.seats, max: SAMPLE_TEAM.maxSeats } : void 0);
822
+ const invoicesEnabled = showInvoices ?? sample;
823
+ const resolvedInvoices = invoices ?? (sample ? SAMPLE_INVOICES : []);
824
+ return /* @__PURE__ */ jsxs(
825
+ "div",
826
+ {
827
+ style: { ...tokensToStyle(tokens), ...containerStyle },
828
+ "data-mk-component": "customer-portal",
829
+ "data-mk-sample": sample ? "true" : void 0,
830
+ children: [
831
+ sample ? /* @__PURE__ */ jsx(SampleNotice, { children: disclaimer }) : null,
832
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", gap: "1rem" }, children: [
833
+ /* @__PURE__ */ jsxs("div", { children: [
834
+ /* @__PURE__ */ jsx("div", { style: { fontSize: "0.75rem", color: "var(--mk-muted)" }, children: "Plan" }),
835
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem", marginTop: "0.125rem" }, children: [
836
+ /* @__PURE__ */ jsx("span", { style: { fontSize: "1.125rem", fontWeight: 700 }, children: resolvedPlanName }),
837
+ /* @__PURE__ */ jsx(
838
+ "span",
839
+ {
840
+ style: {
841
+ fontSize: "0.6875rem",
842
+ fontWeight: 600,
843
+ color: "var(--mk-success)",
844
+ border: "1px solid var(--mk-success)",
845
+ borderRadius: 999,
846
+ padding: "0.0625rem 0.5rem"
847
+ },
848
+ children: "Active"
849
+ }
850
+ )
851
+ ] })
852
+ ] }),
853
+ /* @__PURE__ */ jsx(
854
+ "button",
855
+ {
856
+ type: "button",
857
+ onClick: onManageBilling,
858
+ style: {
859
+ background: "var(--mk-primary)",
860
+ color: "var(--mk-primary-fg)",
861
+ border: "none",
862
+ borderRadius: "var(--mk-radius)",
863
+ padding: "0.5rem 0.875rem",
864
+ fontWeight: 600,
865
+ cursor: "pointer",
866
+ whiteSpace: "nowrap"
867
+ },
868
+ children: "Manage billing"
869
+ }
870
+ )
871
+ ] }),
872
+ sample ? resolvedMeterIds.map((meterId) => {
873
+ const usage = SAMPLE_USAGE[meterId];
874
+ if (!usage) return null;
875
+ return /* @__PURE__ */ jsx(
876
+ SampleUsageRow,
877
+ {
878
+ label: meterId,
879
+ current: usage.current,
880
+ limit: usage.limit,
881
+ locale
882
+ },
883
+ meterId
884
+ );
885
+ }) : resolvedMeterIds.map((meterId) => /* @__PURE__ */ jsx(UsageBanner, { meterId, label: meterId, locale }, meterId)),
886
+ showCredits ? /* @__PURE__ */ jsxs("div", { style: { ...cardStyle, flexDirection: "row", justifyContent: "space-between" }, children: [
532
887
  /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, fontSize: "0.875rem" }, children: "Credits" }),
533
- /* @__PURE__ */ jsx("span", { style: { color: "var(--mk-muted)" }, children: credits.loading ? "\u2026" : formatMoney(credits.balance, credits.currency ?? currency, locale) })
534
- ]
535
- }
536
- ) : null
537
- ] });
888
+ /* @__PURE__ */ jsx("span", { style: { color: "var(--mk-muted)" }, children: creditLoading ? "\u2026" : formatMoney(creditBalance, creditCurrency ?? currency, locale) })
889
+ ] }) : null,
890
+ teamEnabled ? /* @__PURE__ */ jsxs("div", { style: cardStyle, children: [
891
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
892
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, fontSize: "0.875rem" }, children: "Team" }),
893
+ resolvedSeats ? /* @__PURE__ */ jsxs("span", { style: { color: "var(--mk-muted)", fontSize: "0.75rem" }, children: [
894
+ resolvedSeats.used,
895
+ "/",
896
+ resolvedSeats.max >= 9999 ? "Unlimited" : resolvedSeats.max,
897
+ " seats"
898
+ ] }) : null
899
+ ] }),
900
+ resolvedTeam.length === 0 ? /* @__PURE__ */ jsx("span", { style: { color: "var(--mk-muted)", fontSize: "0.8125rem" }, children: "No team members." }) : resolvedTeam.map((member, i) => /* @__PURE__ */ jsxs(
901
+ "div",
902
+ {
903
+ style: {
904
+ display: "flex",
905
+ justifyContent: "space-between",
906
+ alignItems: "center",
907
+ gap: "0.75rem",
908
+ fontSize: "0.8125rem",
909
+ paddingTop: i === 0 ? 0 : "0.5rem",
910
+ ...i === 0 ? {} : ROW_DIVIDER
911
+ },
912
+ children: [
913
+ /* @__PURE__ */ jsxs("div", { style: { minWidth: 0 }, children: [
914
+ /* @__PURE__ */ jsx("div", { style: { fontWeight: 600 }, children: member.name }),
915
+ /* @__PURE__ */ jsx("div", { style: { color: "var(--mk-muted)", fontSize: "0.75rem" }, children: member.email })
916
+ ] }),
917
+ /* @__PURE__ */ jsx(StatusBadge, { label: member.role, color: "var(--mk-muted)" })
918
+ ]
919
+ },
920
+ member.email
921
+ ))
922
+ ] }) : null,
923
+ invoicesEnabled ? /* @__PURE__ */ jsxs("div", { style: cardStyle, children: [
924
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, fontSize: "0.875rem" }, children: "Invoices" }),
925
+ resolvedInvoices.length === 0 ? /* @__PURE__ */ jsx("span", { style: { color: "var(--mk-muted)", fontSize: "0.8125rem" }, children: "No invoices yet." }) : resolvedInvoices.map((invoice, i) => /* @__PURE__ */ jsxs(
926
+ "div",
927
+ {
928
+ style: {
929
+ display: "flex",
930
+ justifyContent: "space-between",
931
+ alignItems: "center",
932
+ gap: "0.75rem",
933
+ fontSize: "0.8125rem",
934
+ paddingTop: i === 0 ? 0 : "0.5rem",
935
+ ...i === 0 ? {} : ROW_DIVIDER
936
+ },
937
+ children: [
938
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 500 }, children: new Date(invoice.date).toLocaleDateString(locale) }),
939
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [
940
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600 }, children: formatMoney(invoice.amount, invoice.currency, locale) }),
941
+ /* @__PURE__ */ jsx(StatusBadge, { label: invoice.status, color: INVOICE_STATUS_COLOR[invoice.status] })
942
+ ] })
943
+ ]
944
+ },
945
+ invoice.id
946
+ ))
947
+ ] }) : null,
948
+ showBranding ? /* @__PURE__ */ jsx("div", { style: { textAlign: "center", fontSize: "0.625rem", color: "var(--mk-muted)" }, children: "Powered by MonetizeKit" }) : null
949
+ ]
950
+ }
951
+ );
538
952
  }
539
953
  function EntitlementGate({
540
954
  feature,
@@ -547,6 +961,6 @@ function EntitlementGate({
547
961
  return /* @__PURE__ */ jsx(Fragment, { children: allowed ? children : fallback });
548
962
  }
549
963
 
550
- export { CustomerPortal, EntitlementGate, MonetizeKitClient, MonetizeKitProvider, Paywall, PricingTable, THEME_PRESETS, UsageBanner, describePlanPrice, describeUsageTerm, formatMoney, formatUnits, resolveTokens, tokensToStyle, useCredits, useEntitlement, useMonetizeKit, useUsage };
964
+ export { CustomerPortal, EntitlementGate, MonetizeKitClient, MonetizeKitProvider, Paywall, PricingTable, SAMPLE_CREDITS, SAMPLE_INVOICES, SAMPLE_NOTICE_TEXT, SAMPLE_PLANS, SAMPLE_PORTAL, SAMPLE_TEAM, SAMPLE_USAGE, SampleNotice, THEME_PRESETS, THEME_PRESET_NAMES, UsageBanner, describePlanPrice, describeUsageTerm, formatMoney, formatUnits, resolveTokens, tokensToStyle, useCredits, useEntitlement, useMonetizeKit, useUsage };
551
965
  //# sourceMappingURL=index.js.map
552
966
  //# sourceMappingURL=index.js.map