// app-preview.jsx — MinutesPreview: formatted legal-style minutes document (function () { const { STATUSES } = window.MeetingData; const STATUS_LABEL = {}; STATUSES.forEach((s) => { STATUS_LABEL[s.key] = s.label; }); function fmtDate(iso) { if (!iso) return ""; const d = new Date(iso + "T00:00:00"); if (isNaN(d)) return iso; return d.toLocaleDateString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric" }); } function fmtDue(iso) { if (!iso) return ""; const d = new Date(iso + "T00:00:00"); if (isNaN(d)) return iso; return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" }); } function voteSentence(v) { const f = parseInt(v.for, 10) || 0; const a = parseInt(v.against, 10) || 0; const ab = parseInt(v.abstain, 10) || 0; if (!f && !a && !ab) return ""; let s = "The motion " + (f > a ? "carried" : "failed") + " by a vote of " + f + " in favor to " + a + " opposed"; if (ab) s += ", with " + ab + " abstaining"; return s + "."; } function MinutesPreview({ meta, items }) { const present = (meta.present || "").split(/[,\n]/).map((s) => s.trim()).filter(Boolean); const absent = (meta.absent || "").split(/[,\n]/).map((s) => s.trim()).filter(Boolean); return (
{meta.org || "Organization Name"}
Minutes of the {meta.kind || "Regular Meeting"} of the Board of Directors
{fmtDate(meta.date) || "Meeting date"} {meta.time ? " · " + meta.time : ""} {meta.location ? " · " + meta.location : ""}
Directors present {present.length ? present.join(", ") : "—"}
{absent.length > 0 && (
Absent {absent.join(", ")}
)}
Quorum {meta.quorum ? "A quorum was present." : "Not established."}
    {items.map((it) => { const vs = it.vote.recorded ? voteSentence(it.vote) : ""; const hasBody = (it.notes && it.notes.trim()) || vs || it.status || it.actions.length; const lvl = it.level || (it.isSub ? 1 : 0); return (
  1. {it.number && {it.number}.} {it.title} {it.presenter && {it.presenter}} {it.status && {STATUS_LABEL[it.status]}} {it.page && p. {it.page}}
    {hasBody && (
    {it.notes && it.notes.trim() && it.notes.trim().split(/\n+/).map((p, i) =>

    {p}

    )} {vs &&

    {vs}

    } {it.actions.length > 0 && (
    Action items
      {it.actions.map((a) => (
    • {a.text || "—"} {a.owner && — {a.owner}} {a.due && (by {fmtDue(a.due)})}
    • ))}
    )}
    )}
  2. ); })}
Secretary
Date approved
); } window.MinutesPreview = MinutesPreview; window.MinutesHelpers = { fmtDate, voteSentence }; })();