From 14fcaea83035476b0d778d4c737ad559c6919176 Mon Sep 17 00:00:00 2001
From: Nik L
Date: Fri, 10 Apr 2026 10:27:34 -0400
Subject: [PATCH] feat: new closed beta flow
---
components/hero.tsx | 87 +++++++++++++++++++++++++++---
components/nav.tsx | 4 +-
components/waitlist.tsx | 116 +++++++++++++++-------------------------
3 files changed, 124 insertions(+), 83 deletions(-)
diff --git a/components/hero.tsx b/components/hero.tsx
index cf2bd72..5419200 100644
--- a/components/hero.tsx
+++ b/components/hero.tsx
@@ -1,4 +1,44 @@
+'use client'
+
+import { useState, FormEvent } from 'react'
+import { Check } from 'lucide-react'
+
export function Hero() {
+ const [mode, setMode] = useState<'button' | 'input' | 'submitting' | 'success'>('button')
+ const [email, setEmail] = useState('')
+
+ async function onSubmit(e: FormEvent) {
+ e.preventDefault()
+ if (mode === 'submitting') return
+ setMode('submitting')
+ try {
+ const res = await fetch('https://api.web3forms.com/submit', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ Accept: 'application/json',
+ },
+ body: JSON.stringify({
+ access_key: '85d3252e-5890-450c-aa93-12dc89c7c9b5',
+ subject: 'Greywall closed beta signup (hero)',
+ from_name: 'Greywall waitlist',
+ email,
+ message: '(hero CTA signup)',
+ botcheck: '',
+ }),
+ })
+ const data = await res.json()
+ if (data.success) {
+ setMode('success')
+ setEmail('')
+ } else {
+ setMode('input')
+ }
+ } catch {
+ setMode('input')
+ }
+ }
+
return (
{/* Subtle background gradient */}
@@ -37,14 +77,45 @@ export function Hero() {
-
-
- Join the SaaS beta
- →
-
+
+ {mode === 'button' && (
+
+ )}
+ {(mode === 'input' || mode === 'submitting') && (
+
+ )}
+ {mode === 'success' && (
+
+
+ You're on the list.
+
+ )}
+
+ No spam. Just one email when it's ready.
+
diff --git a/components/nav.tsx b/components/nav.tsx
index 3428520..425bc5f 100644
--- a/components/nav.tsx
+++ b/components/nav.tsx
@@ -65,8 +65,8 @@ export function Nav() {
href="#waitlist"
className="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-md bg-primary text-primary-foreground text-xs sm:text-sm font-sans font-medium hover:bg-primary/90 transition-colors whitespace-nowrap"
>
- Join the SaaS beta
- SaaS beta
+ Join closed beta
+ Beta
diff --git a/components/waitlist.tsx b/components/waitlist.tsx
index 80d7706..9652604 100644
--- a/components/waitlist.tsx
+++ b/components/waitlist.tsx
@@ -26,18 +26,17 @@ const plugins = [
},
]
-type Status = 'idle' | 'submitting' | 'success' | 'error'
+type Mode = 'button' | 'input' | 'submitting' | 'success' | 'error'
export function Waitlist() {
+ const [mode, setMode] = useState('button')
const [email, setEmail] = useState('')
- const [useCase, setUseCase] = useState('')
- const [status, setStatus] = useState('idle')
const [error, setError] = useState('')
async function onSubmit(e: FormEvent) {
e.preventDefault()
- if (status === 'submitting') return
- setStatus('submitting')
+ if (mode === 'submitting') return
+ setMode('submitting')
setError('')
try {
@@ -52,21 +51,20 @@ export function Waitlist() {
subject: 'Greywall enterprise / plugin SDK waitlist',
from_name: 'Greywall waitlist',
email,
- message: useCase || '(no use case provided)',
+ message: '(waitlist section signup)',
botcheck: '',
}),
})
const data = await res.json()
if (data.success) {
- setStatus('success')
+ setMode('success')
setEmail('')
- setUseCase('')
} else {
- setStatus('error')
+ setMode('error')
setError(data.message || 'Something went wrong. Try again?')
}
} catch {
- setStatus('error')
+ setMode('error')
setError('Network error. Try again?')
}
}
@@ -117,77 +115,49 @@ export function Waitlist() {
- {/* Waitlist form */}
-
- {status === 'success' ? (
-
-
-
-
-
You're on the list.
-
- We'll reach out as the plugin SDK takes shape. Thanks for helping us build it.
-
-
- ) : (
-