Skip to content

Instantly share code, notes, and snippets.

@js044
Last active January 9, 2024 17:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save js044/893901d8a723bc43a938b7abd136ce9e to your computer and use it in GitHub Desktop.
Save js044/893901d8a723bc43a938b7abd136ce9e to your computer and use it in GitHub Desktop.
// Check for dead links using allOrigins API (https://allorigins.win/) to bypass CORS restrictions
function checkDeadLinks(data) {
data.forEach(member => {
fetch(`https://api.allorigins.win/get?url=${member.url}`, { method: 'HEAD' })
.then(response => {
if (response.ok) {
console.log(`Link is reachable: ${member.url}`);
} else {
handleDeadLink(member.url);
}
})
.catch(error => {
console.error('Error checking link:', error.message);
handleDeadLink(member.url);
});
});
}
function handleDeadLink(deadURL) {
console.log(`Dead link detected: ${deadURL}`);
}
// Start checking dead links using the provided JSON data
checkDeadLinks(window.membersData);
// Add members to list from JSON file
const data = window.membersData;
const pageSize = 10; // Number of members per page to set up pagination. You can change this to whatever.
let currentPage = 1; // Current page
const totalEntries = data.length; // Total entries from JSON
// Update the HTML element to display the member count. Include <div id="memberCount"></div> wherever you want this to show up.
const memberCountElement = document.querySelector('#memberCount');
if (memberCountElement) {
memberCountElement.innerHTML = `Member count: ${totalEntries}`;
}
// Create member entries in HTML. Use <div class="member-box"></div> wherever you want this to show up. You only need to list it once.
function createMemberBox(member) {
const memberBox = document.createElement('div');
memberBox.classList.add('member-box');
function getFieldValue(field) {
const fieldValue = member[field];
switch (field) {
case 'name':
return fieldValue ? `Name: ${fieldValue}` : 'Name'; // Default placeholder text
case 'url':
if (fieldValue) {
return `Site: <a href="${fieldValue}">${member['websiteTitle'] || 'Website Title'}</a>`;
} else {
return 'Website Title'; // Placeholder for empty url fields
}
default:
const formattedFieldName = field.replace(/([A-Z])/g, ' $1').trim();
return fieldValue ? `<span class="highlight">${formattedFieldName.charAt(0).toUpperCase() + formattedFieldName.slice(1)}:</span> ${fieldValue}` : formattedFieldName.charAt(0).toUpperCase() + formattedFieldName.slice(1);
}
}
memberBox.innerHTML = `
<div class="field field--name">${getFieldValue('name')}</div>
<div class="field field--url">${getFieldValue('url')}</div>
<div class="field field--description">${getFieldValue('description')}</div>
`;
return memberBox;
}
// Stuff to handle pagination. Initial setup for displaying the first page
displayMembersForPage(currentPage);
// Navigation event listeners
const totalPages = Math.ceil(totalEntries / pageSize);
const prevButton = document.getElementById('prevButton');
const nextButton = document.getElementById('nextButton');
if (totalPages > 1) {
// Show the buttons if there are more than a specified number of entries
prevButton.style.display = 'block';
nextButton.style.display = 'block';
} else {
// Hide the buttons if there are less than a specified number of entries
prevButton.style.display = 'none';
nextButton.style.display = 'none';
}
prevButton.addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
displayMembersForPage(currentPage);
}
});
nextButton.addEventListener('click', () => {
const totalPages = Math.ceil(totalEntries / pageSize);
if (currentPage < totalPages) {
currentPage++;
displayMembersForPage(currentPage);
}
});
// Make sure membersData is attached to the window object in order to make this data globally accessible throughout the application and work with the admin.js
window.membersData = [
{
"name": "Member 1",
"websiteTitle": "Website Title 1",
"url": "https://website1.com/", // MAKE SURE YOU LEAVE THE TRAILING SLASH, this way the members can put their widget on any page and the script will still recognize them
"description": "This is a placeholder description for the first entry."
},
{
"name": "Member 2",
"websiteTitle": "Website Title 2",
"url": "https://website2.com/",
"description": "This is a placeholder description for the second entry."
},
// ... (continue this pattern for other entries)
];
// Replace YourComponent with whatever you want your webring component to be named
class YourComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
// Define default styles for the widget. If you change these classes, remember to change all instances of the script referencing them as well.
this.defaultStyles = `
.widget-container {
/* Placeholder styles for the container */
}
.button-container {
/* Placeholder styles for the button container */
}
.prev-button,
.next-button,
.random-button {
/* Placeholder styles for the buttons */
}
.random-button {
/* Placeholder styles for the random button */
}
.icon {
/* Placeholder styles for the icon */
}
`;
}
connectedCallback() {
const widgetContainer = document.createElement('div');
widgetContainer.classList.add('widget-container');
const fetchData = () => {
const iconType = this.getAttribute('icon') || 'default';
let currentIndex;
// Use embedded JSON data directly
const data = window.membersData;
currentIndex = this.getIndexFromURL(data, window.location.href);
if (currentIndex !== -1) {
const member = data[currentIndex];
// Creating the previous link
const prevLink = document.createElement('a');
prevLink.classList.add('prev-button');
prevLink.href = data[currentIndex === 0 ? data.length - 1 : currentIndex - 1].url;
const prevArrowImage = document.createElement('img');
prevArrowImage.src = this.getArrowImageSrc('prev', iconType);
prevLink.appendChild(prevArrowImage);
// Creating the next link
const nextLink = document.createElement('a');
nextLink.classList.add('next-button');
nextLink.href = data[(currentIndex + 1) % data.length].url;
const nextArrowImage = document.createElement('img');
nextArrowImage.src = this.getArrowImageSrc('next', iconType);
nextLink.appendChild(nextArrowImage);
// Create random button
const randomLink = document.createElement('a');
randomLink.classList.add('random-button');
randomLink.textContent = 'Random';
// Create and style icon
const iconLink = document.createElement('a');
iconLink.href = '#'; // Add your webring homepage URL here
const buttonImage = document.createElement('img');
buttonImage.src = this.getIconSrc(iconType);
buttonImage.classList.add('icon', `icon-${iconType}`);
iconLink.appendChild(buttonImage);
// Create a div for buttons (prev, next, icon)
const buttonDiv = document.createElement('div');
buttonDiv.classList.add('button-container');
buttonDiv.appendChild(prevLink);
buttonDiv.appendChild(iconLink);
buttonDiv.appendChild(nextLink);
// Handle the previous, next, and random link clicks
prevLink.addEventListener('click', (event) => {
event.preventDefault();
window.location.href = event.currentTarget.href;
});
nextLink.addEventListener('click', (event) => {
event.preventDefault();
window.location.href = event.currentTarget.href;
});
randomLink.addEventListener('click', (event) => {
event.preventDefault();
const randomIndex = Math.floor(Math.random() * data.length);
const randomWebsite = data[randomIndex];
window.location.href = randomWebsite.url;
});
// Create a div for the random button
const randomDiv = document.createElement('div');
randomDiv.appendChild(randomLink);
// Append placeholders to the widget container
widgetContainer.appendChild(buttonDiv);
widgetContainer.appendChild(randomDiv);
this.shadowRoot.appendChild(widgetContainer);
const style = document.createElement('style');
style.textContent = this.defaultStyles;
this.shadowRoot.appendChild(style);
} else {
const pendingMessage = document.createElement('p');
pendingMessage.textContent = "This user's application is pending."; // Your pending message here
this.shadowRoot.appendChild(pendingMessage);
}
};
fetchData();
}
getIndexFromURL(data, currentURL) {
return data.findIndex(member => currentURL.includes(member.url));
}
getIconSrc(iconType) {
// Define mapping for different icon types
const iconMap = {
default: '#', // Link to your default icon, should not be a relative link
green: '#', // Sample green color for your icon, you can change it to whatever you want and include as many as you want
};
return iconMap[iconType] || iconMap.default;
}
getArrowImageSrc(direction, iconType) {
// Define arrow image sources
const arrowImageMap = {
prev: {
default: '#', // Your link here
green: '#', // Your link here
},
next: {
default: '#', // Your link here
green: '#', // Your link here
},
};
// Return the arrow image source based on the direction and iconType
return arrowImageMap[direction][iconType] || arrowImageMap[direction]['default'];
}
}
// Define your web component here, should match the name from earlier and semantically follow this naming convention
window.customElements.define('your-component', YourComponent);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment