Bayanihan Multi-Purpose Cooperative
- Member no.
- M-004217
- Member since
- Share capital
- ₱18,500.00
A co-op or credit union member's card: photo or initials, name and number, member since, share capital and status.
Bayanihan Multi-Purpose Cooperative
Associate member
Status: dormantNo transaction since Jan 2025
Lakeshore Teachers Credit Union
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/member_card.qweimport ui/theme.qwe use theme_cssuse ui/member_card.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>The code of the preview above.
view MemberCardDemo() = <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px"> <MemberCard id="member-card-demo-active" name="Lourdes Villanueva" number="M-004217" since="2014-03-04" share_capital={18500} currency="PHP" coop="Bayanihan Multi-Purpose Cooperative" kind="Regular member" href="#member-4217"/> <MemberCard id="member-card-demo-dormant" name="Tomas de la Cruz Reyes" number="M-010388" since="2019-07-15" share_capital={2500.5} currency="PHP" status="dormant" kind="Associate member" note="No transaction since Jan 2025"/> <MemberCard id="member-card-demo-usd" name="Harriet Okafor" number="CU-88213" since="2008-11-20" share_capital="$5.00 (1 share)" coop="Lakeshore Teachers Credit Union" status="suspended"/> </div>// MemberCard: a co-operative's or credit union's member, on a card: the photo or// the initials, the name and member number, since when they are a member, their// share capital and whether the membership is active or dormant.//// <MemberCard name="Lourdes Villanueva" number="M-004217" since="2014-03-04" share_capital={18500}// currency="PHP" coop="Bayanihan Multi-Purpose Cooperative" kind="Regular member"/>// <MemberCard name="Tomas Reyes" number="M-010388" since="2019-07-15" share_capital={2500} currency="PHP"// status="dormant" note="No transaction since Jan 2025" photo="/members/10388.jpg"/>//// name: the member's name. number: their member number. since: the date they// joined, ISO ("2014-03-04"), shown as "Mar 4, 2014"; text that is not a date as// it is. share_capital: what they hold, a number or a decimal written in// `currency` (ISO code, "USD") for `locale` (the program's by default), or text// already formatted. status: "active" (default, green), "dormant" (amber), or any// other word ("suspended", "terminated"), grey. photo: an image; without one the// initials are shown ("LV"). coop: the co-op's name across the top. kind: the// kind of membership ("Regular member", "Associate"). note: a line at the bottom.// href: makes the name a link to the member's page. id: the element's id.import ui/theme.qwe use ui_clslet member_card_css = css`.ui-member-card { display: grid; gap: 14px; min-width: 0; max-width: 380px; padding: 18px 20px; border: 1px solid var(--ui-border); border-radius: var(--ui-radius); background: var(--ui-surface); color: var(--ui-fg); font: 14px/1.45 var(--ui-font); border-top: 4px solid var(--ui-accent); }.ui-member-card-coop { margin: 0; color: var(--ui-muted); font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; }.ui-member-card-head { display: flex; align-items: center; gap: 14px; min-width: 0; }.ui-member-card-photo, .ui-member-card-initials { flex: none; width: 56px; height: 56px; border-radius: 50%; }.ui-member-card-photo { object-fit: cover; background: var(--ui-subtle); }.ui-member-card-initials { display: grid; place-items: center; background: var(--ui-accent-soft); color: var(--ui-accent); font-size: 19px; font-weight: 650; letter-spacing: .02em; }.ui-member-card-who { display: grid; gap: 2px; min-width: 0; }.ui-member-card .ui-member-card-name { display: block; margin: 0; font-size: 17px; font-weight: 650; line-height: 1.25; overflow-wrap: anywhere; }.ui-member-card-name a { color: inherit; text-decoration: none; }.ui-member-card-name a:hover { color: var(--ui-accent); text-decoration: underline; }.ui-member-card-name a:focus-visible { outline: none; box-shadow: var(--ui-focus); border-radius: 3px; }.ui-member-card-kind { margin: 0; color: var(--ui-muted); font-size: 13px; }.ui-member-card-status { justify-self: start; display: inline-flex; align-items: center; gap: 6px; padding: 1px 9px; border-radius: 999px; font-size: 12px; font-weight: 600; background: var(--ui-subtle); color: var(--ui-muted); text-transform: capitalize; }.ui-member-card-status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }.ui-member-card-active .ui-member-card-status { background: var(--ui-success-soft); color: var(--ui-success); }.ui-member-card-dormant .ui-member-card-status { background: var(--ui-warning-soft); color: var(--ui-warning); }.ui-member-card-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 10px 16px; margin: 0; padding-top: 12px; border-top: 1px solid var(--ui-border); }.ui-member-card-facts div { display: grid; gap: 1px; min-width: 0; }.ui-member-card-facts dt { color: var(--ui-muted); font-size: 12px; }.ui-member-card-facts dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; }.ui-member-card-facts time { white-space: nowrap; }.ui-member-card-num { font-family: var(--ui-mono); font-size: 13px; }.ui-member-card-note { margin: 0; color: var(--ui-muted); font-size: 13px; }.ui-member-card-dormant { border-top-color: var(--ui-warning); }.ui-member-card-other { border-top-color: var(--ui-muted); }`// "Lourdes Villanueva" as "LV": the first letters of the first and last names.fn member_card_initials(name: str) -> str { let words = split(trim(name), " ") | filter((w) => w != "") if len(words) == 0 { return "?" } let first = upper(slice(words[0], 0, 1)) len(words) == 1 ? first : first + upper(slice(words[len(words) - 1], 0, 1))}// An amount in its currency; text as it is.fn member_card_money(amount, currency: str, locale: str?) -> str { if amount == null { return "" } if type_of(amount) == "str" { return amount } let m = money.of(dec(amount), currency, "half_up") if is_err(m) { return str(amount) } locale != null ? money.format(m, locale) : money.format(m)}// An ISO date as "Mar 4, 2014"; other text as it is.fn member_card_date(d, locale: str?) -> str = date.valid(str(d), "date") ? date.format(str(d), { locale: locale ?? "en-US", style: "medium" }) : str(d)view MemberCard(name: str, number: str, since = null, share_capital = null, currency: str = "USD", locale: str? = null, status: str = "active", photo: str? = null, coop: str? = null, kind: str? = null, note: str? = null, href: str? = null, id: str? = null, class: str? = null) { style global member_card_css let mood = status == "active" || status == "dormant" ? status : "other" <article class={ui_cls(["ui-member-card", `ui-member-card-${mood}`, class])} id={id} aria-label={`Member ${name}, ${number}`}> {coop != null && <p.ui-member-card-coop>{coop}</p>} <div.ui-member-card-head> {photo != null ? <img.ui-member-card-photo src={photo} alt=""/> : <span.ui-member-card-initials aria-hidden="true">{member_card_initials(name)}</span>} <div.ui-member-card-who> <h3.ui-member-card-name>{href != null ? <a href={href}>{name}</a> : name}</h3> {kind != null && <p.ui-member-card-kind>{kind}</p>} <span.ui-member-card-status><span.ui-sr>Status: </span>{status}</span> </div> </div> <dl.ui-member-card-facts> <div><dt>Member no.</dt><dd.ui-member-card-num>{number}</dd></div> {since != null && <div><dt>Member since</dt><dd><time datetime={str(since)}>{member_card_date(since, locale)}</time></dd></div>} {share_capital != null && <div><dt>Share capital</dt><dd.ui-member-card-capital>{member_card_money(share_capital, currency, locale)}</dd></div>} </dl> {note != null && <p.ui-member-card-note>{note}</p>} </article>}On MemberCard: questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.