// ToolkitBuyForm.jsx — Verigo Global: toolkit purchase inquiry (same pattern as Contact.jsx)
// Replaces the old per-framework custom-quote/PDF builders. No payment is taken here —
// this captures the inquiry into Supabase and triggers the same admin notification email
// as the main Contact form.
const { V: BV, MAXW: BMW, FONT: BFT } = window;
const TIER_OPTIONS = ['Starter', 'Professional', 'Enterprise', 'Not sure yet'];
const TIER_FROM_PARAM = { starter: 'Starter', professional: 'Professional', enterprise: 'Enterprise' };
// Display prices only — the amount actually charged is always resolved
// server-side from server/pricing.js, never trusted from the browser. Keep in
// sync by hand with server/pricing.js and pages/toolkit-*-data.jsx.
const TOOLKIT_PRICING = {
iso27001: { starter: 1495, professional: 4950 },
iso42001: { starter: 1595, professional: 5250 },
cmmc: { starter: 1495, professional: 4950 },
cmmi: { starter: 1495, professional: 4950 },
hitrust: { starter: 1495, professional: 4950 },
nist: { starter: 1495, professional: 4950 },
soc2: { starter: 1495, professional: 4950 },
};
const BuyNowCard = ({ tierKey, tierLabel, price, itemKey, tagline }) => {
const [open, setOpen] = React.useState(false);
const [buyer, setBuyer] = React.useState({ name: '', email: '', company: '' });
const [done, setDone] = React.useState(false);
const ready = buyer.name.trim().length > 1 && /\S+@\S+\.\S+/.test(buyer.email);
const cardStyle = { border: `1.5px solid ${BV.g200}`, borderRadius: 12, padding: '16px 18px', background: '#fff' };
const miniInput = { fontFamily: BFT, fontSize: 13.5, color: BV.black, background: '#fff', border: `1.5px solid ${BV.g200}`, borderRadius: 7, padding: '9px 12px', outline: 'none', width: '100%', boxSizing: 'border-box' };
if (done) {
return (
Payment received for the {tierLabel} package — a confirmation and access details are on their way to your email.
);
}
return (
);
};
const ToolkitBuyForm = ({ framework, standardId, onNav }) => {
const initialTier = (() => {
try {
const tierParam = new URLSearchParams(window.location.search).get('tier');
return TIER_FROM_PARAM[tierParam] || 'Not sure yet';
} catch (e) { return 'Not sure yet'; }
})();
const [form, setForm] = React.useState({ name: '', email: '', company: '', phone: '', tier: initialTier, message: '' });
const [sent, setSent] = React.useState(false);
const [submitting, setSubmitting] = React.useState(false);
const [err, setErr] = React.useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
if (submitting) return;
setSubmitting(true);
setErr(false);
const { error } = await window.submitInquiry({
form_type: 'toolkit-purchase',
name: form.name, email: form.email, company: form.company, phone: form.phone,
framework,
service_interest: 'Implementation Toolkits',
message: form.message,
metadata: { tier: form.tier },
});
setSubmitting(false);
if (error) { setErr(true); return; }
setSent(true);
window.scrollTo({ top: 0, behavior: 'smooth' });
};
const input = { fontFamily: BFT, fontSize: 14, color: BV.black, background: '#fff', border: `1.5px solid ${BV.g200}`, borderRadius: 8, padding: '11px 14px', outline: 'none', width: '100%' };
const label = { fontSize: 12.5, fontWeight: 600, color: BV.black, display: 'block', marginBottom: 7 };
const selectStyle = { ...input, appearance: 'none', backgroundImage: "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239A9AAA' stroke-width='2.5'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\")", backgroundRepeat: 'no-repeat', backgroundPosition: 'right 12px center', paddingRight: 32, cursor: 'pointer' };
if (sent) return (
We'll be in touch.
Thank you for your interest in the {framework} Toolkit. A senior Verigo practitioner will reach out within one business day with pricing and next steps.
onNav('toolkit:' + standardId)}>Back to the {framework} Toolkit
);
return (
{framework} Toolkit
Get the {framework} Toolkit.
Tell us a little about your organization and which package you're interested in — a senior practitioner will follow up with pricing, scope, and next steps.
{[
['clipboard', '1. Tell us what you need', 'Package interest, company size, and timeline.'],
['search', '2. We scope it', 'A practitioner reviews your scope and confirms fixed pricing.'],
['shield', '3. Get to work', 'Editable policies, procedures, and control templates — plus support if you want it.'],
].map(([icon, t, d]) => (
))}
{TOOLKIT_PRICING[standardId] && (
Ready now? Buy instantly.
)}
);
};
Object.assign(window, { ToolkitBuyForm });