PageSourceSearch

https://slytherin.ai/js/forms.js

js slytherin.ai collected 2026-10-05 12:38:32 UTC 2,653 bytes, 67 lines download raw bytes

1// ─────────────────────────────────────────────
2// Slytherin · Form submission
3// POST cross-origin to mc.slytherin.ai/api/website-leads
4// ─────────────────────────────────────────────
5
6const ENDPOINT = 'https://mc.slytherin.ai/api/website-leads';
7
8async function submitForm(form, kind) {
9  const msgEl = form.querySelector('[data-msg]');
10  const submitBtn = form.querySelector('button[type=submit]');
11  msgEl.className = 'form-msg';
12  msgEl.textContent = '';
13
14  const data = Object.fromEntries(new FormData(form));
15  if (!data.email || !data.name) {
16    msgEl.className = 'form-msg error';
17    msgEl.textContent = 'Name and email are required.';
18    return;
19  }
20  data.kind = kind;
21  data.page = location.pathname;
22  data.source = 'slytherin.ai-homepage';
23  data.submittedAt = new Date().toISOString();
24
25  submitBtn.disabled = true;
26  const originalLabel = submitBtn.innerHTML;
27  submitBtn.innerHTML = 'Sending…';
28
29  try {
30    const res = await fetch(ENDPOINT, {
31      method: 'POST',
32      headers: { 'Content-Type': 'application/json' },
33      body: JSON.stringify(data),
34    });
35    const out = await res.json().catch(() => ({}));
36    if (res.ok && out.success !== false) {
37      msgEl.className = 'form-msg success';
38      msgEl.textContent = kind === 'schedule'
39        ? "Got it — we'll confirm your time by email shortly."
40        : "Thank you. We'll be in touch within one business day.";
41      form.reset();
42    } else {
43      throw new Error(out.error || 'Submission failed');
44    }
45  } catch (err) {
46    msgEl.className = 'form-msg error';
47    msgEl.textContent = 'Something went wrong. Email us directly at [email protected].';
48  } finally {
49    submitBtn.disabled = false;
50    submitBtn.innerHTML = originalLabel;
51  }
52}
53
54export function initForms() {
55  document.querySelectorAll('.form-tab').forEach((tab) => {
56    tab.addEventListener('click', () => {
57      const pane = tab.dataset.pane;
58      document.querySelectorAll('.form-tab').forEach(t => t.classList.toggle('active', t === tab));
59      document.querySelectorAll('.form-pane').forEach(p => p.classList.toggle('active', p.dataset.pane === pane));
60    });
61  });
62
63  const lead = document.getElementById('leadForm');
64  const sched = document.getElementById('scheduleForm');
65  if (lead) lead.addEventListener('submit', (e) => { e.preventDefault(); submitForm(e.target, 'lead'); });
66  if (sched) sched.addEventListener('submit', (e) => { e.preventDefault(); submitForm(e.target, 'schedule'); });
67}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.