diff --git a/components/Footer.js b/components/Footer.js index dffa64c..01f3920 100644 --- a/components/Footer.js +++ b/components/Footer.js @@ -171,6 +171,7 @@ const CONNECT_COLUMN = [ BLOG_LINK, byLabel('Discord'), { label: 'GitHub', href: OPENADAPT_REPOSITORY_URL }, + { label: 'Contribute workflows', href: '/contribute' }, ] export default function Footer({ @@ -360,6 +361,11 @@ export default function Footer({
  • About
  • +
  • + + Partners & OEM + +
  • Hosted dashboard diff --git a/components/NavHeader.js b/components/NavHeader.js index bcdf752..6d6ad6e 100644 --- a/components/NavHeader.js +++ b/components/NavHeader.js @@ -26,6 +26,7 @@ const SOLUTIONS_LINKS = [ { label: 'Healthcare', href: '/solutions/healthcare' }, { label: 'Lending', href: '/solutions/lending' }, { label: 'Insurance', href: '/solutions/insurance' }, + { label: 'Partners & OEM', href: '/partners' }, ] const PRODUCT_LINKS = [ diff --git a/components/PartnerInquiryForm.js b/components/PartnerInquiryForm.js new file mode 100644 index 0000000..ea92b2d --- /dev/null +++ b/components/PartnerInquiryForm.js @@ -0,0 +1,251 @@ +import { useState } from 'react' +import Link from 'next/link' + +import { trackEmailCapture } from 'utils/conversion' + +// Dedicated intake for the partner program. +// +// Posts to the durable Netlify Forms lead path (`/form.html`) under its own +// form name, `partner-inquiry`, so partner leads land in their own Netlify +// submissions bucket instead of the generic `contact` queue. The hidden form +// definition lives in public/form.html; Netlify's build-time bots read it +// from there. The `track` selector mirrors the partner tracks on /partners. +// Lead data always travels in the POST body, never in a URL. + +export const PARTNER_TRACKS = [ + { value: 'vertical_oem', label: 'Vertical software / OEM' }, + { value: 'rcm_bpo', label: 'RCM or BPO operator' }, + { value: 'integration_services', label: 'Integration / services' }, + { value: 'msp_deployment', label: 'MSP / deployment' }, +] + +const INITIAL_FORM = { + name: '', + email: '', + company: '', + role: '', + track: '', + systems: '', + message: '', + botField: '', +} + +const fieldClass = + 'rounded-lg border border-ink/30 bg-panel px-3 py-2 text-ink placeholder-ink-3/60 focus:border-accent focus:outline-none' + +export default function PartnerInquiryForm() { + const [form, setForm] = useState(INITIAL_FORM) + const [isSubmitting, setIsSubmitting] = useState(false) + const [isSubmitted, setIsSubmitted] = useState(false) + const [error, setError] = useState('') + + const handleChange = (event) => { + const { name, value } = event.target + setForm((prev) => ({ ...prev, [name]: value })) + } + + const handleSubmit = async (event) => { + event.preventDefault() + setError('') + setIsSubmitting(true) + + try { + const formData = new URLSearchParams() + formData.set('form-name', 'partner-inquiry') + formData.set('name', form.name) + formData.set('email', form.email) + formData.set('company', form.company) + formData.set('role', form.role) + formData.set('track', form.track) + formData.set('systems', form.systems) + formData.set('message', form.message) + formData.set('bot-field', form.botField) + + const response = await fetch('/form.html', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: formData.toString(), + }) + + if (!response.ok) { + throw new Error( + `Form submission failed with status ${response.status}` + ) + } + + // Qualified-lead conversion: partner interest captured. Carries + // first-touch utm_* attribution; never any form contents. + trackEmailCapture({ location: 'partner_inquiry_form' }) + setIsSubmitted(true) + } catch (submitError) { + console.error(submitError) + setError( + 'Submission failed. Please email hello@openadapt.ai directly.' + ) + } finally { + setIsSubmitting(false) + } + } + + return ( +
    + {!isSubmitted ? ( +
    + +

    + +

    + +
    + + + + +
    + + + + + +