Reference
Account area

Account area

Part of @cobuntu/embed-react: headless, data via props, links through your router.

Three components for a member's account pages: their events, their ledger and their library. Each takes the payload of one me.* call as it comes back, so your page fetches on the server and passes the result down. See the Account area guide for the full page.

My events

<MyEvents
  events={await member.me.events()}
  eventHref={(e) => `/events/${e.slug ?? e.id}`}
  receiptHref={(e) => `/account/orders?txn=${e.transactionId}`}
  browseHref="/events"
/>

Upcoming and Past tabs, as in the community app. Each tab joins what the member goes to and what they host; an event that is both shows once, marked Hosting. Rows carry the date, time, and a status: Awaiting review for a place the host has not approved yet, Hosting or Hosted, Attended on past events, and Event cancelled. "View receipt" appears only when the event has a purchase.

Profile events

"use client";
<ProfileEvents
  events={rows}            // me.profile.events(), fetched on your server
  isOwner
  onOpen={(event, kind) => (kind === "draft" ? openDraftSheet(event) : openManageSheet(event))}
/>

The member's own profile Events tab: every event they host on a date timeline (newest day first, undated last), drafts mixed in. For the owner each card shows a listing-state chip, and a status filter appears once there is more than one state to choose from:

StateFromChipFilter
LIVEcatalogStatusLiveLive
PENDINGcatalogStatusIn reviewIn review
UNFINISHEDisDraft: trueDraftDraft
HIDDENcatalogStatusOff-shelfOff-shelf
REJECTED, DRAFTcatalogStatusUnpublishedUnpublished

DRAFT here means listed nowhere (a finished event without a listing), not an unfinished one; only isDraft marks a wizard draft. Without isOwner the chips and the filter are withheld.

A card click calls onOpen(event, kind, state) with kind "draft" (offer Continue setup, to /events/new?draft=<id>, and Delete, through DELETE me/drafts/event/:id) or "event" (offer View and Manage). Modifier clicks follow the card's link instead: eventHref, by default the draft resume URL or /events/<slug or id>.

Ledger

"use client";
const [filters, setFilters] = useState(EMPTY_LEDGER_FILTERS);
const [offset, setOffset] = useState(0);
// fetch from your server route with toLedgerQuery(filters, { limit: 20, offset })
 
<Ledger
  ledger={ledger}
  filters={filters}
  onFiltersChange={(f) => { setFilters(f); setOffset(0); }}
  offset={offset}
  onOffsetChange={setOffset}
  invoiceHref={(e) => `/api/invoice/${e.saleId}`}
  receiptHref={(e) => `/api/receipt/${e.saleId}`}
/>

Summary tiles per currency (spent, refunded, earned, fees), the payout state (pending, ready, in the holding period), a type select, a date range select, a search over the rows on the page, and a table of entries. Each entry shows a signed amount, a status pill, the item, the buyer on a sale, the date, the payout date on a sale, the refund reason, and Invoice and Receipt links when the entry has them. The pager shows when you pass onOffsetChange.

toLedgerQuery(filters, { limit, offset, now? }) turns the filter state into me.ledger params: the range becomes from.

Library

<Library
  items={(await member.me.library()).items}
  itemHref={(i) => (i.product.sku ? `/shop/${i.product.sku}` : null)}
  onDownload={async (i, d) => {
    const { url } = await fetch(`/api/download/${i.saleId}/${d.attachmentId}`).then((r) => r.json());
    window.location.href = url;
  }}
  browseHref="/shop"
/>

A grid of owned items with image, type, creator, purchase date and downloads. LINK deliverables open directly; FILE downloads call onDownload, which goes through your server to me.purchaseDownload. A purchase awaiting the seller's approval shows dimmed with no downloads. Search, a type select and a status select appear once there is more than one item, and only when they would divide the list.

Account props

ComponentProps
MyEventsevents, loading, tab / defaultTab, onTabChange, eventHref (default /events/<slug or id>), receiptHref, browseHref, renderLink, renderExtra, renderPlaceholder, locale, timeZone, labels (MyEventsLabels)
ProfileEventsevents, isOwner, loading, status / onStatusChange ("" for all), onOpen, eventHref, renderPlaceholder, renderExtra, leadingEntry, locale, timeZone, labels (ProfileEventsLabels, states per state)
Ledgerledger, loading, filters, onFiltersChange, pageSize (default 20), offset, onOffsetChange, invoiceHref, receiptHref, onEntryClick, showPayouts, renderLink, renderExtra, locale, labels (LedgerLabels)
Libraryitems, loading, itemHref, onDownload, browseHref, renderLink, renderExtra, locale, labels (LibraryLabels)

Helpers: mergeMyEvents(groups, tab), profileEventState(row), profileEventBucket(state), groupProfileEvents(rows), draftResumeHref(row), PROFILE_EVENT_BUCKETS, toLedgerQuery, ledgerEntryStatus(entry), EMPTY_LEDGER_FILTERS, libraryMatches(item, filters), libraryFacets(items), EMPTY_LIBRARY_FILTERS, and the default*Labels objects.

Class map

See the class map conventions.

My events

ClassElementState attributes
cb-my-eventsRootdata-tab="upcoming | past"
__tabs, __tabTabsdata-active, aria-selected
__list, __skeletonList, loading rowsaria-busy
__empty, __empty-title, __empty-hint, __browseEmpty state
cb-my-eventOne eventdata-hosting, data-status="ok | pending | hosting | attended | cancelled"
__link, __media, __img, __placeholder, __body, __when, __date, __time, __name, __status, __receiptRow

Profile events

ClassElementState attributes
cb-profile-eventsRootdata-owner
__filter, __filter-option, __filter-countStatus filter (owner)option: data-bucket, data-active, aria-pressed
__timeline, __group, __dot, __date, __date-label, __date-day, __cardsTimelinegroup: data-first
__list, __skeletonLoading rowsaria-busy
__empty, __empty-title, __empty-hint, __clear, __leadEmpty states
cb-profile-eventOne eventdata-kind="draft | event", data-state="LIVE | PENDING | HIDDEN | REJECTED | DRAFT | UNFINISHED | none"
__link, __body, __time, __name, __where, __chip, __media, __img, __placeholderCardchip also has cb-listing-state and data-state

Ledger

ClassElementState attributes
cb-ledgerRootaria-busy
__summary, __totals, __payouts, __tile, __tile-label, __tile-amountTilestotals: data-currency; tile: data-kind="spent | refunded | earned | fees | pending | ready | escrow"
__filters, __search, __type, __range, __countFilters
__table, __thTableth: data-col
__loading, __empty, __empty-text, __clearStates
cb-ledger-entryOne rowdata-type="purchase | refund | sale", data-direction="in | out", data-status
__amount, __sign, __status, __pill, __item, __name, __kind, __reason, __payout, __counterpart, __date, __actions, __invoice, __receiptCellspayout: data-payout
__pager, __prev, __page, __nextPagerdisabled

Library

ClassElementState attributes
cb-libraryRootaria-busy
__filters, __search, __type, __status, __countFilters
__grid, __skeletonGrid
__empty, __empty-title, __empty-hint, __browse, __no-matches, __no-matches-text, __clearStates
cb-library-itemOne itemdata-pending, data-type
__link, __media, __img, __placeholder, __type, __name, __creator, __avatar, __metaCard
__downloads, __downloads-title, __download-list, __download, __download-name, __download-actionDownloadsdata-kind="file | link"