The Future Paralegals of America A NJ Non-Profit Corporation

LEGALITY OS™
2.0

2026 – 2027

EXECUTIVE ACCESS

Authorized nonprofit operations portal. Enter your badge access code, then sign in with your organization Microsoft account.

LEGALITY OS™ 4.9 · v19 · Authorized access only. Activity is logged. This workspace supports nonprofit operations and does not provide legal advice or guarantee eligibility.

+Number(c.income).toLocaleString()+' '+esc((c.freq||'').toLowerCase())}
Benefits
${esc(c.benefits.join(", ")||"—")}

Accessibility & documents

Accommodations
${esc(c.access.join(", ")||"None noted")}
Documents
${esc(c.docs.join(", ")||"None received")}
Opposing parties
${esc(c.adverse.join(", ")||"None")}

Cases

${caseRows(casesOf(c))}
${docsSection(c)}
`); bindDocInputs(); if(!state.spDocs[c.id]) loadDocs(c); } /* -------------------------- events --------------------------- */ document.addEventListener("click", e=>{ const t=e.target.closest("[data-open-case],[data-open-client],[data-close],[data-verif],[data-hub-verif],[data-select-verif],[data-reissue-ver],[data-log-photoid],[data-send-remote],#verifLookupBtn,[data-save-case],[data-reveal],[data-hide],[data-hub],[data-tile],[data-copy],[data-welcome],[data-upload-docs],[data-refresh-docs],[data-inc-import],[data-inc-move],[data-scout-q],#liveRetry,#liveReload,#healthCheck,#scoutGo,#scoutCsv,#scoutCopy,#incRefresh,#anotherIntake,#stampPdf,#origPdf,#spAll,#spSave,#spTest"); if(!t) return; if(t.dataset.openCase){ caseDrawer(t.dataset.openCase); return; } if(t.dataset.openClient){ clientDrawer(t.dataset.openClient); return; } if(t.hasAttribute("data-close")) return closeDrawer(); if(t.dataset.verif){ const k=state.cases.find(x=>x.id===t.dataset.case); if(t.dataset.verif==="Verified" && !clientOf(k).docs.includes("Photo ID")){ toast("Record a photo ID in the Verification Hub before verifying"); return; } if(k.verif!==t.dataset.verif){ k.verif=t.dataset.verif; log("Verification set to "+k.verif, k.number); toast("Verification: "+k.verif); } caseDrawer(k.id); route(); return; } if(t.dataset.hubVerif){ const k=state.cases.find(x=>x.id===t.dataset.case); if(!k) return; const c=clientOf(k); if(t.dataset.hubVerif==="Verified"){ if(!$("#chkToken")?.checked){ toast("Confirm the caller read back their verification code first"); return; } if(!c.docs.includes("Photo ID")){ toast("Record a government photo ID before verifying"); return; } } const extra = t.dataset.hubVerif==="Verified" && $("#chkDob")?.checked ? " (code + photo ID + DOB)" : t.dataset.hubVerif==="Verified" ? " (code + photo ID)" : ""; k.verif=t.dataset.hubVerif; log("Verification Hub set status to "+k.verif+extra, k.number); toast("Client verification: "+k.verif); route(); return; } if(t.dataset.sendRemote){ sendRemote(t.dataset.sendRemote); return; } if(t.dataset.selectVerif){ state.activeVerifClient = t.dataset.selectVerif; route(); return; } if(t.dataset.reissueVer){ const c=state.clients.find(x=>x.id===t.dataset.reissueVer); if(!c) return; if(!confirm(`Re-issue the verification number for ${fullName(c)}? The current code stops working.`)) return; const oldVer = c.ver; c.ver = `VER-${rand(4)}-${rand(4)}`; casesOf(c).forEach(k=>{ if(k.verif==="Verified"){ k.verif="Pending"; log("Verification reset to Pending after token re-issue", k.number); } }); if(state.remote[c.id]){ delete state.remote[c.id]; log("Remote verification link withdrawn after token re-issue", c.number); } log(`Re-issued verification number (${oldVer} → ${c.ver})`, c.number); toast("New token issued: "+c.ver); route(); return; } if(t.dataset.logPhotoid){ const c=state.clients.find(x=>x.id===t.dataset.logPhotoid); if(c && !c.docs.includes("Photo ID")){ c.docs.push("Photo ID"); casesOf(c).forEach(k=>{ if(k.verif==="Needs documents") k.verif="Pending"; }); log("Government photo ID recorded", c.number); toast("Photo ID recorded for "+fullName(c)); route(); } return; } if(t.id==="verifLookupBtn"){ const raw = $("#verifLookupInput")?.value || ""; const q = raw.trim().toLowerCase(); state.verifQuery = raw; if(!q){ toast("Enter a VER code, client number, or name"); return; } const exact = state.clients.find(c=>c.ver.toLowerCase()===q || c.number.toLowerCase()===q); const found = exact || state.clients.find(c=>[c.ver, c.number, fullName(c), c.phone].join(" ").toLowerCase().includes(q)); if(found){ state.activeVerifClient = found.id; log("Loaded client in Verification Hub", found.number); route(); toast("Loaded "+fullName(found)); } else { toast("No client matched “"+raw+"”"); } return; } if(t.dataset.saveCase){ const k=state.cases.find(x=>x.id===t.dataset.saveCase); const a=$("#asg").value, s=$("#sts").value; let ns=s; if(a && a!==k.assignee && s==="New") ns="Assigned"; if(a!==k.assignee){ k.assignee=a; log(a?"Assigned to "+staffName(a):"Assignment removed", k.number); } if(ns!==k.status){ k.status=ns; log("Status set to "+ns, k.number); } toast("Case saved"); caseDrawer(k.id); route(); return; } if(t.dataset.reveal){ if(!canImmig()) return; const c=state.clients.find(x=>x.id===t.dataset.reveal); state.revealed.add(c.id); log("Viewed restricted identity fields", c.number); if(!$("#drawer").hidden) refreshDrawer(); else route(); return; } if(t.dataset.hide){ state.revealed.delete(t.dataset.hide); if(!$("#drawer").hidden) refreshDrawer(); else route(); return; } if(t.dataset.hub){ state.hub=t.dataset.hub; route(); return; } if(t.dataset.tile!==undefined){ if(state.hub==="VER"){ location.hash="verification"; return; } if(state.hub==="GRA" && +t.dataset.tile===0){ location.hash="scout"; return; } const [ti,d]=HUBS[state.hub].tiles[+t.dataset.tile]; if(HUBS[state.hub].youth && /under 18/.test(ti)){ openDrawer(`
${state.hub} hub · under 18

${esc(ti)}

${esc(d)}

Governing order
${YOUTH_ORDER.number?`${esc(eoLabel())}`:"Not set"}
Title
${esc(YOUTH_ORDER.title||"—")}
Age scope
Children under 18

Program records will read from SharePoint once the ${esc(HUBS[state.hub].name)} lists are registered.

`); return; } openDrawer(`
${state.hub} hub · preview

${esc(ti)}

${esc(d)}

This workspace is a preview. It will read from SharePoint once the ${esc(HUBS[state.hub].name)} lists are registered.

`); return; } if(t.dataset.copy){ navigator.clipboard?.writeText(t.dataset.copy).then(()=>toast("Copied "+t.dataset.copy),()=>toast("Copy blocked — select the number instead")); return; } if(t.id==="anotherIntake"){ state.lastIssued=null; route(); return; } if(t.id==="stampPdf"){ downloadFilingCopy(); return; } if(t.id==="origPdf"){ downloadOriginalSigned(); return; } if(t.dataset.welcome){ downloadWelcomeLetter(t.dataset.welcome); return; } if(t.dataset.uploadDocs){ uploadDocs(t.dataset.uploadDocs); return; } if(t.dataset.refreshDocs){ const c=state.clients.find(x=>x.id===t.dataset.refreshDocs); state.spDocs[c.id]=null; $("#docsSec").outerHTML=docsSection(c); bindDocInputs(); loadDocs(c); return; } if(t.id==="spAll"){ saveAllToSharePoint(); return; } if(t.id==="liveRetry" || t.id==="liveReload"){ siteCache=null; liveLoad(); return; } if(t.id==="healthCheck"){const out=$('#healthOut');out.textContent='Checking…';api('integrations/validate').then(r=>{out.textContent=r.checks.map(c=>c.name+': '+c.status+(c.detail?' — '+c.detail:'')).join(' · ');}).catch(e=>out.textContent=e.message);return;} if(t.dataset.scoutQ){ scoutSearch(t.dataset.scoutQ); return; } if(t.id==="scoutGo"){ scoutSearch(($("#scoutQ")?.value||"").trim()); return; } if(t.id==="scoutCsv"){ const csv = scoutTotals().map(r=>r.map(v=>`"${String(v).replace(/"/g,'""')}"`).join(",")).join("\n"); const a=document.createElement("a"); a.href=URL.createObjectURL(new Blob([csv],{type:"text/csv"})); a.download=`FPOA_poverty_scout_totals_${new Date().toISOString().slice(0,10)}.csv`; document.body.appendChild(a); a.click(); a.remove(); log("Poverty Scout totals exported (no client names)","SCOUT"); return; } if(t.id==="scoutCopy"){ const T=Object.fromEntries(scoutTotals()); const txt = `In the current period, The Future Paralegals of America A NJ Non-Profit Corporation screened ${T["Clients screened"]} clients across ${STATES.join(", ")}. ${T["At or below 125%"]} had household incomes at or below 125% of the 2026 HHS poverty guidelines and ${T["At or below 200%"]} at or below 200%. ${T["Youth under 18"]} were under 18, ${T["Seniors 60+"]} were 60 or older, and ${T["Rural service area"]} lived in rural service areas. (Source: ${FPG_2026.source}.)`; navigator.clipboard?.writeText(txt).then(()=>toast("Impact summary copied"),()=>toast("Copy blocked")); return; } if(t.id==="incRefresh"){ uploadService = null; state.incoming = {...(state.incoming||{}), at:null}; route(); return; } if(t.dataset.incImport){ importIncoming(t.dataset.incImport, t.dataset.incFile); return; } if(t.dataset.incMove){ const c = state.clients.find(x=>x.id===t.dataset.incClient); t.disabled = true; moveIncomingTo(c, t.dataset.incMove).then(n=>{ log(`Filed ${n} uploaded file${n===1?"":"s"} to client folder`, c.number); toast(`Moved ${n} file${n===1?"":"s"} to ${clientFolder(c)}`); state.incoming=null; route(); }).catch(e=>{ t.disabled=false; toast("SharePoint: "+e.message); }); return; } if(t.id==='spSave'){const out=$('#spMsg');out.textContent='Checking server destination…';api('integrations/config').then(c=>{const u=$('#spurl').value.trim().replace(/\/+$/,''),lib=$('#splib').value.trim();if(u.toLowerCase()!==c.sharepoint.siteUrl.replace(/\/+$/,'').toLowerCase()||lib!==c.sharepoint.library)throw new Error('This differs from the server upload destination. Update the Azure settings through your approved process, then sign in again.');state.sp={url:u,lib,registered:true};spCache=null;siteCache=null;store('los.spurl',u);store('los.splib',lib);out.textContent='Browser and server destinations match.';}).catch(e=>out.textContent=e.message);return;} if(t.id==="spTest"){ $("#spMsg").textContent="Testing…"; $("#spMsg").style.color=""; spTarget().then(x=>{ $("#spMsg").textContent=`Connected: ${x.libName} on ${state.sp.url}`; $("#spMsg").style.color="var(--ok)"; }).catch(e=>{ $("#spMsg").textContent=e.message; $("#spMsg").style.color="var(--danger)"; }); return; } }); function refreshDrawer(){ const h=$("#drawer .dr-h .mono")?.textContent||""; const k=state.cases.find(x=>x.number===h); if(k) return caseDrawer(k.id); const c=state.clients.find(x=>x.number===h); if(c) clientDrawer(c.id); } document.addEventListener("keydown", e=>{ if(e.key==="Escape" && !$("#drawer").hidden) closeDrawer(); if(e.key==="Enter" && e.target.matches("tr[data-open-case],tr[data-open-client],tr[data-select-verif]")) e.target.click(); if(e.key==="Enter" && e.target.id==="verifLookupInput"){ e.preventDefault(); $("#verifLookupBtn")?.click(); } }); document.addEventListener("change", e=>{ if(e.target.matches("#fs,#fv,#fa")) filterCases(); if(e.target.matches("[data-tag]")){ const c = state.clients.find(x=>x.id===e.target.dataset.cid); if(!c) return; if(e.target.dataset.tag==="survivor" && !canImmig()) return; c.tags = c.tags || {}; c.tags[e.target.dataset.tag] = e.target.checked; log(`Poverty Scout tag ${e.target.dataset.tag} ${e.target.checked?"added":"removed"}`, c.number); rerenderIf("scout"); } }); document.addEventListener("keydown", e=>{ if(e.key==="Enter" && e.target.id==="scoutQ"){ e.preventDefault(); scoutSearch(e.target.value.trim()); } }); $("#scrim").addEventListener("click", closeDrawer); $("#searchForm").addEventListener("submit", e=>{ e.preventDefault(); const q=$("#q").value.trim(); if(!q) return; state.q=q; if(location.hash==="#search") route(); else location.hash="search"; }); window.addEventListener("hashchange", route); $("#msSignIn").addEventListener("click", msSignIn); $("#badge").addEventListener("keydown", e=>{ if(e.key==="Enter"){ e.preventDefault(); msSignIn(); } }); $("#signOut").addEventListener("click", signOut); function paintThemeToggle(){ const cur = document.documentElement.dataset.theme || "dark"; document.querySelectorAll(".themeToggle").forEach(b=>{ b.textContent = cur==="dark" ? "☀ Light mode" : "☾ Dark mode"; b.setAttribute("aria-pressed", String(cur==="light")); b.setAttribute("aria-label", cur==="dark" ? "Switch to light mode" : "Switch to dark mode"); }); } document.querySelectorAll(".themeToggle").forEach(b=>b.addEventListener("click", ()=>{ const cur = document.documentElement.dataset.theme || "dark"; const next = cur==="dark" ? "light" : "dark"; document.documentElement.dataset.theme = next; store("los.theme", next); paintThemeToggle(); })); (function init(){ const th=store("los.theme") || "dark"; document.documentElement.dataset.theme=th; paintThemeToggle(); setDataState(); state.live = {status:"off"}; })();