<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>GitHub Profile Viewer</title> <style> body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f6f8fa; color: #24292e; } .container { max-width: 800px; margin: 0 auto; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0,0,0,0.1); } .header { display: flex; align-items: center; margin-bottom: 20px; } .avatar { width: 100px; height: 100px; border-radius: 50%; margin-right: 20px; } .name { font-size: 24px; font-weight: bold; } .bio { margin: 10px 0; } .stats { display: flex; gap: 20px; margin: 20px 0; } .stat { font-weight: bold; } .activity { margin-top: 30px; } .event { border-bottom: 1px solid #e1e4e8; padding: 10px 0; } .event:last-child { border-bottom: none; } .error { color: red; font-weight: bold; } </style> </head> <body> <div class="container"> <div class="header"> <img id="avatar" class="avatar" src="" alt="Avatar"> <div> <h1 id="name" class="name"></h1> <p id="login"></p> </div> </div> <p id="bio" class="bio"></p> <p id="location"></p> <p id="blog"></p> <div class="stats"> <span class="stat">Followers: <span id="followers"></span></span> <span class="stat">Following: <span id="following"></span></span> <span class="stat">Public Repos: <span id="repos"></span></span> <span class="stat">Public Gists: <span id="gists"></span></span> </div> <h2>Recent Activity</h2> <div id="activity" class="activity"></div> <p id="error" class="error"></p> </div> <script> async function loadProfile() { const params = new URLSearchParams(window.location.search); const userId = params.get('id') || 'torvalds'; try { const userResponse = await fetch(`https://api.github.com/users/${userId}`); if (!userResponse.ok) throw new Error('User not found'); const user = await userResponse.json(); document.getElementById('avatar').src = user.avatar_url; document.getElementById('name').textContent = user.name || user.login; document.getElementById('login').textContent = `@${user.login}`; document.getElementById('bio').textContent = user.bio || ''; document.getElementById('location').textContent = user.location ? `Location: ${user.location}` : ''; document.getElementById('blog').textContent = user.blog ? `Website: ${user.blog}` : ''; document.getElementById('followers').textContent = user.followers; document.getElementById('following').textContent = user.following; document.getElementById('repos').textContent = user.public_repos; document.getElementById('gists').textContent = user.public_gists; const eventsResponse = await fetch(`https://api.github.com/users/${userId}/events`); const events = await eventsResponse.json(); const activityDiv = document.getElementById('activity'); activityDiv.innerHTML = ''; events.slice(0, 10).forEach(event => { const eventDiv = document.createElement('div'); eventDiv.className = 'event'; let description = ''; switch (event.type) { case 'PushEvent': description = `Pushed ${event.payload.commits.length} commits to ${event.repo.name}`; break; case 'PullRequestEvent': description = `${event.payload.action.charAt(0).toUpperCase() + event.payload.action.slice(1)} pull request #${event.payload.pull_request.number} in ${event.repo.name}`; break; case 'IssuesEvent': description = `${event.payload.action.charAt(0).toUpperCase() + event.payload.action.slice(1)} issue #${event.payload.issue.number} in ${event.repo.name}`; break; case 'CreateEvent': description = `Created ${event.payload.ref_type} ${event.payload.ref || ''} in ${event.repo.name}`; break; default: description = `${event.type} in ${event.repo.name}`; } eventDiv.textContent = `${new Date(event.created_at).toLocaleString()}: ${description}`; activityDiv.appendChild(eventDiv); }); } catch (error) { document.getElementById('error').textContent = error.message; } } window.onload = loadProfile; </script> </body> </html>