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