<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Clerk + JavaScript App</title>
<style>
/* Style for the table */
table {
border-collapse: collapse; /* Collapse borders into a single border */
border: 1px solid black; /* Border for the entire table */
}
/* Style for table cells */
td,
th {
border: 1px solid black; /* Border for each cell */
padding: 2px; /* Optional: Add padding to cells */
}
</style>
</head>
<body>
<div id="app"></div>
<p id="error-container" hidden>
Error:
<span id="error-message"></span>
</p>
<h2>Membership Requests</h2>
<table id="requests_table">
<thead>
<tr>
<th>User ID</th>
<th>Identifier</th>
<th>Status</th>
<th id="add-member-head" hidden>Add member</th>
</tr>
</thead>
<tbody id="requests_table_body"></tbody>
</table>
<p>Response:</p>
<pre id="response"></pre>
<!-- Initialize Clerk with your
Clerk Publishable key and Frontend API URL -->
<script
async
crossorigin="anonymous"
data-clerk-publishable-key="YOUR_PUBLISHABLE_KEY"
src="https://YOUR_FRONTEND_API_URL/npm/@clerk/clerk-js@latest/dist/clerk.browser.js"
type="text/javascript"
></script>
<script>
window.addEventListener("load", async function () {
await Clerk.load();
if (Clerk.user) {
// Check for an active organization
if (Clerk.organization) {
// Render list of organization membership requests
async function renderMembershipRequests(organization, isAdmin) {
try {
const { data } = await organization.getMembershipRequests();
const membershipRequests = data;
console.log(`getMembershipRequests:`, membershipRequests);
membershipRequests.map((membershipRequest) => {
const requestsTable = document.getElementById("requests_table");
const row = requestsTable.insertRow();
row.insertCell().textContent =
membershipRequest.publicUserData.userId;
row.insertCell().textContent =
membershipRequest.publicUserData.identifier;
row.insertCell().textContent = membershipRequest.status;
// Add administrative actions:
// Add member (removes request)
if (isAdmin) {
// Show add member button
document.getElementById("add-member-head").removeAttribute("hidden");
// Get the user ID of the member
const userId = membershipRequest.publicUserData.userId;
// Add member to organization
const addBtn = document.createElement("button");
addBtn.textContent = "Add member";
addBtn.addEventListener("click", async function (e) {
e.preventDefault();
const role = "org:member";
await organization.addMember({ userId, role })
.then((res) => {
document.getElementById("response").innerHTML =
JSON.stringify(res);
})
.catch((error) => {
document.getElementById("error-container").removeAttribute("hidden");
document.getElementById("error-message").innerHTML =
error.errors[0].longMessage;
console.log("An error occurred:", error.errors);
});
});
row.insertCell().appendChild(addBtn);
}
});
} catch (error) {
document.getElementById("error-container").removeAttribute("hidden");
document.getElementById("error-message").innerHTML =
error.errors[0].longMessage;
console.log("An error occurred:", error.errors);
}
}
/**
* Checks if a user is an admin of the
* currently active organization and
* renders the organization's membership requests.
*/
async function checkAdminAndRenderRequests() {
const organizationId = Clerk.organization.id;
const organizationMemberships =
await Clerk.user.getOrganizationMemberships();
const currentMembership = organizationMemberships.find(
(membership) => membership.organization.id === organizationId
);
const currentOrganization = currentMembership.organization;
if (!currentOrganization) {
return;
}
const isAdmin = currentMembership.role === "org:admin";
console.log(`Organization:`, currentOrganization);
renderMembershipRequests(currentOrganization, isAdmin);
}
checkAdminAndRenderRequests();
} else {
// If there is no active organization,
// mount Clerk's <OrganizationSwitcher />
// to allow the user to set an organization as active
document.getElementById("app").innerHTML = `
<h2>Select an organization to set it as active</h2>
<div id="org-switcher"></div>
`;
const orgSwitcherDiv = document.getElementById("org-switcher");
Clerk.mountOrganizationSwitcher(orgSwitcherDiv);
}
} else {
document.getElementById("app").innerHTML = `
<div id="sign-in"></div>
`;
const signInDiv = document.getElementById("sign-in");
Clerk.mountSignIn(signInDiv);
}
});
</script>
</body>
</html>