Skip to content

Commit a8db9c4

Browse files
feat: Load and display featured projects from GitHub API
1 parent a7a684b commit a8db9c4

2 files changed

Lines changed: 82 additions & 68 deletions

File tree

index.html

Lines changed: 1 addition & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -57,74 +57,7 @@ <h2>Software</h2>
5757
<div class="section-title">
5858
<h2>Featured Projects</h2>
5959
</div>
60-
<div class="grid grid-3">
61-
<div class="card">
62-
<span class="card-icon">🤖</span>
63-
<h3>brofs</h3>
64-
<p class="card-description">The Bro File System CLI</p>
65-
<p class="card-detail">A minimalist file system CLI for developers. Super fast, clean, and open-source.
66-
</p>
67-
<a href="https://github.com/webbro-software/brofs" target="_blank" rel="noopener noreferrer"
68-
class="card-link">
69-
<span class="icon-github"></span>
70-
<span>View Project</span>
71-
<span class="icon-external"></span>
72-
</a>
73-
</div>
74-
75-
<div class="card">
76-
<span class="card-icon">🎨</span>
77-
<h3>uzcss</h3>
78-
<p class="card-description">Uzbek-to-CSS Compiler</p>
79-
<p class="card-detail">Write your styles in Uzbek! A unique compiler translating Uzbek syntax to valid
80-
CSS.</p>
81-
<a href="https://github.com/webbro-software/uzcss" target="_blank" rel="noopener noreferrer"
82-
class="card-link">
83-
<span class="icon-github"></span>
84-
<span>View Project</span>
85-
<span class="icon-external"></span>
86-
</a>
87-
</div>
88-
89-
<div class="card">
90-
<span class="card-icon">🧠</span>
91-
<h3>brainfuck-interpreter</h3>
92-
<p class="card-description">Interpreter for Brainfuck language in C#</p>
93-
<p class="card-detail">For minimalism lovers and low-level explorers.</p>
94-
<a href="https://github.com/webbro-software/brainfuck-interpreter" target="_blank"
95-
rel="noopener noreferrer" class="card-link">
96-
<span class="icon-github"></span>
97-
<span>View Project</span>
98-
<span class="icon-external"></span>
99-
</a>
100-
</div>
101-
102-
<div class="card">
103-
<span class="card-icon">🔊</span>
104-
<h3>easy_speak</h3>
105-
<p class="card-description">Powerful text-to-speech conversion for Python</p>
106-
<p class="card-detail">Simple yet powerful TTS for Python apps.</p>
107-
<a href="https://github.com/webbro-software/easy_speak" target="_blank" rel="noopener noreferrer"
108-
class="card-link">
109-
<span class="icon-github"></span>
110-
<span>View Project</span>
111-
<span class="icon-external"></span>
112-
</a>
113-
</div>
114-
115-
<div class="card">
116-
<span class="card-icon">🎮</span>
117-
<h3>kill-the-monsters-3d</h3>
118-
<p class="card-description">A 3D monster-killing desktop game built with Python</p>
119-
<p class="card-detail">Action-packed 3D gaming experience.</p>
120-
<a href="https://github.com/webbro-software/kill-the-monsters-3d" target="_blank"
121-
rel="noopener noreferrer" class="card-link">
122-
<span class="icon-github"></span>
123-
<span>View Project</span>
124-
<span class="icon-external"></span>
125-
</a>
126-
</div>
127-
</div>
60+
<div class="grid grid-3" id="featured-projects"></div>
12861
</section>
12962

13063
<section class="section section-gray">

script.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,84 @@ const observer = new IntersectionObserver(function (entries) {
3636
document.querySelectorAll(".card").forEach((card) => {
3737
observer.observe(card);
3838
});
39+
40+
async function loadFeaturedProjects() {
41+
const grid = document.getElementById("featured-projects");
42+
if (!grid) return;
43+
44+
try {
45+
const res = await fetch(
46+
"https://api.github.com/orgs/webbro-software/repos?per_page=100&type=public&sort=updated"
47+
);
48+
let repos = await res.json();
49+
50+
const blacklist = [
51+
".github",
52+
"infra",
53+
"infrastructure",
54+
"docs",
55+
"website",
56+
"webbro-software.github.io",
57+
];
58+
repos = repos.filter(
59+
(repo) =>
60+
!repo.private &&
61+
!repo.archived &&
62+
!blacklist.includes(repo.name.toLowerCase()) &&
63+
!repo.name.startsWith(".")
64+
);
65+
66+
if (repos.length === 0) {
67+
grid.innerHTML = "<p>No public projects to show.</p>";
68+
return;
69+
}
70+
71+
function getProjectEmoji(repo) {
72+
const name = repo.name.toLowerCase();
73+
const desc = (repo.description || "").toLowerCase();
74+
75+
if (name.includes("vim") || name.includes("editor")) return "📝";
76+
if (name.includes("game") || name.includes("fun")) return "🎮";
77+
if (name.includes("style") || name.includes("css")) return "🎨";
78+
if (name.includes("console") || name.includes("logger")) return "🖥️";
79+
if (
80+
name.includes("calc") ||
81+
name.includes("math") ||
82+
name.includes("gcd")
83+
)
84+
return "➗";
85+
if (name.includes("voice") || name.includes("speech")) return "🎤";
86+
if (name.includes("translate") || name.includes("lang")) return "🌐";
87+
if (name.includes("infra") || name.includes("deploy")) return "🛠️";
88+
if (name.includes("art") || name.includes("sketch")) return "✏️";
89+
if (name.includes("python")) return "🐍";
90+
if (name.includes("js") || name.includes("javascript")) return "📜";
91+
if (name.includes("vscode") || name.includes("extension")) return "🧩";
92+
if (desc.includes("utility") || desc.includes("tool")) return "🧰";
93+
return "🌟";
94+
}
95+
96+
grid.innerHTML = repos
97+
.map(
98+
(repo) => `
99+
<div class="card">
100+
<span class="card-icon">${getProjectEmoji(repo)}</span>
101+
<h3>${repo.name}</h3>
102+
<p class="card-description">${repo.description || "No description"}</p>
103+
<a href="${
104+
repo.html_url
105+
}" target="_blank" rel="noopener noreferrer" class="card-link">
106+
<span class="icon-github"></span>
107+
<span>View Project</span>
108+
<span class="icon-external"></span>
109+
</a>
110+
</div>
111+
`
112+
)
113+
.join("");
114+
} catch (e) {
115+
grid.innerHTML = "<p>Failed to load projects from GitHub.</p>";
116+
}
117+
}
118+
119+
window.addEventListener("DOMContentLoaded", loadFeaturedProjects);

0 commit comments

Comments
 (0)