create-qa-architect 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +12 -0
- package/.github/CLAUDE_MD_AUTOMATION.md +248 -0
- package/.github/PROGRESSIVE_QUALITY_IMPLEMENTATION.md +408 -0
- package/.github/PROGRESSIVE_QUALITY_PROPOSAL.md +443 -0
- package/.github/RELEASE_CHECKLIST.md +100 -0
- package/.github/dependabot.yml +50 -0
- package/.github/git-sync.sh +48 -0
- package/.github/workflows/claude-md-validation.yml +82 -0
- package/.github/workflows/nightly-gitleaks-verification.yml +176 -0
- package/.github/workflows/pnpm-ci.yml.example +53 -0
- package/.github/workflows/python-ci.yml.example +69 -0
- package/.github/workflows/quality-legacy.yml.backup +165 -0
- package/.github/workflows/quality-progressive.yml.example +291 -0
- package/.github/workflows/quality.yml +436 -0
- package/.github/workflows/release.yml +53 -0
- package/.nvmrc +1 -0
- package/.prettierignore +14 -0
- package/.prettierrc +9 -0
- package/.stylelintrc.json +5 -0
- package/README.md +212 -0
- package/config/.lighthouserc.js +45 -0
- package/config/.pre-commit-config.yaml +66 -0
- package/config/constants.js +128 -0
- package/config/defaults.js +124 -0
- package/config/pyproject.toml +124 -0
- package/config/quality-config.schema.json +97 -0
- package/config/quality-python.yml +89 -0
- package/config/requirements-dev.txt +15 -0
- package/create-saas-monetization.js +1465 -0
- package/eslint.config.cjs +117 -0
- package/eslint.config.ts.cjs +99 -0
- package/legal/README.md +106 -0
- package/legal/copyright.md +76 -0
- package/legal/disclaimer.md +146 -0
- package/legal/privacy-policy.html +324 -0
- package/legal/privacy-policy.md +196 -0
- package/legal/terms-of-service.md +224 -0
- package/lib/billing-dashboard.html +645 -0
- package/lib/config-validator.js +163 -0
- package/lib/dependency-monitoring-basic.js +185 -0
- package/lib/dependency-monitoring-premium.js +1490 -0
- package/lib/error-reporter.js +444 -0
- package/lib/interactive/prompt.js +128 -0
- package/lib/interactive/questions.js +146 -0
- package/lib/license-validator.js +403 -0
- package/lib/licensing.js +989 -0
- package/lib/package-utils.js +187 -0
- package/lib/project-maturity.js +516 -0
- package/lib/security-enhancements.js +340 -0
- package/lib/setup-enhancements.js +317 -0
- package/lib/smart-strategy-generator.js +344 -0
- package/lib/telemetry.js +323 -0
- package/lib/template-loader.js +252 -0
- package/lib/typescript-config-generator.js +210 -0
- package/lib/ui-helpers.js +74 -0
- package/lib/validation/base-validator.js +174 -0
- package/lib/validation/cache-manager.js +158 -0
- package/lib/validation/config-security.js +741 -0
- package/lib/validation/documentation.js +326 -0
- package/lib/validation/index.js +186 -0
- package/lib/validation/validation-factory.js +153 -0
- package/lib/validation/workflow-validation.js +172 -0
- package/lib/yaml-utils.js +120 -0
- package/marketing/beta-user-email-campaign.md +372 -0
- package/marketing/landing-page.html +721 -0
- package/package.json +165 -0
- package/setup.js +2076 -0
|
@@ -0,0 +1,645 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Create Quality Automation - Billing Dashboard</title>
|
|
7
|
+
<script src="https://js.stripe.com/v3/"></script>
|
|
8
|
+
<style>
|
|
9
|
+
* {
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 0;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
}
|
|
14
|
+
body {
|
|
15
|
+
font-family:
|
|
16
|
+
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
17
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
18
|
+
min-height: 100vh;
|
|
19
|
+
color: #333;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.container {
|
|
23
|
+
max-width: 900px;
|
|
24
|
+
margin: 0 auto;
|
|
25
|
+
padding: 20px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.header {
|
|
29
|
+
text-align: center;
|
|
30
|
+
color: white;
|
|
31
|
+
margin-bottom: 40px;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.header h1 {
|
|
35
|
+
font-size: 2.5rem;
|
|
36
|
+
margin-bottom: 10px;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.header p {
|
|
40
|
+
font-size: 1.2rem;
|
|
41
|
+
opacity: 0.9;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.dashboard-card {
|
|
45
|
+
background: white;
|
|
46
|
+
border-radius: 12px;
|
|
47
|
+
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
|
|
48
|
+
padding: 30px;
|
|
49
|
+
margin-bottom: 30px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.tier-selector {
|
|
53
|
+
display: grid;
|
|
54
|
+
grid-template-columns: 1fr 1fr;
|
|
55
|
+
gap: 20px;
|
|
56
|
+
margin-bottom: 30px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.tier-card {
|
|
60
|
+
border: 2px solid #e1e5e9;
|
|
61
|
+
border-radius: 12px;
|
|
62
|
+
padding: 25px;
|
|
63
|
+
text-align: center;
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
transition: all 0.3s ease;
|
|
66
|
+
position: relative;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.tier-card:hover {
|
|
70
|
+
border-color: #667eea;
|
|
71
|
+
transform: translateY(-5px);
|
|
72
|
+
box-shadow: 0 10px 25px rgba(102, 126, 234, 0.15);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.tier-card.selected {
|
|
76
|
+
border-color: #667eea;
|
|
77
|
+
background: linear-gradient(135deg, #667eea10, #764ba210);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.tier-card.popular::before {
|
|
81
|
+
content: 'MOST POPULAR';
|
|
82
|
+
position: absolute;
|
|
83
|
+
top: -10px;
|
|
84
|
+
left: 50%;
|
|
85
|
+
transform: translateX(-50%);
|
|
86
|
+
background: linear-gradient(135deg, #667eea, #764ba2);
|
|
87
|
+
color: white;
|
|
88
|
+
padding: 5px 15px;
|
|
89
|
+
border-radius: 20px;
|
|
90
|
+
font-size: 0.8rem;
|
|
91
|
+
font-weight: bold;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.tier-name {
|
|
95
|
+
font-size: 1.5rem;
|
|
96
|
+
font-weight: bold;
|
|
97
|
+
margin-bottom: 10px;
|
|
98
|
+
color: #333;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.tier-price {
|
|
102
|
+
font-size: 2rem;
|
|
103
|
+
font-weight: bold;
|
|
104
|
+
color: #667eea;
|
|
105
|
+
margin-bottom: 15px;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.tier-price .period {
|
|
109
|
+
font-size: 1rem;
|
|
110
|
+
color: #666;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.tier-features {
|
|
114
|
+
text-align: left;
|
|
115
|
+
margin-bottom: 20px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.tier-features li {
|
|
119
|
+
list-style: none;
|
|
120
|
+
padding: 5px 0;
|
|
121
|
+
position: relative;
|
|
122
|
+
padding-left: 25px;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.tier-features li::before {
|
|
126
|
+
content: '✅';
|
|
127
|
+
position: absolute;
|
|
128
|
+
left: 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.founder-discount {
|
|
132
|
+
background: linear-gradient(135deg, #f093fb, #f5576c);
|
|
133
|
+
color: white;
|
|
134
|
+
padding: 15px;
|
|
135
|
+
border-radius: 8px;
|
|
136
|
+
margin: 20px 0;
|
|
137
|
+
text-align: center;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.founder-discount h3 {
|
|
141
|
+
margin-bottom: 10px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.founder-discount .original-price {
|
|
145
|
+
text-decoration: line-through;
|
|
146
|
+
opacity: 0.7;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.founder-price {
|
|
150
|
+
font-size: 1.5rem;
|
|
151
|
+
font-weight: bold;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.checkout-btn {
|
|
155
|
+
background: linear-gradient(135deg, #667eea, #764ba2);
|
|
156
|
+
color: white;
|
|
157
|
+
border: none;
|
|
158
|
+
padding: 15px 30px;
|
|
159
|
+
border-radius: 8px;
|
|
160
|
+
font-size: 1.1rem;
|
|
161
|
+
font-weight: bold;
|
|
162
|
+
cursor: pointer;
|
|
163
|
+
width: 100%;
|
|
164
|
+
transition: all 0.3s ease;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.checkout-btn:hover {
|
|
168
|
+
transform: translateY(-2px);
|
|
169
|
+
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.checkout-btn:disabled {
|
|
173
|
+
opacity: 0.6;
|
|
174
|
+
cursor: not-allowed;
|
|
175
|
+
transform: none;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.license-activation {
|
|
179
|
+
border-top: 1px solid #e1e5e9;
|
|
180
|
+
padding-top: 30px;
|
|
181
|
+
margin-top: 30px;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.input-group {
|
|
185
|
+
margin-bottom: 20px;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
.input-group label {
|
|
189
|
+
display: block;
|
|
190
|
+
margin-bottom: 5px;
|
|
191
|
+
font-weight: 600;
|
|
192
|
+
color: #333;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.input-group input {
|
|
196
|
+
width: 100%;
|
|
197
|
+
padding: 12px;
|
|
198
|
+
border: 2px solid #e1e5e9;
|
|
199
|
+
border-radius: 6px;
|
|
200
|
+
font-size: 1rem;
|
|
201
|
+
transition: border-color 0.3s ease;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.input-group input:focus {
|
|
205
|
+
outline: none;
|
|
206
|
+
border-color: #667eea;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.activate-btn {
|
|
210
|
+
background: #28a745;
|
|
211
|
+
color: white;
|
|
212
|
+
border: none;
|
|
213
|
+
padding: 12px 25px;
|
|
214
|
+
border-radius: 6px;
|
|
215
|
+
font-weight: bold;
|
|
216
|
+
cursor: pointer;
|
|
217
|
+
transition: background 0.3s ease;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.activate-btn:hover {
|
|
221
|
+
background: #218838;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.status-message {
|
|
225
|
+
padding: 15px;
|
|
226
|
+
border-radius: 6px;
|
|
227
|
+
margin: 15px 0;
|
|
228
|
+
font-weight: 500;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.status-success {
|
|
232
|
+
background: #d4edda;
|
|
233
|
+
color: #155724;
|
|
234
|
+
border: 1px solid #c3e6cb;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.status-error {
|
|
238
|
+
background: #f8d7da;
|
|
239
|
+
color: #721c24;
|
|
240
|
+
border: 1px solid #f5c6cb;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.loading {
|
|
244
|
+
display: inline-block;
|
|
245
|
+
width: 20px;
|
|
246
|
+
height: 20px;
|
|
247
|
+
border: 3px solid #f3f3f3;
|
|
248
|
+
border-top: 3px solid #667eea;
|
|
249
|
+
border-radius: 50%;
|
|
250
|
+
animation: spin 1s linear infinite;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
@keyframes spin {
|
|
254
|
+
0% {
|
|
255
|
+
transform: rotate(0deg);
|
|
256
|
+
}
|
|
257
|
+
100% {
|
|
258
|
+
transform: rotate(360deg);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.features-comparison {
|
|
263
|
+
display: grid;
|
|
264
|
+
grid-template-columns: 2fr 1fr 1fr;
|
|
265
|
+
gap: 15px;
|
|
266
|
+
align-items: center;
|
|
267
|
+
margin: 20px 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.features-comparison .feature-row {
|
|
271
|
+
display: contents;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.features-comparison .feature-name {
|
|
275
|
+
font-weight: 500;
|
|
276
|
+
padding: 10px;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.features-comparison .feature-value {
|
|
280
|
+
text-align: center;
|
|
281
|
+
padding: 10px;
|
|
282
|
+
background: #f8f9fa;
|
|
283
|
+
border-radius: 4px;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.features-comparison .header-row {
|
|
287
|
+
font-weight: bold;
|
|
288
|
+
background: linear-gradient(135deg, #667eea, #764ba2);
|
|
289
|
+
color: white;
|
|
290
|
+
text-align: center;
|
|
291
|
+
padding: 15px 10px;
|
|
292
|
+
border-radius: 6px;
|
|
293
|
+
}
|
|
294
|
+
</style>
|
|
295
|
+
</head>
|
|
296
|
+
<body>
|
|
297
|
+
<div class="container">
|
|
298
|
+
<div class="header">
|
|
299
|
+
<h1>Create Quality Automation</h1>
|
|
300
|
+
<p>Choose your plan and start building quality software faster</p>
|
|
301
|
+
</div>
|
|
302
|
+
|
|
303
|
+
<div class="dashboard-card">
|
|
304
|
+
<h2>🚀 Choose Your Plan</h2>
|
|
305
|
+
|
|
306
|
+
<div class="tier-selector">
|
|
307
|
+
<!-- Pro Tier -->
|
|
308
|
+
<div
|
|
309
|
+
class="tier-card popular"
|
|
310
|
+
data-tier="pro"
|
|
311
|
+
onclick="selectTier('pro')"
|
|
312
|
+
>
|
|
313
|
+
<div class="tier-name">Pro</div>
|
|
314
|
+
<div class="tier-price">$59<span class="period">/month</span></div>
|
|
315
|
+
<div style="color: #22c55e; font-size: 0.9rem">
|
|
316
|
+
or $590/year (save $118)
|
|
317
|
+
</div>
|
|
318
|
+
|
|
319
|
+
<ul class="tier-features">
|
|
320
|
+
<li>Unlimited repos, LOC, runs</li>
|
|
321
|
+
<li>Smart Test Strategy (70% faster)</li>
|
|
322
|
+
<li>Security scanning (Gitleaks + ESLint)</li>
|
|
323
|
+
<li>Multi-language (Python, Rust, Ruby)</li>
|
|
324
|
+
<li>Framework-aware dependency grouping</li>
|
|
325
|
+
<li>Email support (24-48h response)</li>
|
|
326
|
+
</ul>
|
|
327
|
+
</div>
|
|
328
|
+
|
|
329
|
+
<!-- Team Tier -->
|
|
330
|
+
<div class="tier-card" data-tier="team" onclick="selectTier('team')">
|
|
331
|
+
<div class="tier-name">Team</div>
|
|
332
|
+
<div class="tier-price">
|
|
333
|
+
$15<span class="period">/user/month</span>
|
|
334
|
+
</div>
|
|
335
|
+
<div style="color: #666; font-size: 0.9rem">
|
|
336
|
+
5-seat minimum ($75/mo)
|
|
337
|
+
</div>
|
|
338
|
+
|
|
339
|
+
<ul class="tier-features">
|
|
340
|
+
<li>All PRO features included</li>
|
|
341
|
+
<li>Per-seat licensing for orgs</li>
|
|
342
|
+
<li>Shared quota & usage reporting</li>
|
|
343
|
+
<li>Team-wide config policies</li>
|
|
344
|
+
<li>Slack/email alerts for failures</li>
|
|
345
|
+
<li>Priority support (business hours)</li>
|
|
346
|
+
</ul>
|
|
347
|
+
</div>
|
|
348
|
+
|
|
349
|
+
<!-- Enterprise Tier -->
|
|
350
|
+
<div
|
|
351
|
+
class="tier-card"
|
|
352
|
+
data-tier="enterprise"
|
|
353
|
+
onclick="selectTier('enterprise')"
|
|
354
|
+
>
|
|
355
|
+
<div class="tier-name">Enterprise</div>
|
|
356
|
+
<div class="tier-price">$249<span class="period">/month</span></div>
|
|
357
|
+
<div style="color: #666; font-size: 0.9rem">
|
|
358
|
+
annual + $499 onboarding
|
|
359
|
+
</div>
|
|
360
|
+
|
|
361
|
+
<ul class="tier-features">
|
|
362
|
+
<li>All TEAM features included</li>
|
|
363
|
+
<li>SSO/SAML integration</li>
|
|
364
|
+
<li>Custom risk patterns & policies</li>
|
|
365
|
+
<li>Audit logs export & compliance</li>
|
|
366
|
+
<li>Dedicated TAM + 24×5 SLA</li>
|
|
367
|
+
<li>Optional on-prem license server</li>
|
|
368
|
+
</ul>
|
|
369
|
+
</div>
|
|
370
|
+
</div>
|
|
371
|
+
|
|
372
|
+
<div
|
|
373
|
+
class="features-comparison"
|
|
374
|
+
style="grid-template-columns: 2fr 1fr 1fr 1fr"
|
|
375
|
+
>
|
|
376
|
+
<div class="header-row">Features</div>
|
|
377
|
+
<div class="header-row">Pro</div>
|
|
378
|
+
<div class="header-row">Team</div>
|
|
379
|
+
<div class="header-row">Enterprise</div>
|
|
380
|
+
|
|
381
|
+
<div
|
|
382
|
+
class="feature-row"
|
|
383
|
+
style="grid-template-columns: 2fr 1fr 1fr 1fr"
|
|
384
|
+
>
|
|
385
|
+
<div class="feature-name">Smart Test Strategy</div>
|
|
386
|
+
<div class="feature-value">✅</div>
|
|
387
|
+
<div class="feature-value">✅</div>
|
|
388
|
+
<div class="feature-value">✅</div>
|
|
389
|
+
</div>
|
|
390
|
+
|
|
391
|
+
<div
|
|
392
|
+
class="feature-row"
|
|
393
|
+
style="grid-template-columns: 2fr 1fr 1fr 1fr"
|
|
394
|
+
>
|
|
395
|
+
<div class="feature-name">Multi-language</div>
|
|
396
|
+
<div class="feature-value">✅</div>
|
|
397
|
+
<div class="feature-value">✅</div>
|
|
398
|
+
<div class="feature-value">✅</div>
|
|
399
|
+
</div>
|
|
400
|
+
|
|
401
|
+
<div
|
|
402
|
+
class="feature-row"
|
|
403
|
+
style="grid-template-columns: 2fr 1fr 1fr 1fr"
|
|
404
|
+
>
|
|
405
|
+
<div class="feature-name">Team Policies</div>
|
|
406
|
+
<div class="feature-value">❌</div>
|
|
407
|
+
<div class="feature-value">✅</div>
|
|
408
|
+
<div class="feature-value">✅</div>
|
|
409
|
+
</div>
|
|
410
|
+
|
|
411
|
+
<div
|
|
412
|
+
class="feature-row"
|
|
413
|
+
style="grid-template-columns: 2fr 1fr 1fr 1fr"
|
|
414
|
+
>
|
|
415
|
+
<div class="feature-name">SSO/SAML</div>
|
|
416
|
+
<div class="feature-value">❌</div>
|
|
417
|
+
<div class="feature-value">❌</div>
|
|
418
|
+
<div class="feature-value">✅</div>
|
|
419
|
+
</div>
|
|
420
|
+
|
|
421
|
+
<div
|
|
422
|
+
class="feature-row"
|
|
423
|
+
style="grid-template-columns: 2fr 1fr 1fr 1fr"
|
|
424
|
+
>
|
|
425
|
+
<div class="feature-name">Support SLA</div>
|
|
426
|
+
<div class="feature-value">48h</div>
|
|
427
|
+
<div class="feature-value">24h</div>
|
|
428
|
+
<div class="feature-value">4h</div>
|
|
429
|
+
</div>
|
|
430
|
+
</div>
|
|
431
|
+
|
|
432
|
+
<button
|
|
433
|
+
class="checkout-btn"
|
|
434
|
+
onclick="startCheckout()"
|
|
435
|
+
id="checkout-btn"
|
|
436
|
+
disabled
|
|
437
|
+
>
|
|
438
|
+
Select a plan above
|
|
439
|
+
</button>
|
|
440
|
+
|
|
441
|
+
<div class="license-activation">
|
|
442
|
+
<h3>🔑 Already have a license key?</h3>
|
|
443
|
+
<p>
|
|
444
|
+
Enter your license key from the Stripe purchase confirmation email.
|
|
445
|
+
</p>
|
|
446
|
+
|
|
447
|
+
<div class="input-group">
|
|
448
|
+
<label for="license-key">License Key</label>
|
|
449
|
+
<input
|
|
450
|
+
type="text"
|
|
451
|
+
id="license-key"
|
|
452
|
+
placeholder="CQA-XXXX-XXXX-XXXX-XXXX"
|
|
453
|
+
/>
|
|
454
|
+
</div>
|
|
455
|
+
|
|
456
|
+
<div class="input-group">
|
|
457
|
+
<label for="email">Email Address</label>
|
|
458
|
+
<input type="email" id="email" placeholder="your@email.com" />
|
|
459
|
+
</div>
|
|
460
|
+
|
|
461
|
+
<button class="activate-btn" onclick="activateLicense()">
|
|
462
|
+
Activate License
|
|
463
|
+
</button>
|
|
464
|
+
|
|
465
|
+
<div id="activation-status"></div>
|
|
466
|
+
</div>
|
|
467
|
+
</div>
|
|
468
|
+
</div>
|
|
469
|
+
|
|
470
|
+
<script>
|
|
471
|
+
const stripe = Stripe('pk_test_your_stripe_publishable_key_here') // Replace with actual key
|
|
472
|
+
let selectedTier = null
|
|
473
|
+
let isFounder = true // Enable founder pricing
|
|
474
|
+
|
|
475
|
+
function selectTier(tier) {
|
|
476
|
+
selectedTier = tier
|
|
477
|
+
|
|
478
|
+
// Update UI
|
|
479
|
+
document.querySelectorAll('.tier-card').forEach(card => {
|
|
480
|
+
card.classList.remove('selected')
|
|
481
|
+
})
|
|
482
|
+
|
|
483
|
+
document
|
|
484
|
+
.querySelector(`[data-tier="${tier}"]`)
|
|
485
|
+
.classList.add('selected')
|
|
486
|
+
|
|
487
|
+
// Enable checkout button
|
|
488
|
+
const checkoutBtn = document.getElementById('checkout-btn')
|
|
489
|
+
checkoutBtn.disabled = false
|
|
490
|
+
|
|
491
|
+
if (tier === 'pro') {
|
|
492
|
+
checkoutBtn.textContent = isFounder
|
|
493
|
+
? 'Start Pro Subscription - $24.50/month (Founder Price)'
|
|
494
|
+
: 'Start Pro Subscription - $49/month'
|
|
495
|
+
} else if (tier === 'enterprise') {
|
|
496
|
+
checkoutBtn.textContent = isFounder
|
|
497
|
+
? 'Start Enterprise Subscription - $74.50/month (Founder Price)'
|
|
498
|
+
: 'Start Enterprise Subscription - $149/month'
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
async function startCheckout() {
|
|
503
|
+
if (!selectedTier) return
|
|
504
|
+
|
|
505
|
+
const checkoutBtn = document.getElementById('checkout-btn')
|
|
506
|
+
checkoutBtn.disabled = true
|
|
507
|
+
checkoutBtn.innerHTML =
|
|
508
|
+
'<span class="loading"></span> Creating checkout session...'
|
|
509
|
+
|
|
510
|
+
try {
|
|
511
|
+
// Call your backend to create Stripe checkout session
|
|
512
|
+
const response = await fetch('/api/create-checkout-session', {
|
|
513
|
+
method: 'POST',
|
|
514
|
+
headers: {
|
|
515
|
+
'Content-Type': 'application/json',
|
|
516
|
+
},
|
|
517
|
+
body: JSON.stringify({
|
|
518
|
+
tier: selectedTier.toUpperCase(),
|
|
519
|
+
isFounder: isFounder,
|
|
520
|
+
successUrl: window.location.origin + '/success',
|
|
521
|
+
cancelUrl: window.location.origin + '/billing',
|
|
522
|
+
}),
|
|
523
|
+
})
|
|
524
|
+
|
|
525
|
+
const session = await response.json()
|
|
526
|
+
|
|
527
|
+
if (session.error) {
|
|
528
|
+
throw new Error(session.error)
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// Redirect to Stripe Checkout
|
|
532
|
+
const result = await stripe.redirectToCheckout({
|
|
533
|
+
sessionId: session.sessionId,
|
|
534
|
+
})
|
|
535
|
+
|
|
536
|
+
if (result.error) {
|
|
537
|
+
throw new Error(result.error.message)
|
|
538
|
+
}
|
|
539
|
+
} catch (error) {
|
|
540
|
+
console.error('Checkout error:', error)
|
|
541
|
+
showStatus(
|
|
542
|
+
'activation-status',
|
|
543
|
+
`Checkout error: ${error.message}`,
|
|
544
|
+
'error'
|
|
545
|
+
)
|
|
546
|
+
} finally {
|
|
547
|
+
checkoutBtn.disabled = false
|
|
548
|
+
if (selectedTier === 'pro') {
|
|
549
|
+
checkoutBtn.textContent = isFounder
|
|
550
|
+
? 'Start Pro Subscription - $24.50/month (Founder Price)'
|
|
551
|
+
: 'Start Pro Subscription - $49/month'
|
|
552
|
+
} else {
|
|
553
|
+
checkoutBtn.textContent = isFounder
|
|
554
|
+
? 'Start Enterprise Subscription - $74.50/month (Founder Price)'
|
|
555
|
+
: 'Start Enterprise Subscription - $149/month'
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
async function activateLicense() {
|
|
561
|
+
const licenseKey = document.getElementById('license-key').value.trim()
|
|
562
|
+
const email = document.getElementById('email').value.trim()
|
|
563
|
+
|
|
564
|
+
if (!licenseKey || !email) {
|
|
565
|
+
showStatus(
|
|
566
|
+
'activation-status',
|
|
567
|
+
'Please enter both license key and email address.',
|
|
568
|
+
'error'
|
|
569
|
+
)
|
|
570
|
+
return
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
try {
|
|
574
|
+
showStatus('activation-status', 'Activating license...', 'loading')
|
|
575
|
+
|
|
576
|
+
// Call your backend to activate license
|
|
577
|
+
const response = await fetch('/api/activate-license', {
|
|
578
|
+
method: 'POST',
|
|
579
|
+
headers: {
|
|
580
|
+
'Content-Type': 'application/json',
|
|
581
|
+
},
|
|
582
|
+
body: JSON.stringify({
|
|
583
|
+
licenseKey: licenseKey,
|
|
584
|
+
email: email,
|
|
585
|
+
}),
|
|
586
|
+
})
|
|
587
|
+
|
|
588
|
+
const result = await response.json()
|
|
589
|
+
|
|
590
|
+
if (result.success) {
|
|
591
|
+
showStatus(
|
|
592
|
+
'activation-status',
|
|
593
|
+
`✅ License activated successfully! Tier: ${result.tier}${result.isFounder ? ' (Founder)' : ''}`,
|
|
594
|
+
'success'
|
|
595
|
+
)
|
|
596
|
+
|
|
597
|
+
// Clear form
|
|
598
|
+
document.getElementById('license-key').value = ''
|
|
599
|
+
document.getElementById('email').value = ''
|
|
600
|
+
} else {
|
|
601
|
+
throw new Error(result.error)
|
|
602
|
+
}
|
|
603
|
+
} catch (error) {
|
|
604
|
+
console.error('Activation error:', error)
|
|
605
|
+
showStatus(
|
|
606
|
+
'activation-status',
|
|
607
|
+
`Activation failed: ${error.message}`,
|
|
608
|
+
'error'
|
|
609
|
+
)
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
function showStatus(elementId, message, type) {
|
|
614
|
+
const statusEl = document.getElementById(elementId)
|
|
615
|
+
statusEl.className = `status-message ${type === 'error' ? 'status-error' : type === 'success' ? 'status-success' : ''}`
|
|
616
|
+
statusEl.textContent = message
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// Initialize page
|
|
620
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
621
|
+
// Check for success/error parameters in URL
|
|
622
|
+
const urlParams = new URLSearchParams(window.location.search)
|
|
623
|
+
|
|
624
|
+
if (urlParams.get('success')) {
|
|
625
|
+
showStatus(
|
|
626
|
+
'activation-status',
|
|
627
|
+
'✅ Payment successful! Check your email for license activation instructions.',
|
|
628
|
+
'success'
|
|
629
|
+
)
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
if (urlParams.get('canceled')) {
|
|
633
|
+
showStatus(
|
|
634
|
+
'activation-status',
|
|
635
|
+
'Payment was canceled. You can try again anytime.',
|
|
636
|
+
'error'
|
|
637
|
+
)
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
// Pre-select Pro tier as most popular
|
|
641
|
+
selectTier('pro')
|
|
642
|
+
})
|
|
643
|
+
</script>
|
|
644
|
+
</body>
|
|
645
|
+
</html>
|