// Shared JavaScript across all pages class GitHubAnalyzer { constructor() { this.baseURL = 'https://api.github.com'; this.init(); } init() { this.bindEvents(); } bindEvents() { const repoForm = document.getElementById('repoForm'); if (repoForm) { repoForm.addEventListener('submit', (e) => this.handleRepoSubmit(e)); } } async handleRepoSubmit(e) { e.preventDefault(); const username = document.getElementById('username').value.trim(); const repoName = document.getElementById('repoName').value.trim(); if (!username || !repoName) { this.showError('Please enter both username and repository name'); return; } this.showLoading(); this.showResultsSection(); try { const repoData = await this.fetchRepoData(username, repoName); const contributorData = await this.fetchContributors(username, repoName); const languagesData = await this.fetchLanguages(username, repoName); this.displayAnalysisResults(repoData, contributorData, languagesData); } catch (error) { this.showError('Failed to fetch repository data. Please check the username and repository name.'); console.error('Error:', error); } finally { this.hideLoading(); } } async fetchRepoData(username, repoName) { const response = await fetch(`${this.baseURL}/repos/${username}/${repoName}`); if (!response.ok) { throw new Error('Repository not found'); } return await response.json(); } async fetchContributors(username, repoName) { const response = await fetch(`${this.baseURL}/repos/${username}/${repoName}/contributors`); if (!response.ok) { return []; } return await response.json(); } async fetchLanguages(username, repoName) { const response = await fetch(`${this.baseURL}/repos/${username}/${repoName}/languages`); if (!response.ok) { return {}; } return await response.json(); } displayAnalysisResults(repoData, contributors, languages) { const analysisData = document.getElementById('analysisData'); // Calculate metrics const stars = repoData.stargazers_count; const forks = repoData.forks_count; const openIssues = repoData.open_issues_count; const watchers = repoData.watchers_count; const sizeKB = Math.round(repoData.size / 1024); const createdAt = new Date(repoData.created_at).toLocaleDateString(); const lastUpdate = new Date(repoData.updated_at).toLocaleDateString(); // Language distribution const totalBytes = Object.values(languages).reduce((sum, bytes) => sum + bytes, 0); const languagePercentages = Object.entries(languages).map(([lang, bytes]) => ({ language: lang, percentage: Math.round((bytes / totalBytes) * 100) })); analysisData.innerHTML = `

Repository Overview

${stars}
Stars
${forks}
Forks
${openIssues}
Open Issues
${watchers}
Watchers

Languages

${languagePercentages.map(lang => `
${lang.language} ${lang.percentage}%
`).join('')}

Contributors (${contributors.length})

${contributors.slice(0, 8).map(contributor => `
${contributor.login}
${contributor.login}
${contributor.contributions} commits
`).join('')}

Repository Details

Size ${sizeKB} KB
Created ${createdAt}
Last Updated ${lastUpdate}
Default Branch ${repoData.default_branch}
${repoData.description ? `

Description

${repoData.description}

` : ''} `; feather.replace(); } showLoading() { const loading = document.getElementById('loading'); if (loading) loading.classList.remove('hidden'); } hideLoading() { const loading = document.getElementById('loading'); if (loading) loading.classList.add('hidden'); } showResultsSection() { const results = document.getElementById('results'); if (results) results.classList.remove('hidden'); } showError(message) { alert(message); // In a real app, you'd use a better notification system } } // Initialize the analyzer when DOM is loaded document.addEventListener('DOMContentLoaded', () => { new GitHubAnalyzer(); }); // Utility function for API calls async function fetchWithErrorHandling(url, options = {}) { const response = await fetch(url, options); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); }