Add enterprise inquiry form with headcount filter, wire /api/enterprise-inquiry
This commit is contained in:
@@ -86,9 +86,138 @@ fn enterprise() -> String {
|
||||
<p class=\"ent-terms-text\">The full Enterprise Agreement is published. Read it before reaching out — no NDA required to evaluate the terms.</p>
|
||||
<a href=\"/legal/enterprise-terms\" class=\"ent-terms-link\">Read the Enterprise Agreement →</a>
|
||||
</div>
|
||||
|
||||
<!-- Enterprise inquiry form -->
|
||||
<div style=\"margin-top:3rem;padding-top:2.5rem;border-top:1px solid var(--border)\">
|
||||
<p class=\"label\" style=\"margin-bottom:0.75rem;font-size:0.65rem\">Express interest</p>
|
||||
<p style=\"font-family:var(--body);font-weight:300;font-size:0.9rem;color:var(--t2);line-height:1.75;margin-bottom:2rem\">I review every inquiry myself. Fill this out honestly — the questions are a filter, not a formality.</p>
|
||||
|
||||
<form id=\"enterprise-form\" style=\"display:grid;grid-template-columns:1fr 1fr;gap:1rem\">
|
||||
|
||||
<div style=\"display:flex;flex-direction:column;gap:0.4rem\">
|
||||
<label for=\"ent-name\" style=\"font-family:var(--body);font-size:0.7rem;font-weight:500;letter-spacing:0.08em;text-transform:uppercase;color:var(--t3)\">Name</label>
|
||||
<input id=\"ent-name\" name=\"name\" type=\"text\" required placeholder=\"Your name\"
|
||||
style=\"font-family:var(--body);font-size:0.9rem;font-weight:300;color:var(--t1);background:#fff;border:1px solid rgba(0,82,160,.22);padding:0.7rem 0.9rem;outline:none;border-radius:0;-webkit-appearance:none\">
|
||||
</div>
|
||||
|
||||
<div style=\"display:flex;flex-direction:column;gap:0.4rem\">
|
||||
<label for=\"ent-email\" style=\"font-family:var(--body);font-size:0.7rem;font-weight:500;letter-spacing:0.08em;text-transform:uppercase;color:var(--t3)\">Work email</label>
|
||||
<input id=\"ent-email\" name=\"email\" type=\"email\" required placeholder=\"you@company.com\"
|
||||
style=\"font-family:var(--body);font-size:0.9rem;font-weight:300;color:var(--t1);background:#fff;border:1px solid rgba(0,82,160,.22);padding:0.7rem 0.9rem;outline:none;border-radius:0;-webkit-appearance:none\">
|
||||
</div>
|
||||
|
||||
<div style=\"display:flex;flex-direction:column;gap:0.4rem\">
|
||||
<label for=\"ent-company\" style=\"font-family:var(--body);font-size:0.7rem;font-weight:500;letter-spacing:0.08em;text-transform:uppercase;color:var(--t3)\">Organization</label>
|
||||
<input id=\"ent-company\" name=\"company\" type=\"text\" required placeholder=\"Company or organization name\"
|
||||
style=\"font-family:var(--body);font-size:0.9rem;font-weight:300;color:var(--t1);background:#fff;border:1px solid rgba(0,82,160,.22);padding:0.7rem 0.9rem;outline:none;border-radius:0;-webkit-appearance:none\">
|
||||
</div>
|
||||
|
||||
<div style=\"display:flex;flex-direction:column;gap:0.4rem\">
|
||||
<label for=\"ent-size\" style=\"font-family:var(--body);font-size:0.7rem;font-weight:500;letter-spacing:0.08em;text-transform:uppercase;color:var(--t3)\">Team size</label>
|
||||
<select id=\"ent-size\" name=\"size\" required
|
||||
style=\"font-family:var(--body);font-size:0.9rem;font-weight:300;color:var(--t1);background:#fff;border:1px solid rgba(0,82,160,.22);padding:0.7rem 0.9rem;outline:none;border-radius:0;-webkit-appearance:none;cursor:pointer\">
|
||||
<option value=\"\">Select…</option>
|
||||
<option value=\"2-10\">2–10 people</option>
|
||||
<option value=\"11-50\">11–50 people</option>
|
||||
<option value=\"51-200\">51–200 people</option>
|
||||
<option value=\"201-500\">201–500 people</option>
|
||||
<option value=\"500+\">500+ people</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div style=\"grid-column:1/-1;display:flex;flex-direction:column;gap:0.4rem\">
|
||||
<label for=\"ent-use\" style=\"font-family:var(--body);font-size:0.7rem;font-weight:500;letter-spacing:0.08em;text-transform:uppercase;color:var(--t3)\">What do you want to use Neuron for?</label>
|
||||
<textarea id=\"ent-use\" name=\"use_case\" required rows=\"3\" placeholder=\"Describe your intended use case — be specific.\"
|
||||
style=\"font-family:var(--body);font-size:0.9rem;font-weight:300;color:var(--t1);background:#fff;border:1px solid rgba(0,82,160,.22);padding:0.7rem 0.9rem;outline:none;border-radius:0;resize:vertical;-webkit-appearance:none\"></textarea>
|
||||
</div>
|
||||
|
||||
<div style=\"grid-column:1/-1;display:flex;flex-direction:column;gap:0.4rem\">
|
||||
<label for=\"ent-headcount\" style=\"font-family:var(--body);font-size:0.7rem;font-weight:500;letter-spacing:0.08em;text-transform:uppercase;color:var(--t3)\">Is reducing headcount a primary goal of this deployment?</label>
|
||||
<select id=\"ent-headcount\" name=\"headcount\" required onchange=\"document.getElementById('ent-filter-msg').style.display=this.value==='yes'?'block':'none'\"
|
||||
style=\"font-family:var(--body);font-size:0.9rem;font-weight:300;color:var(--t1);background:#fff;border:1px solid rgba(0,82,160,.22);padding:0.7rem 0.9rem;outline:none;border-radius:0;-webkit-appearance:none;cursor:pointer\">
|
||||
<option value=\"\">Select…</option>
|
||||
<option value=\"no\">No — making our team more capable</option>
|
||||
<option value=\"secondary\">It's a secondary factor, not the primary goal</option>
|
||||
<option value=\"yes\">Yes — replacing roles with automation</option>
|
||||
</select>
|
||||
<p id=\"ent-filter-msg\" style=\"display:none;font-family:var(--body);font-size:0.875rem;font-weight:300;color:#c0392b;line-height:1.65;padding:0.75rem 1rem;background:rgba(192,57,43,.05);border-left:2px solid rgba(192,57,43,.4)\">
|
||||
Neuron isn't the right fit here. I built this to expand what people can do, not to replace them. If that changes, I'm here.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id=\"ent-form-error\" style=\"grid-column:1/-1;display:none;font-family:var(--body);font-size:0.875rem;color:#c0392b;padding:0.75rem 1rem;background:rgba(192,57,43,.05);border-left:2px solid rgba(192,57,43,.4)\"></div>
|
||||
|
||||
<div style=\"grid-column:1/-1\">
|
||||
<button type=\"submit\" id=\"ent-submit\"
|
||||
style=\"font-family:var(--body);font-size:0.75rem;font-weight:600;letter-spacing:0.12em;text-transform:uppercase;background:var(--navy);color:#fff;border:none;padding:0.95rem 2rem;cursor:pointer;transition:background .2s\">
|
||||
Send inquiry →
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<div id=\"enterprise-success\" style=\"display:none;padding:2rem;background:rgba(0,82,160,.04);border-left:3px solid var(--navy)\">
|
||||
<p style=\"font-family:var(--head);font-size:1.25rem;font-weight:500;color:var(--t1);margin-bottom:0.5rem\">Received.</p>
|
||||
<p style=\"font-family:var(--body);font-weight:300;font-size:0.9375rem;color:var(--t2);line-height:1.8\">I review these personally. If it's a fit, I'll respond directly to your email — usually within a few days.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var form = document.getElementById('enterprise-form');
|
||||
var submitBtn = document.getElementById('ent-submit');
|
||||
var successDiv = document.getElementById('enterprise-success');
|
||||
var errorDiv = document.getElementById('ent-form-error');
|
||||
|
||||
if (!form) return;
|
||||
|
||||
form.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
var headcount = document.getElementById('ent-headcount').value;
|
||||
if (headcount === 'yes') {
|
||||
document.getElementById('ent-filter-msg').style.display = 'block';
|
||||
return;
|
||||
}
|
||||
|
||||
var name = document.getElementById('ent-name').value.trim();
|
||||
var email = document.getElementById('ent-email').value.trim();
|
||||
var company = document.getElementById('ent-company').value.trim();
|
||||
var size = document.getElementById('ent-size').value;
|
||||
var useCase = document.getElementById('ent-use').value.trim();
|
||||
|
||||
if (!name || !email || !company || !size || !useCase || !headcount) {
|
||||
errorDiv.textContent = 'Please fill out all fields.';
|
||||
errorDiv.style.display = 'block';
|
||||
return;
|
||||
}
|
||||
|
||||
errorDiv.style.display = 'none';
|
||||
submitBtn.textContent = 'Sending…';
|
||||
submitBtn.disabled = true;
|
||||
|
||||
fetch('/api/enterprise-inquiry', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name: name, email: email, company: company, size: size, use_case: useCase, headcount: headcount })
|
||||
})
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(data) {
|
||||
form.style.display = 'none';
|
||||
successDiv.style.display = 'block';
|
||||
})
|
||||
.catch(function() {
|
||||
submitBtn.textContent = 'Send inquiry →';
|
||||
submitBtn.disabled = false;
|
||||
errorDiv.textContent = 'Something went wrong. Email enterprise@neurontechnologies.ai directly.';
|
||||
errorDiv.style.display = 'block';
|
||||
});
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
"
|
||||
}
|
||||
|
||||
+24
@@ -239,6 +239,28 @@ fn handle_request(method: String, path: String, body: String) -> String {
|
||||
return "{\"__status__\":500,\"error\":\"Stripe session creation failed\"}"
|
||||
}
|
||||
|
||||
// ── Enterprise inquiry ────────────────────────────────────────────────────
|
||||
if str_eq(path, "/api/enterprise-inquiry") {
|
||||
let resend_key: String = state_get("__resend_api_key__")
|
||||
let name_val: String = if str_contains(body, "\"name\"") { "submitted" } else { "" }
|
||||
if str_eq(name_val, "") {
|
||||
return "{\"error\":\"invalid request\"}"
|
||||
}
|
||||
// Log to stdout regardless of email delivery
|
||||
println("[enterprise-inquiry] " + body)
|
||||
// Send via Resend if key is configured
|
||||
if !str_eq(resend_key, "") {
|
||||
let email_body: String = "{\"from\":\"Neuron Enterprise <enterprise@neurontechnologies.ai>\",\"to\":[\"enterprise@neurontechnologies.ai\"],\"subject\":\"Enterprise Inquiry\",\"text\":" + body + "}"
|
||||
let resp: String = http_post_auth(
|
||||
"https://api.resend.com/emails",
|
||||
resend_key,
|
||||
email_body
|
||||
)
|
||||
println("[enterprise-inquiry] resend: " + resp)
|
||||
}
|
||||
return "{\"received\":true}"
|
||||
}
|
||||
|
||||
// ── Stripe webhook ────────────────────────────────────────────────────────
|
||||
if str_eq(path, "/api/webhooks/stripe") {
|
||||
if str_contains(body, "checkout.session.completed") {
|
||||
@@ -322,11 +344,13 @@ let stripe_pub_key: String = env("STRIPE_PUBLISHABLE_KEY")
|
||||
let stripe_price_founding: String = env("STRIPE_PRICE_FOUNDING")
|
||||
let stripe_price_professional: String = env("STRIPE_PRICE_PROFESSIONAL")
|
||||
let license_api_url: String = env("NEURON_LICENSE_API_URL")
|
||||
let resend_api_key: String = env("RESEND_API_KEY")
|
||||
state_set("__stripe_secret_key__", stripe_key)
|
||||
state_set("__stripe_publishable_key__", stripe_pub_key)
|
||||
state_set("__stripe_price_founding__", stripe_price_founding)
|
||||
state_set("__stripe_price_professional__", stripe_price_professional)
|
||||
state_set("__license_api_url__", license_api_url)
|
||||
state_set("__resend_api_key__", resend_api_key)
|
||||
|
||||
println(color_bold("Neuron landing") + " — http://localhost:3001")
|
||||
println(" HTML generated by El → " + html_path)
|
||||
|
||||
Reference in New Issue
Block a user