// Documents page with e-signature flow function DocumentsPage({ persona, employeeId, savedSignedIds }) { const [filter, setFilter] = React.useState("all"); const [openDoc, setOpenDoc] = React.useState(null); // Merge default signed docs with any saved from the database const defaultSigned = new Set(DOCS.filter(d => d.status === "signed").map(d => d.id)); const [signedIds, setSignedIds] = React.useState(() => { if (savedSignedIds && savedSignedIds.size > 0) { return new Set([...defaultSigned, ...savedSignedIds]); } return defaultSigned; }); // Sync if parent passes updated savedSignedIds (e.g. after API load) React.useEffect(() => { if (savedSignedIds && savedSignedIds.size > 0) { setSignedIds(new Set([...defaultSigned, ...savedSignedIds])); } }, [savedSignedIds]); const filtered = DOCS.filter(d => { if (filter === "pending") return !signedIds.has(d.id); if (filter === "signed") return signedIds.has(d.id); return true; }); const handleSign = async (id) => { setSignedIds(prev => new Set([...prev, id])); if (employeeId && window.onboardingAPI) { try { await window.onboardingAPI.apiSignDoc(employeeId, id); } catch (e) {} } }; const total = DOCS.length; const signed = signedIds.size; const pct = Math.round(signed / total * 100); return (
E-signature

Documents to sign

Government forms, employment paperwork, and policy acknowledgements. All signatures are legally binding under the U.S. ESIGN Act.

{signed} of {total}
documents signed
{pct}% complete · 2 due tomorrow · ~25 min remaining
256-bit encrypted · DocuSign
setFilter("all")}/> setFilter("pending")}/> setFilter("signed")}/>
{filtered.map(d => { const isSigned = signedIds.has(d.id); return ( ); })}
Document Category Pages Status / Due
isSigned ? null : setOpenDoc(d)}>
{d.title}
{d.priority === "high" && !isSigned &&
High priority
} {isSigned &&
Signed {d.signedOn}
}
{d.category} {d.pages} pages {isSigned ? Signed : Due {d.due}} {isSigned ? ( ) : ( )}
{openDoc && ( setOpenDoc(null)} onSign={(id) => { handleSign(id); setOpenDoc(null); }} /> )}
); } function FilterPill({ label, active, onClick }) { return ( ); } // ──────────────── Signature modal (e-sign flow) ──────────────── function SignModal({ doc, onClose, onSign }) { const [step, setStep] = React.useState(1); // 1=review, 2=sign, 3=confirm const [sigType, setSigType] = React.useState("typed"); const [typedSig, setTypedSig] = React.useState("Riley Park"); const [agreed, setAgreed] = React.useState(false); const [drawn, setDrawn] = React.useState(false); const canvasRef = React.useRef(null); React.useEffect(() => { if (sigType !== "drawn" || !canvasRef.current) return; const c = canvasRef.current; const ctx = c.getContext("2d"); let drawing = false; let last = null; const cssToPx = (e) => { const r = c.getBoundingClientRect(); const x = (e.clientX - r.left) * (c.width / r.width); const y = (e.clientY - r.top) * (c.height / r.height); return [x, y]; }; const start = (e) => { drawing = true; last = cssToPx(e); }; const move = (e) => { if (!drawing) return; const [x, y] = cssToPx(e); ctx.strokeStyle = getComputedStyle(document.documentElement).getPropertyValue("--text").trim(); ctx.lineWidth = 2.5; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.beginPath(); ctx.moveTo(last[0], last[1]); ctx.lineTo(x, y); ctx.stroke(); last = [x, y]; setDrawn(true); }; const end = () => { drawing = false; }; c.addEventListener("pointerdown", start); c.addEventListener("pointermove", move); window.addEventListener("pointerup", end); return () => { c.removeEventListener("pointerdown", start); c.removeEventListener("pointermove", move); window.removeEventListener("pointerup", end); }; }, [sigType]); const clearCanvas = () => { const c = canvasRef.current; if (!c) return; c.getContext("2d").clearRect(0, 0, c.width, c.height); setDrawn(false); }; return (
e.stopPropagation()}>
{doc.category} · {doc.pages} pages

{doc.title}

= 1 ? "active" : "")}>1Review
= 2 ? "active" : "")}>2Sign
= 3 ? "active" : "")}>3Done
{step === 1 && } {step === 2 && (
Signature required on Page {doc.pages} Convoso, Inc. — {doc.title}

By signing below, I, {PROFILE.legalName}, acknowledge that I have read and understood the terms of this document and agree to be bound by them under the U.S. ESIGN Act.

Signed at {new Date().toLocaleString()} from IP 73.42.118.204

{sigType === "typed" && ( <> setTypedSig(e.target.value)} placeholder="Type your full legal name" />
{typedSig || "—"}
)} {sigType === "drawn" && (
Draw your signature with your mouse or touch
)} {sigType === "upload" && (
Drop a PNG or JPG of your signature
or click to browse · max 2 MB
)}
)} {step === 3 && (

Signed and submitted

A copy of {doc.title} has been emailed to {PROFILE.email}. People Ops has been notified.

Document IDDSGN-{doc.id.toUpperCase()}-9F2A
Signed by{PROFILE.legalName}
Timestamp{new Date().toLocaleString()}
StatusCompleted
)}
{step === 1 && ( <> Encrypted in transit and at rest )} {step === 2 && ( <> )} {step === 3 && ( <> )}
); } // fake document preview pane function DocPreview({ doc }) { return (
Page 1 of {doc.pages}
CONVOSO
6320 Canoga Ave · Woodland Hills, CA 91367
convoso.com

{doc.title}

Effective date: May 11, 2026 · Document ID DSGN-{doc.id.toUpperCase()}-9F2A

Employee: {PROFILE.legalName} ({PROFILE.email})

Position: Software Engineer, Platform — Voice Infrastructure

1. Purpose

This {doc.category.toLowerCase()} document outlines the terms and obligations of {PROFILE.legalName} (the "Employee") as they relate to Convoso, Inc. (the "Company"). By signing below, the Employee acknowledges that they have read this document in its entirety and agree to its terms.

2. Acknowledgement

The Employee confirms that all information provided herein is accurate to the best of their knowledge. The Employee further agrees to comply with all applicable Company policies, including but not limited to the Employee Handbook and Code of Conduct.

); } window.DocumentsPage = DocumentsPage;