From e390d63ba462a0f656e44f12b4bd36a443e50a19 Mon Sep 17 00:00:00 2001 From: Yeghro <130201060+Yeghro@users.noreply.github.com> Date: Fri, 24 Jan 2025 21:28:52 -0800 Subject: [PATCH] fixed contributers/contributing displays and got the search working --- script.js | 222 +++++++++++++++++++++++++++++++++++++++++++++++------ styles.css | 104 ++++++++++++++++++++++++- 2 files changed, 301 insertions(+), 25 deletions(-) diff --git a/script.js b/script.js index dd64bea..34fa263 100644 --- a/script.js +++ b/script.js @@ -19,13 +19,82 @@ menuToggle.addEventListener('click', () => { // Search functionality const searchInput = document.getElementById('search'); -const resourceCards = document.querySelectorAll('.resource-card'); searchInput.addEventListener('input', (e) => { const searchTerm = e.target.value.toLowerCase(); - resourceCards.forEach(card => { - const text = card.textContent.toLowerCase(); - card.style.display = text.includes(searchTerm) ? 'block' : 'none'; + const container = document.getElementById('resources-container'); + + if (!searchTerm) { + // If search is empty, restore current category view + const currentCategory = document.querySelector('.nav-links a.active')?.getAttribute('href')?.replace('#', ''); + if (currentCategory) { + populateResources(currentCategory, window.parsedResources); + } + return; + } + + // Clear current container + container.innerHTML = ''; + + // Search through all categories + Object.entries(window.parsedResources).forEach(([category, resources]) => { + resources.forEach(resource => { + let shouldShow = false; + + if (resource.type) { + // Handle special sections (contributors, contributing) + if (resource.type === 'markdown') { + shouldShow = resource.content.toLowerCase().includes(searchTerm); + } else if (resource.type === 'github-contributors') { + // Skip contributors section in search + return; + } + } else { + // Regular resources + const searchableText = [ + resource.name, + resource.description, + resource.link + ].filter(Boolean).join(' ').toLowerCase(); + + shouldShow = searchableText.includes(searchTerm); + } + + if (shouldShow) { + let card; + if (resource.type) { + card = createSpecialSectionCard(resource); + } else { + card = createResourceCard(resource); + } + + // Add category label to card + const categoryLabel = document.createElement('div'); + categoryLabel.className = 'category-label'; + categoryLabel.textContent = category.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase()); + card.insertBefore(categoryLabel, card.firstChild); + + container.appendChild(card); + } + }); + }); + + // Show "no results" message if nothing found + if (!container.children.length) { + container.innerHTML = ` +
+ No resources found matching "${searchTerm}" +
+ `; + } +}); + +// Add active class handling for navigation +document.querySelectorAll('.nav-links a').forEach(link => { + link.addEventListener('click', () => { + document.querySelectorAll('.nav-links a').forEach(l => l.classList.remove('active')); + link.classList.add('active'); + searchInput.value = ''; // Clear search when changing categories }); }); @@ -50,7 +119,42 @@ sortSelect.addEventListener('change', (e) => { cards.forEach(card => container.appendChild(card)); }); -// Function to parse resources from README content +// Add this function to fetch contributors from GitHub API +async function fetchContributors(owner, repo) { + try { + let page = 1; + let allContributors = []; + + while (true) { + const response = await fetch( + `https://api.github.com/repos/${owner}/${repo}/contributors?per_page=100&page=${page}` + ); + + if (!response.ok) throw new Error('Failed to fetch contributors'); + + const contributors = await response.json(); + if (contributors.length === 0) break; // No more contributors + + allContributors = [...allContributors, ...contributors]; + page++; + + // Check if we've reached the last page + const linkHeader = response.headers.get('Link'); + if (!linkHeader || !linkHeader.includes('rel="next"')) { + break; + } + } + + console.log(`Total contributors fetched: ${allContributors.length}`); + return allContributors; + + } catch (error) { + console.error('Error fetching contributors:', error); + return []; + } +} + +// Modify the parseResources function to handle contributors differently function parseResources(content) { const resources = { 'most-popular': [], @@ -84,31 +188,36 @@ function parseResources(content) { 'contributors': [] }; - // Split content by lines and process each line const lines = content.split('\n'); let currentMainSection = ''; let currentSubSection = ''; + let contributingContent = ''; + + // Extract repo info from contributors section + let repoInfo = null; + const repoRegex = /github\.com\/([\w-]+)\/([\w-]+)\/graphs\/contributors/; lines.forEach(line => { - // Detect main section headers (##) if (line.startsWith('## ')) { currentMainSection = line.slice(3).trim(); currentSubSection = ''; + } else if (currentMainSection.toLowerCase() === 'contributors') { + const match = line.match(repoRegex); + if (match) { + repoInfo = { + owner: match[1], + repo: match[2] + }; + } + } else if (currentMainSection.toLowerCase() === 'contributing') { + if (line.trim() && !line.startsWith('##')) { + contributingContent += line + '\n'; + } } // Detect subsection headers (###) else if (line.startsWith('### ')) { currentSubSection = line.slice(4).trim(); } - // Special handling for contributors section with HTML content - else if (currentMainSection.toLowerCase() === 'contributors' && line.includes(' { - const card = createResourceCard(resource); + if (resource.type === 'github-contributors') { + card.className += ' contributors-card'; + card.innerHTML = ` +
Contributors
+
+
Loading contributors...
+
+ `; + + if (resource.repoInfo) { + console.log('Fetching contributors for:', resource.repoInfo); // Debug log + const contributors = await fetchContributors(resource.repoInfo.owner, resource.repoInfo.repo); + console.log('Number of contributors:', contributors.length); // Debug log + const contributorsHtml = contributors.map(contributor => ` + + ${contributor.login} + ${contributor.login} + + `).join(''); + + const grid = card.querySelector('.contributors-grid'); + grid.innerHTML = contributorsHtml || 'No contributors found'; + } + } else if (resource.type === 'markdown') { + // For contributing section + const formattedContent = resource.content + .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1'); + + card.innerHTML = ` +
How to Contribute
+
+ ${formattedContent} +
+ `; + } + + return card; +} + +// Update populateResources to handle both special and regular resources +async function populateResources(categoryId, resources) { + const container = document.getElementById('resources-container'); + container.innerHTML = ''; + + const categoryResources = resources[categoryId]; + if (!categoryResources) return; + + for (const resource of categoryResources) { + let card; + if (resource.type) { + // Handle special sections (contributors and contributing) + card = await createSpecialSectionCard(resource); + } else { + // Handle regular resource cards + card = createResourceCard(resource); + } container.appendChild(card); - }); + } } // Function to get icon for category diff --git a/styles.css b/styles.css index 8e196d0..c8b547c 100644 --- a/styles.css +++ b/styles.css @@ -107,6 +107,8 @@ body { margin-left: 280px; padding: 2rem; flex: 1; + min-height: 100vh; + overflow: auto; } .content-header { @@ -123,11 +125,14 @@ body { /* Resource Cards */ .resource-card { - background: var(--card-bg); + background: var(--card-background); border-radius: 8px; padding: 16px; margin-bottom: 16px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); + width: 100%; + height: auto; + overflow: visible; } .resource-title { @@ -210,4 +215,101 @@ body { .markdown-content a:hover { text-decoration: underline; +} + +/* Update contributors grid styles */ +.contributors-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); + gap: 16px; + padding: 20px; + width: 100%; + height: auto; + min-height: 100px; + justify-items: center; + overflow: visible; +} + +.contributors-grid a { + display: flex; + flex-direction: column; + align-items: center; + text-decoration: none; + color: var(--text-color); + font-size: 0.8em; + text-align: center; +} + +.contributors-grid img { + border-radius: 50%; + width: 64px; + height: 64px; + transition: transform 0.2s; + margin-bottom: 8px; +} + +.contributors-grid a:hover { + text-decoration: none; +} + +.contributors-grid a:hover img { + transform: scale(1.1); +} + +.contributors-grid .loading { + grid-column: 1 / -1; + text-align: center; + padding: 20px; + color: var(--text-color); + font-style: italic; +} + +/* Update the resource card for contributors */ +.resource-card.contributors-card { + max-width: none; + width: 100%; + height: auto; + min-height: 200px; +} + +.resource-description a { + color: var(--primary-color); + text-decoration: none; +} + +.resource-description a:hover { + text-decoration: underline; +} + +#resources-container { + width: 100%; + height: auto; + min-height: 200px; + overflow: visible; +} + +/* Category label styles */ +.category-label { + font-size: 0.8em; + color: var(--primary-color); + text-transform: capitalize; + margin-bottom: 8px; + padding: 2px 8px; + background-color: rgba(110, 84, 148, 0.1); + border-radius: 4px; + display: inline-block; +} + +/* No results styles */ +.no-results { + text-align: center; + padding: 2rem; + color: var(--text-color); + font-style: italic; +} + +/* Active nav link style */ +.nav-links a.active { + background-color: var(--primary-color); + color: white; } \ No newline at end of file