Skip to content

<seva-member-directory>

The <seva-member-directory> component renders a trigger button and a modal overlay that displays a searchable, alphabetically indexed member directory.

When opened, the modal fetches the organization’s member directory from the API and displays members grouped by last-name initial with an alphabetical sidebar for quick navigation. A real-time search bar filters members by first or last name. If the user is not authenticated, the modal shows a sign-in prompt with an embedded <seva-auth> form.

This is a modal component — it self-manages authentication from localStorage and does not require a glue script to propagate auth tokens. See Inline vs. modal components for details.

<script
type="module"
src="YOUR_COMPONENTS_URL/seva-member-directory.js"
></script>
<seva-member-directory tenant-slug="my-club" api-url="https://api.seva.tools">
</seva-member-directory>

The component renders its own trigger button labeled “Member Directory”. You can also open the modal programmatically by calling openModal() on the element.

Note: Unlike <seva-my-profile> and <seva-my-registrations>, this component does not have a seva:open-member-directory event. Use the built-in trigger button or call openModal() directly.

AttributeTypeDefaultDescription
tenant-slugstring''Required. Your organization’s tenant slug.
api-urlstring'https://api.seva.tools'Base URL of the Seva API.
theme'light' | 'dark''light'Color theme.
auth-tokenstringnullSession token. Modal components typically self-manage this from localStorage, so you rarely need to set it manually.
EventEffect
seva:signed-outDispatched on document if the API returns 401/403 while loading the directory. Other Seva components listening for this event will clear their auth state.

The component listens on document for:

EventEffect
seva:authenticatedStores the token, loads the directory.
seva:signed-outClears auth state and member data.

Note: There is no seva:open-member-directory event. To open the modal programmatically, call element.openModal() instead. See Opening the modal below.

A search bar at the top filters members by first or last name as you type. The search is case-insensitive and matches partial names. A member count updates to reflect the filtered results.

A vertical sidebar on the right displays letters A–Z and # (for members whose last name doesn’t start with a letter). Letters with matching members are highlighted; others are dimmed.

  • Click a letter to scroll to that section.
  • Click and drag along the sidebar to scroll rapidly through the directory.

Members are grouped by the first letter of their last name. Each group has a letter heading followed by member cards.

Each member card shows:

  • Initials avatar — First letters of first and last name in a circle.
  • Full name
  • Email — Linked as mailto:.
  • Phone — Linked as tel:.

The modal can be opened in two ways:

  1. Built-in trigger button — The component renders a “Member Directory” button automatically.
  2. Direct method call — Call openModal() on the element:
    document.querySelector("seva-member-directory").openModal();

There is no document-level custom event to open this modal (unlike profile and registrations). If you need a custom trigger button:

<button onclick="document.querySelector('seva-member-directory').openModal()">
Browse Members
</button>
  • 401 Unauthorized — Session expired. Auth state is cleared and seva:signed-out is dispatched.
  • 404 Not Found — The organization has not enabled the member directory, or the user is not a member. The message displayed is: “Member directory is not available for this organization.”
interface DirectoryMember {
id: string;
firstName: string | null;
lastName: string | null;
email: string | null;
phone: string | null;
membershipTypeName: string | null;
membershipTypeId: string | null;
}
interface DirectoryResponse {
members: DirectoryMember[];
membershipTypes: DirectoryMembershipType[];
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Member Directory</title>
<script
type="module"
src="YOUR_COMPONENTS_URL/seva-member-directory.js"
></script>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 400px;
margin: 2rem auto;
}
</style>
</head>
<body>
<h1>Our Members</h1>
<seva-member-directory
tenant-slug="my-club"
api-url="https://api.seva.tools"
>
</seva-member-directory>
<!-- Or use a custom trigger -->
<button
onclick="document.querySelector('seva-member-directory').openModal()"
>
Browse Members
</button>
</body>
</html>