paddle-checkout-accelerator 2.1.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 (88) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +388 -0
  3. package/dist/package/index.d.ts +28 -0
  4. package/dist/package/index.js +28 -0
  5. package/dist/src/components/paddle/BillingHistory.d.ts +1 -0
  6. package/dist/src/components/paddle/BillingHistory.js +17 -0
  7. package/dist/src/components/paddle/CustomerPortal.d.ts +1 -0
  8. package/dist/src/components/paddle/CustomerPortal.js +5 -0
  9. package/dist/src/components/paddle/CustomerPortalButton.d.ts +1 -0
  10. package/dist/src/components/paddle/CustomerPortalButton.js +31 -0
  11. package/dist/src/components/paddle/InlineCheckout.d.ts +5 -0
  12. package/dist/src/components/paddle/InlineCheckout.js +13 -0
  13. package/dist/src/components/paddle/PricingTable.d.ts +1 -0
  14. package/dist/src/components/paddle/PricingTable.js +27 -0
  15. package/dist/src/components/paddle/SubscriptionCard.d.ts +6 -0
  16. package/dist/src/components/paddle/SubscriptionCard.js +5 -0
  17. package/dist/src/components/paddle/TrialBanner.d.ts +5 -0
  18. package/dist/src/components/paddle/TrialBanner.js +5 -0
  19. package/dist/src/components/paddle/UpgradeModal.d.ts +11 -0
  20. package/dist/src/components/paddle/UpgradeModal.js +35 -0
  21. package/dist/src/components/paddle/UsageMeter.d.ts +6 -0
  22. package/dist/src/components/paddle/UsageMeter.js +8 -0
  23. package/dist/src/components/paddle/gates/SubscriptionGate.d.ts +7 -0
  24. package/dist/src/components/paddle/gates/SubscriptionGate.js +8 -0
  25. package/dist/src/lib/billing/adapters/index.d.ts +3 -0
  26. package/dist/src/lib/billing/adapters/index.js +3 -0
  27. package/dist/src/lib/billing/adapters/memory.d.ts +2 -0
  28. package/dist/src/lib/billing/adapters/memory.js +41 -0
  29. package/dist/src/lib/billing/adapters/prisma/index.d.ts +28 -0
  30. package/dist/src/lib/billing/adapters/prisma/index.js +80 -0
  31. package/dist/src/lib/billing/adapters/types.d.ts +13 -0
  32. package/dist/src/lib/billing/adapters/types.js +1 -0
  33. package/dist/src/lib/billing/configure.d.ts +6 -0
  34. package/dist/src/lib/billing/configure.js +13 -0
  35. package/dist/src/lib/billing/customer-repair.d.ts +4 -0
  36. package/dist/src/lib/billing/customer-repair.js +19 -0
  37. package/dist/src/lib/billing/demo-seed.d.ts +1 -0
  38. package/dist/src/lib/billing/demo-seed.js +13 -0
  39. package/dist/src/lib/billing/entitlements.d.ts +3 -0
  40. package/dist/src/lib/billing/entitlements.js +16 -0
  41. package/dist/src/lib/billing/events.d.ts +12 -0
  42. package/dist/src/lib/billing/events.js +20 -0
  43. package/dist/src/lib/billing/plans.d.ts +9 -0
  44. package/dist/src/lib/billing/plans.js +41 -0
  45. package/dist/src/lib/billing/protection.d.ts +6 -0
  46. package/dist/src/lib/billing/protection.js +16 -0
  47. package/dist/src/lib/billing/refresh.d.ts +1 -0
  48. package/dist/src/lib/billing/refresh.js +32 -0
  49. package/dist/src/lib/billing/subscriptions.d.ts +16 -0
  50. package/dist/src/lib/billing/subscriptions.js +36 -0
  51. package/dist/src/lib/billing/teams.d.ts +42 -0
  52. package/dist/src/lib/billing/teams.js +104 -0
  53. package/dist/src/lib/billing/usage.d.ts +17 -0
  54. package/dist/src/lib/billing/usage.js +40 -0
  55. package/dist/src/lib/billing/webhook-sync.d.ts +26 -0
  56. package/dist/src/lib/billing/webhook-sync.js +39 -0
  57. package/dist/src/lib/paddle/api.d.ts +1 -0
  58. package/dist/src/lib/paddle/api.js +21 -0
  59. package/dist/src/lib/paddle/client.d.ts +1 -0
  60. package/dist/src/lib/paddle/client.js +13 -0
  61. package/dist/src/lib/paddle/customers.d.ts +15 -0
  62. package/dist/src/lib/paddle/customers.js +14 -0
  63. package/dist/src/lib/paddle/events.d.ts +10 -0
  64. package/dist/src/lib/paddle/events.js +11 -0
  65. package/dist/src/lib/paddle/hooks.d.ts +4 -0
  66. package/dist/src/lib/paddle/hooks.js +11 -0
  67. package/dist/src/lib/paddle/portal.d.ts +8 -0
  68. package/dist/src/lib/paddle/portal.js +28 -0
  69. package/dist/src/lib/paddle/subscriptions.d.ts +20 -0
  70. package/dist/src/lib/paddle/subscriptions.js +10 -0
  71. package/dist/src/lib/paddle/types.d.ts +8 -0
  72. package/dist/src/lib/paddle/types.js +1 -0
  73. package/dist/src/lib/paddle/webhook.d.ts +1 -0
  74. package/dist/src/lib/paddle/webhook.js +8 -0
  75. package/dist/src/lib/utils.d.ts +2 -0
  76. package/dist/src/lib/utils.js +5 -0
  77. package/docs/agency-use-case.md +19 -0
  78. package/docs/quickstart.md +24 -0
  79. package/docs/recipes/prisma/adapter.example.txt +70 -0
  80. package/docs/recipes/prisma/client.example.txt +4 -0
  81. package/docs/recipes/prisma/schema.prisma +30 -0
  82. package/package.json +59 -0
  83. package/recipes/README.md +20 -0
  84. package/recipes/nextjs/app/billing.ts +14 -0
  85. package/recipes/nextjs/custom-adapter.ts +26 -0
  86. package/recipes/nextjs/protected-api-route.ts +27 -0
  87. package/recipes/nextjs/server-page-gate.tsx +18 -0
  88. package/recipes/nextjs/webhook-route.ts +23 -0
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Commercial License
2
+
3
+ Copyright (c) NamahLogistics.
4
+
5
+ This source code is proprietary. You may not copy, redistribute, resell, sublicense, or publish this code without written permission.
6
+
7
+ License terms are granted separately to paying customers.
package/README.md ADDED
@@ -0,0 +1,388 @@
1
+ # Paddle Checkout Accelerator
2
+
3
+ Production-ready Paddle Billing infrastructure for Next.js SaaS applications.
4
+
5
+ Stop rebuilding billing systems for every SaaS project.
6
+
7
+ Paddle Checkout Accelerator provides checkout flows, webhook verification, subscription synchronization, entitlements, usage limits, customer repair tooling, team billing, and route protection out of the box.
8
+
9
+ ---
10
+
11
+ # Why This Exists
12
+
13
+ Every SaaS founder eventually rebuilds the same billing infrastructure:
14
+
15
+ * Checkout flows
16
+ * Subscription synchronization
17
+ * Webhook processing
18
+ * Feature gating
19
+ * Usage limits
20
+ * Customer portal access
21
+ * Team seat management
22
+ * Failed payment recovery
23
+ * Customer repair tools
24
+
25
+ Most teams spend days or weeks building and testing this infrastructure before they can focus on their actual product.
26
+
27
+ Paddle Checkout Accelerator provides a reusable billing layer so developers can focus on shipping features instead of rebuilding billing.
28
+
29
+ ---
30
+
31
+ # Features
32
+
33
+ ## Paddle Billing
34
+
35
+ * Paddle Checkout Launcher
36
+ * Paddle Webhook Verification
37
+ * Subscription Synchronization
38
+ * Customer Portal Sessions
39
+ * Paddle Customer Lookup
40
+ * Subscription Refresh Utilities
41
+ * Subscription Repair Utilities
42
+
43
+ ## Access Control
44
+
45
+ * Plan Protection
46
+ * Feature Protection
47
+ * Usage Protection
48
+ * Entitlement Engine
49
+
50
+ ## Team Billing
51
+
52
+ * Team Creation
53
+ * Owner/Admin/Member Roles
54
+ * Seat Limits by Plan
55
+ * Seat Usage Tracking
56
+ * Team Member Management
57
+
58
+ ## Billing Events
59
+
60
+ * Subscription Timeline
61
+ * Payment Events
62
+ * Repair Events
63
+ * Portal Events
64
+ * Audit Trail Foundation
65
+
66
+ ## Developer Experience
67
+
68
+ * Pluggable Billing Adapter
69
+ * Memory Adapter
70
+ * Prisma Adapter
71
+ * Unified Billing Configuration
72
+ * TypeScript Support
73
+ * Vitest Test Suite
74
+
75
+ ---
76
+
77
+ # Screenshots
78
+
79
+ ## Repair Failed Subscriptions
80
+
81
+ Fix customer accounts when payment succeeds but access was never unlocked.
82
+
83
+ ![Customer Repair](screenshots/customer-repair.png)
84
+
85
+ ---
86
+
87
+ ## Protect Paid API Routes
88
+
89
+ Verify plans, features, and usage limits before executing premium SaaS actions.
90
+
91
+ ![API Protection](screenshots/api-protection.png)
92
+
93
+ ---
94
+
95
+ ## SaaS Billing Dashboard
96
+
97
+ Manage subscriptions, usage, invoices, and customer billing access.
98
+
99
+ ![Billing Dashboard](screenshots/billing-dashboard.png)
100
+
101
+ ---
102
+
103
+ # Problems It Solves
104
+
105
+ * User paid but account did not unlock
106
+ * Webhook failed or arrived late
107
+ * Need to verify active subscriptions
108
+ * Need paid API route protection
109
+ * Need feature-level access control
110
+ * Need monthly usage limits
111
+ * Need customer lookup by email
112
+ * Need customer portal access
113
+ * Need team seat management
114
+ * Need a reusable billing layer across multiple SaaS products
115
+
116
+ ---
117
+
118
+ # Installation
119
+
120
+ ```bash
121
+ npm install @namahlogisticspaddle-checkout-accelerator
122
+ ```
123
+
124
+ ---
125
+
126
+ # Environment Variables
127
+
128
+ ```env
129
+ NEXT_PUBLIC_PADDLE_CLIENT_TOKEN=
130
+ PADDLE_API_KEY=
131
+ PADDLE_WEBHOOK_SECRET=
132
+ ```
133
+
134
+ ---
135
+
136
+ # One-File Billing Setup
137
+
138
+ Create a single billing setup file.
139
+
140
+ ```ts
141
+ import {
142
+ configureBilling,
143
+ createPrismaBillingAdapter,
144
+ } from "@namahlogisticspaddle-checkout-accelerator";
145
+
146
+ import { prisma } from "@/lib/prisma";
147
+
148
+ const adapter =
149
+ createPrismaBillingAdapter(prisma);
150
+
151
+ export const billing =
152
+ configureBilling({
153
+ adapter,
154
+ });
155
+ ```
156
+
157
+ ---
158
+
159
+ # Core Usage
160
+
161
+ ## Protect Plans
162
+
163
+ ```ts
164
+ await protectPlan(
165
+ userId,
166
+ "pro"
167
+ );
168
+ ```
169
+
170
+ ## Protect Features
171
+
172
+ ```ts
173
+ await protectFeature(
174
+ userId,
175
+ "api_access"
176
+ );
177
+ ```
178
+
179
+ ## Protect Usage
180
+
181
+ ```ts
182
+ await protectUsage(
183
+ userId,
184
+ "ai_generation"
185
+ );
186
+ ```
187
+
188
+ ## Refresh Subscription
189
+
190
+ ```ts
191
+ await refreshSubscriptionFromPaddle(
192
+ subscriptionId
193
+ );
194
+ ```
195
+
196
+ ## Repair Customer Access
197
+
198
+ ```ts
199
+ await repairSubscriptionByEmail(
200
+ email
201
+ );
202
+ ```
203
+
204
+ ---
205
+
206
+ # Team Billing
207
+
208
+ Create teams:
209
+
210
+ ```ts
211
+ await createTeam({
212
+ teamId: "team_1",
213
+ name: "Acme",
214
+ ownerId: userId,
215
+ });
216
+ ```
217
+
218
+ Add members:
219
+
220
+ ```ts
221
+ await addTeamMember({
222
+ teamId: "team_1",
223
+ userId: "user_2",
224
+ });
225
+ ```
226
+
227
+ Check seat usage:
228
+
229
+ ```ts
230
+ await getSeatUsage(
231
+ "team_1"
232
+ );
233
+ ```
234
+
235
+ ---
236
+
237
+ # Billing Events
238
+
239
+ Record events:
240
+
241
+ ```ts
242
+ await recordBillingEvent({
243
+ id: "evt_1",
244
+ userId,
245
+ type: "payment_succeeded",
246
+ createdAt:
247
+ new Date().toISOString(),
248
+ });
249
+ ```
250
+
251
+ Read timeline:
252
+
253
+ ```ts
254
+ await getBillingEvents(
255
+ userId
256
+ );
257
+ ```
258
+
259
+ ---
260
+
261
+ # Included API Routes
262
+
263
+ ```txt
264
+ /api/paddle/webhook
265
+ /api/paddle/portal-session
266
+ /api/paddle/refresh-subscription
267
+ /api/paddle/repair-by-email
268
+ /api/demo/protected-generation
269
+ ```
270
+
271
+ ---
272
+
273
+ # Included Demo Pages
274
+
275
+ ```txt
276
+ /demo/pricing
277
+ /demo/upgrade
278
+ /demo/dashboard
279
+ /demo/api-protection
280
+ /demo/customer-lookup
281
+ /demo/customer-repair
282
+ /demo/saas
283
+ ```
284
+
285
+ ---
286
+
287
+ # Adapter Support
288
+
289
+ ## Included
290
+
291
+ * Memory Adapter
292
+ * Prisma Adapter
293
+
294
+ ## Planned
295
+
296
+ * Supabase Adapter
297
+ * PostgreSQL Adapter
298
+ * Clerk Integration
299
+ * Auth.js Integration
300
+ * CLI Installer
301
+
302
+ ---
303
+
304
+ # Verification
305
+
306
+ ```bash
307
+ npm run test
308
+ npm run lint
309
+ npm run build
310
+ npm run build:package
311
+ ```
312
+
313
+ ---
314
+
315
+ # Test Coverage
316
+
317
+ Current test suite covers:
318
+
319
+ * Plan Protection
320
+ * Feature Protection
321
+ * Usage Limits
322
+ * Team Billing
323
+ * Billing Events
324
+
325
+ ---
326
+
327
+ # Ideal For
328
+
329
+ * AI SaaS
330
+ * Developer Tools
331
+ * API Products
332
+ * Membership Platforms
333
+ * Internal SaaS Platforms
334
+ * B2B SaaS Products
335
+ * Agencies Implementing Paddle Billing
336
+
337
+ ---
338
+
339
+ # Roadmap
340
+
341
+ ## v3.x
342
+
343
+ * Supabase Adapter
344
+ * PostgreSQL Adapter
345
+ * Expanded Event Tracking
346
+
347
+ ## v4.x
348
+
349
+ * Clerk Integration
350
+ * Auth.js Integration
351
+ * Firebase Auth Integration
352
+
353
+ ## v5.x
354
+
355
+ * CLI Installer
356
+
357
+ ```bash
358
+ npx paddle-accelerator init
359
+ ```
360
+
361
+ ## v6.x
362
+
363
+ * Hosted Configuration Dashboard
364
+
365
+ ## v7.x
366
+
367
+ * Near One-Click Billing Setup
368
+
369
+ ---
370
+
371
+ # Version History
372
+
373
+ * v0.1.0 — Billing Engine
374
+ * v0.2.0 — Paddle Sync + Repair Layer
375
+ * v0.3.0 — Customer Lookup + Email Repair
376
+ * v0.4.0 — Billing Test Suite
377
+ * v0.4.1 — Release Cleanup
378
+ * v1.0.0 — Production Release
379
+ * v2.0.0 — Team Billing + Seat Limits
380
+ * v2.1.0 — Installable Package + Prisma Adapter + Unified Configuration
381
+
382
+ ---
383
+
384
+ # License
385
+
386
+ Copyright © NamahLogistics.
387
+
388
+ Commercial license. Redistribution, resale, sublicensing, or republication of the source code is prohibited without written permission.
@@ -0,0 +1,28 @@
1
+ export * from "../src/components/paddle/UpgradeModal";
2
+ export * from "../src/components/paddle/UsageMeter";
3
+ export * from "../src/components/paddle/TrialBanner";
4
+ export * from "../src/components/paddle/BillingHistory";
5
+ export * from "../src/components/paddle/CustomerPortalButton";
6
+ export * from "../src/components/paddle/SubscriptionCard";
7
+ export * from "../src/components/paddle/gates/SubscriptionGate";
8
+ export * from "../src/lib/paddle/hooks";
9
+ export * from "../src/lib/paddle/client";
10
+ export * from "../src/lib/paddle/types";
11
+ export * from "../src/lib/paddle/webhook";
12
+ export * from "../src/lib/billing/plans";
13
+ export * from "../src/lib/billing/subscriptions";
14
+ export * from "../src/lib/billing/entitlements";
15
+ export * from "../src/lib/billing/usage";
16
+ export * from "../src/lib/billing/webhook-sync";
17
+ export * from "../src/lib/billing/adapters";
18
+ export * from "../src/lib/billing/protection";
19
+ export * from "../src/lib/billing/demo-seed";
20
+ export * from "../src/lib/paddle/portal";
21
+ export * from "../src/lib/paddle/api";
22
+ export * from "../src/lib/paddle/subscriptions";
23
+ export * from "../src/lib/billing/refresh";
24
+ export * from "../src/lib/paddle/customers";
25
+ export * from "../src/lib/billing/customer-repair";
26
+ export * from "../src/lib/billing/teams";
27
+ export * from "../src/lib/billing/events";
28
+ export * from "../src/lib/billing/configure";
@@ -0,0 +1,28 @@
1
+ export * from "../src/components/paddle/UpgradeModal";
2
+ export * from "../src/components/paddle/UsageMeter";
3
+ export * from "../src/components/paddle/TrialBanner";
4
+ export * from "../src/components/paddle/BillingHistory";
5
+ export * from "../src/components/paddle/CustomerPortalButton";
6
+ export * from "../src/components/paddle/SubscriptionCard";
7
+ export * from "../src/components/paddle/gates/SubscriptionGate";
8
+ export * from "../src/lib/paddle/hooks";
9
+ export * from "../src/lib/paddle/client";
10
+ export * from "../src/lib/paddle/types";
11
+ export * from "../src/lib/paddle/webhook";
12
+ export * from "../src/lib/billing/plans";
13
+ export * from "../src/lib/billing/subscriptions";
14
+ export * from "../src/lib/billing/entitlements";
15
+ export * from "../src/lib/billing/usage";
16
+ export * from "../src/lib/billing/webhook-sync";
17
+ export * from "../src/lib/billing/adapters";
18
+ export * from "../src/lib/billing/protection";
19
+ export * from "../src/lib/billing/demo-seed";
20
+ export * from "../src/lib/paddle/portal";
21
+ export * from "../src/lib/paddle/api";
22
+ export * from "../src/lib/paddle/subscriptions";
23
+ export * from "../src/lib/billing/refresh";
24
+ export * from "../src/lib/paddle/customers";
25
+ export * from "../src/lib/billing/customer-repair";
26
+ export * from "../src/lib/billing/teams";
27
+ export * from "../src/lib/billing/events";
28
+ export * from "../src/lib/billing/configure";
@@ -0,0 +1 @@
1
+ export declare function BillingHistory(): import("react").JSX.Element;
@@ -0,0 +1,17 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ const invoices = [
4
+ {
5
+ id: "INV-001",
6
+ amount: "$79",
7
+ status: "Paid",
8
+ },
9
+ {
10
+ id: "INV-002",
11
+ amount: "$79",
12
+ status: "Paid",
13
+ },
14
+ ];
15
+ export function BillingHistory() {
16
+ return (_jsx("div", { className: "rounded-xl border", children: invoices.map((invoice) => (_jsxs("div", { className: "flex justify-between border-b p-4", children: [_jsx("div", { children: invoice.id }), _jsx("div", { children: invoice.amount }), _jsx("div", { children: invoice.status })] }, invoice.id))) }));
17
+ }
@@ -0,0 +1 @@
1
+ export default function CustomerPortal(): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ export default function CustomerPortal() {
4
+ return (_jsxs("div", { className: "rounded-3xl border p-8", children: [_jsx("h2", { className: "text-3xl font-bold", children: "Customer Portal" }), _jsxs("div", { className: "mt-8 space-y-4", children: [_jsx("div", { className: "rounded-xl border p-4", children: "Current Plan: Pro" }), _jsx("div", { className: "rounded-xl border p-4", children: "Status: Active" }), _jsx("div", { className: "rounded-xl border p-4", children: "Renewal Date: July 1, 2026" }), _jsx("button", { className: "rounded-xl bg-black px-5 py-3 text-white", children: "Manage Subscription" })] })] }));
5
+ }
@@ -0,0 +1 @@
1
+ export declare function CustomerPortalButton(): import("react").JSX.Element;
@@ -0,0 +1,31 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ export function CustomerPortalButton() {
5
+ const [loading, setLoading] = useState(false);
6
+ const [error, setError] = useState(null);
7
+ async function launchPortal() {
8
+ try {
9
+ setLoading(true);
10
+ setError(null);
11
+ const response = await fetch("/api/paddle/portal-session", { method: "POST" });
12
+ const data = (await response.json());
13
+ if (!response.ok || !data.success || !data.url) {
14
+ throw new Error(data.error ??
15
+ "Unable to open billing portal");
16
+ }
17
+ window.location.href = data.url;
18
+ }
19
+ catch (err) {
20
+ setError(err instanceof Error
21
+ ? err.message
22
+ : "Unable to open billing portal");
23
+ }
24
+ finally {
25
+ setLoading(false);
26
+ }
27
+ }
28
+ return (_jsxs("div", { className: "space-y-3", children: [_jsx("button", { onClick: launchPortal, disabled: loading, className: "rounded-xl bg-black px-4 py-3 text-white disabled:opacity-60", children: loading
29
+ ? "Opening Billing..."
30
+ : "Manage Billing" }), error && (_jsx("div", { className: "rounded-xl border border-red-200 bg-red-50 p-3 text-sm text-red-700", children: error }))] }));
31
+ }
@@ -0,0 +1,5 @@
1
+ interface Props {
2
+ priceId: string;
3
+ }
4
+ export default function InlineCheckout({ priceId, }: Props): import("react").JSX.Element;
5
+ export {};
@@ -0,0 +1,13 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
4
+ export default function InlineCheckout({ priceId, }) {
5
+ const [loading, setLoading] = useState(true);
6
+ useEffect(() => {
7
+ const timer = setTimeout(() => {
8
+ setLoading(false);
9
+ }, 1500);
10
+ return () => clearTimeout(timer);
11
+ }, []);
12
+ return (_jsx("div", { className: "rounded-3xl border bg-white p-6", children: loading ? (_jsxs("div", { className: "space-y-4 animate-pulse", children: [_jsx("div", { className: "h-10 rounded bg-gray-100" }), _jsx("div", { className: "h-10 rounded bg-gray-100" }), _jsx("div", { className: "h-40 rounded bg-gray-100" })] })) : (_jsxs("div", { children: [_jsx("div", { className: "mb-4 text-sm text-gray-500", children: "Paddle Inline Checkout" }), _jsx("div", { id: "paddle-inline-checkout", "data-price-id": priceId, className: "min-h-[500px] rounded-xl border" })] })) }));
13
+ }
@@ -0,0 +1 @@
1
+ export default function PricingTable(): import("react").JSX.Element;
@@ -0,0 +1,27 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Check } from "lucide-react";
4
+ const plans = [
5
+ {
6
+ name: "Starter",
7
+ price: "$29",
8
+ features: [
9
+ "1 Project",
10
+ "Lifetime Updates",
11
+ "Source Code"
12
+ ]
13
+ },
14
+ {
15
+ name: "Pro",
16
+ price: "$79",
17
+ featured: true,
18
+ features: [
19
+ "Unlimited Projects",
20
+ "Premium Components",
21
+ "Priority Support"
22
+ ]
23
+ }
24
+ ];
25
+ export default function PricingTable() {
26
+ return (_jsx("div", { className: "grid gap-8 md:grid-cols-2", children: plans.map((plan) => (_jsxs("div", { className: `rounded-3xl border p-8 ${plan.featured ? "ring-2 ring-black" : ""}`, children: [_jsx("h3", { className: "text-2xl font-bold", children: plan.name }), _jsx("div", { className: "mt-6 text-5xl font-bold", children: plan.price }), _jsx("ul", { className: "mt-8 space-y-4", children: plan.features.map((feature) => (_jsxs("li", { className: "flex gap-3", children: [_jsx(Check, { size: 18 }), feature] }, feature))) }), _jsx("button", { className: "mt-8 w-full rounded-xl bg-black py-3 text-white", children: "Buy Now" })] }, plan.name))) }));
27
+ }
@@ -0,0 +1,6 @@
1
+ interface SubscriptionCardProps {
2
+ plan: string;
3
+ status: string;
4
+ }
5
+ export declare function SubscriptionCard({ plan, status, }: SubscriptionCardProps): import("react").JSX.Element;
6
+ export {};
@@ -0,0 +1,5 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ export function SubscriptionCard({ plan, status, }) {
4
+ return (_jsxs("div", { className: "rounded-2xl border p-6", children: [_jsx("div", { className: "text-sm text-gray-500", children: "Current Plan" }), _jsx("div", { className: "mt-2 text-3xl font-bold", children: plan }), _jsxs("div", { className: "mt-4", children: ["Status: ", status] })] }));
5
+ }
@@ -0,0 +1,5 @@
1
+ interface TrialBannerProps {
2
+ daysRemaining: number;
3
+ }
4
+ export declare function TrialBanner({ daysRemaining, }: TrialBannerProps): import("react").JSX.Element;
5
+ export {};
@@ -0,0 +1,5 @@
1
+ "use client";
2
+ import { jsxs as _jsxs } from "react/jsx-runtime";
3
+ export function TrialBanner({ daysRemaining, }) {
4
+ return (_jsxs("div", { className: "rounded-xl border border-yellow-300 bg-yellow-50 p-4", children: ["Trial expires in", " ", _jsxs("strong", { children: [daysRemaining, " days"] }), "."] }));
5
+ }
@@ -0,0 +1,11 @@
1
+ interface UpgradeModalProps {
2
+ open: boolean;
3
+ onClose: () => void;
4
+ currentPlan: string;
5
+ targetPlan: string;
6
+ targetPriceId: string;
7
+ yearlySavings?: string;
8
+ onUpgradeSuccess?: (data: unknown) => void;
9
+ }
10
+ export declare function UpgradeModal({ open, onClose, currentPlan, targetPlan, targetPriceId, yearlySavings, onUpgradeSuccess, }: UpgradeModalProps): import("react").JSX.Element | null;
11
+ export {};
@@ -0,0 +1,35 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { ArrowRight, Check, Loader2, X, } from "lucide-react";
5
+ import { openCheckout } from "@/lib/paddle/hooks";
6
+ export function UpgradeModal({ open, onClose, currentPlan, targetPlan, targetPriceId, yearlySavings, onUpgradeSuccess, }) {
7
+ const [loading, setLoading] = useState(false);
8
+ const [error, setError] = useState(null);
9
+ if (!open)
10
+ return null;
11
+ async function handleUpgrade() {
12
+ try {
13
+ setLoading(true);
14
+ setError(null);
15
+ await openCheckout([
16
+ {
17
+ priceId: targetPriceId,
18
+ quantity: 1,
19
+ },
20
+ ]);
21
+ onUpgradeSuccess?.({
22
+ targetPlan,
23
+ });
24
+ }
25
+ catch (err) {
26
+ setError(err instanceof Error
27
+ ? err.message
28
+ : "Unable to launch checkout");
29
+ }
30
+ finally {
31
+ setLoading(false);
32
+ }
33
+ }
34
+ return (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", children: _jsxs("div", { className: "w-full max-w-lg rounded-3xl border bg-white shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b p-6", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-xl font-semibold", children: "Upgrade Plan" }), _jsx("p", { className: "mt-1 text-sm text-slate-500", children: "Unlock additional features" })] }), _jsx("button", { onClick: onClose, className: "rounded-lg p-2 hover:bg-slate-100", children: _jsx(X, { size: 18 }) })] }), _jsxs("div", { className: "p-6", children: [_jsx("div", { className: "rounded-2xl border p-5", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm text-slate-500", children: "Current" }), _jsx("div", { className: "mt-1 font-semibold", children: currentPlan })] }), _jsx(ArrowRight, { className: "text-slate-400", size: 20 }), _jsxs("div", { className: "text-right", children: [_jsx("div", { className: "text-sm text-slate-500", children: "Upgrade To" }), _jsx("div", { className: "mt-1 font-semibold", children: targetPlan })] })] }) }), _jsx("div", { className: "mt-6 rounded-2xl bg-slate-50 p-5", children: _jsxs("ul", { className: "space-y-3", children: [_jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Unlimited projects"] }), _jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Advanced billing"] }), _jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Priority support"] }), _jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Team access"] })] }) }), yearlySavings && (_jsxs("div", { className: "mt-4 rounded-xl border border-emerald-200 bg-emerald-50 p-3 text-sm", children: ["Save ", yearlySavings] })), error && (_jsx("div", { className: "mt-4 rounded-xl border border-red-200 bg-red-50 p-3 text-sm text-red-700", children: error })), _jsx("button", { onClick: handleUpgrade, disabled: loading, className: "mt-6 flex w-full items-center justify-center gap-2 rounded-2xl bg-black px-5 py-4 text-white transition hover:opacity-90 disabled:opacity-50", children: loading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 18, className: "animate-spin" }), "Launching Checkout..."] })) : (_jsxs(_Fragment, { children: ["Upgrade Now", _jsx(ArrowRight, { size: 18 })] })) })] })] }) }));
35
+ }
@@ -0,0 +1,6 @@
1
+ interface UsageMeterProps {
2
+ current: number;
3
+ limit: number;
4
+ }
5
+ export declare function UsageMeter({ current, limit, }: UsageMeterProps): import("react").JSX.Element;
6
+ export {};
@@ -0,0 +1,8 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ export function UsageMeter({ current, limit, }) {
4
+ const percentage = Math.min(100, (current / limit) * 100);
5
+ return (_jsxs("div", { className: "rounded-xl border p-5", children: [_jsxs("div", { className: "flex justify-between", children: [_jsx("span", { children: "Usage" }), _jsxs("span", { children: [current, "/", limit] })] }), _jsx("div", { className: "mt-3 h-3 rounded-full bg-gray-100", children: _jsx("div", { className: "h-3 rounded-full bg-black", style: {
6
+ width: `${percentage}%`,
7
+ } }) })] }));
8
+ }
@@ -0,0 +1,7 @@
1
+ interface SubscriptionGateProps {
2
+ active: boolean;
3
+ children: React.ReactNode;
4
+ fallback?: React.ReactNode;
5
+ }
6
+ export declare function SubscriptionGate({ active, children, fallback, }: SubscriptionGateProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined>;
7
+ export {};