Skip to content

Commit 2905cd0

Browse files
feat: aprimorar exibição de contribuidores com badges e contagem de contribuições de issues
1 parent de0dc1b commit 2905cd0

File tree

2 files changed

+215
-37
lines changed

2 files changed

+215
-37
lines changed

docs/index.html

Lines changed: 104 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -805,19 +805,38 @@
805805
transition: all 0.3s;
806806
}
807807

808+
.contributor a {
809+
position: relative;
810+
display: inline-block;
811+
}
812+
813+
.contributor-badge {
814+
position: absolute;
815+
bottom: 0;
816+
right: 0;
817+
font-size: 1rem;
818+
background: var(--bg-dark);
819+
border-radius: 50%;
820+
padding: 3px;
821+
line-height: 1;
822+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
823+
}
824+
808825
.contributor:hover img {
809826
border-color: var(--gold-light);
810827
box-shadow: 0 6px 25px rgba(201, 162, 39, 0.5);
811828
}
812829

813-
.contributor span {
830+
.contributor > span,
831+
.contributor span:not(.contributor-badge) {
814832
margin-top: 0.5rem;
815833
font-size: 0.8rem;
816834
color: var(--text-secondary);
817835
font-weight: 500;
836+
display: block;
818837
}
819838

820-
.contributor:hover span {
839+
.contributor:hover > span {
821840
color: var(--gold-primary);
822841
}
823842

@@ -2391,33 +2410,103 @@ <h4>Comunidade</h4>
23912410
}
23922411
}
23932412

2394-
// Load Contributors
2413+
// Load Contributors (repo contributors + issue authors)
23952414
async function loadContributors() {
23962415
const orbit = document.getElementById('contributors-orbit');
23972416
if (!orbit) return;
23982417

23992418
try {
2400-
const response = await fetch('https://api.github.com/repos/rodrigomiquilino/wwm_brasileiro/contributors?per_page=10');
2401-
if (!response.ok) throw new Error('Failed to fetch');
2419+
// Buscar em paralelo: contributors do repo + autores de issues aprovadas
2420+
const [contributorsResp, issuesResp] = await Promise.all([
2421+
fetch('https://api.github.com/repos/rodrigomiquilino/wwm_brasileiro/contributors?per_page=15'),
2422+
fetch('https://api.github.com/repos/rodrigomiquilino/wwm_brasileiro/issues?state=closed&labels=applied&per_page=50')
2423+
]);
24022424

2403-
const contributors = await response.json();
2404-
const displayContributors = contributors
2425+
// Processar contributors do repo (commits)
2426+
let repoContributors = [];
2427+
if (contributorsResp.ok) {
2428+
repoContributors = await contributorsResp.json();
2429+
}
2430+
2431+
// Processar autores de issues aprovadas (traduções via site)
2432+
let issueAuthors = [];
2433+
if (issuesResp.ok) {
2434+
const issues = await issuesResp.json();
2435+
const authorCounts = {};
2436+
issues.forEach(issue => {
2437+
if (issue.user && issue.user.type === 'User') {
2438+
const login = issue.user.login;
2439+
if (!authorCounts[login]) {
2440+
authorCounts[login] = {
2441+
login: login,
2442+
avatar_url: issue.user.avatar_url,
2443+
html_url: issue.user.html_url,
2444+
contributions: 0,
2445+
source: 'issues'
2446+
};
2447+
}
2448+
try {
2449+
const jsonMatch = issue.body?.match(/"total"\s*:\s*(\d+)/);
2450+
const count = jsonMatch ? parseInt(jsonMatch[1]) : 1;
2451+
authorCounts[login].contributions += count;
2452+
} catch (e) {
2453+
authorCounts[login].contributions += 1;
2454+
}
2455+
}
2456+
});
2457+
issueAuthors = Object.values(authorCounts);
2458+
}
2459+
2460+
// Combinar e mesclar
2461+
const allContributors = new Map();
2462+
2463+
repoContributors
24052464
.filter(c => c.type === 'User')
2465+
.forEach(c => {
2466+
allContributors.set(c.login, {
2467+
login: c.login,
2468+
avatar_url: c.avatar_url,
2469+
html_url: c.html_url,
2470+
contributions: c.contributions,
2471+
source: 'commits'
2472+
});
2473+
});
2474+
2475+
issueAuthors.forEach(author => {
2476+
if (allContributors.has(author.login)) {
2477+
const existing = allContributors.get(author.login);
2478+
existing.contributions += author.contributions;
2479+
existing.source = 'both';
2480+
} else {
2481+
allContributors.set(author.login, author);
2482+
}
2483+
});
2484+
2485+
const displayContributors = Array.from(allContributors.values())
2486+
.sort((a, b) => b.contributions - a.contributions)
24062487
.slice(0, 7);
24072488

24082489
if (displayContributors.length === 0) {
24092490
orbit.innerHTML = '<div class="no-contributors">Seja o primeiro a contribuir!</div>';
24102491
return;
24112492
}
24122493

2413-
orbit.innerHTML = displayContributors.map((contributor, index) => `
2414-
<div class="contributor" style="animation-delay: ${index * 0.4}s;">
2415-
<a href="${contributor.html_url}" target="_blank" rel="noopener" title="${contributor.login} - ${contributor.contributions} contribuições">
2416-
<img src="${contributor.avatar_url}" alt="${contributor.login}" loading="lazy">
2417-
</a>
2418-
<span>@${contributor.login}</span>
2419-
</div>
2420-
`).join('');
2494+
orbit.innerHTML = displayContributors.map((contributor, index) => {
2495+
const badgeIcon = contributor.source === 'issues' ? '💬' :
2496+
contributor.source === 'both' ? '⭐' : '💻';
2497+
const badgeTitle = contributor.source === 'issues' ? 'Tradutor via site' :
2498+
contributor.source === 'both' ? 'Tradutor + Desenvolvedor' : 'Desenvolvedor';
2499+
2500+
return `
2501+
<div class="contributor" style="animation-delay: ${index * 0.4}s;">
2502+
<a href="${contributor.html_url}" target="_blank" rel="noopener" title="${contributor.login} - ${contributor.contributions} contribuições (${badgeTitle})">
2503+
<img src="${contributor.avatar_url}" alt="${contributor.login}" loading="lazy">
2504+
<span class="contributor-badge" title="${badgeTitle}">${badgeIcon}</span>
2505+
</a>
2506+
<span>@${contributor.login}</span>
2507+
</div>
2508+
`;
2509+
}).join('');
24212510

24222511
} catch (error) {
24232512
console.error('Error loading contributors:', error);

docs/translate.html

Lines changed: 111 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -865,10 +865,27 @@
865865
background: var(--bg-dark);
866866
}
867867

868-
.contributor span {
868+
.contributor a {
869+
position: relative;
870+
display: inline-block;
871+
}
872+
873+
.contributor-badge {
874+
position: absolute;
875+
bottom: -2px;
876+
right: -2px;
877+
font-size: 0.8rem;
878+
background: var(--bg-dark);
879+
border-radius: 50%;
880+
padding: 2px;
881+
line-height: 1;
882+
}
883+
884+
.contributor span:not(.contributor-badge) {
869885
margin-top: 0.3rem;
870886
font-size: 0.75rem;
871887
color: var(--text-secondary);
888+
display: block;
872889
}
873890

874891
@keyframes float {
@@ -2464,44 +2481,116 @@ <h4><i class="fas fa-clipboard-list"></i> Sugestões (<span id="cart-count">0</s
24642481
document.getElementById('table-scroll').scrollTop = 0;
24652482
}
24662483

2467-
// Load contributors from GitHub
2484+
// Load contributors from GitHub + Issue authors
24682485
async function loadContributors() {
2486+
const orbit = document.getElementById('contributors-orbit');
2487+
if (!orbit) return;
2488+
24692489
try {
2470-
// Get contributors who have PRs merged (simplified - using repo contributors)
2471-
const response = await fetch(`https://api.github.com/repos/${CONFIG.GITHUB_REPO}/contributors?per_page=10`);
2472-
if (!response.ok) throw new Error('Failed to fetch contributors');
2490+
// Buscar em paralelo: contributors do repo + autores de issues aprovadas
2491+
const [contributorsResp, issuesResp] = await Promise.all([
2492+
fetch(`https://api.github.com/repos/${CONFIG.GITHUB_REPO}/contributors?per_page=15`),
2493+
fetch(`https://api.github.com/repos/${CONFIG.GITHUB_OWNER}/${CONFIG.GITHUB_REPO_NAME}/issues?state=closed&labels=applied&per_page=50`)
2494+
]);
24732495

2474-
const contributors = await response.json();
2475-
const orbit = document.getElementById('contributors-orbit');
2496+
// Processar contributors do repo (commits)
2497+
let repoContributors = [];
2498+
if (contributorsResp.ok) {
2499+
repoContributors = await contributorsResp.json();
2500+
}
24762501

2477-
if (contributors.length === 0) {
2478-
orbit.innerHTML = '<div class="no-contributors">Seja o primeiro a contribuir!</div>';
2479-
return;
2502+
// Processar autores de issues aprovadas (traduções via site)
2503+
let issueAuthors = [];
2504+
if (issuesResp.ok) {
2505+
const issues = await issuesResp.json();
2506+
// Contar contribuições por autor
2507+
const authorCounts = {};
2508+
issues.forEach(issue => {
2509+
if (issue.user && issue.user.type === 'User') {
2510+
const login = issue.user.login;
2511+
if (!authorCounts[login]) {
2512+
authorCounts[login] = {
2513+
login: login,
2514+
avatar_url: issue.user.avatar_url,
2515+
html_url: issue.user.html_url,
2516+
contributions: 0,
2517+
type: 'User',
2518+
source: 'issues'
2519+
};
2520+
}
2521+
// Contar sugestões dentro da issue
2522+
try {
2523+
const jsonMatch = issue.body?.match(/"total"\s*:\s*(\d+)/);
2524+
const count = jsonMatch ? parseInt(jsonMatch[1]) : 1;
2525+
authorCounts[login].contributions += count;
2526+
} catch (e) {
2527+
authorCounts[login].contributions += 1;
2528+
}
2529+
}
2530+
});
2531+
issueAuthors = Object.values(authorCounts);
24802532
}
24812533

2482-
// Filter to show only non-bot contributors (except the owner which should show)
2483-
const displayContributors = contributors
2534+
// Combinar e mesclar (evitar duplicatas)
2535+
const allContributors = new Map();
2536+
2537+
// Primeiro, adicionar contributors do repo
2538+
repoContributors
24842539
.filter(c => c.type === 'User')
2540+
.forEach(c => {
2541+
allContributors.set(c.login, {
2542+
login: c.login,
2543+
avatar_url: c.avatar_url,
2544+
html_url: c.html_url,
2545+
contributions: c.contributions,
2546+
source: 'commits'
2547+
});
2548+
});
2549+
2550+
// Depois, adicionar/mesclar autores de issues
2551+
issueAuthors.forEach(author => {
2552+
if (allContributors.has(author.login)) {
2553+
// Já existe - somar contribuições
2554+
const existing = allContributors.get(author.login);
2555+
existing.contributions += author.contributions;
2556+
existing.source = 'both';
2557+
} else {
2558+
// Novo contributor via issues
2559+
allContributors.set(author.login, author);
2560+
}
2561+
});
2562+
2563+
// Ordenar por contribuições e pegar top 8
2564+
const displayContributors = Array.from(allContributors.values())
2565+
.sort((a, b) => b.contributions - a.contributions)
24852566
.slice(0, 8);
24862567

24872568
if (displayContributors.length === 0) {
24882569
orbit.innerHTML = '<div class="no-contributors">Seja o primeiro a contribuir!</div>';
24892570
return;
24902571
}
24912572

2492-
orbit.innerHTML = displayContributors.map((contributor, index) => `
2493-
<div class="contributor" style="animation-delay: ${index * 0.3}s; left: ${10 + (index * 12)}%; top: ${15 + Math.sin(index) * 25}%;">
2494-
<a href="${contributor.html_url}" target="_blank" rel="noopener" title="${contributor.login}">
2495-
<img src="${contributor.avatar_url}" alt="${contributor.login}">
2496-
</a>
2497-
<span>@${contributor.login}</span>
2498-
</div>
2499-
`).join('');
2573+
orbit.innerHTML = displayContributors.map((contributor, index) => {
2574+
// Ícone baseado no tipo de contribuição
2575+
const badgeIcon = contributor.source === 'issues' ? '💬' :
2576+
contributor.source === 'both' ? '⭐' : '💻';
2577+
const badgeTitle = contributor.source === 'issues' ? 'Tradutor via site' :
2578+
contributor.source === 'both' ? 'Tradutor + Desenvolvedor' : 'Desenvolvedor';
2579+
2580+
return `
2581+
<div class="contributor" style="animation-delay: ${index * 0.3}s; left: ${10 + (index * 12)}%; top: ${15 + Math.sin(index) * 25}%;">
2582+
<a href="${contributor.html_url}" target="_blank" rel="noopener" title="${contributor.login} - ${contributor.contributions} contribuições (${badgeTitle})">
2583+
<img src="${contributor.avatar_url}" alt="${contributor.login}">
2584+
<span class="contributor-badge" title="${badgeTitle}">${badgeIcon}</span>
2585+
</a>
2586+
<span>@${contributor.login}</span>
2587+
</div>
2588+
`;
2589+
}).join('');
25002590

25012591
} catch (error) {
25022592
console.error('Error loading contributors:', error);
2503-
document.getElementById('contributors-orbit').innerHTML =
2504-
'<div class="no-contributors">Seja o primeiro a contribuir!</div>';
2593+
orbit.innerHTML = '<div class="no-contributors">Seja o primeiro a contribuir!</div>';
25052594
}
25062595
}
25072596

0 commit comments

Comments
 (0)