Feature/badge endpoint - #158
Conversation
This component allows users to generate and copy embeddable badges for their DevGlobe stats in Markdown or HTML format.
This document provides instructions on how developers can embed a live-updating badge in their GitHub README, personal site, or blog. It includes examples in Markdown and HTML, options for customizing the badge display, and details on how the badge updates automatically.
|
@HereIsMuhammad is attempting to deploy a commit to the sajeetharan's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
@sajeetharan this is ready for review whenever you get a chance — closes #145 |
There was a problem hiding this comment.
Pull request overview
Adds a new embeddable SVG badge feature intended to let developers display live DevGlobe stats in READMEs/sites, plus supporting UI/docs/tests. The core functionality is in a new badge renderer/stat resolver and a new route handler, with a snippet UI for copy-paste embeds.
Changes:
- Introduces badge stat resolution + SVG rendering utilities (
lib/badge.js) and a badge-safe developer lookup (lib/badge-lookup.js). - Adds a route handler for serving the SVG badge and unit tests for rendering/stat behavior.
- Adds UI/CSS/docs for a “Get your badge” snippet experience and a link from the developer detail panel.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| app/badge/[login]/route.js | Adds the badge SVG route handler (currently located under /badge/...). |
| lib/badge.js | Implements supported stats, fallback behavior, and SVG rendering/escaping. |
| lib/badge-lookup.js | Fetches a badge-safe developer record from Cosmos with sample-data fallback. |
| components/BadgeSnippet.jsx | New “Get your badge” snippet UI for choosing stat + Markdown/HTML formats. |
| components/DetailPanel.jsx | Adds “Get Badge” link and a new callback hook; updates share text composition. |
| docs/prd/badge.md | Documents embedding, supported stats, and caching/fallback behavior. |
| tests/badge.test.js | Unit tests for stat resolution, SVG escaping, and auto-width behavior. |
| styles/main.css | Adds styling for the badge snippet card and includes other layout/UI adjustments. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| import { BADGE_STATS, DEFAULT_BADGE_STAT, renderBadgeSvg, resolveBadgeStat } from '../../../../lib/badge.js'; | ||
| import { getBadgeDeveloper } from '../../../../lib/badge-lookup.js'; | ||
|
|
||
| export const runtime = 'nodejs'; |
| async function getFromSampleData(login) { | ||
| const filePath = path.join(process.cwd(), 'data', 'developers-sample.json'); | ||
| const raw = await fs.readFile(filePath, 'utf-8'); | ||
| const data = JSON.parse(raw); | ||
| const developers = addDeveloperRanks(scoreAll(data)); | ||
| return developers.find(d => d.login.toLowerCase() === login.toLowerCase()) || null; | ||
| } |
| | `globalRank` (default) | `Global #4` | | ||
| | `countryRank` | `USA #2` | | ||
| | `score` | `91/100` | | ||
| | `stars` | `182.0K stars` | |
| <div className="badge-card__stats" role="tablist" aria-label="Badge stat"> | ||
| {STAT_OPTIONS.map(option => ( | ||
| <button | ||
| key={option.value} | ||
| type="button" | ||
| role="tab" | ||
| aria-selected={stat === option.value} | ||
| className={`badge-card__stat${stat === option.value ? ' badge-card__stat--active' : ''}`} |
| export default function BadgeSnippet({ login, siteUrl }) { | ||
| const [stat, setStat] = useState('globalRank'); | ||
| const [format, setFormat] = useState('markdown'); |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
@HereIsMuhammad there are some comments from copilot, can you fix if they are valid |
|
@sajeetharan |
|
@HereIsMuhammad what the difference between is get badge and generate card? it looks the same to me based on the deployed version! |
|
@sajeetharan Get Badge provides an embeddable Markdown badge specifically for GitHub profile READMEs, whereas Generate Card creates a larger visual preview meant for sharing or portfolio displays |
|
oh can you try this on deployed version and works as expected? because when i click on get badge it takes me to the same ui as card! if its the same image, can we have the get badge as parr of the generate image? somewhere after generated image! |
|
ok will push changes |
Summary
Adds an embeddable SVG badge that developers can drop into a GitHub README or personal site to show a live-updating DevGlobe stat, similar to shields.io / committers.top badges.
Closes #145
What's included
app/badge/[login]/route.js— publicGET /api/badge/[login].svgendpoint. Validates the login, validates the?stat=query param, and falls back to a grey "unranked"/"unavailable" badge instead of a broken image on any error or missing data.lib/badge.js— SVG rendering + stat resolution. SupportsglobalRank(default),countryRank,cityRank,score, andstars. Auto-sizing width based on text length, XML-escaped values.lib/badge-lookup.js— badge-safe developer lookup (only fields already public via/api/developer), backed by Cosmos DB with a fallback to bundled sample data, same pattern as/api/card.components/BadgeSnippet.jsx— "Get your badge" UI on the developer's share page: pick a stat, pick Markdown/HTML format, copy the snippet.components/DetailPanel.jsx— adds a "Get Badge ↗" link from the developer detail panel to their share page's badge section, and anonCardGeneratedcallback hook.docs/prd/badge.md— usage docs (embed snippet, available stats, caching/freshness behavior).tests/badge.test.js— coverage for stat resolution, unranked/error fallback, SVG escaping, and auto-width.Design
#1d4ed8value segment, white text on both.s-maxage=3600,stale-while-revalidate=86400) so it stays cheap on frequent README reads while staying reasonably fresh.Testing
npm test— all badge unit tests pass./api/badge/<login>.svgrenders correctly for a ranked developer, an unranked developer, and an invalid login/stat.Notes for reviewers
styles/main.cssalso includes a few pre-existing local changes unrelated to the badge feature (search bar / sidebar top offset, activity banner block, header button visibility at 768px) that were already present in my working copy — flagging in case you'd rather I split those out.