qariyb-event-card

Displays a single event in a card format with cover image, details, and a "Get Tickets" button that opens checkout in a modal.

<qariyb-event-card event-id="01HWXYZ123ABC456"></qariyb-event-card>

Features

  • Cover image with lazy loading
  • Event title, date, and location
  • Feature icons (halal, prayer space, etc.)
  • Starting price display
  • "Get Tickets" button with modal checkout
  • Sold out state handling

Attributes

Required

  • Name
    event-id
    Type
    string
    Description

    The event ULID from your Qariyb dashboard.

Optional

  • Name
    theme
    Type
    'light' | 'dark' | 'flat' | 'minimal'
    Description

    Theme preset. Defaults to 'light'.

  • Name
    accent-color
    Type
    string
    Description

    Primary color in hex format. Defaults to '#10b981'.

  • Name
    show-image
    Type
    'true' | 'false'
    Description

    Show cover image. Defaults to 'true'.

  • Name
    show-price
    Type
    'true' | 'false'
    Description

    Show starting price. Defaults to 'true'.

  • Name
    show-features
    Type
    'true' | 'false'
    Description

    Show feature icons. Defaults to 'true'.

Callback Attributes

  • Name
    on-ready
    Type
    function
    Description

    Called when component mounts. Receives { eventId }.

  • Name
    on-loaded
    Type
    function
    Description

    Called when event data loads. Receives { event }.

  • Name
    on-clicked
    Type
    function
    Description

    Called on card interaction. Receives { event, action }.

  • Name
    on-error
    Type
    function
    Description

    Called on error. Receives { error, eventId }.


Events

qariyb:card:ready

Emitted when component mounts.

interface CardReadyDetail {
  eventId: string;
}

qariyb:card:loaded

Emitted when event data is fetched.

interface CardLoadedDetail {
  event: QariybEvent;
}
card.addEventListener('qariyb:card:loaded', (e) => {
  const event = e.detail.data.event;
  console.log('Event loaded:', event.title);
  console.log('Price from:', event.ticket_types[0]?.price_cents);
});

qariyb:card:clicked

Emitted when user interacts with the card.

interface CardClickedDetail {
  event: QariybEvent;
  action: 'view' | 'tickets';
}
ActionDescription
viewCard body clicked
tickets"Get Tickets" button clicked
card.addEventListener('qariyb:card:clicked', (e) => {
  const { event, action } = e.detail.data;

  if (action === 'tickets') {
    analytics.track('get_tickets_clicked', {
      event_id: event.id,
      event_title: event.title,
    });
  }
});

qariyb:card:error

Emitted when an error occurs.

interface CardErrorDetail {
  error: string;
  eventId: string;
}

Public Methods

getEvent()

Returns the loaded event data.

getEvent(): QariybEvent | null
const card = document.querySelector('qariyb-event-card');
const event = card.getEvent();

if (event) {
  console.log('Event title:', event.title);
  console.log('Is sold out:', event.is_sold_out);
}

refresh()

Refetch event data from the API.

refresh(): void
const card = document.querySelector('qariyb-event-card');
card.refresh();

Card Layout

The card displays:

+----------------------------+
|                            |
|     [Cover Image]          |  <- show-image="true"
|                            |
+----------------------------+
| Event Title                |
| Mar 15, 2025 - 2:00 PM     |
| London, UK                 |
|                            |
| [halal] [prayer] [family]  |  <- show-features="true"
|                            |
+----------------------------+
| From $25      [Get Tickets]|  <- show-price="true"
+----------------------------+

Examples

Basic Card

<qariyb-event-card event-id="01HWXYZ123ABC456"></qariyb-event-card>

Without Image (Compact)

<qariyb-event-card
  event-id="01HWXYZ123ABC456"
  show-image="false"
></qariyb-event-card>

Minimal Display

<qariyb-event-card
  event-id="01HWXYZ123ABC456"
  show-image="false"
  show-features="false"
  show-price="false"
></qariyb-event-card>

Dark Theme

<qariyb-event-card
  event-id="01HWXYZ123ABC456"
  theme="dark"
  accent-color="#8b5cf6"
></qariyb-event-card>

Card Grid

<style>
  .events-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 24px;
    padding: 20px;
  }
</style>

<div class="events-grid">
  <qariyb-event-card event-id="01HWEVENT1"></qariyb-event-card>
  <qariyb-event-card event-id="01HWEVENT2"></qariyb-event-card>
  <qariyb-event-card event-id="01HWEVENT3"></qariyb-event-card>
</div>

With Analytics

<qariyb-event-card
  event-id="01HWXYZ123ABC456"
  on-loaded="trackImpression"
  on-clicked="trackClick"
></qariyb-event-card>

<script>
  function trackImpression(data) {
    gtag('event', 'view_item', {
      items: [{
        item_id: data.event.id,
        item_name: data.event.title,
      }],
    });
  }

  function trackClick(data) {
    if (data.action === 'tickets') {
      gtag('event', 'select_item', {
        items: [{
          item_id: data.event.id,
          item_name: data.event.title,
        }],
      });
    }
  }
</script>

Dynamic Card Loading

<div id="event-container"></div>

<script>
  async function loadEventCard(eventId) {
    const container = document.getElementById('event-container');

    const card = document.createElement('qariyb-event-card');
    card.setAttribute('event-id', eventId);
    card.setAttribute('theme', 'light');

    card.addEventListener('qariyb:card:loaded', (e) => {
      console.log('Card loaded:', e.detail.data.event.title);
    });

    card.addEventListener('qariyb:card:error', (e) => {
      console.error('Failed to load card:', e.detail.data.error);
    });

    container.appendChild(card);
  }

  loadEventCard('01HWXYZ123ABC456');
</script>

Feature Icons

When show-features="true", the card displays feature icons based on the event's features:

Icons are inline SVGs chosen by each feature's slug — not emoji — so they inherit the theme's icon colour and stay crisp at any size. Each carries the feature's name as its tooltip.

At most four features are shown, in the order the API returns them; any beyond that are omitted rather than wrapped.

A feature with no matching icon falls back to a generic marker, so an unknown slug never breaks the row.


Sold out and sales-closed states

The card disables its button in two different situations, and they read differently to the buyer:

  • Sold out (is_sold_out: true) — the button shows the soldOut label ("Sold Out" by default). There is no stock left.
  • Sales closed (registration_open: false, not sold out) — the button shows the salesClosed label ("Sales Closed" by default). Stock remains, but the sale window is shut.

In both cases the button is disabled with the same muted styling and clicking it does nothing. Both strings are overridable through labels.

card.addEventListener('qariyb:card:loaded', (e) => {
  if (e.detail.data.event.is_sold_out) {
    console.log('This event is sold out');
  }
});

When the "Get Tickets" button is clicked:

  1. Modal overlay appears
  2. <qariyb-checkout> loads inside
  3. User completes or cancels checkout
  4. Modal closes

Listen for checkout events on the document:

document.addEventListener('qariyb:checkout:success', (e) => {
  console.log('Purchase from card:', e.detail.data.order.id);
});

Styling

Custom Theme Variables

window.QariybConfig = {
  publishableKey: 'pk_live_...',
  theme: 'light',
  variables: {
    colorPrimary: '#4f46e5',
    borderRadius: '16px',
  },
  rules: {
    '.EventCard': {
      boxShadow: '0 4px 20px rgba(0, 0, 0, 0.1)',
    },
    '.EventTitle': {
      fontSize: '1.25rem',
    },
    '.EventImage': {
      height: '200px',
    },
  },
};

Available CSS Classes

  • .EventCard - Card container
  • .EventImage - Cover image
  • .EventTitle - Event title
  • .EventDate - Date and time
  • .EventLocation - Venue/address
  • .EventFeatures - Feature icons container
  • .tickets-btn - Get Tickets button
  • .tickets-btn.sold-out - Sold out state

Complete Example

<!DOCTYPE html>
<html>
<head>
  <title>Upcoming Events</title>
  <script>
    window.QariybConfig = {
      publishableKey: 'pk_live_...',
      theme: 'light',
      variables: {
        colorPrimary: '#059669',
        borderRadius: '12px',
      },
    };
  </script>
  <script src="https://js.qariyb.com/v1/qariyb.js"></script>
  <style>
    body { font-family: system-ui, sans-serif; padding: 40px 20px; }
    h1 { text-align: center; margin-bottom: 40px; }
    .grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
      gap: 24px;
      max-width: 1200px;
      margin: 0 auto;
    }
  </style>
</head>
<body>
  <h1>Upcoming Events</h1>

  <div class="grid">
    <qariyb-event-card event-id="01HWEVENT1" on-clicked="trackEventClick"></qariyb-event-card>
    <qariyb-event-card event-id="01HWEVENT2" on-clicked="trackEventClick"></qariyb-event-card>
    <qariyb-event-card event-id="01HWEVENT3" on-clicked="trackEventClick"></qariyb-event-card>
  </div>

  <script>
    function trackEventClick(data) {
      console.log('Event clicked:', data.event.title, data.action);
    }

    document.addEventListener('qariyb:checkout:success', (e) => {
      console.log('Purchase complete:', e.detail.data.order.id);
    });
  </script>
</body>
</html>

Was this page helpful?