Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions website/templates/bounties_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,147 @@ <h2 class="text-xl font-semibold text-gray-800">Manage Bounty Payouts</h2>
View Payouts
</a>
</div>
<!-- Statistics Section -->
<div class="w-[97%] mt-6">
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
<!-- Total $5 Issues -->
<div class="bg-white p-6 rounded-lg shadow-md border-l-4 border-[#e74c3c]">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-600 text-sm font-medium">Total $5 Issues</p>
<p class="text-3xl font-bold text-gray-900 mt-2">{{ total_issues_count|default:0 }}</p>
</div>
<div class="bg-[#e74c3c] bg-opacity-10 p-3 rounded-full">
<svg class="w-8 h-8 text-[#e74c3c]"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z">
</path>
</svg>
</div>
</div>
<p class="text-sm text-gray-500 mt-2">Closed issues with $5 bounty</p>
</div>
<!-- Paid Issues Count -->
<div class="bg-white p-6 rounded-lg shadow-md border-l-4 border-green-500">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-600 text-sm font-medium">Paid Issues</p>
<p class="text-3xl font-bold text-gray-900 mt-2">{{ paid_count|default:0 }}</p>
</div>
<div class="bg-green-500 bg-opacity-10 p-3 rounded-full">
<svg class="w-8 h-8 text-green-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z">
</path>
</svg>
</div>
</div>
<p class="text-sm text-gray-500 mt-2">Successfully processed payments</p>
</div>
<!-- Grand Total Payouts -->
<div class="bg-white p-6 rounded-lg shadow-md border-l-4 border-blue-500">
<div class="flex items-center justify-between">
<div>
<p class="text-gray-600 text-sm font-medium">Total Payouts</p>
<p class="text-3xl font-bold text-gray-900 mt-2">${{ grand_total_payouts|default:0 }}</p>
</div>
<div class="bg-blue-500 bg-opacity-10 p-3 rounded-full">
<svg class="w-8 h-8 text-blue-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z">
</path>
</svg>
</div>
</div>
<p class="text-sm text-gray-500 mt-2">Total amount distributed</p>
</div>
</div>
<!-- Leaderboard Section -->
{% if leaderboard %}
<div class="bg-white p-6 rounded-lg shadow-md">
<div class="flex items-center justify-between mb-6">
<h2 class="text-2xl font-bold text-gray-800 flex items-center">
<svg class="w-6 h-6 text-[#e74c3c] mr-2"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z">
</path>
</svg>
Top Earners Leaderboard
</h2>
<span class="text-sm text-gray-500">Top 10 contributors</span>
</div>
<div class="overflow-x-auto">
<table class="min-w-full">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Rank
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Contributor
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Issues Completed
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Total Earned
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
{% for earner in leaderboard %}
<tr class="hover:bg-gray-50">
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
{% if forloop.counter <= 3 %}
<span class="text-2xl font-bold {% if forloop.counter == 1 %}text-yellow-500{% elif forloop.counter == 2 %}text-gray-400{% else %}text-orange-600{% endif %}">
#{{ forloop.counter }}
</span>
{% else %}
<span class="text-lg font-semibold text-gray-600">#{{ forloop.counter }}</span>
{% endif %}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<img src="{{ earner.avatar_url }}"
alt="{{ earner.name }}"
class="w-10 h-10 rounded-full mr-3">
<a href="{{ earner.github_url }}"
target="_blank"
class="text-sm font-medium text-blue-600 hover:text-[#e74c3c]">
{{ earner.name }}
</a>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-3 py-1 inline-flex text-sm leading-5 font-semibold rounded-full bg-green-100 text-green-800">
{{ earner.issues_completed }}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="text-lg font-bold text-[#e74c3c]">${{ earner.total_earned }}</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endif %}
</div>
<div class="w-[97%] p-5 mt-4 rounded-lg bg-white shadow-md">
<form action="#" method="get">
<div class="relative flex justify-between">
Expand Down
35 changes: 35 additions & 0 deletions website/views/organization.py
Original file line number Diff line number Diff line change
Expand Up @@ -503,12 +503,47 @@ def get(self, request, *args, **kwargs):
logger.error(f"Error fetching GitHub issues: {str(e)}")
github_issues = []

# Calculate bounty statistics
BOUNTY_AMOUNT = 5 # Dollar amount per bounty issue
dollar5_issues = GitHubIssue.objects.filter(has_dollar_tag=True, state="closed")
total_issues_count = dollar5_issues.count()
paid_issues = dollar5_issues.filter(Q(sponsors_tx_id__isnull=False) | Q(bch_tx_id__isnull=False))
paid_count = paid_issues.count()
grand_total_payouts = paid_count * BOUNTY_AMOUNT

# Build leaderboard of top earners
# Group by assignee and count their paid issues
top_earners = (
paid_issues.filter(assignee__isnull=False)
.select_related("assignee")
.values("assignee__name", "assignee__github_url", "assignee__avatar_url")
.annotate(issues_completed=Count("id"))
.order_by("-issues_completed")[:10] # Top 10 earners
)

# Calculate earnings for each top earner
leaderboard = []
for earner in top_earners:
leaderboard.append(
{
"name": earner["assignee__name"],
"github_url": earner["assignee__github_url"],
"avatar_url": earner["assignee__avatar_url"],
"issues_completed": earner["issues_completed"],
"total_earned": earner["issues_completed"] * BOUNTY_AMOUNT,
}
)

context = {
"hunts": hunts,
"domains": Domain.objects.values("id", "name").all(),
"github_issues": github_issues,
"current_page": 1,
"selected_issue_state": issue_state,
"total_issues_count": total_issues_count,
"paid_count": paid_count,
"grand_total_payouts": grand_total_payouts,
"leaderboard": leaderboard,
}

return render(request, self.template_name, context)
Expand Down