Finance

AssemblyNotice

A general assembly notice: date and time, the venue or online link, the quorum, a numbered agenda and an RSVP form.

#finance#coop#forms#event#no-js

Demo

Preview

Bayanihan Multi-Purpose Cooperative

Notice of meeting

38th Annual General Assembly

When
9:00 AM to 1:00 PM · registration from 7:30 AM
Where
Municipal GymnasiumRizal Avenue, Poblacion, San Isidroor Join online (opens in a new tab)
Quorum
25% of the 4,812 regular members in good standing (1,203 members)

Agenda

  1. Call to order and invocation
  2. Determination of quorum
  3. Approval of the minutes of the 37th General Assembly
  4. Reports of the Board, the Treasurer and the committeesThe audited financial statements for 2025
  5. Allocation of net surplusDividend on share capital and patronage refund
  6. Election of directorsThree seats on the Board, two on the Audit Committee
  7. Other matters
  8. Adjournment

Only regular members in good standing may vote. Bring your member ID; members joining online vote through the link sent by text message.

Ma. Cristina OcampoBoard Secretary

Will you attend?

Please answer by .

Attendance

Get it

It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.

$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/assembly_notice.qwe
main.qwe
import ui/theme.qwe use theme_cssuse ui/assembly_notice.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>

Example

The code of the preview above.

demos/assembly_notice.qwe
view AssemblyNoticeDemo() =    <AssemblyNotice id="assembly-notice-demo" coop="Bayanihan Multi-Purpose Cooperative" title="38th Annual General Assembly"                    date="2026-03-14" time="9:00 AM to 1:00 PM · registration from 7:30 AM" venue="Municipal Gymnasium"                    address="Rizal Avenue, Poblacion, San Isidro" online="https://meet.example.org/bmpc-aga-2026"                    quorum="25% of the 4,812 regular members in good standing (1,203 members)"                    agenda={[                        "Call to order and invocation",                        "Determination of quorum",                        "Approval of the minutes of the 37th General Assembly",                        { title: "Reports of the Board, the Treasurer and the committees", detail: "The audited financial statements for 2025" },                        { title: "Allocation of net surplus", detail: "Dividend on share capital and patronage refund" },                        { title: "Election of directors", detail: "Three seats on the Board, two on the Audit Committee" },                        "Other matters",                        "Adjournment",                    ]}                    text="Only regular members in good standing may vote. Bring your member ID; members joining online vote through the link sent by text message."                    by={{ name: "Ma. Cristina Ocampo", role: "Board Secretary" }} issued="2026-02-12"                    action="#assembly-rsvp" rsvp_by="2026-03-06" hidden={{ assembly: "aga-2026" }}                    member={{ number: "M-004217", name: "Lourdes Villanueva" }}/>

Source

ui/assembly_notice.qwe
// AssemblyNotice: the notice of a co-op's or credit union's general assembly:// when and where (a hall, an online link, or both), the quorum it needs, the// agenda as a numbered list, who gives notice, and a form to say whether the member// will come. The form is a plain <form method="post">: member_number, name,// attendance ("in_person", "online" or "absent") and question, with any `hidden`// fields.////   <AssemblyNotice coop="Bayanihan Multi-Purpose Cooperative" title="38th Annual General Assembly"//                   date="2026-03-14" time="9:00 AM to 1:00 PM" venue="Municipal Gymnasium, Poblacion"//                   online="https://meet.example.org/bmpc-aga" quorum="25% of the 4,812 regular members in good standing"//                   agenda={["Call to order", "Determination of quorum", { title: "Election of directors", detail: "Three seats" }]}//                   action="/assembly/2026/rsvp" rsvp_by="2026-03-06" hidden={{ assembly: "aga-2026" }}/>//// title: what meets ("Annual General Assembly"). coop: the co-op's name above it.// kind: a word above the title ("Notice of meeting"). date: an ISO date, shown in// full ("Saturday, March 14, 2026"); time: as text ("9:00 AM", "9:00 AM to// 1:00 PM"). venue: where, as text; address: a line under it. online: a link to// join online (online_label, "Join online"); with it the form offers attending// online. quorum: the quorum, as text. agenda: the items in order, each text or// { title, detail? }. text: a paragraph under the agenda (who may vote, what to// bring). by: who gives the notice, { name, role } ("Board Secretary"); issued:// the notice's date. action: where the RSVP posts ("/rsvp"); rsvp_by: the date to// answer by; hidden: other fields to send, as { name: value }; rsvp: false leaves// the form out. member: a member to fill in, { number, name }. id: a prefix for its// ids, unique on the page ("assembly-notice").import ui/theme.qwe use ui_clslet assembly_notice_css = css`.ui-assembly-notice { display: grid; gap: 20px; min-width: 0; max-width: 720px; padding: 26px 28px; border: 1px solid var(--ui-border);  border-radius: var(--ui-radius); background: var(--ui-surface); color: var(--ui-fg); font: 14px/1.5 var(--ui-font); }.ui-assembly-notice-head { display: grid; gap: 4px; text-align: center; padding-bottom: 16px; border-bottom: 1px solid var(--ui-border); }.ui-assembly-notice-coop { margin: 0; color: var(--ui-muted); font-size: 12px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }.ui-assembly-notice-kind { margin: 0; color: var(--ui-accent); font-size: 13px; font-weight: 600; }.ui-assembly-notice .ui-assembly-notice-title { display: block; margin: 0; font-size: 22px; font-weight: 700; line-height: 1.2; letter-spacing: -.01em; }.ui-assembly-notice-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; margin: 0; }.ui-assembly-notice-facts div { display: grid; gap: 2px; align-content: start; min-width: 0; padding: 12px 14px; border-radius: var(--ui-radius-sm); background: var(--ui-subtle); }.ui-assembly-notice-facts dt { color: var(--ui-muted); font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }.ui-assembly-notice-facts dd { margin: 0; font-weight: 600; overflow-wrap: anywhere; }.ui-assembly-notice-facts .ui-assembly-notice-sub { display: block; color: var(--ui-muted); font-weight: 400; font-size: 13px; }.ui-assembly-notice-facts a { color: var(--ui-accent); font-weight: 600; }.ui-assembly-notice-facts a:focus-visible { outline: none; box-shadow: var(--ui-focus); border-radius: 3px; }.ui-assembly-notice h4 { margin: 0 0 8px; font-size: 13px; font-weight: 650; letter-spacing: .04em; text-transform: uppercase; color: var(--ui-muted); }.ui-assembly-notice-agenda { margin: 0; padding-left: 26px; display: grid; gap: 6px; }.ui-assembly-notice-agenda li { padding-left: 4px; }.ui-assembly-notice-agenda li::marker { color: var(--ui-muted); font-weight: 600; font-variant-numeric: tabular-nums; }.ui-assembly-notice-detail { display: block; color: var(--ui-muted); font-size: 13px; }.ui-assembly-notice-text { margin: 0; color: var(--ui-muted); }.ui-assembly-notice-by { margin: 0; display: grid; gap: 0; }.ui-assembly-notice-by b { font-weight: 600; }.ui-assembly-notice-by span { color: var(--ui-muted); font-size: 13px; }.ui-assembly-notice-rsvp { display: grid; gap: 14px; padding: 18px; border: 1px solid var(--ui-border); border-radius: var(--ui-radius-sm); }.ui-assembly-notice-rsvp h4 { margin: 0; }.ui-assembly-notice-due { margin: -8px 0 0; color: var(--ui-muted); font-size: 13px; }.ui-assembly-notice-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: 12px; }.ui-assembly-notice-field { display: grid; gap: 5px; min-width: 0; }.ui-assembly-notice-field label, .ui-assembly-notice-choice legend { font-size: 13px; font-weight: 500; }.ui-assembly-notice-req { margin-left: 2px; color: var(--ui-danger); }.ui-assembly-notice-input { box-sizing: border-box; width: 100%; height: 38px; margin: 0; padding: 0 12px; border: 1px solid var(--ui-border);  border-radius: var(--ui-radius-sm); background: var(--ui-surface); color: var(--ui-fg); font: 14px/1.5 var(--ui-font); }textarea.ui-assembly-notice-input { height: auto; padding: 8px 12px; resize: vertical; }.ui-assembly-notice-input:hover { border-color: var(--ui-strong); }.ui-assembly-notice-input:focus { outline: none; border-color: var(--ui-accent); box-shadow: var(--ui-focus); }.ui-assembly-notice-choice { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 0; padding: 0; border: 0; min-width: 0; }.ui-assembly-notice-choice legend { width: 100%; margin-bottom: 6px; padding: 0; }.ui-assembly-notice-choice label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }.ui-assembly-notice-choice input { margin: 0; accent-color: var(--ui-accent); }.ui-assembly-notice-send { justify-self: start; height: 40px; padding: 0 20px; border: 0; border-radius: var(--ui-radius-sm); background: var(--ui-accent);  color: var(--ui-accent-fg); font: 600 14px var(--ui-font); cursor: pointer; }.ui-assembly-notice-send:hover { filter: brightness(1.08); }.ui-assembly-notice-send:focus-visible { outline: none; box-shadow: var(--ui-focus); }@media (max-width: 560px) { .ui-assembly-notice { padding: 20px 16px; } .ui-assembly-notice-row { grid-template-columns: 1fr; } }@media print { .ui-assembly-notice { border: 0; padding: 0; background: #fff; color: #000; } .ui-assembly-notice-rsvp { display: none; } }`// An ISO date in full ("Saturday, March 14, 2026"), or long ("March 14, 2026"); other text as it is.fn assembly_notice_date(d, style: str = "full") -> str =    date.valid(str(d), "date") ? date.format(str(d), { locale: "en-US", style }) : str(d)view AssemblyNotice(title: str = "Annual General Assembly", coop: str? = null, kind: str? = "Notice of meeting", date = null,                    time: str? = null, venue: str? = null, address: str? = null, online: str? = null, online_label: str = "Join online",                    quorum: str? = null, agenda: list = [], text: str? = null, by: map? = null, issued = null,                    action: str = "/rsvp", rsvp_by = null, hidden: map = {}, rsvp: bool = true, member: map? = null,                    id: str = "assembly-notice", class: str? = null) {    style global assembly_notice_css    <article class={ui_cls(["ui-assembly-notice", class])} aria-labelledby={`${id}-title`}>        <header.ui-assembly-notice-head>            {coop != null && <p.ui-assembly-notice-coop>{coop}</p>}            {kind != null && <p.ui-assembly-notice-kind>{kind}</p>}            <h3.ui-assembly-notice-title id={`${id}-title`}>{title}</h3>        </header>        <dl.ui-assembly-notice-facts>            {date != null && <div.ui-assembly-notice-when>                <dt>When</dt>                <dd><time datetime={str(date)}>{assembly_notice_date(date)}</time>{time != null && <span.ui-assembly-notice-sub>{time}</span>}</dd>            </div>}            {(venue != null || online != null) && <div.ui-assembly-notice-where>                <dt>Where</dt>                <dd>                    {venue != null && venue}                    {address != null && <span.ui-assembly-notice-sub>{address}</span>}                    {online != null && <span class={venue != null ? "ui-assembly-notice-sub" : null}>                        {venue != null && "or "}<a href={online} target="_blank" rel="noopener">{online_label}<span.ui-sr> (opens in a new tab)</span></a>                    </span>}                </dd>            </div>}            {quorum != null && <div.ui-assembly-notice-quorum><dt>Quorum</dt><dd>{quorum}</dd></div>}        </dl>        {len(agenda) > 0 && <section aria-labelledby={`${id}-agenda`}>            <h4 id={`${id}-agenda`}>Agenda</h4>            <ol.ui-assembly-notice-agenda>                {for [i, a] in enumerate(agenda) => <li key={i}>                    {type_of(a) == "map" ? [a.title, a.detail != null && <span.ui-assembly-notice-detail>{a.detail}</span>] : a}                </li>}            </ol>        </section>}        {text != null && <p.ui-assembly-notice-text>{text}</p>}        {by != null && <p.ui-assembly-notice-by>            <b>{by.name}</b>            {by.role != null && <span>{by.role}</span>}            {issued != null && <span><time datetime={str(issued)}>{assembly_notice_date(issued, "long")}</time></span>}        </p>}        {rsvp && <form.ui-assembly-notice-rsvp method="post" action={action} aria-labelledby={`${id}-rsvp`}>            {for k in keys(hidden) => <input type="hidden" name={k} value={str(hidden[k])}/>}            <h4 id={`${id}-rsvp`}>Will you attend?</h4>            {rsvp_by != null && <p.ui-assembly-notice-due>Please answer by <time datetime={str(rsvp_by)}>{assembly_notice_date(rsvp_by, "long")}</time>.</p>}            <div.ui-assembly-notice-row>                <div.ui-assembly-notice-field>                    <label for={`${id}-number`}>Member number<span.ui-assembly-notice-req aria-hidden="true">*</span></label>                    <input.ui-assembly-notice-input id={`${id}-number`} name="member_number" required={true} autocomplete="off"                           value={member != null ? member.number : null}/>                </div>                <div.ui-assembly-notice-field>                    <label for={`${id}-name`}>Name<span.ui-assembly-notice-req aria-hidden="true">*</span></label>                    <input.ui-assembly-notice-input id={`${id}-name`} name="name" required={true} autocomplete="name"                           value={member != null ? member.name : null}/>                </div>            </div>            <fieldset.ui-assembly-notice-choice>                <legend>Attendance<span.ui-assembly-notice-req aria-hidden="true">*</span></legend>                <label><input type="radio" name="attendance" value="in_person" required={true}/> In person</label>                {online != null && <label><input type="radio" name="attendance" value="online"/> Online</label>}                <label><input type="radio" name="attendance" value="absent"/> I cannot attend</label>            </fieldset>            <div.ui-assembly-notice-field>                <label for={`${id}-question`}>A question for the board (optional)</label>                <textarea.ui-assembly-notice-input id={`${id}-question`} name="question" rows="2"></textarea>            </div>            <button.ui-assembly-notice-send type="submit">Send my answer</button>        </form>}    </article>}
Thread
66Useful? Like it, or add to its thread below.

Thread 0 posts

On AssemblyNotice: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.