makaronz's picture
Can you analyze my github repository and create frontend?
5e7c085 verified
// 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 -->
<div class="analysis-card bg-white/10 backdrop-blur-lg rounded-xl p-6 border border-white/20">
<h3 class="text-xl font-semibold text-white mb-4 flex items-center">
<i data-feather="book" class="mr-2"></i>
Repository Overview
</h3>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<div class="text-center">
<div class="text-2xl font-bold text-purple-400">${stars}</div>
<div class="text-sm text-gray-300">Stars</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-purple-400">${forks}</div>
<div class="text-sm text-gray-300">Forks</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-purple-400">${openIssues}</div>
<div class="text-sm text-gray-300">Open Issues</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-purple-400">${watchers}</div>
<div class="text-sm text-gray-300">Watchers</div>
</div>
</div>
</div>
<!-- Language Distribution -->
<div class="analysis-card bg-white/10 backdrop-blur-lg rounded-xl p-6 border border-white/20">
<h3 class="text-xl font-semibold text-white mb-4 flex items-center">
<i data-feather="code" class="mr-2"></i>
Languages
</h3>
<div class="space-y-3">
${languagePercentages.map(lang => `
<div class="flex items-center justify-between">
<span class="text-gray-300">${lang.language}</span>
<span class="text-purple-400 font-semibold">${lang.percentage}%</span>
</div>
`).join('')}
</div>
</div>
<!-- Contributors -->
<div class="analysis-card bg-white/10 backdrop-blur-lg rounded-xl p-6 border border-white/20">
<h3 class="text-xl font-semibold text-white mb-4 flex items-center">
<i data-feather="users" class="mr-2"></i>
Contributors (${contributors.length})
</h3>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
${contributors.slice(0, 8).map(contributor => `
<div class="text-center">
<img src="${contributor.avatar_url}" alt="${contributor.login}" class="w-12 h-12 rounded-full mx-auto mb-2 border-2 border-purple-400">
<div class="text-sm text-gray-300 truncate">${contributor.login}</div>
<div class="text-xs text-purple-400">${contributor.contributions} commits</div>
</div>
`).join('')}
</div>
</div>
<!-- Repository Details -->
<div class="analysis-card bg-white/10 backdrop-blur-lg rounded-xl p-6 border border-white/20">
<h3 class="text-xl font-semibold text-white mb-4 flex items-center">
<i data-feather="info" class="mr-2"></i>
Repository Details
</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="flex justify-between">
<span class="text-gray-300">Size</span>
<span class="text-purple-400">${sizeKB} KB</span>
</div>
<div class="flex justify-between">
<span class="text-gray-300">Created</span>
<span class="text-purple-400">${createdAt}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-300">Last Updated</span>
<span class="text-purple-400">${lastUpdate}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-300">Default Branch</span>
<span class="text-purple-400">${repoData.default_branch}</span>
</div>
</div>
</div>
<!-- Repository Description -->
${repoData.description ? `
<div class="analysis-card bg-white/10 backdrop-blur-lg rounded-xl p-6 border border-white/20">
<h3 class="text-xl font-semibold text-white mb-4 flex items-center">
<i data-feather="file-text" class="mr-2"></i>
Description
</h3>
<p class="text-gray-300">${repoData.description}</p>
</div>
` : ''}
`;
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();
}