Skip to content
Binary file modified .gitignore
Binary file not shown.
51 changes: 51 additions & 0 deletions .new-footer-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const http = require('http');
Comment thread
khushijanadri marked this conversation as resolved.
const fs = require('fs');
const path = require('path');

const root = path.resolve(__dirname);
const types = {
'.html': 'text/html; charset=utf-8',
'.css': 'text/css; charset=utf-8',
'.js': 'application/javascript; charset=utf-8',
'.json': 'application/json; charset=utf-8',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.svg': 'image/svg+xml',
'.webmanifest': 'application/manifest+json',
'.xml': 'application/xml; charset=utf-8',
'.txt': 'text/plain; charset=utf-8',
};

http.createServer((req, res) => {
Comment thread
khushijanadri marked this conversation as resolved.
try {
const url = new URL(req.url || '/', 'http://127.0.0.1:5000');
let pathname = decodeURIComponent(url.pathname);
if (pathname === '/') pathname = '/index.html';

const file = path.resolve(root, `.${pathname}`);

// FIX: Path traversal security fix
const relative = path.relative(root, file);
if (relative.startsWith('..') || path.isAbsolute(relative)) {
res.writeHead(403);
res.end('Forbidden');
return;
}

fs.readFile(file, (err, data) => {
if (err) {
res.writeHead(404);
res.end('Not found');
return;
}

res.writeHead(200, { 'Content-Type': types[path.extname(file).toLowerCase()] || 'application/octet-stream' });
res.end(data);
});
} catch (err) {
// FIX: Prevents unhandled crashes from malformed URI component parameters
res.writeHead(400);
res.end('Bad Request: Malformed URL');
}
}).listen(5000, '127.0.0.1');
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1299,7 +1299,7 @@
<span class="material-symbols-outlined text-lg">schedule</span>
Comment thread
khushijanadri marked this conversation as resolved.
Timeline
</a>
<a href="#orgs" class="mobile-menu-link flex items-center gap-3 px-4 py-3 rounded-lg text-zinc-700 hover:bg-zinc-100 font-medium text-sm transition-colors" data-section="orgs">
<a href="index.html#orgs" class="mobile-menu-link flex items-center gap-3 px-4 py-3 rounded-lg text-zinc-700 hover:bg-zinc-100 font-medium text-sm transition-colors" data-section="orgs">
<span class="material-symbols-outlined text-lg">business</span>
Organizations
</a>
Expand Down
157 changes: 67 additions & 90 deletions src/components/footer.html
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
<footer class="w-full premium-footer pb-6 pt-12 px-6 sm:px-8">
<div class="max-w-7xl mx-auto grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-10 mb-12">
<!-- Branding Section -->
<div class="lg:col-span-2 flex flex-col gap-4">
<div class="flex items-center gap-3">
<div
class="w-10 h-10 rounded-xl bg-gradient-to-br from-primary to-primary-container flex items-center justify-center shadow-lg shadow-orange-500/20">
<span class="text-white font-extrabold text-xl font-headline">G</span>
<footer class="premium-footer" aria-labelledby="footer-brand">
<div class="footer-shell">
<div class="footer-grid">
Comment on lines +1 to +3

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟑 Minor | ⚑ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Validate div/section tag balance in footer.html
fd -a footer.html src/components --exec cat -n {}

Repository: S3DFX-CYBER/GSoC-Org-Finder-

Length of output: 9912


🏁 Script executed:

python3 - <<'PY'
from pathlib import Path
import re

path = Path("src/components/footer.html")
text = path.read_text()

# Ignore tags that are self-closing or not part of normal HTML nesting.
void = {
    "area","base","br","col","embed","hr","img","input","link","meta",
    "param","source","track","wbr"
}

stack = []
for m in re.finditer(r"<\s*(/)?\s*([a-zA-Z][\w:-]*)\b[^>]*?(\/?)\s*>", text):
    closing, tag, self_close = m.group(1), m.group(2).lower(), m.group(3)
    if tag in void or self_close:
        continue
    if closing:
        if stack and stack[-1] == tag:
            stack.pop()
        else:
            print(f"mismatch at {m.start()}: expected {stack[-1] if stack else None}, found /{tag}")
            break
    else:
        stack.append(tag)
else:
    print("open_tags_remaining:", stack)

print("doctype_present:", "<!doctype" in text.lower())
PY

Repository: S3DFX-CYBER/GSoC-Org-Finder-

Length of output: 235


🏁 Script executed:

python3 - <<'PY'
from pathlib import Path
from html.parser import HTMLParser

VOID = {"area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"}
SVG_VOID_LIKE = {"path","circle","ellipse","line","polyline","polygon","rect","stop","use","animate","animateTransform","animateMotion","feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"}

class Checker(HTMLParser):
    def __init__(self):
        super().__init__()
        self.stack = []
        self.errors = []

    def handle_starttag(self, tag, attrs):
        tag = tag.lower()
        if tag in VOID or tag in SVG_VOID_LIKE:
            return
        self.stack.append(tag)

    def handle_endtag(self, tag):
        tag = tag.lower()
        while self.stack and self.stack[-1] != tag:
            # record the first clear mismatch and stop early
            self.errors.append((self.getpos(), self.stack[-1], tag))
            return
        if self.stack and self.stack[-1] == tag:
            self.stack.pop()
        else:
            self.errors.append((self.getpos(), None, tag))

text = Path("src/components/footer.html").read_text()
p = Checker()
p.feed(text)
print("errors:", p.errors[:5])
print("remaining_stack_tail:", p.stack[-10:])
print("remaining_stack_len:", len(p.stack))
PY

Repository: S3DFX-CYBER/GSoC-Org-Finder-

Length of output: 386


Close the unbalanced Quick Links <div> src/components/footer.html:22-121 β€” the Quick Links block is opened at line 22 but never closed before </footer>, so the tag-pair warning is real here. The doctype-first hint can still be ignored for this partial.

🧰 Tools
πŸͺ› HTMLHint (1.9.2)

[error] 1-1: Doctype must be declared before any non-comment content.

(doctype-first)


[error] 3-3: Tag must be paired, missing: [ ], start tag match failed [

] on line 3.

(tag-pair)

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/footer.html` around lines 1 - 3, The Quick Links section in
footer.html has an unclosed div, so the footer markup is unbalanced. Locate the
Quick Links block in the footer template and add the missing closing div before
the closing footer tag, keeping the existing structure around premium-footer,
footer-shell, and footer-grid intact. Ignore the doctype-first hint since this
is only a partial.

<section class="footer-brand-panel" aria-labelledby="footer-brand">
<a class="footer-brand" href="index.html" aria-label="FindMyGSoC home">
<span class="footer-logo" aria-hidden="true">G</span>
<span class="footer-brand-copy">
<span class="footer-eyebrow">Open source discovery</span>
<span id="footer-brand" class="footer-brand-name">FindMy<span>GSoC</span></span>
</span>
</a>
<p class="footer-description">
Discover Google Summer of Code organizations, compare project fit, and track beginner-friendly issues from one community-built dashboard.
</p>
<div class="footer-community-card">
<span class="material-symbols-outlined" aria-hidden="true">diversity_3</span>
<p>Built with contributors, mentors, and first-time open source builders in mind.</p>
</div>
<span class="text-2xl font-extrabold font-headline tracking-tight text-zinc-900 dark:text-zinc-50">FindMy<span
class="text-primary">GSoC</span></span>
</div>
<p class="text-sm text-zinc-500 dark:text-zinc-400 leading-relaxed max-w-sm">
Discover Google Summer of Code organizations, search beginner-friendly issues, and compare programs in real
time.
</p>
<p class="text-xs text-zinc-400 dark:text-zinc-500 italic max-w-sm">
Built by developers, for developers, to empower the next generation of open source contributors.
</p>
</div>
</section>

<!-- Quick Links Column -->
<div>
Expand Down Expand Up @@ -45,7 +44,6 @@ <h3 class="text-xs font-bold uppercase tracking-widest text-zinc-900 dark:text-z
<span class="material-symbols-outlined text-base">forum</span> Community
</a>
</nav>
</div>

<!-- Programs Column -->
<div>
Expand All @@ -63,82 +61,61 @@ <h3 class="text-xs font-bold uppercase tracking-widest text-zinc-900 dark:text-z
<a class="footer-link text-sm text-zinc-600 hover:text-primary dark:text-zinc-300 dark:hover:text-primary transition-all"
href="https://gssoc.girlscript.org/" target="_blank" rel="noopener noreferrer">GSSoC</a>
</nav>
</div>

<!-- Platform Stats Column -->
<div>
<h3 class="text-xs font-bold uppercase tracking-widest text-zinc-900 dark:text-zinc-100 mb-4 font-headline">
Platform Stats</h3>
<div class="flex flex-col gap-3">
<div class="footer-stat-card px-4 py-3 rounded-2xl flex items-center gap-3">
<span class="material-symbols-outlined text-primary text-xl">groups</span>
<div>
<p class="text-[10px] uppercase tracking-wider text-zinc-400 font-bold">Total Orgs</p>
<p class="font-bold text-sm text-zinc-900 dark:text-zinc-50 font-mono" id="footerOrgCount">--</p>
</div>
<section class="footer-column footer-stats" aria-labelledby="footer-stats-title">
<h2 id="footer-stats-title" class="footer-heading">Platform Stats</h2>
<div class="footer-stat-card">
<span class="material-symbols-outlined" aria-hidden="true">apartment</span>
<span>
<span class="footer-stat-label">Total orgs</span>
<strong id="footerOrgCount">--</strong>
</span>
</div>
<div class="footer-stat-card px-4 py-3 rounded-2xl flex items-center gap-3">
<span class="material-symbols-outlined text-secondary text-xl">military_tech</span>
<div>
<p class="text-[10px] uppercase tracking-wider text-zinc-400 font-bold">Veterans</p>
<p class="font-bold text-sm text-zinc-900 dark:text-zinc-50 font-mono" id="footerVeteranOrgCount">--</p>
</div>
<div class="footer-stat-card">
<span class="material-symbols-outlined" aria-hidden="true">military_tech</span>
<span>
<span class="footer-stat-label">Veterans</span>
<strong id="footerVeteranOrgCount">--</strong>
</span>
</div>
<div class="footer-stat-card px-4 py-3 rounded-2xl flex items-center gap-3">
<span class="material-symbols-outlined text-primary-container text-xl">fiber_new</span>
<div>
<p class="text-[10px] uppercase tracking-wider text-zinc-400 font-bold">Newcomers</p>
<p class="font-bold text-sm text-zinc-900 dark:text-zinc-50 font-mono" id="footerNewcomerOrgCount">--</p>
</div>
<div class="footer-stat-card">
<span class="material-symbols-outlined" aria-hidden="true">fiber_new</span>
<span>
<span class="footer-stat-label">Newcomers</span>
<strong id="footerNewcomerOrgCount">--</strong>
</span>
</div>
</div>
</section>
</div>
</div>

<!-- Bottom Divider and Legal Section -->
<div
class="max-w-7xl mx-auto pt-8 border-t border-zinc-200/50 dark:border-zinc-800/50 flex flex-col sm:flex-row justify-between items-center gap-6">
<div class="flex flex-col gap-1.5 text-center sm:text-left">
<p class="text-xs font-bold text-zinc-500 dark:text-zinc-400">
Β© 2026 S3DFX-CYBER Β· Built for the Open Source Community
</p>
<p class="text-[10px] text-zinc-400 dark:text-zinc-500 max-w-md">
FindMyGSoC is an independent open-source project and is not affiliated with Google LLC.
</p>
</div>
<div class="footer-bottom">
<div class="footer-bottom-copy">
<p class="footer-copyright">&copy; 2026 S3DFX-CYBER &middot; Built for the open source community.</p>
<p>FindMyGSoC is an independent open-source project and is not affiliated with Google LLC.</p>
</div>

<!-- Social Links and Privacy link -->
<div class="flex items-center gap-4 flex-wrap justify-center">
<a class="footer-link text-xs font-bold uppercase tracking-widest text-zinc-600 hover:text-primary dark:text-zinc-300 transition-colors mr-2"
href="privacy.html">Privacy Policy</a>
<a class="social-link github" href="https://github.com/S3DFX-CYBER/GSoC-Org-Finder-" target="_blank"
rel="noopener noreferrer" aria-label="GitHub Repository">
<svg class="w-5 h-5 fill-current" viewBox="0 0 24 24">
<path
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
</svg>
</a>
<a class="social-link discord" href="https://discord.com/invite/Kwj76sCzp" target="_blank" rel="noopener noreferrer"
aria-label="Discord Server">
<svg class="w-5 h-5 fill-current" viewBox="0 0 24 24">
<path
d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994.021-.041.001-.09-.041-.106a13.094 13.094 0 0 1-1.873-.894.077.077 0 0 1-.008-.128c.126-.093.252-.19.372-.287a.075.075 0 0 1 .077-.011c3.92 1.793 8.18 1.793 12.061 0a.073.073 0 0 1 .078.009c.12.099.246.195.373.289a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.894.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.078.078 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03a.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.156-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.156 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.156-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.156 2.418z" />
</svg>
</a>
<a class="social-link linkedin" href="https://www.linkedin.com/in/savio-d-souza-0a1810349/" target="_blank" rel="noopener noreferrer"
aria-label="LinkedIn Profile">
<svg class="w-5 h-5 fill-current" viewBox="0 0 24 24">
<path
d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.779-1.75-1.75s.784-1.75 1.75-1.75 1.75.779 1.75 1.75-.784 1.75-1.75 1.75zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z" />
</svg>
</a>
<a class="social-link twitter" href="https://x.com/S3DXVI" target="_blank" rel="noopener noreferrer"
aria-label="Twitter/X Profile">
<svg class="w-5 h-5 fill-current" viewBox="0 0 24 24">
<path
d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" />
</svg>
</a>
<nav class="footer-socials" aria-label="Social media links">
<a class="social-link github" href="https://github.com/S3DFX-CYBER/GSoC-Org-Finder-" target="_blank" rel="noopener noreferrer" aria-label="GitHub repository">
<svg aria-hidden="true" viewBox="0 0 24 24">
<path d="M12 .5C5.65.5.5 5.65.5 12c0 5.09 3.29 9.39 7.86 10.91.58.11.79-.25.79-.56v-2.14c-3.2.7-3.87-1.36-3.87-1.36-.52-1.33-1.28-1.68-1.28-1.68-1.05-.71.08-.7.08-.7 1.16.08 1.77 1.19 1.77 1.19 1.03 1.76 2.7 1.25 3.36.96.1-.75.4-1.25.73-1.54-2.55-.29-5.23-1.28-5.23-5.69 0-1.26.45-2.29 1.18-3.09-.12-.29-.51-1.47.11-3.05 0 0 .97-.31 3.17 1.18a10.9 10.9 0 0 1 5.76 0c2.2-1.49 3.16-1.18 3.16-1.18.63 1.58.24 2.76.12 3.05.74.8 1.18 1.83 1.18 3.09 0 4.42-2.69 5.4-5.25 5.68.41.35.78 1.04.78 2.1v3.18c0 .31.21.68.79.56A11.51 11.51 0 0 0 23.5 12C23.5 5.65 18.35.5 12 .5Z" />
</svg>
</a>
<a class="social-link linkedin" href="https://www.linkedin.com/in/savio-d-souza-0a1810349/" target="_blank" rel="noopener noreferrer" aria-label="LinkedIn profile">
<svg aria-hidden="true" viewBox="0 0 24 24">
<path d="M20.45 20.45h-3.56v-5.58c0-1.33-.02-3.04-1.85-3.04-1.86 0-2.14 1.45-2.14 2.95v5.67H9.34V9h3.42v1.56h.05c.48-.9 1.64-1.85 3.37-1.85 3.6 0 4.27 2.37 4.27 5.46v6.28ZM5.32 7.43a2.06 2.06 0 1 1 0-4.12 2.06 2.06 0 0 1 0 4.12Zm1.78 13.02H3.53V9H7.1v11.45ZM22.23 0H1.76C.79 0 0 .77 0 1.73v20.54C0 23.23.79 24 1.76 24h20.47c.97 0 1.77-.77 1.77-1.73V1.73C24 .77 23.2 0 22.23 0Z" />
</svg>
</a>
<a class="social-link discord" href="https://discord.gg/mgWV3xSV7" target="_blank" rel="noopener noreferrer" aria-label="Discord community">
<svg aria-hidden="true" viewBox="0 0 24 24">
<path d="M20.32 4.37a19.8 19.8 0 0 0-4.89-1.52.08.08 0 0 0-.08.04c-.21.38-.44.86-.61 1.25a18.3 18.3 0 0 0-5.48 0c-.17-.4-.41-.88-.62-1.25a.08.08 0 0 0-.08-.04c-1.7.29-3.34.8-4.89 1.52a.07.07 0 0 0-.03.03C.53 9.05-.32 13.58.1 18.06c0 .02.01.04.03.06a19.9 19.9 0 0 0 5.99 3.03.08.08 0 0 0 .09-.03c.46-.63.87-1.3 1.23-1.99.02-.04 0-.09-.04-.11-.65-.25-1.28-.55-1.87-.89a.08.08 0 0 1-.01-.13c.13-.09.25-.19.37-.29a.08.08 0 0 1 .08-.01c3.92 1.79 8.18 1.79 12.06 0a.08.08 0 0 1 .08.01c.12.1.25.2.37.29.04.03.04.1 0 .13-.6.35-1.22.64-1.87.89a.08.08 0 0 0-.04.11c.36.69.77 1.36 1.22 1.99.02.03.05.04.09.03a19.84 19.84 0 0 0 6-3.03.08.08 0 0 0 .03-.05c.5-5.18-.84-9.68-3.55-13.66a.06.06 0 0 0-.03-.04ZM8.02 15.33c-1.18 0-2.16-1.09-2.16-2.42 0-1.33.96-2.42 2.16-2.42 1.21 0 2.18 1.1 2.16 2.42 0 1.33-.96 2.42-2.16 2.42Zm7.98 0c-1.18 0-2.16-1.09-2.16-2.42 0-1.33.96-2.42 2.16-2.42 1.21 0 2.18 1.1 2.16 2.42 0 1.33-.95 2.42-2.16 2.42Z" />
</svg>
</a>
<a class="social-link twitter" href="https://x.com/S3DXVI" target="_blank" rel="noopener noreferrer" aria-label="Twitter/X profile">
<svg aria-hidden="true" viewBox="0 0 24 24">
<path d="M18.24 2.25h3.31l-7.23 8.26 8.5 11.24h-6.66l-5.21-6.82-5.97 6.82H1.67l7.73-8.84L1.25 2.25h6.82l4.72 6.23 5.45-6.23Zm-1.16 17.52h1.83L7.08 4.13H5.12l11.96 15.64Z" />
</svg>
</a>
</nav>
</div>
</div>
</footer>
</footer>
1 change: 1 addition & 0 deletions src/js/landing.js
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ function renderLiveStats() {
setText('dash-org-count', `${totalOrgs} Orgs`);
setText('footerOrgCount', String(totalOrgs));
setText('footerVeteranOrgCount', String(veteranOrgs));
setText('footerNewcomerOrgCount', String(newcomerOrgs));
Comment thread
khushijanadri marked this conversation as resolved.
}

// ── Bootstrap ─────────────────────────────────────────────────────────────────
Expand Down
Loading