Fix initStripe load order, subscription webhook email extraction, chat textarea UX
Dev — Build & local smoke test / build-smoke (pull_request) Successful in 1m18s

- checkout.el: swap stripe_el_script before auth_script so initStripe is
  defined when Supabase auth fires onAuthStateChange on page load
- main.el: fix Stripe webhook email extraction for checkout.session.completed
  (subscription) events — customer_details is nested at data.object level,
  not at root; previous code only worked for payment_intent.succeeded
- page_close.c: replace <input type="text"> with <textarea rows="1"> in
  the chat widget input row so long questions are visible as you type
- page_css.c: update #neuron-demo-text CSS for textarea (resize:none,
  overflow:hidden, min/max-height, align-items:flex-end on row)
- chat-widget.el: add auto-resize event listener (grows up to ~4 lines),
  reset height to auto on send
This commit is contained in:
2026-05-12 12:22:59 -05:00
parent 869dcec0bb
commit c72127032e
5 changed files with 23 additions and 5 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+6
View File
@@ -1764,6 +1764,7 @@ el_val_t page_css(void) {
"\n"
" #neuron-demo-input-row {\n"
" display: flex;\n"
" align-items: flex-end;\n"
" border-top: 1px solid var(--border);\n"
" flex-shrink: 0;\n"
" }\n"
@@ -1771,11 +1772,16 @@ el_val_t page_css(void) {
" flex: 1;\n"
" font-family: var(--body);\n"
" font-size: 0.875rem;\n"
" line-height: 1.5;\n"
" color: var(--t1);\n"
" background: var(--bg);\n"
" border: none;\n"
" outline: none;\n"
" padding: 0.875rem 1rem;\n"
" resize: none;\n"
" overflow: hidden;\n"
" min-height: 2.75rem;\n"
" max-height: 7.5rem;\n"
" }\n"
" #neuron-demo-text::placeholder { color: var(--t3); }\n"
" #neuron-demo-send {\n"
+1 -1
View File
@@ -341,7 +341,7 @@ fn checkout_page(plan: String, pub_key: String) -> String {
let stripe_el_script: String = el_script_src("/js/checkout-stripe.js", true)
let free_init_script: String = ""
return nav_html + main_html + supabase_script + stripe_script + style_html + auth_script + cfg_script + stripe_el_script + free_init_script
return nav_html + main_html + supabase_script + stripe_script + style_html + stripe_el_script + cfg_script + auth_script + free_init_script
}
fn checkout_style_html() -> String {
+5
View File
@@ -497,6 +497,7 @@ fn main() -> Void {
return;
}
input.value = '';
input.style.height = 'auto';
btn.disabled = true;
addMsg('user', msg);
@@ -617,6 +618,10 @@ fn main() -> Void {
inp.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); window.neuronDemoSend(); }
});
inp.addEventListener('input', function() {
this.style.height = 'auto';
this.style.height = Math.min(this.scrollHeight, 120) + 'px';
});
}
})()")
}
+10 -3
View File
@@ -1548,13 +1548,20 @@ fn handle_request_inner(method: String, path: String, headers: Map, body: String
if is_session_done || is_pi_done || is_si_done {
// Pull email/name/customer_id - fields differ slightly across event
// types, walk a few candidates.
// types. Walk several candidates:
// receipt_email - PaymentIntent (founding one-time)
// data.object.* - full dot-path for checkout.session.completed (subscription)
// customer_details.email - substring fallback if nested key appears at any level
// billing_details.email - Elements payment intents
let customer_email: String = json_get(body, "receipt_email")
if str_eq(customer_email, "") { let customer_email = json_get(body, "data.object.customer_details.email") }
if str_eq(customer_email, "") { let customer_email = json_get(body, "customer_details.email") }
if str_eq(customer_email, "") { let customer_email = json_get(body, "billing_details.email") }
let customer_name: String = json_get(body, "customer_details.name")
let customer_name: String = json_get(body, "data.object.customer_details.name")
if str_eq(customer_name, "") { let customer_name = json_get(body, "customer_details.name") }
if str_eq(customer_name, "") { let customer_name = json_get(body, "billing_details.name") }
let customer_id: String = json_get(body, "customer")
let customer_id: String = json_get(body, "data.object.customer")
if str_eq(customer_id, "") { let customer_id = json_get(body, "customer") }
// Plan inference from metadata
let plan: String = "free"