Subscriptions
Memberships and recurring subscriptions use the same <u-ticketable-list> component as tickets — set ticketable-type="subscription". Filter by state for an active-only view, or show the full history with colored state badges.
View this guide as MarkdownActive subscriptions
Cards for currently active subscriptions using filter="state=active". ticketable-conditional hides the end date when a subscription runs indefinitely, and unidy-attr wires the manage link from the data.
- ticketable-type="subscription" — one component for tickets and memberships
- State filtering — filter="state=active" server-side
- Conditional markup — end date only when present
<u-signed-in>
<!-- Same list component as tickets — just a different ticketable-type -->
<u-ticketable-list
ticketable-type="subscription"
filter="state=active"
limit="3"
container-class="grid gap-4">
<template>
<div class="rounded-lg border border-border bg-white p-5 shadow-sm">
<div class="flex items-start justify-between gap-4">
<div>
<h3 class="text-lg font-bold">
<ticketable-value name="title"></ticketable-value>
</h3>
<p class="mt-1 text-sm text-text-light">
Since <ticketable-value name="starts_at" date-format="dd.MM.yyyy"></ticketable-value>
<ticketable-conditional when="ends_at">
· renews/ends <ticketable-value name="ends_at" date-format="dd.MM.yyyy"
></ticketable-value>
</ticketable-conditional>
</p>
<p class="mt-2 font-semibold text-primary">
<ticketable-value name="price" default="—"></ticketable-value>
</p>
</div>
<span class="state-badge">
<ticketable-value name="state"></ticketable-value>
</span>
</div>
<a
unidy-attr
unidy-attr-href="{{button_cta_url}}"
class="btn btn-primary !min-h-0 !px-3 !py-1.5 mt-4 text-sm">
Manage
</a>
</div>
</template>
<!-- shown when there are no active subscriptions -->
<p slot="empty" class="py-6 text-center text-sm text-text-light">No active subscriptions.</p>
</u-ticketable-list>
</u-signed-in>
<u-signed-in not>
<p class="text-text-light">
Sign in on the <a href="/auth" class="text-primary underline">Auth page</a> to see your subscriptions.
</p>
</u-signed-in> Subscription history
The unfiltered list shows every subscription with its lifecycle state. A data-state attribute stamped from the item data drives the badge colors in plain CSS — active is green, cancelled red.
- Full lifecycle — active, cancelled and expired together
- State badges — unidy-attr-data-state + CSS attribute selectors
- Pagination — same u-pagination components as tickets
<u-signed-in>
<!-- No state filter: active, cancelled and expired subscriptions together -->
<u-ticketable-list
ticketable-type="subscription"
target="#subscription-history-body"
limit="5"
skeleton-all-text="true">
<div class="overflow-x-auto">
<table class="min-w-full rounded-lg border border-border bg-white">
<thead
class="bg-background-light text-left text-xs uppercase tracking-wider text-text-muted">
<tr>
<th class="px-4 py-3">Subscription</th>
<th class="px-4 py-3">Period</th>
<th class="px-4 py-3">Price</th>
<th class="px-4 py-3">State</th>
</tr>
</thead>
<tbody id="subscription-history-body" class="divide-y divide-border"></tbody>
</table>
</div>
<div class="mt-4 flex items-center gap-2">
<u-pagination-button
direction="prev"
class-name="px-3 py-2 rounded-lg border border-border bg-white text-sm cursor-pointer hover:bg-background-light disabled:opacity-50 disabled:cursor-not-allowed">
</u-pagination-button>
<u-pagination-page class-name="px-3 py-2 text-sm"></u-pagination-page>
<u-pagination-button
direction="next"
class-name="px-3 py-2 rounded-lg border border-border bg-white text-sm cursor-pointer hover:bg-background-light disabled:opacity-50 disabled:cursor-not-allowed">
</u-pagination-button>
</div>
<template>
<tr class="transition-colors hover:bg-background-light">
<td class="whitespace-nowrap px-4 py-3 font-medium">
<ticketable-value name="title"></ticketable-value>
</td>
<td class="whitespace-nowrap px-4 py-3 text-sm text-text-light">
<ticketable-value name="starts_at" date-format="dd.MM.yyyy"></ticketable-value>
– <ticketable-value name="ends_at" date-format="dd.MM.yyyy" default="ongoing"
></ticketable-value>
</td>
<td class="whitespace-nowrap px-4 py-3 font-semibold text-primary">
<ticketable-value name="price" default="—"></ticketable-value>
</td>
<td class="whitespace-nowrap px-4 py-3">
<!-- ticketable-state on the row lets CSS color the badge per state -->
<span class="state-badge" unidy-attr unidy-attr-data-state="{{state}}">
<ticketable-value name="state"></ticketable-value>
</span>
</td>
</tr>
</template>
<!-- shown when the user has no subscriptions -->
<p slot="empty" class="py-6 text-center text-sm text-text-light">No subscriptions yet.</p>
</u-ticketable-list>
</u-signed-in>
<u-signed-in not>
<p class="text-text-light">
Sign in on the <a href="/auth" class="text-primary underline">Auth page</a> to see your subscription
history.
</p>
</u-signed-in> Live demo
| Subscription | Period | Price | State |
|---|
No subscriptions yet.
Sign in on the Auth page to see your subscription history.