nav order matches page; pricing moved last; setup-intent attach fix
Page section order is now: hero → pillars → how-it-works → inference →
efficiency → comparison → enterprise → mission → local-first → safety →
environmental → marketplace → viral → pricing → footer. Pricing is the
last content block so visitors scroll the whole story before being asked
to commit. Nav (desktop + mobile + dropdown) reordered to mirror the
page: How it works → Enterprise → Mission ▾ → Marketplace → Pricing →
About / Gallery / Account.
Stripe attach bug: /api/link-customer was hitting
POST /v1/payment_intents/{id} for every Intent regardless of type, so
SetupIntents (seti_*) returned 404 from Stripe. Branched on the id
prefix - SetupIntents go to /v1/setup_intents/{id} and skip the
receipt_email param (PaymentIntent-only field). Caught from a live
422 in the dashboard the moment Will tested timing=later.
This commit is contained in:
+21
-5
@@ -146,6 +146,10 @@ fn persist_founding_count(sold: Int) {
|
||||
// ── Page assembly ─────────────────────────────────────────────────────────────
|
||||
|
||||
fn page(sold: Int, total: Int) -> String {
|
||||
// Page order is the source of truth; nav must mirror it section-for-section.
|
||||
// Pricing is intentionally last so a visitor can scroll the whole story
|
||||
// (what / how / why / who-it's-for / safety / planet) before being asked
|
||||
// to commit to a plan.
|
||||
return page_open()
|
||||
+ nav()
|
||||
+ hero()
|
||||
@@ -159,9 +163,9 @@ fn page(sold: Int, total: Int) -> String {
|
||||
+ local_first()
|
||||
+ safety()
|
||||
+ environmental()
|
||||
+ pricing(sold, total)
|
||||
+ marketplace()
|
||||
+ viral()
|
||||
+ pricing(sold, total)
|
||||
+ footer()
|
||||
+ page_close()
|
||||
}
|
||||
@@ -521,11 +525,23 @@ fn handle_request(method: String, path: String, body: String) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Attach customer + receipt_email to the PaymentIntent
|
||||
// 3. Attach customer to the live Intent. SetupIntents (seti_*) and
|
||||
// PaymentIntents (pi_*) live at different REST endpoints, so
|
||||
// branch on the id prefix. SetupIntents do not accept
|
||||
// receipt_email - that's a PaymentIntent-only field.
|
||||
if !str_eq(lc_cus_id, "") {
|
||||
let lc_attach_body: String = "customer=" + lc_cus_id + "&receipt_email=" + lc_email_enc
|
||||
let lc_attach_url: String = "https://api.stripe.com/v1/payment_intents/" + lc_pi_id
|
||||
let lc_attach: String = http_post_form_auth(lc_attach_url, lc_attach_body, lc_auth)
|
||||
let lc_is_setup: Bool = str_starts_with(lc_pi_id, "seti_")
|
||||
let lc_attach_url: String = if lc_is_setup {
|
||||
"https://api.stripe.com/v1/setup_intents/" + lc_pi_id
|
||||
} else {
|
||||
"https://api.stripe.com/v1/payment_intents/" + lc_pi_id
|
||||
}
|
||||
let lc_attach_body: String = if lc_is_setup {
|
||||
"customer=" + lc_cus_id
|
||||
} else {
|
||||
"customer=" + lc_cus_id + "&receipt_email=" + lc_email_enc
|
||||
}
|
||||
let _lc_attach: String = http_post_form_auth(lc_attach_url, lc_attach_body, lc_auth)
|
||||
}
|
||||
|
||||
// 4. Upsert the Supabase waitlist row so /account can find this purchase by email
|
||||
|
||||
+7
-4
@@ -9,8 +9,11 @@ fn nav() -> String {
|
||||
<div class=\"nav-inner\">
|
||||
<a href=\"/\" class=\"nav-logo\" aria-label=\"Neuron home\"><img src=\"/assets/brand/neuron-wordmark-on-light.png\" srcset=\"/assets/brand/neuron-wordmark-on-light@2x.png 2x\" alt=\"Neuron\" height=\"28\"></a>
|
||||
|
||||
<!-- Order mirrors page section order: how-it-works → enterprise →
|
||||
mission/safety/environment → marketplace → pricing. -->
|
||||
<div class=\"nav-links\">
|
||||
<a href=\"/#how-it-works\" class=\"nav-link\">How it works</a>
|
||||
<a href=\"/#how-it-works\" class=\"nav-link\">How it works</a>
|
||||
<a href=\"/#enterprise\" class=\"nav-link\">Enterprise</a>
|
||||
<div class=\"nav-dropdown\">
|
||||
<button class=\"nav-link nav-dropdown-btn\" aria-haspopup=\"true\" aria-expanded=\"false\">Mission ▾</button>
|
||||
<div class=\"nav-dropdown-menu\">
|
||||
@@ -19,9 +22,8 @@ fn nav() -> String {
|
||||
<a href=\"/#environmental\" class=\"nav-dropdown-item\">Environment</a>
|
||||
</div>
|
||||
</div>
|
||||
<a href=\"/#marketplace\" class=\"nav-link\">Marketplace</a>
|
||||
<a href=\"/#pricing\" class=\"nav-link\">Pricing</a>
|
||||
<a href=\"/#marketplace\" class=\"nav-link\">Marketplace</a>
|
||||
<a href=\"/#enterprise\" class=\"nav-link\">Enterprise</a>
|
||||
<a href=\"/about\" class=\"nav-link\">About</a>
|
||||
<a href=\"/said\" class=\"nav-link\">Gallery</a>
|
||||
<a href=\"/account\" class=\"nav-link\">Account</a>
|
||||
@@ -36,11 +38,12 @@ fn nav() -> String {
|
||||
|
||||
<div class=\"nav-mobile\" id=\"nav-mobile\" role=\"navigation\" aria-label=\"Mobile navigation\">
|
||||
<a href=\"/#how-it-works\" class=\"nav-mobile-link\">How it works</a>
|
||||
<a href=\"/#enterprise\" class=\"nav-mobile-link\">Enterprise</a>
|
||||
<a href=\"/#mission\" class=\"nav-mobile-link\">Mission</a>
|
||||
<a href=\"/#safety\" class=\"nav-mobile-link\" style=\"padding-left:1.75rem;font-size:0.8rem;color:var(--t3)\">- Safety</a>
|
||||
<a href=\"/#environmental\" class=\"nav-mobile-link\" style=\"padding-left:1.75rem;font-size:0.8rem;color:var(--t3)\">- Environment</a>
|
||||
<a href=\"/#marketplace\" class=\"nav-mobile-link\">Marketplace</a>
|
||||
<a href=\"/#pricing\" class=\"nav-mobile-link\">Pricing</a>
|
||||
<a href=\"/#enterprise\" class=\"nav-mobile-link\">Enterprise</a>
|
||||
<a href=\"/about\" class=\"nav-mobile-link\">About</a>
|
||||
<a href=\"/said\" class=\"nav-mobile-link\">Gallery</a>
|
||||
<a href=\"/account\" class=\"nav-mobile-link\">Account</a>
|
||||
|
||||
Reference in New Issue
Block a user