@contractspec/bundle.marketing 2.1.0 → 2.1.1
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/.turbo/turbo-build.log +73 -73
- package/CHANGELOG.md +20 -0
- package/README.md +6 -1
- package/dist/browser/components/marketing/CofounderPage.js +2 -2
- package/dist/browser/components/marketing/ContactClient.js +57 -961
- package/dist/browser/components/marketing/DesignPartnerPage.js +2 -2
- package/dist/browser/components/marketing/LandingPage.js +6 -6
- package/dist/browser/components/marketing/PricingClient.js +107 -1127
- package/dist/browser/components/marketing/ProductClientPage.js +2 -2
- package/dist/browser/components/marketing/index.js +157 -1064
- package/dist/browser/components/marketing/pricing-thinking-modal.js +3 -3
- package/dist/browser/components/marketing/sections/CorePositioningSection.js +2 -2
- package/dist/browser/components/marketing/sections/CtaSection.js +2 -2
- package/dist/browser/components/marketing/sections/HeroMarketingSection.js +2 -2
- package/dist/browser/components/marketing/studio-signup-section.js +87 -0
- package/dist/browser/components/templates/TemplatesClientPage.js +175 -1082
- package/dist/browser/components/templates/index.js +181 -1088
- package/dist/browser/index.js +505 -1157
- package/dist/browser/registry/engine.js +158 -1080
- package/dist/browser/registry/index.js +158 -1080
- package/dist/browser/registry/registry-docs.js +2 -17
- package/dist/browser/registry/registry-landing.js +156 -1063
- package/dist/browser/registry/registry.js +158 -1080
- package/dist/browser/registry/utils.js +158 -1080
- package/dist/components/marketing/CofounderPage.js +2 -2
- package/dist/components/marketing/ContactClient.js +57 -961
- package/dist/components/marketing/DesignPartnerPage.js +2 -2
- package/dist/components/marketing/LandingPage.js +6 -6
- package/dist/components/marketing/PricingClient.js +107 -1127
- package/dist/components/marketing/ProductClientPage.js +2 -2
- package/dist/components/marketing/index.d.ts +1 -1
- package/dist/components/marketing/index.js +157 -1064
- package/dist/components/marketing/pricing-thinking-modal.js +3 -3
- package/dist/components/marketing/sections/CorePositioningSection.js +2 -2
- package/dist/components/marketing/sections/CtaSection.js +2 -2
- package/dist/components/marketing/sections/HeroMarketingSection.js +2 -2
- package/dist/components/marketing/studio-signup-section.d.ts +5 -0
- package/dist/components/marketing/studio-signup-section.js +82 -0
- package/dist/components/templates/TemplatesClientPage.js +175 -1082
- package/dist/components/templates/index.js +181 -1088
- package/dist/index.js +505 -1157
- package/dist/node/components/marketing/CofounderPage.js +2 -2
- package/dist/node/components/marketing/ContactClient.js +57 -961
- package/dist/node/components/marketing/DesignPartnerPage.js +2 -2
- package/dist/node/components/marketing/LandingPage.js +6 -6
- package/dist/node/components/marketing/PricingClient.js +107 -1127
- package/dist/node/components/marketing/ProductClientPage.js +2 -2
- package/dist/node/components/marketing/index.js +157 -1064
- package/dist/node/components/marketing/pricing-thinking-modal.js +3 -3
- package/dist/node/components/marketing/sections/CorePositioningSection.js +2 -2
- package/dist/node/components/marketing/sections/CtaSection.js +2 -2
- package/dist/node/components/marketing/sections/HeroMarketingSection.js +2 -2
- package/dist/node/components/marketing/studio-signup-section.js +82 -0
- package/dist/node/components/templates/TemplatesClientPage.js +175 -1082
- package/dist/node/components/templates/index.js +181 -1088
- package/dist/node/index.js +505 -1157
- package/dist/node/registry/engine.js +158 -1080
- package/dist/node/registry/index.js +158 -1080
- package/dist/node/registry/registry-docs.js +2 -17
- package/dist/node/registry/registry-landing.js +156 -1063
- package/dist/node/registry/registry.js +158 -1080
- package/dist/node/registry/utils.js +158 -1080
- package/dist/registry/engine.js +158 -1080
- package/dist/registry/index.js +158 -1080
- package/dist/registry/registry-docs.js +2 -17
- package/dist/registry/registry-landing.js +156 -1063
- package/dist/registry/registry.js +158 -1080
- package/dist/registry/utils.js +158 -1080
- package/package.json +26 -26
- package/src/components/marketing/CofounderPage.tsx +2 -2
- package/src/components/marketing/ContactClient.tsx +3 -3
- package/src/components/marketing/DesignPartnerPage.tsx +3 -3
- package/src/components/marketing/PricingClient.tsx +39 -38
- package/src/components/marketing/ProductClientPage.tsx +2 -2
- package/src/components/marketing/index.ts +1 -1
- package/src/components/marketing/pricing-thinking-modal.tsx +5 -5
- package/src/components/marketing/sections/CorePositioningSection.tsx +2 -2
- package/src/components/marketing/sections/CtaSection.tsx +2 -2
- package/src/components/marketing/sections/HeroMarketingSection.tsx +2 -2
- package/src/components/marketing/studio-signup-section.tsx +56 -0
- package/src/components/templates/TemplatesClientPage.tsx +12 -9
- package/src/registry/registry-docs.ts +0 -40
- package/dist/browser/components/marketing/waitlist-section.js +0 -1104
- package/dist/components/marketing/waitlist-section.d.ts +0 -7
- package/dist/components/marketing/waitlist-section.js +0 -1099
- package/dist/node/components/marketing/waitlist-section.js +0 -1099
- package/src/components/marketing/waitlist-section.tsx +0 -606
|
@@ -181,978 +181,76 @@ Submitted via ContractSpec contact form
|
|
|
181
181
|
return { success: true, text: "Message sent successfully!" };
|
|
182
182
|
};
|
|
183
183
|
|
|
184
|
-
// src/
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
var WAITLIST_SEND_ERROR = "Failed to join waitlist. Please try again later or contact us directly.";
|
|
188
|
-
var joinWaitlist = async (formData) => {
|
|
189
|
-
const email = (formData.get("email") ?? "").toString().trim();
|
|
190
|
-
if (!email || !email.includes("@")) {
|
|
191
|
-
return {
|
|
192
|
-
success: false,
|
|
193
|
-
text: "Please enter a valid email address."
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
const configResult = getEmailConfig();
|
|
197
|
-
if (!configResult.ok || !configResult.config) {
|
|
198
|
-
return {
|
|
199
|
-
success: false,
|
|
200
|
-
text: configResult.errorMessage ?? WAITLIST_MISSING_CONFIG
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
const waitlistText = `
|
|
204
|
-
You're on the waitlist!
|
|
205
|
-
|
|
206
|
-
Thanks for joining the ContractSpec waitlist. You're now in line for early access to:
|
|
207
|
-
|
|
208
|
-
\u2022 Stabilize your AI-generated code with ContractSpec
|
|
209
|
-
\u2022 Multi-surface consistency (API, DB, UI, events)
|
|
210
|
-
\u2022 Safe regeneration without breaking changes
|
|
211
|
-
\u2022 AI governance and contract enforcement
|
|
212
|
-
|
|
213
|
-
We'll notify you as soon as early access is available. In the meantime, you can:
|
|
214
|
-
|
|
215
|
-
\u2022 Check out our docs: https://contractspec.io/docs
|
|
216
|
-
\u2022 Follow our progress on GitHub
|
|
217
|
-
\u2022 Book a demo call to see ContractSpec in action
|
|
218
|
-
|
|
219
|
-
We're excited to have you on board!
|
|
220
|
-
|
|
221
|
-
---
|
|
222
|
-
ContractSpec Team
|
|
223
|
-
https://contractspec.io
|
|
224
|
-
|
|
225
|
-
To remove yourself from the waitlist, reply to this email with "remove"
|
|
226
|
-
`.trim();
|
|
227
|
-
const waitlistHtml = `
|
|
228
|
-
<div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
|
|
229
|
-
<h1 style="color: #8b5cf6;">You're on the waitlist!</h1>
|
|
230
|
-
<p>Thanks for joining the ContractSpec waitlist. You're now in line for early access to:</p>
|
|
231
|
-
<ul style="line-height: 1.8;">
|
|
232
|
-
<li>Stabilize your AI-generated code with ContractSpec</li>
|
|
233
|
-
<li>Multi-surface consistency (API, DB, UI, events)</li>
|
|
234
|
-
<li>Safe regeneration without breaking changes</li>
|
|
235
|
-
<li>AI governance and contract enforcement</li>
|
|
236
|
-
</ul>
|
|
237
|
-
<p>We'll notify you as soon as early access is available. In the meantime, you can:</p>
|
|
238
|
-
<ul style="line-height: 1.8;">
|
|
239
|
-
<li>Check out our <a href="https://contractspec.io/docs" style="color: #8b5cf6;">docs</a></li>
|
|
240
|
-
<li>Follow our progress on GitHub</li>
|
|
241
|
-
<li>Book a demo call to see ContractSpec in action</li>
|
|
242
|
-
</ul>
|
|
243
|
-
<p>We're excited to have you on board!</p>
|
|
244
|
-
<hr style="margin: 30px 0; border: none; border-top: 1px solid #e5e7eb;" />
|
|
245
|
-
<p style="color: #6b7280; font-size: 14px;">
|
|
246
|
-
ContractSpec Team<br />
|
|
247
|
-
<a href="https://contractspec.io" style="color: #8b5cf6;">contractspec.io</a>
|
|
248
|
-
</p>
|
|
249
|
-
<p style="color: #9ca3af; font-size: 12px;">
|
|
250
|
-
To remove yourself from the waitlist, reply to this email with "remove"
|
|
251
|
-
</p>
|
|
252
|
-
</div>
|
|
253
|
-
`;
|
|
254
|
-
const userSend = await sendEmail(configResult.config, {
|
|
255
|
-
to: [{ email }],
|
|
256
|
-
subject: "You're on the ContractSpec waitlist!",
|
|
257
|
-
text: waitlistText,
|
|
258
|
-
html: waitlistHtml,
|
|
259
|
-
context: "waitlist-welcome"
|
|
260
|
-
});
|
|
261
|
-
if (!userSend.success) {
|
|
262
|
-
return { success: false, text: WAITLIST_SEND_ERROR };
|
|
263
|
-
}
|
|
264
|
-
const teamNotificationText = `New waitlist signup from: ${email}`;
|
|
265
|
-
const teamNotificationHtml = `
|
|
266
|
-
<div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
|
|
267
|
-
<p style="margin: 0 0 8px;">New waitlist signup</p>
|
|
268
|
-
<p style="margin: 0;"><strong>Email:</strong> ${formatMultilineHtml(email)}</p>
|
|
269
|
-
</div>
|
|
270
|
-
`;
|
|
271
|
-
const teamSend = await sendEmail(configResult.config, {
|
|
272
|
-
to: [configResult.config.teamInbox],
|
|
273
|
-
subject: `New Waitlist Signup: ${email}`,
|
|
274
|
-
text: teamNotificationText,
|
|
275
|
-
html: teamNotificationHtml,
|
|
276
|
-
context: "waitlist-team-notification"
|
|
277
|
-
});
|
|
278
|
-
if (!teamSend.success) {
|
|
279
|
-
return { success: false, text: WAITLIST_SEND_ERROR };
|
|
280
|
-
}
|
|
281
|
-
return { success: true, text: "Successfully joined waitlist!" };
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
// src/libs/email/waitlist-application.ts
|
|
285
|
-
"use server";
|
|
286
|
-
var APPLICATION_MISSING_CONFIG = "Waitlist application service is not configured. Please try again later.";
|
|
287
|
-
var APPLICATION_SEND_ERROR = "Failed to submit application. Please try again later or contact us directly.";
|
|
288
|
-
var submitWaitlistApplication = async (formData) => {
|
|
289
|
-
const email = (formData.get("email") ?? "").toString().trim();
|
|
290
|
-
const name = (formData.get("name") ?? "").toString().trim();
|
|
291
|
-
const company = (formData.get("company") ?? "").toString().trim();
|
|
292
|
-
const role = (formData.get("role") ?? "").toString().trim();
|
|
293
|
-
const useCase = (formData.get("useCase") ?? "").toString().trim();
|
|
294
|
-
const currentStack = (formData.get("currentStack") ?? "").toString().trim();
|
|
295
|
-
const whatBuilding = (formData.get("whatBuilding") ?? "").toString().trim();
|
|
296
|
-
const whatSolving = (formData.get("whatSolving") ?? "").toString().trim();
|
|
297
|
-
const teamSize = (formData.get("teamSize") ?? "").toString().trim();
|
|
298
|
-
const timeline = (formData.get("timeline") ?? "").toString().trim();
|
|
299
|
-
const openToSessions = formData.get("openToSessions") === "on";
|
|
300
|
-
const okayWithCaseStudies = formData.get("okayWithCaseStudies") === "on";
|
|
301
|
-
if (!email || !email.includes("@")) {
|
|
302
|
-
return {
|
|
303
|
-
success: false,
|
|
304
|
-
text: "Please enter a valid email address."
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
if (!name || !whatBuilding || !whatSolving) {
|
|
308
|
-
return {
|
|
309
|
-
success: false,
|
|
310
|
-
text: "Please fill in all required fields."
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
const configResult = getEmailConfig();
|
|
314
|
-
if (!configResult.ok || !configResult.config) {
|
|
315
|
-
return {
|
|
316
|
-
success: false,
|
|
317
|
-
text: configResult.errorMessage ?? APPLICATION_MISSING_CONFIG
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
const applicantText = `
|
|
321
|
-
You're on the list.
|
|
322
|
-
|
|
323
|
-
Thanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.
|
|
324
|
-
|
|
325
|
-
What happens next:
|
|
326
|
-
\u2022 We review applications weekly
|
|
327
|
-
\u2022 If selected, we'll reach out via email to schedule an intro call
|
|
328
|
-
\u2022 During early access, you'll get hands-on support and influence over the roadmap
|
|
329
|
-
|
|
330
|
-
In the meantime:
|
|
331
|
-
\u2022 Check out our docs: https://contractspec.io/docs
|
|
332
|
-
\u2022 Book a demo call: https://contractspec.io/contact
|
|
333
|
-
|
|
334
|
-
We're excited about the possibility of working together!
|
|
335
|
-
|
|
336
|
-
---
|
|
337
|
-
ContractSpec Team
|
|
338
|
-
https://contractspec.io
|
|
339
|
-
`.trim();
|
|
340
|
-
const applicantHtml = `
|
|
341
|
-
<div style="font-family: sans-serif; max-width: 640px; margin: 0 auto;">
|
|
342
|
-
<h1 style="color: #8b5cf6;">You're on the list.</h1>
|
|
343
|
-
<p>Thanks for applying to the ContractSpec design partner program. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally.</p>
|
|
344
|
-
<h2 style="color: #8b5cf6; margin-top: 24px;">What happens next:</h2>
|
|
345
|
-
<ul style="line-height: 1.8;">
|
|
346
|
-
<li>We review applications weekly</li>
|
|
347
|
-
<li>If selected, we'll reach out via email to schedule an intro call</li>
|
|
348
|
-
<li>During early access, you'll get hands-on support and influence over the roadmap</li>
|
|
349
|
-
</ul>
|
|
350
|
-
<h2 style="color: #8b5cf6; margin-top: 24px;">In the meantime:</h2>
|
|
351
|
-
<ul style="line-height: 1.8;">
|
|
352
|
-
<li>Check out our <a href="https://contractspec.io/docs" style="color: #8b5cf6;">docs</a></li>
|
|
353
|
-
<li>Book a demo call: <a href="https://contractspec.io/contact" style="color: #8b5cf6;">contractspec.io/contact</a></li>
|
|
354
|
-
</ul>
|
|
355
|
-
<p>We're excited about the possibility of working together!</p>
|
|
356
|
-
<hr style="margin: 30px 0; border: none; border-top: 1px solid #e5e7eb;" />
|
|
357
|
-
<p style="color: #6b7280; font-size: 14px;">
|
|
358
|
-
ContractSpec Team<br />
|
|
359
|
-
<a href="https://contractspec.io" style="color: #8b5cf6;">contractspec.io</a>
|
|
360
|
-
</p>
|
|
361
|
-
</div>
|
|
362
|
-
`;
|
|
363
|
-
const applicantSend = await sendEmail(configResult.config, {
|
|
364
|
-
to: [{ email }],
|
|
365
|
-
subject: "You're on the ContractSpec design partner waitlist!",
|
|
366
|
-
text: applicantText,
|
|
367
|
-
html: applicantHtml,
|
|
368
|
-
context: "waitlist-application-welcome"
|
|
369
|
-
});
|
|
370
|
-
if (!applicantSend.success) {
|
|
371
|
-
return { success: false, text: APPLICATION_SEND_ERROR };
|
|
372
|
-
}
|
|
373
|
-
const preferencesText = `
|
|
374
|
-
Open to 1:1 product/design sessions: ${openToSessions ? "Yes" : "No"}
|
|
375
|
-
Okay with anonymized case studies: ${okayWithCaseStudies ? "Yes" : "No"}
|
|
376
|
-
`.trim();
|
|
377
|
-
const teamEmailText = `
|
|
378
|
-
New Design Partner Waitlist Application
|
|
379
|
-
|
|
380
|
-
Contact Information:
|
|
381
|
-
- Name: ${name}
|
|
382
|
-
- Email: ${email}
|
|
383
|
-
${company ? `- Company/Project: ${company}` : ""}
|
|
384
|
-
${role ? `- Role: ${role}` : ""}
|
|
385
|
-
|
|
386
|
-
Application Details:
|
|
387
|
-
- What are you building with AI today?
|
|
388
|
-
${whatBuilding}
|
|
389
|
-
|
|
390
|
-
- What do you hope ContractSpec will solve for you?
|
|
391
|
-
${whatSolving}
|
|
392
|
-
|
|
393
|
-
- Primary use case: ${useCase || "Not specified"}
|
|
394
|
-
- Current stack: ${currentStack || "Not specified"}
|
|
395
|
-
- Team Size: ${teamSize || "Not specified"}
|
|
396
|
-
- Timeline: ${timeline || "Not specified"}
|
|
397
|
-
|
|
398
|
-
Preferences:
|
|
399
|
-
- Open to 1:1 product/design sessions: ${openToSessions ? "Yes" : "No"}
|
|
400
|
-
- Okay with anonymized case studies: ${okayWithCaseStudies ? "Yes" : "No"}
|
|
401
|
-
|
|
402
|
-
---
|
|
403
|
-
Submitted via ContractSpec waitlist application form
|
|
404
|
-
`.trim();
|
|
405
|
-
const teamEmailHtml = `
|
|
406
|
-
<div style="font-family: sans-serif; max-width: 720px; margin: 0 auto;">
|
|
407
|
-
<h1 style="color: #8b5cf6;">New Design Partner Waitlist Application</h1>
|
|
408
|
-
<h2 style="color: #8b5cf6; margin: 16px 0 8px;">Contact Information</h2>
|
|
409
|
-
<ul style="padding-left: 16px; line-height: 1.6; margin: 0 0 16px;">
|
|
410
|
-
<li>Name: ${escapeHtml(name)}</li>
|
|
411
|
-
<li>Email: ${escapeHtml(email)}</li>
|
|
412
|
-
${company ? `<li>Company/Project: ${escapeHtml(company)}</li>` : ""}
|
|
413
|
-
${role ? `<li>Role: ${escapeHtml(role)}</li>` : ""}
|
|
414
|
-
</ul>
|
|
415
|
-
<h2 style="color: #8b5cf6; margin: 16px 0 8px;">Application Details</h2>
|
|
416
|
-
<p style="margin: 0 0 8px; font-weight: 600;">What are you building with AI today?</p>
|
|
417
|
-
<div style="border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; white-space: pre-wrap; line-height: 1.6;">
|
|
418
|
-
${formatMultilineHtml(whatBuilding)}
|
|
419
|
-
</div>
|
|
420
|
-
<p style="margin: 16px 0 8px; font-weight: 600;">What do you hope ContractSpec will solve for you?</p>
|
|
421
|
-
<div style="border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; white-space: pre-wrap; line-height: 1.6;">
|
|
422
|
-
${formatMultilineHtml(whatSolving)}
|
|
423
|
-
</div>
|
|
424
|
-
<ul style="padding-left: 16px; line-height: 1.6; margin: 16px 0;">
|
|
425
|
-
<li>Primary use case: ${escapeHtml(useCase || "Not specified")}</li>
|
|
426
|
-
<li>Current stack: ${escapeHtml(currentStack || "Not specified")}</li>
|
|
427
|
-
<li>Team Size: ${escapeHtml(teamSize || "Not specified")}</li>
|
|
428
|
-
<li>Timeline: ${escapeHtml(timeline || "Not specified")}</li>
|
|
429
|
-
</ul>
|
|
430
|
-
<h2 style="color: #8b5cf6; margin: 16px 0 8px;">Preferences</h2>
|
|
431
|
-
<div style="border: 1px solid #e5e7eb; border-radius: 8px; padding: 12px; background: #f9fafb; line-height: 1.6;">
|
|
432
|
-
${formatMultilineHtml(preferencesText)}
|
|
433
|
-
</div>
|
|
434
|
-
<p style="color: #6b7280; font-size: 12px; margin-top: 20px;">Submitted via ContractSpec waitlist application form</p>
|
|
435
|
-
</div>
|
|
436
|
-
`;
|
|
437
|
-
const teamSend = await sendEmail(configResult.config, {
|
|
438
|
-
to: [configResult.config.teamInbox],
|
|
439
|
-
subject: `New Design Partner Application: ${name} (${email})`,
|
|
440
|
-
text: teamEmailText,
|
|
441
|
-
html: teamEmailHtml,
|
|
442
|
-
replyTo: email,
|
|
443
|
-
context: "waitlist-application-team-notification"
|
|
444
|
-
});
|
|
445
|
-
if (!teamSend.success) {
|
|
446
|
-
return { success: false, text: APPLICATION_SEND_ERROR };
|
|
447
|
-
}
|
|
448
|
-
return {
|
|
449
|
-
success: true,
|
|
450
|
-
text: "Application submitted successfully!"
|
|
451
|
-
};
|
|
452
|
-
};
|
|
453
|
-
|
|
454
|
-
// src/components/marketing/waitlist-section.tsx
|
|
455
|
-
import { useEffect, useState } from "react";
|
|
456
|
-
import { useForm } from "react-hook-form";
|
|
457
|
-
import { zodResolver } from "@hookform/resolvers/zod";
|
|
458
|
-
import z from "zod";
|
|
459
|
-
import { AlertCircle, CheckCircle } from "lucide-react";
|
|
184
|
+
// src/components/marketing/studio-signup-section.tsx
|
|
185
|
+
import Link from "next/link";
|
|
186
|
+
import { ArrowRight, Rocket } from "lucide-react";
|
|
460
187
|
import { Button } from "@contractspec/lib.design-system";
|
|
461
|
-
import {
|
|
462
|
-
import { Label } from "@contractspec/lib.ui-kit-web/ui/label";
|
|
463
|
-
import {
|
|
464
|
-
Select,
|
|
465
|
-
SelectContent,
|
|
466
|
-
SelectItem,
|
|
467
|
-
SelectTrigger,
|
|
468
|
-
SelectValue
|
|
469
|
-
} from "@contractspec/lib.ui-kit-web/ui/select";
|
|
470
|
-
import { Checkbox } from "@contractspec/lib.ui-kit-web/ui/checkbox";
|
|
471
|
-
import { Switch } from "@contractspec/lib.ui-kit-web/ui/switch";
|
|
472
|
-
import { Input } from "@contractspec/lib.design-system";
|
|
473
|
-
import { jsxDEV, Fragment } from "react/jsx-dev-runtime";
|
|
188
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
474
189
|
"use client";
|
|
475
|
-
var
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
name: z.string().min(1, "Name is required"),
|
|
480
|
-
email: z.email("Please enter a valid email address"),
|
|
481
|
-
company: z.string().optional(),
|
|
482
|
-
role: z.string().optional(),
|
|
483
|
-
useCase: z.string().optional(),
|
|
484
|
-
currentStack: z.string().optional(),
|
|
485
|
-
whatBuilding: z.string().min(1, "Please tell us what you are building"),
|
|
486
|
-
whatSolving: z.string().min(1, "Please tell us what ContractSpec will solve for you"),
|
|
487
|
-
teamSize: z.string().optional(),
|
|
488
|
-
timeline: z.string().optional(),
|
|
489
|
-
openToSessions: z.boolean().default(false),
|
|
490
|
-
okayWithCaseStudies: z.boolean().default(false)
|
|
491
|
-
});
|
|
492
|
-
function WaitlistSection({
|
|
493
|
-
variant = "default",
|
|
494
|
-
context = "pricing"
|
|
190
|
+
var studioUrl = "https://app.contractspec.studio";
|
|
191
|
+
var studioDocsUrl = "https://app.contractspec.studio/docs";
|
|
192
|
+
function StudioSignupSection({
|
|
193
|
+
variant = "default"
|
|
495
194
|
}) {
|
|
496
|
-
const [isDesignPartner, setIsDesignPartner] = useState(false);
|
|
497
|
-
const [submitResult, setSubmitResult] = useState(null);
|
|
498
|
-
const [isPending, setIsPending] = useState(false);
|
|
499
|
-
const simpleForm = useForm({
|
|
500
|
-
resolver: zodResolver(simpleWaitlistSchema),
|
|
501
|
-
defaultValues: {
|
|
502
|
-
email: ""
|
|
503
|
-
}
|
|
504
|
-
});
|
|
505
|
-
const designPartnerForm = useForm({
|
|
506
|
-
resolver: zodResolver(designPartnerSchema),
|
|
507
|
-
defaultValues: {
|
|
508
|
-
name: "",
|
|
509
|
-
email: "",
|
|
510
|
-
company: "",
|
|
511
|
-
role: "",
|
|
512
|
-
useCase: "",
|
|
513
|
-
currentStack: "",
|
|
514
|
-
whatBuilding: "",
|
|
515
|
-
whatSolving: "",
|
|
516
|
-
teamSize: "",
|
|
517
|
-
timeline: "",
|
|
518
|
-
openToSessions: false,
|
|
519
|
-
okayWithCaseStudies: false
|
|
520
|
-
}
|
|
521
|
-
});
|
|
522
|
-
const simpleEmail = simpleForm.watch("email");
|
|
523
|
-
const designPartnerEmail = designPartnerForm.watch("email");
|
|
524
|
-
useEffect(() => {
|
|
525
|
-
const currentDesignPartnerEmail = designPartnerForm.getValues("email");
|
|
526
|
-
if (simpleEmail && simpleEmail !== currentDesignPartnerEmail) {
|
|
527
|
-
designPartnerForm.setValue("email", simpleEmail, { shouldDirty: false });
|
|
528
|
-
}
|
|
529
|
-
}, [simpleEmail, designPartnerForm]);
|
|
530
|
-
useEffect(() => {
|
|
531
|
-
const currentSimpleEmail = simpleForm.getValues("email");
|
|
532
|
-
if (designPartnerEmail && designPartnerEmail !== currentSimpleEmail) {
|
|
533
|
-
simpleForm.setValue("email", designPartnerEmail, { shouldDirty: false });
|
|
534
|
-
}
|
|
535
|
-
}, [designPartnerEmail, simpleForm]);
|
|
536
|
-
const handleSimpleSubmit = async (data) => {
|
|
537
|
-
setIsPending(true);
|
|
538
|
-
setSubmitResult(null);
|
|
539
|
-
try {
|
|
540
|
-
const formData = new FormData;
|
|
541
|
-
formData.set("email", data.email);
|
|
542
|
-
const result = await joinWaitlist(formData);
|
|
543
|
-
if (result.success) {
|
|
544
|
-
setSubmitResult({
|
|
545
|
-
success: true,
|
|
546
|
-
text: "Thanks for joining the waitlist! Check your inbox for a confirmation."
|
|
547
|
-
});
|
|
548
|
-
simpleForm.reset();
|
|
549
|
-
} else {
|
|
550
|
-
setSubmitResult({
|
|
551
|
-
success: false,
|
|
552
|
-
text: result.text || "Failed to join waitlist. Please try again."
|
|
553
|
-
});
|
|
554
|
-
}
|
|
555
|
-
} catch (_error) {
|
|
556
|
-
setSubmitResult({
|
|
557
|
-
success: false,
|
|
558
|
-
text: "Failed to join waitlist. Please try again."
|
|
559
|
-
});
|
|
560
|
-
} finally {
|
|
561
|
-
setIsPending(false);
|
|
562
|
-
}
|
|
563
|
-
};
|
|
564
|
-
const handleDesignPartnerSubmit = async (data) => {
|
|
565
|
-
setIsPending(true);
|
|
566
|
-
setSubmitResult(null);
|
|
567
|
-
try {
|
|
568
|
-
const formData = new FormData;
|
|
569
|
-
formData.set("email", data.email);
|
|
570
|
-
formData.set("name", data.name);
|
|
571
|
-
if (data.company)
|
|
572
|
-
formData.set("company", data.company);
|
|
573
|
-
if (data.role)
|
|
574
|
-
formData.set("role", data.role);
|
|
575
|
-
if (data.useCase)
|
|
576
|
-
formData.set("useCase", data.useCase);
|
|
577
|
-
if (data.currentStack)
|
|
578
|
-
formData.set("currentStack", data.currentStack);
|
|
579
|
-
formData.set("whatBuilding", data.whatBuilding);
|
|
580
|
-
formData.set("whatSolving", data.whatSolving);
|
|
581
|
-
if (data.teamSize)
|
|
582
|
-
formData.set("teamSize", data.teamSize);
|
|
583
|
-
if (data.timeline)
|
|
584
|
-
formData.set("timeline", data.timeline);
|
|
585
|
-
if (data.openToSessions)
|
|
586
|
-
formData.set("openToSessions", "on");
|
|
587
|
-
if (data.okayWithCaseStudies)
|
|
588
|
-
formData.set("okayWithCaseStudies", "on");
|
|
589
|
-
const result = await submitWaitlistApplication(formData);
|
|
590
|
-
if (result.success) {
|
|
591
|
-
setSubmitResult({
|
|
592
|
-
success: true,
|
|
593
|
-
text: "You're on the list. Thanks for applying. We're slowly onboarding design partners in waves. If your use case is a good fit, we'll reach out personally."
|
|
594
|
-
});
|
|
595
|
-
designPartnerForm.reset();
|
|
596
|
-
} else {
|
|
597
|
-
setSubmitResult({
|
|
598
|
-
success: false,
|
|
599
|
-
text: result.text || "Failed to submit application. Please try again."
|
|
600
|
-
});
|
|
601
|
-
}
|
|
602
|
-
} catch (_error) {
|
|
603
|
-
setSubmitResult({
|
|
604
|
-
success: false,
|
|
605
|
-
text: "Failed to submit application. Please try again."
|
|
606
|
-
});
|
|
607
|
-
} finally {
|
|
608
|
-
setIsPending(false);
|
|
609
|
-
}
|
|
610
|
-
};
|
|
611
|
-
const onSubmit = isDesignPartner ? designPartnerForm.handleSubmit(handleDesignPartnerSubmit) : simpleForm.handleSubmit(handleSimpleSubmit);
|
|
612
195
|
const isCompact = variant === "compact";
|
|
613
196
|
return /* @__PURE__ */ jsxDEV("div", {
|
|
614
|
-
id: "
|
|
197
|
+
id: "studio-signup",
|
|
615
198
|
className: isCompact ? "space-y-4" : "card-subtle space-y-6 p-8",
|
|
616
199
|
children: [
|
|
617
|
-
|
|
200
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
618
201
|
className: "space-y-4",
|
|
619
202
|
children: [
|
|
620
203
|
/* @__PURE__ */ jsxDEV("div", {
|
|
621
204
|
className: "inline-flex items-center gap-2 rounded-full border border-violet-500/20 bg-violet-500/10 px-3 py-1",
|
|
622
|
-
children: /* @__PURE__ */ jsxDEV("span", {
|
|
623
|
-
className: "text-sm font-medium text-violet-300",
|
|
624
|
-
children: isDesignPartner ? "Design Partner Waitlist" : "Join the Waitlist"
|
|
625
|
-
}, undefined, false, undefined, this)
|
|
626
|
-
}, undefined, false, undefined, this),
|
|
627
|
-
/* @__PURE__ */ jsxDEV("h2", {
|
|
628
|
-
className: "text-2xl font-bold",
|
|
629
|
-
children: isDesignPartner ? "Apply for early access to ContractSpec" : "Get early access to ContractSpec"
|
|
630
|
-
}, undefined, false, undefined, this),
|
|
631
|
-
/* @__PURE__ */ jsxDEV("p", {
|
|
632
|
-
className: "text-muted-foreground text-sm",
|
|
633
|
-
children: isDesignPartner ? "Tell us what you're building. We'll prioritize teams where ContractSpec can have a big impact, and where we can learn the most." : "Join the waitlist to be notified when ContractSpec becomes available."
|
|
634
|
-
}, undefined, false, undefined, this)
|
|
635
|
-
]
|
|
636
|
-
}, undefined, true, undefined, this),
|
|
637
|
-
!isCompact && /* @__PURE__ */ jsxDEV("div", {
|
|
638
|
-
className: "border-border bg-muted/20 flex items-center justify-between gap-4 rounded-lg border p-4",
|
|
639
|
-
children: [
|
|
640
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
641
|
-
className: "space-y-1",
|
|
642
205
|
children: [
|
|
643
|
-
/* @__PURE__ */ jsxDEV(
|
|
644
|
-
|
|
645
|
-
className: "text-
|
|
646
|
-
children: "Apply as a design partner"
|
|
206
|
+
/* @__PURE__ */ jsxDEV(Rocket, {
|
|
207
|
+
size: 14,
|
|
208
|
+
className: "text-violet-300"
|
|
647
209
|
}, undefined, false, undefined, this),
|
|
648
|
-
/* @__PURE__ */ jsxDEV("
|
|
649
|
-
className: "text-
|
|
650
|
-
children:
|
|
210
|
+
/* @__PURE__ */ jsxDEV("span", {
|
|
211
|
+
className: "text-sm font-medium text-violet-300",
|
|
212
|
+
children: "ContractSpec Studio"
|
|
651
213
|
}, undefined, false, undefined, this)
|
|
652
214
|
]
|
|
653
215
|
}, undefined, true, undefined, this),
|
|
654
|
-
/* @__PURE__ */ jsxDEV(
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
disabled: isPending || submitResult?.success
|
|
659
|
-
}, undefined, false, undefined, this)
|
|
660
|
-
]
|
|
661
|
-
}, undefined, true, undefined, this),
|
|
662
|
-
!isCompact && isDesignPartner && /* @__PURE__ */ jsxDEV("div", {
|
|
663
|
-
className: "space-y-2",
|
|
664
|
-
children: [
|
|
216
|
+
/* @__PURE__ */ jsxDEV("h2", {
|
|
217
|
+
className: isCompact ? "text-xl font-bold" : "text-2xl font-bold",
|
|
218
|
+
children: "Try ContractSpec Studio"
|
|
219
|
+
}, undefined, false, undefined, this),
|
|
665
220
|
/* @__PURE__ */ jsxDEV("p", {
|
|
666
|
-
className: "text-
|
|
667
|
-
children: "
|
|
221
|
+
className: "text-muted-foreground text-sm",
|
|
222
|
+
children: "The AI-powered product decision engine that turns product signals into spec-first deliverables."
|
|
668
223
|
}, undefined, false, undefined, this),
|
|
669
|
-
/* @__PURE__ */ jsxDEV("
|
|
670
|
-
className: "text-muted-foreground
|
|
671
|
-
children:
|
|
672
|
-
|
|
673
|
-
children: "\u2022 Early access to ContractSpec Studio"
|
|
674
|
-
}, undefined, false, undefined, this),
|
|
675
|
-
/* @__PURE__ */ jsxDEV("li", {
|
|
676
|
-
children: "\u2022 1:1 onboarding and architecture sessions"
|
|
677
|
-
}, undefined, false, undefined, this),
|
|
678
|
-
/* @__PURE__ */ jsxDEV("li", {
|
|
679
|
-
children: "\u2022 Priority support via direct channels"
|
|
680
|
-
}, undefined, false, undefined, this),
|
|
681
|
-
/* @__PURE__ */ jsxDEV("li", {
|
|
682
|
-
children: "\u2022 Influence over roadmap and features"
|
|
683
|
-
}, undefined, false, undefined, this),
|
|
684
|
-
/* @__PURE__ */ jsxDEV("li", {
|
|
685
|
-
children: "\u2022 Founding discount when paid plans launch"
|
|
686
|
-
}, undefined, false, undefined, this)
|
|
687
|
-
]
|
|
688
|
-
}, undefined, true, undefined, this)
|
|
224
|
+
/* @__PURE__ */ jsxDEV("p", {
|
|
225
|
+
className: "text-muted-foreground text-xs",
|
|
226
|
+
children: "Evidence -> Correlation -> Decision -> Change -> Export -> Check -> Notify -> Autopilot"
|
|
227
|
+
}, undefined, false, undefined, this)
|
|
689
228
|
]
|
|
690
229
|
}, undefined, true, undefined, this),
|
|
691
|
-
/* @__PURE__ */ jsxDEV("
|
|
692
|
-
|
|
693
|
-
className: "space-y-4",
|
|
230
|
+
/* @__PURE__ */ jsxDEV("div", {
|
|
231
|
+
className: "flex flex-col gap-3 sm:flex-row",
|
|
694
232
|
children: [
|
|
695
|
-
isDesignPartner ? /* @__PURE__ */ jsxDEV(Fragment, {
|
|
696
|
-
children: [
|
|
697
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
698
|
-
className: "grid gap-4 md:grid-cols-2",
|
|
699
|
-
children: [
|
|
700
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
701
|
-
className: "space-y-2",
|
|
702
|
-
children: [
|
|
703
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
704
|
-
htmlFor: "waitlist-name",
|
|
705
|
-
className: "text-sm font-medium",
|
|
706
|
-
children: [
|
|
707
|
-
"Name ",
|
|
708
|
-
/* @__PURE__ */ jsxDEV("span", {
|
|
709
|
-
className: "text-red-400",
|
|
710
|
-
children: "*"
|
|
711
|
-
}, undefined, false, undefined, this)
|
|
712
|
-
]
|
|
713
|
-
}, undefined, true, undefined, this),
|
|
714
|
-
/* @__PURE__ */ jsxDEV(Input, {
|
|
715
|
-
id: "waitlist-name",
|
|
716
|
-
...designPartnerForm.register("name"),
|
|
717
|
-
type: "text",
|
|
718
|
-
placeholder: "Your name",
|
|
719
|
-
disabled: isPending || submitResult?.success
|
|
720
|
-
}, undefined, false, undefined, this),
|
|
721
|
-
designPartnerForm.formState.errors.name && /* @__PURE__ */ jsxDEV("p", {
|
|
722
|
-
className: "text-xs text-red-400",
|
|
723
|
-
children: designPartnerForm.formState.errors.name.message
|
|
724
|
-
}, undefined, false, undefined, this)
|
|
725
|
-
]
|
|
726
|
-
}, undefined, true, undefined, this),
|
|
727
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
728
|
-
className: "space-y-2",
|
|
729
|
-
children: [
|
|
730
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
731
|
-
htmlFor: "waitlist-email",
|
|
732
|
-
className: "text-sm font-medium",
|
|
733
|
-
children: [
|
|
734
|
-
"Email ",
|
|
735
|
-
/* @__PURE__ */ jsxDEV("span", {
|
|
736
|
-
className: "text-red-400",
|
|
737
|
-
children: "*"
|
|
738
|
-
}, undefined, false, undefined, this)
|
|
739
|
-
]
|
|
740
|
-
}, undefined, true, undefined, this),
|
|
741
|
-
/* @__PURE__ */ jsxDEV(Input, {
|
|
742
|
-
id: "waitlist-email",
|
|
743
|
-
...designPartnerForm.register("email"),
|
|
744
|
-
type: "email",
|
|
745
|
-
placeholder: "your@email.com",
|
|
746
|
-
disabled: isPending || submitResult?.success
|
|
747
|
-
}, undefined, false, undefined, this),
|
|
748
|
-
designPartnerForm.formState.errors.email && /* @__PURE__ */ jsxDEV("p", {
|
|
749
|
-
className: "text-xs text-red-400",
|
|
750
|
-
children: designPartnerForm.formState.errors.email.message
|
|
751
|
-
}, undefined, false, undefined, this)
|
|
752
|
-
]
|
|
753
|
-
}, undefined, true, undefined, this)
|
|
754
|
-
]
|
|
755
|
-
}, undefined, true, undefined, this),
|
|
756
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
757
|
-
className: "grid gap-4 md:grid-cols-2",
|
|
758
|
-
children: [
|
|
759
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
760
|
-
className: "space-y-2",
|
|
761
|
-
children: [
|
|
762
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
763
|
-
htmlFor: "waitlist-company",
|
|
764
|
-
className: "text-sm font-medium",
|
|
765
|
-
children: "Company / Project Name"
|
|
766
|
-
}, undefined, false, undefined, this),
|
|
767
|
-
/* @__PURE__ */ jsxDEV(Input, {
|
|
768
|
-
id: "waitlist-company",
|
|
769
|
-
...designPartnerForm.register("company"),
|
|
770
|
-
type: "text",
|
|
771
|
-
placeholder: "Your company or project",
|
|
772
|
-
disabled: isPending || submitResult?.success
|
|
773
|
-
}, undefined, false, undefined, this)
|
|
774
|
-
]
|
|
775
|
-
}, undefined, true, undefined, this),
|
|
776
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
777
|
-
className: "space-y-2",
|
|
778
|
-
children: [
|
|
779
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
780
|
-
htmlFor: "waitlist-role",
|
|
781
|
-
className: "text-sm font-medium",
|
|
782
|
-
children: "Role"
|
|
783
|
-
}, undefined, false, undefined, this),
|
|
784
|
-
/* @__PURE__ */ jsxDEV(Select, {
|
|
785
|
-
value: designPartnerForm.watch("role") || "",
|
|
786
|
-
onValueChange: (value) => designPartnerForm.setValue("role", value),
|
|
787
|
-
disabled: isPending || submitResult?.success,
|
|
788
|
-
children: [
|
|
789
|
-
/* @__PURE__ */ jsxDEV(SelectTrigger, {
|
|
790
|
-
id: "waitlist-role",
|
|
791
|
-
className: "w-full",
|
|
792
|
-
children: /* @__PURE__ */ jsxDEV(SelectValue, {
|
|
793
|
-
placeholder: "Select your role"
|
|
794
|
-
}, undefined, false, undefined, this)
|
|
795
|
-
}, undefined, false, undefined, this),
|
|
796
|
-
/* @__PURE__ */ jsxDEV(SelectContent, {
|
|
797
|
-
children: [
|
|
798
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
799
|
-
value: "founder",
|
|
800
|
-
children: "Founder"
|
|
801
|
-
}, undefined, false, undefined, this),
|
|
802
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
803
|
-
value: "cto",
|
|
804
|
-
children: "CTO"
|
|
805
|
-
}, undefined, false, undefined, this),
|
|
806
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
807
|
-
value: "lead-engineer",
|
|
808
|
-
children: "Lead Engineer"
|
|
809
|
-
}, undefined, false, undefined, this),
|
|
810
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
811
|
-
value: "engineer",
|
|
812
|
-
children: "Engineer"
|
|
813
|
-
}, undefined, false, undefined, this),
|
|
814
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
815
|
-
value: "product-manager",
|
|
816
|
-
children: "Product Manager"
|
|
817
|
-
}, undefined, false, undefined, this),
|
|
818
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
819
|
-
value: "other",
|
|
820
|
-
children: "Other"
|
|
821
|
-
}, undefined, false, undefined, this)
|
|
822
|
-
]
|
|
823
|
-
}, undefined, true, undefined, this)
|
|
824
|
-
]
|
|
825
|
-
}, undefined, true, undefined, this)
|
|
826
|
-
]
|
|
827
|
-
}, undefined, true, undefined, this)
|
|
828
|
-
]
|
|
829
|
-
}, undefined, true, undefined, this),
|
|
830
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
831
|
-
className: "grid gap-4 md:grid-cols-2",
|
|
832
|
-
children: [
|
|
833
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
834
|
-
className: "space-y-2",
|
|
835
|
-
children: [
|
|
836
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
837
|
-
htmlFor: "waitlist-use-case",
|
|
838
|
-
className: "text-sm font-medium",
|
|
839
|
-
children: "Primary use case"
|
|
840
|
-
}, undefined, false, undefined, this),
|
|
841
|
-
/* @__PURE__ */ jsxDEV(Select, {
|
|
842
|
-
value: designPartnerForm.watch("useCase") || "",
|
|
843
|
-
onValueChange: (value) => designPartnerForm.setValue("useCase", value),
|
|
844
|
-
disabled: isPending || submitResult?.success,
|
|
845
|
-
children: [
|
|
846
|
-
/* @__PURE__ */ jsxDEV(SelectTrigger, {
|
|
847
|
-
id: "waitlist-use-case",
|
|
848
|
-
className: "w-full",
|
|
849
|
-
children: /* @__PURE__ */ jsxDEV(SelectValue, {
|
|
850
|
-
placeholder: "Select a use case"
|
|
851
|
-
}, undefined, false, undefined, this)
|
|
852
|
-
}, undefined, false, undefined, this),
|
|
853
|
-
/* @__PURE__ */ jsxDEV(SelectContent, {
|
|
854
|
-
children: [
|
|
855
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
856
|
-
value: "api-platform",
|
|
857
|
-
children: "API platform"
|
|
858
|
-
}, undefined, false, undefined, this),
|
|
859
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
860
|
-
value: "ai-ops",
|
|
861
|
-
children: "AI operations"
|
|
862
|
-
}, undefined, false, undefined, this),
|
|
863
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
864
|
-
value: "integration-hub",
|
|
865
|
-
children: "Integration hub"
|
|
866
|
-
}, undefined, false, undefined, this),
|
|
867
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
868
|
-
value: "internal-tools",
|
|
869
|
-
children: "Internal tools"
|
|
870
|
-
}, undefined, false, undefined, this),
|
|
871
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
872
|
-
value: "data-pipelines",
|
|
873
|
-
children: "Data pipelines"
|
|
874
|
-
}, undefined, false, undefined, this),
|
|
875
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
876
|
-
value: "other",
|
|
877
|
-
children: "Other"
|
|
878
|
-
}, undefined, false, undefined, this)
|
|
879
|
-
]
|
|
880
|
-
}, undefined, true, undefined, this)
|
|
881
|
-
]
|
|
882
|
-
}, undefined, true, undefined, this)
|
|
883
|
-
]
|
|
884
|
-
}, undefined, true, undefined, this),
|
|
885
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
886
|
-
className: "space-y-2",
|
|
887
|
-
children: [
|
|
888
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
889
|
-
htmlFor: "waitlist-current-stack",
|
|
890
|
-
className: "text-sm font-medium",
|
|
891
|
-
children: "Current stack"
|
|
892
|
-
}, undefined, false, undefined, this),
|
|
893
|
-
/* @__PURE__ */ jsxDEV(Input, {
|
|
894
|
-
id: "waitlist-current-stack",
|
|
895
|
-
...designPartnerForm.register("currentStack"),
|
|
896
|
-
type: "text",
|
|
897
|
-
placeholder: "e.g. Next.js, Postgres, OpenAPI",
|
|
898
|
-
disabled: isPending || submitResult?.success
|
|
899
|
-
}, undefined, false, undefined, this)
|
|
900
|
-
]
|
|
901
|
-
}, undefined, true, undefined, this)
|
|
902
|
-
]
|
|
903
|
-
}, undefined, true, undefined, this),
|
|
904
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
905
|
-
className: "space-y-2",
|
|
906
|
-
children: [
|
|
907
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
908
|
-
htmlFor: "waitlist-what-building",
|
|
909
|
-
className: "text-sm font-medium",
|
|
910
|
-
children: [
|
|
911
|
-
"What are you building with AI today?",
|
|
912
|
-
" ",
|
|
913
|
-
/* @__PURE__ */ jsxDEV("span", {
|
|
914
|
-
className: "text-red-400",
|
|
915
|
-
children: "*"
|
|
916
|
-
}, undefined, false, undefined, this)
|
|
917
|
-
]
|
|
918
|
-
}, undefined, true, undefined, this),
|
|
919
|
-
/* @__PURE__ */ jsxDEV(Textarea, {
|
|
920
|
-
id: "waitlist-what-building",
|
|
921
|
-
...designPartnerForm.register("whatBuilding"),
|
|
922
|
-
placeholder: "Tell us about your project...",
|
|
923
|
-
disabled: isPending || submitResult?.success,
|
|
924
|
-
rows: 4
|
|
925
|
-
}, undefined, false, undefined, this),
|
|
926
|
-
designPartnerForm.formState.errors.whatBuilding && /* @__PURE__ */ jsxDEV("p", {
|
|
927
|
-
className: "text-xs text-red-400",
|
|
928
|
-
children: designPartnerForm.formState.errors.whatBuilding.message
|
|
929
|
-
}, undefined, false, undefined, this)
|
|
930
|
-
]
|
|
931
|
-
}, undefined, true, undefined, this),
|
|
932
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
933
|
-
className: "space-y-2",
|
|
934
|
-
children: [
|
|
935
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
936
|
-
htmlFor: "waitlist-what-solving",
|
|
937
|
-
className: "text-sm font-medium",
|
|
938
|
-
children: [
|
|
939
|
-
"What do you hope ContractSpec will solve for you?",
|
|
940
|
-
" ",
|
|
941
|
-
/* @__PURE__ */ jsxDEV("span", {
|
|
942
|
-
className: "text-red-400",
|
|
943
|
-
children: "*"
|
|
944
|
-
}, undefined, false, undefined, this)
|
|
945
|
-
]
|
|
946
|
-
}, undefined, true, undefined, this),
|
|
947
|
-
/* @__PURE__ */ jsxDEV(Textarea, {
|
|
948
|
-
id: "waitlist-what-solving",
|
|
949
|
-
...designPartnerForm.register("whatSolving"),
|
|
950
|
-
placeholder: "What problems are you trying to solve?",
|
|
951
|
-
disabled: isPending || submitResult?.success,
|
|
952
|
-
rows: 4
|
|
953
|
-
}, undefined, false, undefined, this),
|
|
954
|
-
designPartnerForm.formState.errors.whatSolving && /* @__PURE__ */ jsxDEV("p", {
|
|
955
|
-
className: "text-xs text-red-400",
|
|
956
|
-
children: designPartnerForm.formState.errors.whatSolving.message
|
|
957
|
-
}, undefined, false, undefined, this)
|
|
958
|
-
]
|
|
959
|
-
}, undefined, true, undefined, this),
|
|
960
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
961
|
-
className: "grid gap-4 md:grid-cols-2",
|
|
962
|
-
children: [
|
|
963
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
964
|
-
className: "space-y-2",
|
|
965
|
-
children: [
|
|
966
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
967
|
-
htmlFor: "waitlist-team-size",
|
|
968
|
-
className: "text-sm font-medium",
|
|
969
|
-
children: "Team Size"
|
|
970
|
-
}, undefined, false, undefined, this),
|
|
971
|
-
/* @__PURE__ */ jsxDEV(Select, {
|
|
972
|
-
value: designPartnerForm.watch("teamSize") || "",
|
|
973
|
-
onValueChange: (value) => designPartnerForm.setValue("teamSize", value),
|
|
974
|
-
disabled: isPending || submitResult?.success,
|
|
975
|
-
children: [
|
|
976
|
-
/* @__PURE__ */ jsxDEV(SelectTrigger, {
|
|
977
|
-
id: "waitlist-team-size",
|
|
978
|
-
className: "w-full",
|
|
979
|
-
children: /* @__PURE__ */ jsxDEV(SelectValue, {
|
|
980
|
-
placeholder: "Select team size"
|
|
981
|
-
}, undefined, false, undefined, this)
|
|
982
|
-
}, undefined, false, undefined, this),
|
|
983
|
-
/* @__PURE__ */ jsxDEV(SelectContent, {
|
|
984
|
-
children: [
|
|
985
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
986
|
-
value: "solo",
|
|
987
|
-
children: "Solo"
|
|
988
|
-
}, undefined, false, undefined, this),
|
|
989
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
990
|
-
value: "2-5",
|
|
991
|
-
children: "2-5"
|
|
992
|
-
}, undefined, false, undefined, this),
|
|
993
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
994
|
-
value: "6-20",
|
|
995
|
-
children: "6-20"
|
|
996
|
-
}, undefined, false, undefined, this),
|
|
997
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
998
|
-
value: "20+",
|
|
999
|
-
children: "20+"
|
|
1000
|
-
}, undefined, false, undefined, this)
|
|
1001
|
-
]
|
|
1002
|
-
}, undefined, true, undefined, this)
|
|
1003
|
-
]
|
|
1004
|
-
}, undefined, true, undefined, this)
|
|
1005
|
-
]
|
|
1006
|
-
}, undefined, true, undefined, this),
|
|
1007
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
1008
|
-
className: "space-y-2",
|
|
1009
|
-
children: [
|
|
1010
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
1011
|
-
htmlFor: "waitlist-timeline",
|
|
1012
|
-
className: "text-sm font-medium",
|
|
1013
|
-
children: "Timeline"
|
|
1014
|
-
}, undefined, false, undefined, this),
|
|
1015
|
-
/* @__PURE__ */ jsxDEV(Select, {
|
|
1016
|
-
value: designPartnerForm.watch("timeline") || "",
|
|
1017
|
-
onValueChange: (value) => designPartnerForm.setValue("timeline", value),
|
|
1018
|
-
disabled: isPending || submitResult?.success,
|
|
1019
|
-
children: [
|
|
1020
|
-
/* @__PURE__ */ jsxDEV(SelectTrigger, {
|
|
1021
|
-
id: "waitlist-timeline",
|
|
1022
|
-
className: "w-full",
|
|
1023
|
-
children: /* @__PURE__ */ jsxDEV(SelectValue, {
|
|
1024
|
-
placeholder: "Select timeline"
|
|
1025
|
-
}, undefined, false, undefined, this)
|
|
1026
|
-
}, undefined, false, undefined, this),
|
|
1027
|
-
/* @__PURE__ */ jsxDEV(SelectContent, {
|
|
1028
|
-
children: [
|
|
1029
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
1030
|
-
value: "now",
|
|
1031
|
-
children: "Now"
|
|
1032
|
-
}, undefined, false, undefined, this),
|
|
1033
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
1034
|
-
value: "1-3-months",
|
|
1035
|
-
children: "1-3 months"
|
|
1036
|
-
}, undefined, false, undefined, this),
|
|
1037
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
1038
|
-
value: "3-6-months",
|
|
1039
|
-
children: "3-6 months"
|
|
1040
|
-
}, undefined, false, undefined, this),
|
|
1041
|
-
/* @__PURE__ */ jsxDEV(SelectItem, {
|
|
1042
|
-
value: "exploring",
|
|
1043
|
-
children: "Exploring"
|
|
1044
|
-
}, undefined, false, undefined, this)
|
|
1045
|
-
]
|
|
1046
|
-
}, undefined, true, undefined, this)
|
|
1047
|
-
]
|
|
1048
|
-
}, undefined, true, undefined, this)
|
|
1049
|
-
]
|
|
1050
|
-
}, undefined, true, undefined, this)
|
|
1051
|
-
]
|
|
1052
|
-
}, undefined, true, undefined, this),
|
|
1053
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
1054
|
-
className: "space-y-3",
|
|
1055
|
-
children: [
|
|
1056
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
1057
|
-
className: "flex items-start gap-3",
|
|
1058
|
-
children: [
|
|
1059
|
-
/* @__PURE__ */ jsxDEV(Checkbox, {
|
|
1060
|
-
id: "waitlist-open-to-sessions",
|
|
1061
|
-
checked: designPartnerForm.watch("openToSessions"),
|
|
1062
|
-
onCheckedChange: (checked) => designPartnerForm.setValue("openToSessions", checked === true),
|
|
1063
|
-
disabled: isPending || submitResult?.success
|
|
1064
|
-
}, undefined, false, undefined, this),
|
|
1065
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
1066
|
-
htmlFor: "waitlist-open-to-sessions",
|
|
1067
|
-
className: "cursor-pointer text-sm leading-relaxed",
|
|
1068
|
-
children: "I'm open to 1:1 product/design sessions"
|
|
1069
|
-
}, undefined, false, undefined, this)
|
|
1070
|
-
]
|
|
1071
|
-
}, undefined, true, undefined, this),
|
|
1072
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
1073
|
-
className: "flex items-start gap-3",
|
|
1074
|
-
children: [
|
|
1075
|
-
/* @__PURE__ */ jsxDEV(Checkbox, {
|
|
1076
|
-
id: "waitlist-case-studies",
|
|
1077
|
-
checked: designPartnerForm.watch("okayWithCaseStudies"),
|
|
1078
|
-
onCheckedChange: (checked) => designPartnerForm.setValue("okayWithCaseStudies", checked === true),
|
|
1079
|
-
disabled: isPending || submitResult?.success
|
|
1080
|
-
}, undefined, false, undefined, this),
|
|
1081
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
1082
|
-
htmlFor: "waitlist-case-studies",
|
|
1083
|
-
className: "cursor-pointer text-sm leading-relaxed",
|
|
1084
|
-
children: "I'm okay with anonymized case studies about our usage"
|
|
1085
|
-
}, undefined, false, undefined, this)
|
|
1086
|
-
]
|
|
1087
|
-
}, undefined, true, undefined, this)
|
|
1088
|
-
]
|
|
1089
|
-
}, undefined, true, undefined, this)
|
|
1090
|
-
]
|
|
1091
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV("div", {
|
|
1092
|
-
className: "space-y-2",
|
|
1093
|
-
children: [
|
|
1094
|
-
/* @__PURE__ */ jsxDEV(Label, {
|
|
1095
|
-
htmlFor: "waitlist-email",
|
|
1096
|
-
className: "text-sm font-medium",
|
|
1097
|
-
children: [
|
|
1098
|
-
"Email ",
|
|
1099
|
-
/* @__PURE__ */ jsxDEV("span", {
|
|
1100
|
-
className: "text-red-400",
|
|
1101
|
-
children: "*"
|
|
1102
|
-
}, undefined, false, undefined, this)
|
|
1103
|
-
]
|
|
1104
|
-
}, undefined, true, undefined, this),
|
|
1105
|
-
/* @__PURE__ */ jsxDEV(Input, {
|
|
1106
|
-
id: "waitlist-email",
|
|
1107
|
-
...simpleForm.register("email"),
|
|
1108
|
-
type: "email",
|
|
1109
|
-
placeholder: "your@email.com",
|
|
1110
|
-
disabled: isPending || submitResult?.success
|
|
1111
|
-
}, undefined, false, undefined, this),
|
|
1112
|
-
simpleForm.formState.errors.email && /* @__PURE__ */ jsxDEV("p", {
|
|
1113
|
-
className: "text-xs text-red-400",
|
|
1114
|
-
children: simpleForm.formState.errors.email.message
|
|
1115
|
-
}, undefined, false, undefined, this)
|
|
1116
|
-
]
|
|
1117
|
-
}, undefined, true, undefined, this),
|
|
1118
|
-
submitResult && !isPending && /* @__PURE__ */ jsxDEV("div", {
|
|
1119
|
-
className: `flex items-start gap-2 rounded-lg p-4 text-sm ${submitResult.success ? "border border-green-500/20 bg-green-500/10 text-green-400" : "border border-red-500/20 bg-red-500/10 text-red-400"}`,
|
|
1120
|
-
children: [
|
|
1121
|
-
submitResult.success ? /* @__PURE__ */ jsxDEV(CheckCircle, {
|
|
1122
|
-
size: 20,
|
|
1123
|
-
className: "mt-0.5 shrink-0"
|
|
1124
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV(AlertCircle, {
|
|
1125
|
-
size: 20,
|
|
1126
|
-
className: "mt-0.5 shrink-0"
|
|
1127
|
-
}, undefined, false, undefined, this),
|
|
1128
|
-
/* @__PURE__ */ jsxDEV("div", {
|
|
1129
|
-
className: "flex-1",
|
|
1130
|
-
children: submitResult.success ? /* @__PURE__ */ jsxDEV(Fragment, {
|
|
1131
|
-
children: [
|
|
1132
|
-
/* @__PURE__ */ jsxDEV("p", {
|
|
1133
|
-
className: "mb-1 font-semibold",
|
|
1134
|
-
children: "You're on the list."
|
|
1135
|
-
}, undefined, false, undefined, this),
|
|
1136
|
-
/* @__PURE__ */ jsxDEV("p", {
|
|
1137
|
-
className: "text-sm",
|
|
1138
|
-
children: submitResult.text
|
|
1139
|
-
}, undefined, false, undefined, this)
|
|
1140
|
-
]
|
|
1141
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV("p", {
|
|
1142
|
-
children: submitResult.text
|
|
1143
|
-
}, undefined, false, undefined, this)
|
|
1144
|
-
}, undefined, false, undefined, this)
|
|
1145
|
-
]
|
|
1146
|
-
}, undefined, true, undefined, this),
|
|
1147
233
|
/* @__PURE__ */ jsxDEV(Button, {
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
234
|
+
asChild: true,
|
|
235
|
+
className: "w-full sm:w-auto",
|
|
236
|
+
children: /* @__PURE__ */ jsxDEV(Link, {
|
|
237
|
+
href: studioUrl,
|
|
238
|
+
children: [
|
|
239
|
+
"Get Started Free ",
|
|
240
|
+
/* @__PURE__ */ jsxDEV(ArrowRight, {
|
|
241
|
+
className: "ml-2 h-4 w-4"
|
|
242
|
+
}, undefined, false, undefined, this)
|
|
243
|
+
]
|
|
244
|
+
}, undefined, true, undefined, this)
|
|
1152
245
|
}, undefined, false, undefined, this),
|
|
1153
|
-
/* @__PURE__ */ jsxDEV(
|
|
1154
|
-
|
|
1155
|
-
|
|
246
|
+
/* @__PURE__ */ jsxDEV(Button, {
|
|
247
|
+
asChild: true,
|
|
248
|
+
variant: "outline",
|
|
249
|
+
className: "w-full sm:w-auto",
|
|
250
|
+
children: /* @__PURE__ */ jsxDEV(Link, {
|
|
251
|
+
href: studioDocsUrl,
|
|
252
|
+
children: "Read Studio Docs"
|
|
253
|
+
}, undefined, false, undefined, this)
|
|
1156
254
|
}, undefined, false, undefined, this)
|
|
1157
255
|
]
|
|
1158
256
|
}, undefined, true, undefined, this)
|
|
@@ -1165,14 +263,14 @@ import { useActionState } from "react";
|
|
|
1165
263
|
import {
|
|
1166
264
|
Calendar,
|
|
1167
265
|
MessageSquare,
|
|
1168
|
-
CheckCircle
|
|
1169
|
-
AlertCircle
|
|
266
|
+
CheckCircle,
|
|
267
|
+
AlertCircle
|
|
1170
268
|
} from "lucide-react";
|
|
1171
269
|
import {
|
|
1172
270
|
ActionForm,
|
|
1173
271
|
Button as Button2,
|
|
1174
|
-
Input
|
|
1175
|
-
Textarea
|
|
272
|
+
Input,
|
|
273
|
+
Textarea
|
|
1176
274
|
} from "@contractspec/lib.design-system";
|
|
1177
275
|
import { VStack, HStack } from "@contractspec/lib.ui-kit-web/ui/stack";
|
|
1178
276
|
import {
|
|
@@ -1217,9 +315,7 @@ function ContactClient() {
|
|
|
1217
315
|
}, undefined, false, undefined, this)
|
|
1218
316
|
]
|
|
1219
317
|
}, undefined, true, undefined, this),
|
|
1220
|
-
/* @__PURE__ */ jsxDEV2(
|
|
1221
|
-
context: "contact"
|
|
1222
|
-
}, undefined, false, undefined, this),
|
|
318
|
+
/* @__PURE__ */ jsxDEV2(StudioSignupSection, {}, undefined, false, undefined, this),
|
|
1223
319
|
/* @__PURE__ */ jsxDEV2(VStack, {
|
|
1224
320
|
className: "card-subtle gap-6 p-8",
|
|
1225
321
|
id: "call",
|
|
@@ -1296,7 +392,7 @@ function ContactClient() {
|
|
|
1296
392
|
className: "text-sm font-medium",
|
|
1297
393
|
children: "Name"
|
|
1298
394
|
}, undefined, false, undefined, this),
|
|
1299
|
-
/* @__PURE__ */ jsxDEV2(
|
|
395
|
+
/* @__PURE__ */ jsxDEV2(Input, {
|
|
1300
396
|
id: "contact-name",
|
|
1301
397
|
name: "name",
|
|
1302
398
|
type: "text",
|
|
@@ -1313,7 +409,7 @@ function ContactClient() {
|
|
|
1313
409
|
className: "text-sm font-medium",
|
|
1314
410
|
children: "Email"
|
|
1315
411
|
}, undefined, false, undefined, this),
|
|
1316
|
-
/* @__PURE__ */ jsxDEV2(
|
|
412
|
+
/* @__PURE__ */ jsxDEV2(Input, {
|
|
1317
413
|
id: "contact-email",
|
|
1318
414
|
name: "email",
|
|
1319
415
|
type: "email",
|
|
@@ -1331,7 +427,7 @@ function ContactClient() {
|
|
|
1331
427
|
className: "text-sm font-medium",
|
|
1332
428
|
children: "Message"
|
|
1333
429
|
}, undefined, false, undefined, this),
|
|
1334
|
-
/* @__PURE__ */ jsxDEV2(
|
|
430
|
+
/* @__PURE__ */ jsxDEV2(Textarea, {
|
|
1335
431
|
id: "contact-message",
|
|
1336
432
|
name: "message",
|
|
1337
433
|
placeholder: "Tell us what's on your mind...",
|
|
@@ -1344,9 +440,9 @@ function ContactClient() {
|
|
|
1344
440
|
contactResult && !contactPending && /* @__PURE__ */ jsxDEV2(HStack, {
|
|
1345
441
|
className: `items-center gap-2 rounded-lg p-3 text-sm ${contactResult.success ? "border border-green-500/20 bg-green-500/10 text-green-400" : "border border-red-500/20 bg-red-500/10 text-red-400"}`,
|
|
1346
442
|
children: [
|
|
1347
|
-
contactResult.success ? /* @__PURE__ */ jsxDEV2(
|
|
443
|
+
contactResult.success ? /* @__PURE__ */ jsxDEV2(CheckCircle, {
|
|
1348
444
|
size: 16
|
|
1349
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV2(
|
|
445
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV2(AlertCircle, {
|
|
1350
446
|
size: 16
|
|
1351
447
|
}, undefined, false, undefined, this),
|
|
1352
448
|
/* @__PURE__ */ jsxDEV2(Small, {
|