-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 52d1f1d
Showing
6 changed files
with
345 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Auto detect text files and perform LF normalization | ||
* text=auto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"liveServer.settings.port": 8081 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# githubportfoliosite | ||
A quick site to make viewing and filtering repos nicer. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Kris Crawford - GitHub</title> | ||
<link rel="stylesheet" href="styles.css"> | ||
<script src="https://apis.google.com/js/api.js"></script> | ||
</head> | ||
<body> | ||
<header> | ||
<h1 id="header-title">Kris Crawford</h1> | ||
<h2 id="header-subtitle">GitHub Repositories</h2> | ||
</header> | ||
|
||
<div id="tags-container"> | ||
</div> | ||
|
||
<div id="repos-container"></div> | ||
<div id="youtube-container"></div> | ||
|
||
<script src="script.js"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
|
||
const username = 'krismakesstuff'; | ||
const reposContainer = document.getElementById('repos-container'); | ||
const youtubeContainer = document.getElementById('youtube-container'); | ||
const tagsContainer = document.getElementById('tags-container'); | ||
// const youtubeApiKey = 'YOUR_YOUTUBE_API_KEY'; | ||
// const youtubeChannelId = 'UCkrismakesmusic7901'; | ||
|
||
var languages = {}; | ||
// remove any repeated language tags | ||
var languageTags =[]; | ||
|
||
async function fetchRepos() { | ||
const response = await fetch(`https://api.github.com/users/${username}/repos`); | ||
let repos = await response.json(); | ||
|
||
// Sort by updated date | ||
repos = repos.sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at)); | ||
|
||
// fetch readme also displays the repo | ||
repos.forEach(repo => fetchReadme(repo)); | ||
|
||
} | ||
|
||
|
||
async function fetchReadme(repo) { | ||
|
||
const branch = repo.default_branch; | ||
const readme = repo.html_url + '/blob/' + branch +'/README.md'; | ||
|
||
// fecth languages | ||
const response = await fetch(repo.languages_url); | ||
languages = await response.json(); | ||
console.log('Languages:', languages); | ||
|
||
// show repos | ||
displayRepo(repo, readme, languages); | ||
|
||
let tags = []; | ||
// add languages to languageTags | ||
for (const language in languages) { | ||
tags.push(language); | ||
} | ||
|
||
languageTags = [...new Set(tags)]; | ||
|
||
console.log('Language Tags:', languageTags); | ||
|
||
// show language tags | ||
showLanguageTags(languageTags); | ||
} | ||
|
||
|
||
|
||
function displayRepo(repo, readmeURL) { | ||
const repoDiv = document.createElement('div'); | ||
repoDiv.className = 'repo'; | ||
// convert updated and created dates to Date objects | ||
let updated = new Date(repo.updated_at); | ||
let created = new Date(repo.created_at); | ||
let languageString = ''; | ||
|
||
// calculate the total number of bytes of code | ||
let languageCount = 0; | ||
for (const language in languages) { | ||
languageCount += languages[language]; | ||
} | ||
|
||
// calculate the percentage of code in each language | ||
for (const language in languages) { | ||
languageString += language + ':' + (languages[language]/languageCount).toFixed(0) * 100 + '% '; | ||
} | ||
|
||
// add the repo to the page | ||
repoDiv.innerHTML = ` | ||
<h2><a href="${repo.html_url}" target="_blank">${repo.name}</a></h2> | ||
<h3>${repo.description || ''}</h3> | ||
<p><strong>Language:</strong> ${languageString}</p> | ||
<p><strong>Updated:</strong> ${updated.toDateString()}</p> | ||
<p><strong>Created:</strong> ${created.toLocaleDateString()}</p> | ||
<br> | ||
<a href="${readmeURL}" target="_blank">Readme.md</a> | ||
`; | ||
|
||
// add div to the page | ||
reposContainer.appendChild(repoDiv); | ||
} | ||
|
||
function showLanguageTags(languageTags) { | ||
// make a grid of buttons for each language in languages | ||
console.log('languageTags:', languageTags); | ||
|
||
const languageTagsArray = languageTags.entries(); | ||
|
||
for (const language of languageTags) { | ||
|
||
// check if the language is already in the tagsContainer | ||
// if it is, skip it | ||
if (tagsContainer.innerHTML.includes(language)) { | ||
continue; | ||
} | ||
|
||
let languageButton = document.createElement('button'); | ||
languageButton.className = 'language-tag'; | ||
languageButton.innerHTML = language; | ||
|
||
|
||
|
||
|
||
|
||
languageButton.addEventListener('click', () => { | ||
// use button state to highlight repos with the selected language | ||
// buttons should be toggled on and off and change the border color of the repos as well as the button color | ||
if (languageButton.style.backgroundColor === 'red') { | ||
languageButton.style.backgroundColor = 'var(--light-blue)'; | ||
//removeLanguageHighlights(language); | ||
unclickButton(language); | ||
} | ||
else { | ||
languageButton.style.backgroundColor = 'red'; | ||
highlightRepos(language); | ||
} | ||
|
||
|
||
console.log('Clicked:', language); | ||
}); | ||
console.log("made button"); | ||
tagsContainer.appendChild(languageButton); | ||
} | ||
|
||
} | ||
|
||
function highlightRepos(language) { | ||
// highlight repos with the selected language | ||
const repos = document.getElementsByClassName('repo'); | ||
for (const repo of repos) { | ||
const languageString = repo.querySelector('p').innerText; | ||
if (languageString.includes(language)) { | ||
// set custom css variable | ||
|
||
|
||
} else { | ||
repo.style.border = '1px solid var(--light-blue);'; | ||
} | ||
} | ||
} | ||
|
||
function removeLanguageHighlights(language) { | ||
// remove highlights from repos with the selected language | ||
const repos = document.getElementsByClassName('repo'); | ||
for (const repo of repos) { | ||
const languageString = repo.querySelector('p').innerText; | ||
if (languageString.includes(language)) { | ||
repo.style.border = '1px solid var(--light-blue);'; | ||
|
||
} | ||
} | ||
} | ||
|
||
function unclickButton(language) { | ||
// unclick the button | ||
const buttons = document.getElementsByClassName('language-tag'); | ||
for (const button of buttons) { | ||
if (button.innerHTML === language) { | ||
button.style.backgroundColor = 'var(--light-blue)'; | ||
} | ||
} | ||
} | ||
|
||
async function fetchYouTubeVideos() { | ||
const response = await fetch(`https://www.googleapis.com/youtube/v3/search?key=${youtubeApiKey}&channelId=${youtubeChannelId}&part=snippet,id&order=date&maxResults=10`); | ||
const data = await response.json(); | ||
console.log('YouTube Data:', data); | ||
data.items.forEach(video => displayVideo(video)); | ||
} | ||
|
||
function displayVideo(video) { | ||
const videoDiv = document.createElement('div'); | ||
videoDiv.className = 'video'; | ||
videoDiv.innerHTML = ` | ||
<h2>${video.snippet.title}</h2> | ||
<img src="${video.snippet.thumbnails.medium.url}" alt="${video.snippet.title}"> | ||
<p><a href="https://www.youtube.com/watch?v=${video.id.videoId}" target="_blank">Watch on YouTube</a></p> | ||
`; | ||
youtubeContainer.appendChild(videoDiv); | ||
} | ||
|
||
|
||
|
||
try { | ||
|
||
// on successful fetch | ||
fetchRepos() | ||
|
||
// I'll come back to this later | ||
//fetchYouTubeVideos(); | ||
|
||
} catch (error) { | ||
console.error('Error:', error); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* Color Palette */ | ||
:root { | ||
--dark-blue: #072638; | ||
--light-blue: #A9CCE9; | ||
--red: #FF6663; | ||
--yellow: #E0FF4F; | ||
--white: #FEFFFE; | ||
|
||
} | ||
|
||
body { | ||
font-family: monospace, sans-serif; | ||
margin: 0; | ||
padding: 0; | ||
/* background-color: var(--dark-blue); */ | ||
background: linear-gradient(to right, var(--light-blue), var(--red)); | ||
|
||
} | ||
|
||
header { | ||
padding-left: 20px; | ||
padding-right: 20px; | ||
padding-top: 30px; | ||
padding-bottom: 15px; | ||
|
||
position: static; | ||
background: linear-gradient(to right, var(--yellow), var(--dark-blue)); | ||
/* background-color: var(--light-blue); */ | ||
color: var(--dark-blue); | ||
text-align: left; | ||
|
||
display: grid; | ||
grid-template-columns: 1fr; | ||
grid-template-rows: 2.5rem 2.5rem ; | ||
align-items: center; | ||
|
||
} | ||
|
||
#header-title { | ||
/* background-color: var(--red); */ | ||
color: var(--dark-blue); | ||
padding-bottom: 15px; | ||
|
||
} | ||
|
||
#header-subtitle { | ||
color: var(--red); | ||
} | ||
|
||
#tags-container { | ||
display: flex; | ||
justify-content: center; | ||
padding: 20px; | ||
gap: 10px; | ||
grid-column: 1/3; | ||
grid-row: 2/3; | ||
} | ||
|
||
#repos-container, #youtube-container { | ||
display: flex; | ||
flex-wrap: wrap; | ||
justify-content: center; | ||
padding: 20px; | ||
} | ||
|
||
.repo, .video { | ||
background-color: var(--dark-blue); | ||
color: var(--red); | ||
border: 1px solid var(--light-blue); | ||
border-radius: 5px; | ||
margin: 10px; | ||
padding: 20px; | ||
width: 300px; | ||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); | ||
} | ||
|
||
.repo h2, .video h2 { | ||
font-size: 1.5em; | ||
margin-bottom: 10px; | ||
color: var(--yellow); | ||
} | ||
|
||
.repo h3, .video h3 { | ||
font-size: 1.2em; | ||
margin-bottom: 10px; | ||
color: var(--light-blue); | ||
|
||
} | ||
|
||
.repo p, .video p { | ||
font-size: 1em; | ||
margin-bottom: 2px; | ||
} | ||
|
||
.repo a, .video a { | ||
color: var(--yellow); | ||
text-decoration: none; | ||
} | ||
|
||
.repo a:hover, .video a:hover { | ||
text-decoration: underline; | ||
} | ||
|
||
.readme-content { | ||
background-color: var(--white); | ||
color: var(--red); | ||
padding: 10px; | ||
border-radius: 5px; | ||
overflow-y: auto; | ||
height: 200px; /* Fixed height for the README content */ | ||
} |